5#include "flutter/shell/platform/android/image_external_texture_gl.h"
7#include <android/hardware_buffer_jni.h>
8#include <android/sensor.h>
10#include "flutter/common/graphics/texture.h"
11#include "flutter/impeller/core/formats.h"
12#include "flutter/impeller/display_list/dl_image_impeller.h"
13#include "flutter/impeller/toolkit/android/hardware_buffer.h"
14#include "flutter/impeller/toolkit/egl/image.h"
15#include "flutter/impeller/toolkit/gles/texture.h"
27 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade)
47 std::optional<HardwareBufferKey>
key =
49 latest_hardware_buffer);
51 if (existing_image !=
nullptr) {
57 if (!egl_image.is_valid()) {
62 if (
key.has_value()) {
70 if (
image.is_null()) {
85 if (hardware_buffer ==
nullptr) {
89 EGLDisplay display = eglGetCurrentDisplay();
92 EGLClientBuffer client_buffer =
96 if (client_buffer ==
nullptr) {
97 FML_LOG(
ERROR) <<
"eglGetNativeClientBufferAndroid returned null.";
103 eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
111 const std::shared_ptr<AndroidContextGLSkia>& context,
114 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade)
117void ImageExternalTextureGLSkia::Attach(
PaintContext& context) {
125void ImageExternalTextureGLSkia::Detach() {
129void ImageExternalTextureGLSkia::BindImageToTexture(
132 if (!
image.is_valid() || tex == 0) {
135 glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
136 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
141 PaintContext& context,
143 std::optional<HardwareBufferKey>
id,
146 glGenTextures(1, &texture_name);
149 unique_texture.
reset(gl_texture);
151 BindImageToTexture(egl_image, unique_texture.
get().texture_name);
153 GL_TEXTURE_EXTERNAL_OES, unique_texture.
get().texture_name, GL_RGBA8_OES};
154 auto backendTexture =
157 gl_entries_[
id.value_or(0)] = GlEntry{.egl_image = std::move(egl_image),
158 .texture = std::move(unique_texture)};
165 const std::shared_ptr<impeller::ContextGLES>& context,
168 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade)
170 impeller_context_(context) {}
172void ImageExternalTextureGLImpeller::Detach() {}
174void ImageExternalTextureGLImpeller::Attach(PaintContext& context) {
181 PaintContext& context,
183 std::optional<HardwareBufferKey>
id,
189 desc.size = {
static_cast<int>(
bounds.width()),
190 static_cast<int>(
bounds.height())};
192 auto texture = std::make_shared<impeller::TextureGLES>(
193 impeller_context_->GetReactor(),
desc,
201 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
202 (GLeglImageOES)egl_image.get().image);
204 .egl_image = std::move(egl_image),
struct AHardwareBuffer AHardwareBuffer
@ kTopLeft_GrSurfaceOrigin
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
static sk_sp< DlImage > Make(const SkImage *image)
ImageExternalTextureGLImpeller(const std::shared_ptr< impeller::ContextGLES > &context, int64_t id, const fml::jni::ScopedJavaGlobalRef< jobject > &hardware_buffer_texture_entry, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade)
ImageExternalTextureGLSkia(const std::shared_ptr< AndroidContextGLSkia > &context, int64_t id, const fml::jni::ScopedJavaGlobalRef< jobject > &image_textury_entry, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade)
void ProcessFrame(PaintContext &context, const SkRect &bounds) override
void UpdateImage(JavaLocalRef &hardware_buffer, const SkRect &bounds, PaintContext &context)
virtual sk_sp< flutter::DlImage > CreateDlImage(PaintContext &context, const SkRect &bounds, std::optional< HardwareBufferKey > id, impeller::UniqueEGLImageKHR &&egl_image)=0
impeller::UniqueEGLImageKHR CreateEGLImage(AHardwareBuffer *buffer)
std::unordered_map< HardwareBufferKey, GlEntry > gl_entries_
ImageExternalTextureGL(int64_t id, const fml::jni::ScopedJavaGlobalRef< jobject > &image_textury_entry, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade)
void Attach(PaintContext &context) override
AHardwareBuffer * AHardwareBufferFor(const fml::jni::JavaRef< jobject > &hardware_buffer)
JavaLocalRef HardwareBufferFor(const fml::jni::JavaRef< jobject > &image)
void CloseHardwareBuffer(const fml::jni::JavaRef< jobject > &hardware_buffer)
sk_sp< flutter::DlImage > dl_image_
JavaLocalRef AcquireLatestImage()
HardwareBufferKey AddImage(const sk_sp< flutter::DlImage > &image, HardwareBufferKey key)
Add a new image to the cache with a key, returning the key of the LRU entry that was removed.
sk_sp< flutter::DlImage > FindImage(std::optional< HardwareBufferKey > key)
Retrieve the image associated with the given [key], or nullptr.
void Clear()
Remove all entires from the image cache.
void reset(const T &value=Traits::InvalidValue())
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
std::optional< uint64_t > GetSystemUniqueID() const
Get the system wide unique ID of the hardware buffer if possible. This is only available on Android A...
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
SK_API GrBackendTexture MakeGL(int width, int height, skgpu::Mipmapped, const GrGLTextureInfo &glInfo, std::string_view label={})
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
Optional< SkRect > bounds
sk_sp< const SkImage > image
std::nullptr_t JavaLocalRef
const ProcTable & GetProcTable()
fml::UniqueObject< EGLImageKHRWithDisplay, EGLImageKHRWithDisplayTraits > UniqueEGLImageKHR
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...