88#include < android/sensor.h>
99
1010#include " flutter/common/graphics/texture.h"
11+ #include " flutter/display_list/effects/dl_color_source.h"
12+ #include " flutter/flow/layers/layer.h"
1113#include " flutter/impeller/core/formats.h"
1214#include " flutter/impeller/display_list/dl_image_impeller.h"
15+ #include " flutter/impeller/renderer/backend/gles/texture_gles.h"
1316#include " flutter/impeller/toolkit/egl/image.h"
1417#include " flutter/impeller/toolkit/gles/texture.h"
1518#include " flutter/shell/platform/android/ndk_helpers.h"
1619#include " third_party/skia/include/core/SkAlphaType.h"
20+ #include " third_party/skia/include/core/SkColorSpace.h"
1721#include " third_party/skia/include/core/SkColorType.h"
22+ #include " third_party/skia/include/core/SkImage.h"
23+ #include " third_party/skia/include/gpu/GrBackendSurface.h"
24+ #include " third_party/skia/include/gpu/GrDirectContext.h"
1825#include " third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
1926#include " third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
2027#include " third_party/skia/include/gpu/gl/GrGLTypes.h"
@@ -29,61 +36,40 @@ ImageExternalTextureGL::ImageExternalTextureGL(
2936
3037void ImageExternalTextureGL::Attach (PaintContext& context) {
3138 if (state_ == AttachmentState::kUninitialized ) {
32- if (!latest_android_image_.is_null () && !latest_bounds_.isEmpty ()) {
33- // After detach the cache of textures will have been cleared. If
34- // there is an android image we must populate it now so that the
35- // first frame isn't blank.
36- JavaLocalRef hardware_buffer = HardwareBufferFor (latest_android_image_);
37- UpdateImage (hardware_buffer, context);
39+ if (!android_image_.is_null ()) {
40+ JavaLocalRef hardware_buffer = HardwareBufferFor (android_image_);
41+ AHardwareBuffer* hardware_buffer_ahw =
42+ AHardwareBufferFor (hardware_buffer);
43+ egl_image_ = CreateEGLImage (hardware_buffer_ahw);
3844 CloseHardwareBuffer (hardware_buffer);
3945 }
4046 state_ = AttachmentState::kAttached ;
4147 }
4248}
4349
44- void ImageExternalTextureGL::UpdateImage (JavaLocalRef& hardware_buffer,
45- PaintContext& context) {
46- AHardwareBuffer* latest_hardware_buffer = AHardwareBufferFor (hardware_buffer);
47- HardwareBufferKey key =
48- flutter::NDKHelpers::AHardwareBuffer_getId (latest_hardware_buffer);
49- auto existing_image = image_lru_.FindImage (key);
50- if (existing_image != nullptr ) {
51- dl_image_ = existing_image;
52- return ;
53- }
54-
55- auto egl_image = CreateEGLImage (latest_hardware_buffer);
56- if (!egl_image.is_valid ()) {
57- return ;
58- }
59-
60- dl_image_ = CreateDlImage (context, latest_bounds_, key, std::move (egl_image));
61- gl_entries_.erase (image_lru_.AddImage (dl_image_, key));
50+ void ImageExternalTextureGL::Detach () {
51+ egl_image_.reset ();
6252}
6353
64- void ImageExternalTextureGL::ProcessFrame (PaintContext& context,
65- const SkRect& bounds) {
54+ bool ImageExternalTextureGL::MaybeSwapImages () {
6655 JavaLocalRef image = AcquireLatestImage ();
6756 if (image.is_null ()) {
68- return ;
57+ return false ;
6958 }
70- JavaLocalRef hardware_buffer = HardwareBufferFor (image);
71- UpdateImage (hardware_buffer, context);
72- CloseHardwareBuffer (hardware_buffer);
73-
7459 // NOTE: In the following code it is important that old_android_image is
7560 // not closed until after the update of egl_image_ otherwise the image might
7661 // be closed before the old EGLImage referencing it has been deleted. After
7762 // an image is closed the underlying HardwareBuffer may be recycled and used
7863 // for a future frame.
79- JavaLocalRef old_android_image (latest_android_image_);
80- latest_android_image_.Reset (image);
64+ JavaLocalRef old_android_image (android_image_);
65+ android_image_.Reset (image);
66+ JavaLocalRef hardware_buffer = HardwareBufferFor (image);
67+ egl_image_ = CreateEGLImage (AHardwareBufferFor (hardware_buffer));
68+ CloseHardwareBuffer (hardware_buffer);
69+ // IMPORTANT: We only close the old image after egl_image_ stops referencing
70+ // it.
8171 CloseImage (old_android_image);
82- }
83-
84- void ImageExternalTextureGL::Detach () {
85- image_lru_.Clear ();
86- gl_entries_.clear ();
72+ return true ;
8773}
8874
8975impeller::UniqueEGLImageKHR ImageExternalTextureGL::CreateEGLImage (
@@ -124,11 +110,26 @@ void ImageExternalTextureGLSkia::Attach(PaintContext& context) {
124110 // After this call state_ will be AttachmentState::kAttached and egl_image_
125111 // will have been created if we still have an Image associated with us.
126112 ImageExternalTextureGL::Attach (context);
113+ GLuint texture_name;
114+ glGenTextures (1 , &texture_name);
115+ texture_.reset (impeller::GLTexture{texture_name});
127116 }
128117}
129118
130119void ImageExternalTextureGLSkia::Detach () {
131120 ImageExternalTextureGL::Detach ();
121+ texture_.reset ();
122+ }
123+
124+ void ImageExternalTextureGLSkia::ProcessFrame (PaintContext& context,
125+ const SkRect& bounds) {
126+ const bool swapped = MaybeSwapImages ();
127+ if (!swapped && !egl_image_.is_valid ()) {
128+ // Nothing to do.
129+ return ;
130+ }
131+ BindImageToTexture (egl_image_, texture_.get ().texture_name );
132+ dl_image_ = CreateDlImage (context, bounds);
132133}
133134
134135void ImageExternalTextureGLSkia::BindImageToTexture (
@@ -144,22 +145,11 @@ void ImageExternalTextureGLSkia::BindImageToTexture(
144145
145146sk_sp<flutter::DlImage> ImageExternalTextureGLSkia::CreateDlImage (
146147 PaintContext& context,
147- const SkRect& bounds,
148- HardwareBufferKey id,
149- impeller::UniqueEGLImageKHR&& egl_image) {
150- GLuint texture_name;
151- glGenTextures (1 , &texture_name);
152- auto gl_texture = impeller::GLTexture{texture_name};
153- impeller::UniqueGLTexture unique_texture;
154- unique_texture.reset (gl_texture);
155-
156- BindImageToTexture (egl_image, unique_texture.get ().texture_name );
157- GrGLTextureInfo textureInfo = {
158- GL_TEXTURE_EXTERNAL_OES, unique_texture.get ().texture_name , GL_RGBA8_OES};
148+ const SkRect& bounds) {
149+ GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES,
150+ texture_.get ().texture_name , GL_RGBA8_OES};
159151 auto backendTexture =
160152 GrBackendTextures::MakeGL (1 , 1 , skgpu::Mipmapped::kNo , textureInfo);
161- gl_entries_[id] = GlEntry{.egl_image = std::move (egl_image),
162- .texture = std::move (unique_texture)};
163153 return DlImage::Make (SkImages::BorrowTextureFrom (
164154 context.gr_context , backendTexture, kTopLeft_GrSurfaceOrigin ,
165155 kRGBA_8888_SkColorType , kPremul_SkAlphaType , nullptr ));
@@ -181,11 +171,19 @@ void ImageExternalTextureGLImpeller::Attach(PaintContext& context) {
181171 }
182172}
183173
174+ void ImageExternalTextureGLImpeller::ProcessFrame (PaintContext& context,
175+ const SkRect& bounds) {
176+ const bool swapped = MaybeSwapImages ();
177+ if (!swapped && !egl_image_.is_valid ()) {
178+ // Nothing to do.
179+ return ;
180+ }
181+ dl_image_ = CreateDlImage (context, bounds);
182+ }
183+
184184sk_sp<flutter::DlImage> ImageExternalTextureGLImpeller::CreateDlImage (
185185 PaintContext& context,
186- const SkRect& bounds,
187- HardwareBufferKey id,
188- impeller::UniqueEGLImageKHR&& egl_image) {
186+ const SkRect& bounds) {
189187 impeller::TextureDescriptor desc;
190188 desc.type = impeller::TextureType::kTextureExternalOES ;
191189 desc.storage_mode = impeller::StorageMode::kDevicePrivate ;
@@ -203,10 +201,7 @@ sk_sp<flutter::DlImage> ImageExternalTextureGLImpeller::CreateDlImage(
203201 }
204202 // Associate the hardware buffer image with the texture.
205203 glEGLImageTargetTexture2DOES (GL_TEXTURE_EXTERNAL_OES,
206- (GLeglImageOES)egl_image.get ().image );
207- gl_entries_[id] = GlEntry{
208- .egl_image = std::move (egl_image),
209- };
204+ (GLeglImageOES)egl_image_.get ().image );
210205 return impeller::DlImageImpeller::Make (texture);
211206}
212207
0 commit comments