Flutter Engine
 
Loading...
Searching...
No Matches
image_external_texture_gl.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <android/hardware_buffer_jni.h>
8#include <android/sensor.h>
9
16#include "third_party/skia/include/core/SkAlphaType.h"
17#include "third_party/skia/include/core/SkColorType.h"
18#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
19#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
20#include "third_party/skia/include/gpu/ganesh/gl/GrGLTypes.h"
21
22namespace flutter {
23
25 int64_t id,
26 const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry,
27 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
29 : ImageExternalTexture(id, image_texture_entry, jni_facade, lifecycle) {}
30
33 // TODO(johnmccurtchan): We currently display the first frame after an
34 // attach-detach cycle as blank. There seems to be an issue on some
35 // devices where ImageReaders/Images from before the detach aren't
36 // valid after the attach. According to Android folks this doesn't
37 // match the spec. Revisit this in the future.
38 // See https://github.com/flutter/flutter/issues/142978 and
39 // https://github.com/flutter/flutter/issues/139039.
41 }
42}
43
45 const SkRect& bounds,
46 PaintContext& context) {
47 AHardwareBuffer* latest_hardware_buffer = AHardwareBufferFor(hardware_buffer);
48 std::optional<HardwareBufferKey> key =
50 latest_hardware_buffer);
51 auto existing_image = image_lru_.FindImage(key);
52 if (existing_image != nullptr) {
53 dl_image_ = existing_image;
54 return;
55 }
56
57 auto egl_image = CreateEGLImage(latest_hardware_buffer);
58 if (!egl_image.is_valid()) {
59 return;
60 }
61
62 dl_image_ = CreateDlImage(context, bounds, key, std::move(egl_image));
63 if (key.has_value()) {
65 }
66}
67
69 const SkRect& bounds) {
71 if (image.is_null()) {
72 return;
73 }
74 JavaLocalRef hardware_buffer = HardwareBufferFor(image);
75 UpdateImage(hardware_buffer, bounds, context);
76 CloseHardwareBuffer(hardware_buffer);
77}
78
83
85 AHardwareBuffer* hardware_buffer) {
86 if (hardware_buffer == nullptr) {
88 }
89
90 EGLDisplay display = eglGetCurrentDisplay();
91 if (display == EGL_NO_DISPLAY) {
92 // This could happen when running in a deferred task that executes after
93 // the thread has lost its EGL state.
95 }
96
97 EGLClientBuffer client_buffer =
98 impeller::android::GetProcTable().eglGetNativeClientBufferANDROID(
99 hardware_buffer);
100 FML_DCHECK(client_buffer != nullptr);
101 if (client_buffer == nullptr) {
102 FML_LOG(ERROR) << "eglGetNativeClientBufferAndroid returned null.";
104 }
105
108 eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
109 client_buffer, 0),
110 display};
111
112 return impeller::UniqueEGLImageKHR(maybe_image);
113}
114
115} // namespace flutter
void ProcessFrame(PaintContext &context, const SkRect &bounds) override
Subclasses override this method to bind the latest representation of the hardware buffer wrapped by t...
void UpdateImage(JavaLocalRef &hardware_buffer, const SkRect &bounds, PaintContext &context)
ImageExternalTextureGL(int64_t id, const fml::jni::ScopedJavaGlobalRef< jobject > &image_textury_entry, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade, ImageExternalTexture::ImageLifecycle lifecycle)
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_
void Attach(PaintContext &context) override
External texture peered to a sequence of android.hardware.HardwareBuffers.
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_
ImageLifecycle
Whether the last image should be reset when the context is destroyed.
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.
Definition image_lru.cc:42
sk_sp< flutter::DlImage > FindImage(std::optional< HardwareBufferKey > key)
Retrieve the image associated with the given [key], or nullptr.
Definition image_lru.cc:9
void Clear()
Remove all entires from the image cache.
Definition image_lru.cc:60
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...
FlutterVulkanImage * image
#define FML_LOG(severity)
Definition logging.h:101
#define FML_DCHECK(condition)
Definition logging.h:122
std::nullptr_t JavaLocalRef
const ProcTable & GetProcTable()
Definition proc_table.cc:12
fml::UniqueObject< EGLImageKHRWithDisplay, EGLImageKHRWithDisplayTraits > UniqueEGLImageKHR
Definition image.h:62
const uintptr_t id