blob: 4c9735ccc0eba9332f2914afa5edf60b29c25538 [file] [log] [blame]
// 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