| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/shell/platform/android/image_external_texture.h" |
| |
| #include <android/hardware_buffer_jni.h> |
| #include <android/sensor.h> |
| |
| #include "flutter/fml/platform/android/jni_util.h" |
| #include "flutter/impeller/toolkit/android/proc_table.h" |
| #include "flutter/shell/platform/android/jni/platform_view_android_jni.h" |
| |
| namespace flutter { |
| |
| ImageExternalTexture::ImageExternalTexture( |
| int64_t id, |
| const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry, |
| const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade) |
| : Texture(id), |
| image_texture_entry_(image_texture_entry), |
| jni_facade_(jni_facade) {} |
| |
| // Implementing flutter::Texture. |
| void ImageExternalTexture::Paint(PaintContext& context, |
| const SkRect& bounds, |
| bool freeze, |
| const DlImageSampling sampling) { |
| if (state_ == AttachmentState::kDetached) { |
| return; |
| } |
| Attach(context); |
| const bool should_process_frame = !freeze; |
| if (should_process_frame) { |
| ProcessFrame(context, bounds); |
| } |
| if (dl_image_) { |
| context.canvas->DrawImageRect( |
| dl_image_, // image |
| SkRect::Make(dl_image_->bounds()), // source rect |
| bounds, // destination rect |
| sampling, // sampling |
| context.paint, // paint |
| flutter::DlCanvas::SrcRectConstraint::kStrict // enforce edges |
| ); |
| } else { |
| FML_LOG(INFO) << "No DlImage available for ImageExternalTexture to paint."; |
| } |
| } |
| |
| // Implementing flutter::Texture. |
| void ImageExternalTexture::MarkNewFrameAvailable() { |
| // NOOP. |
| } |
| |
| // Implementing flutter::Texture. |
| void ImageExternalTexture::OnTextureUnregistered() {} |
| |
| // Implementing flutter::ContextListener. |
| void ImageExternalTexture::OnGrContextCreated() { |
| state_ = AttachmentState::kUninitialized; |
| } |
| |
| // Implementing flutter::ContextListener. |
| void ImageExternalTexture::OnGrContextDestroyed() { |
| if (state_ == AttachmentState::kAttached) { |
| dl_image_.reset(); |
| image_lru_.Clear(); |
| Detach(); |
| } |
| state_ = AttachmentState::kDetached; |
| } |
| |
| JavaLocalRef ImageExternalTexture::AcquireLatestImage() { |
| JNIEnv* env = fml::jni::AttachCurrentThread(); |
| FML_CHECK(env != nullptr); |
| |
| // ImageTextureEntry.acquireLatestImage. |
| JavaLocalRef image_java = |
| jni_facade_->ImageProducerTextureEntryAcquireLatestImage( |
| JavaLocalRef(image_texture_entry_)); |
| return image_java; |
| } |
| |
| void ImageExternalTexture::CloseImage(const fml::jni::JavaRef<jobject>& image) { |
| if (image.obj() == nullptr) { |
| return; |
| } |
| jni_facade_->ImageClose(JavaLocalRef(image)); |
| } |
| |
| void ImageExternalTexture::CloseHardwareBuffer( |
| const fml::jni::JavaRef<jobject>& hardware_buffer) { |
| if (hardware_buffer.obj() == nullptr) { |
| return; |
| } |
| jni_facade_->HardwareBufferClose(JavaLocalRef(hardware_buffer)); |
| } |
| |
| JavaLocalRef ImageExternalTexture::HardwareBufferFor( |
| const fml::jni::JavaRef<jobject>& image) { |
| if (image.obj() == nullptr) { |
| return JavaLocalRef(); |
| } |
| // Image.getHardwareBuffer. |
| return jni_facade_->ImageGetHardwareBuffer(JavaLocalRef(image)); |
| } |
| |
| AHardwareBuffer* ImageExternalTexture::AHardwareBufferFor( |
| const fml::jni::JavaRef<jobject>& hardware_buffer) { |
| JNIEnv* env = fml::jni::AttachCurrentThread(); |
| FML_CHECK(env != nullptr); |
| const auto& proc = |
| impeller::android::GetProcTable().AHardwareBuffer_fromHardwareBuffer; |
| return proc ? proc(env, hardware_buffer.obj()) : nullptr; |
| } |
| |
| } // namespace flutter |