Add support for SurfaceTexture based external textures on Android under Impeller/GLES. (flutter/engine#44734)

- Refactor AndroidExternalTextureGL into SurfaceTextureExternalTexture
base class with two specialized implementations:
- Add SurfaceTextureExternalTextureGL for legacy GL rendering.
- Add SurfaceTextureExternalTextureImpellerGL for Impeller GLES
rendering.

NOTE: There is still no support for SurfaceTextures under Vulkan
rendering.
This commit is contained in:
John McCutchan 2023-08-15 14:25:03 -07:00 committed by GitHub
parent 4beaef6a06
commit 50190fcaa6
11 changed files with 340 additions and 174 deletions

View File

@ -2317,8 +2317,6 @@ ORIGIN: ../../../flutter/shell/platform/android/android_egl_surface.h + ../../..
ORIGIN: ../../../flutter/shell/platform/android/android_environment_gl.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/android_environment_gl.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/android_exports.lst + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/android_external_texture_gl.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/android_external_texture_gl.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/android_image_generator.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/android_image_generator.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/android_shell_holder.cc + ../../../flutter/LICENSE
@ -2505,6 +2503,10 @@ ORIGIN: ../../../flutter/shell/platform/android/surface/android_surface_mock.cc
ORIGIN: ../../../flutter/shell/platform/android/surface/android_surface_mock.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/surface/snapshot_surface_producer.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/surface/snapshot_surface_producer.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/vsync_waiter_android.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/android/vsync_waiter_android.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/common/accessibility_bridge.cc + ../../../flutter/LICENSE
@ -5043,8 +5045,6 @@ FILE: ../../../flutter/shell/platform/android/android_egl_surface.h
FILE: ../../../flutter/shell/platform/android/android_environment_gl.cc
FILE: ../../../flutter/shell/platform/android/android_environment_gl.h
FILE: ../../../flutter/shell/platform/android/android_exports.lst
FILE: ../../../flutter/shell/platform/android/android_external_texture_gl.cc
FILE: ../../../flutter/shell/platform/android/android_external_texture_gl.h
FILE: ../../../flutter/shell/platform/android/android_image_generator.cc
FILE: ../../../flutter/shell/platform/android/android_image_generator.h
FILE: ../../../flutter/shell/platform/android/android_shell_holder.cc
@ -5243,6 +5243,10 @@ FILE: ../../../flutter/shell/platform/android/surface/android_surface_mock.cc
FILE: ../../../flutter/shell/platform/android/surface/android_surface_mock.h
FILE: ../../../flutter/shell/platform/android/surface/snapshot_surface_producer.cc
FILE: ../../../flutter/shell/platform/android/surface/snapshot_surface_producer.h
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture.cc
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture.h
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl.cc
FILE: ../../../flutter/shell/platform/android/surface_texture_external_texture_gl.h
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.cc
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.h
FILE: ../../../flutter/shell/platform/common/accessibility_bridge.cc

View File

@ -82,8 +82,6 @@ source_set("flutter_shell_native_src") {
"android_egl_surface.h",
"android_environment_gl.cc",
"android_environment_gl.h",
"android_external_texture_gl.cc",
"android_external_texture_gl.h",
"android_shell_holder.cc",
"android_shell_holder.h",
"android_surface_gl_impeller.cc",
@ -115,6 +113,10 @@ source_set("flutter_shell_native_src") {
"platform_view_android.h",
"platform_view_android_jni_impl.cc",
"platform_view_android_jni_impl.h",
"surface_texture_external_texture.cc",
"surface_texture_external_texture.h",
"surface_texture_external_texture_gl.cc",
"surface_texture_external_texture_gl.h",
"vsync_waiter_android.cc",
"vsync_waiter_android.h",
]

View File

@ -1,139 +0,0 @@
// 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/android_external_texture_gl.h"
#include <GLES/glext.h>
#include <utility>
#include "flutter/display_list/effects/dl_color_source.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
namespace flutter {
AndroidExternalTextureGL::AndroidExternalTextureGL(
int64_t id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: Texture(id),
jni_facade_(std::move(jni_facade)),
surface_texture_(surface_texture),
transform(SkMatrix::I()) {}
AndroidExternalTextureGL::~AndroidExternalTextureGL() {
if (state_ == AttachmentState::kAttached) {
glDeleteTextures(1, &texture_name_);
}
}
void AndroidExternalTextureGL::OnGrContextCreated() {
state_ = AttachmentState::kUninitialized;
}
void AndroidExternalTextureGL::MarkNewFrameAvailable() {
new_frame_ready_ = true;
}
void AndroidExternalTextureGL::Paint(PaintContext& context,
const SkRect& bounds,
bool freeze,
const DlImageSampling sampling) {
if (state_ == AttachmentState::kDetached) {
return;
}
if (state_ == AttachmentState::kUninitialized) {
glGenTextures(1, &texture_name_);
Attach(static_cast<jint>(texture_name_));
state_ = AttachmentState::kAttached;
}
if (!freeze && new_frame_ready_) {
Update();
new_frame_ready_ = false;
}
GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_,
GL_RGBA8_OES};
auto backendTexture =
GrBackendTextures::MakeGL(1, 1, skgpu::Mipmapped::kNo, textureInfo);
sk_sp<SkImage> image = SkImages::BorrowTextureFrom(
context.gr_context, backendTexture, kTopLeft_GrSurfaceOrigin,
kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
if (image) {
DlAutoCanvasRestore autoRestore(context.canvas, true);
// The incoming texture is vertically flipped, so we flip it
// back. OpenGL's coordinate system has Positive Y equivalent to up, while
// Skia's coordinate system has Negative Y equvalent to up.
context.canvas->Translate(bounds.x(), bounds.y() + bounds.height());
context.canvas->Scale(bounds.width(), -bounds.height());
auto dl_image = DlImage::Make(image);
if (!transform.isIdentity()) {
DlImageColorSource source(dl_image, DlTileMode::kRepeat,
DlTileMode::kRepeat, sampling, &transform);
DlPaint paintWithShader;
if (context.paint) {
paintWithShader = *context.paint;
}
paintWithShader.setColorSource(&source);
context.canvas->DrawRect(SkRect::MakeWH(1, 1), paintWithShader);
} else {
context.canvas->DrawImage(dl_image, {0, 0}, sampling, context.paint);
}
}
}
void AndroidExternalTextureGL::UpdateTransform() {
jni_facade_->SurfaceTextureGetTransformMatrix(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_), transform);
// Android's SurfaceTexture transform matrix works on texture coordinate
// lookups in the range 0.0-1.0, while Skia's Shader transform matrix works on
// the image itself, as if it were inscribed inside a clip rect.
// An Android transform that scales lookup by 0.5 (displaying 50% of the
// texture) is the same as a Skia transform by 2.0 (scaling 50% of the image
// outside of the virtual "clip rect"), so we invert the incoming matrix.
SkMatrix inverted;
if (!transform.invert(&inverted)) {
FML_LOG(FATAL) << "Invalid SurfaceTexture transformation matrix";
}
transform = inverted;
}
void AndroidExternalTextureGL::OnGrContextDestroyed() {
if (state_ == AttachmentState::kAttached) {
Detach();
glDeleteTextures(1, &texture_name_);
}
state_ = AttachmentState::kDetached;
}
void AndroidExternalTextureGL::Attach(jint textureName) {
jni_facade_->SurfaceTextureAttachToGLContext(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_), textureName);
}
void AndroidExternalTextureGL::Update() {
jni_facade_->SurfaceTextureUpdateTexImage(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
UpdateTransform();
}
void AndroidExternalTextureGL::Detach() {
jni_facade_->SurfaceTextureDetachFromGLContext(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
}
void AndroidExternalTextureGL::OnTextureUnregistered() {}
} // namespace flutter

View File

@ -14,6 +14,8 @@
namespace flutter {
// External texture peered to a sequence of android.hardware.HardwareBuffers.
//
class HardwareBufferExternalTexture : public flutter::Texture {
public:
explicit HardwareBufferExternalTexture(

View File

@ -81,8 +81,8 @@ public class SurfaceTextureWrapper {
// This causes the texture to be in an uninitialized state.
// This should *not* be an issue once platform views are always rendered as TextureLayers
// since thread merging will be always disabled on Android.
// For more see: AndroidExternalTextureGL::OnGrContextCreated in
// android_external_texture_gl.cc, and
// For more see: SurfaceTextureExternalTextureGL::OnGrContextCreated in
// surface_texture_external_texture_gl.cc, and
// https://github.com/flutter/flutter/issues/98155
if (attached) {
surfaceTexture.detachFromGLContext();

View File

@ -14,14 +14,14 @@
#include "flutter/shell/platform/android/android_context_gl_impeller.h"
#include "flutter/shell/platform/android/android_context_gl_skia.h"
#include "flutter/shell/platform/android/android_context_vulkan_impeller.h"
#include "flutter/shell/platform/android/android_external_texture_gl.h"
#include "flutter/shell/platform/android/android_surface_gl_impeller.h"
#include "flutter/shell/platform/android/android_surface_gl_skia.h"
#include "flutter/shell/platform/android/android_surface_software.h"
#include "flutter/shell/platform/android/hardware_buffer_external_texture_gl.h"
#include "flutter/shell/platform/android/hardware_buffer_external_texture_vk.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_gl.h"
#if IMPELLER_ENABLE_VULKAN // b/258506856 for why this is behind an if
#include "flutter/shell/platform/android/android_surface_vulkan_impeller.h"
#include "flutter/shell/platform/android/hardware_buffer_external_texture_vk.h"
#endif
#include "flutter/shell/platform/android/context/android_context.h"
#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
@ -301,10 +301,20 @@ void PlatformViewAndroid::RegisterExternalTexture(
int64_t texture_id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture) {
if (android_context_->RenderingApi() == AndroidRenderingAPI::kOpenGLES) {
RegisterTexture(std::make_shared<AndroidExternalTextureGL>(
texture_id, surface_texture, jni_facade_));
if (android_context_->GetImpellerContext()) {
// Impeller GLES.
RegisterTexture(std::make_shared<SurfaceTextureExternalTextureImpellerGL>(
std::static_pointer_cast<impeller::ContextGLES>(
android_context_->GetImpellerContext()),
texture_id, surface_texture, jni_facade_));
} else {
// Legacy GL.
RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGL>(
texture_id, surface_texture, jni_facade_));
}
} else {
FML_LOG(INFO) << "Attempted to use a GL texture in a non GL context.";
FML_LOG(INFO) << "Attempted to use a SurfaceTextureExternalTexture with an "
"unsupported rendering API.";
}
}
@ -312,7 +322,7 @@ void PlatformViewAndroid::RegisterImageTexture(
int64_t texture_id,
const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry) {
if (android_context_->RenderingApi() == AndroidRenderingAPI::kOpenGLES) {
if (android_context_->GetImpellerContext() != nullptr) {
if (android_context_->GetImpellerContext()) {
// Impeller GLES.
RegisterTexture(std::make_shared<HardwareBufferExternalTextureImpellerGL>(
std::static_pointer_cast<impeller::ContextGLES>(

View File

@ -28,13 +28,13 @@
#include "flutter/lib/ui/plugins/callback_cache.h"
#include "flutter/runtime/dart_service_isolate.h"
#include "flutter/shell/common/run_configuration.h"
#include "flutter/shell/platform/android/android_external_texture_gl.h"
#include "flutter/shell/platform/android/android_shell_holder.h"
#include "flutter/shell/platform/android/apk_asset_provider.h"
#include "flutter/shell/platform/android/flutter_main.h"
#include "flutter/shell/platform/android/hardware_buffer_external_texture_gl.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
#include "flutter/shell/platform/android/platform_view_android.h"
#include "flutter/shell/platform/android/surface_texture_external_texture_gl.h"
#define ANDROID_SHELL_HOLDER \
(reinterpret_cast<AndroidShellHolder*>(shell_holder))

View File

@ -0,0 +1,114 @@
// 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/surface_texture_external_texture.h"
#include <GLES/glext.h>
#include <utility>
#include "flutter/display_list/effects/dl_color_source.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
namespace flutter {
SurfaceTextureExternalTexture::SurfaceTextureExternalTexture(
int64_t id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: Texture(id),
jni_facade_(std::move(jni_facade)),
surface_texture_(surface_texture),
transform_(SkMatrix::I()) {}
SurfaceTextureExternalTexture::~SurfaceTextureExternalTexture() {}
void SurfaceTextureExternalTexture::OnGrContextCreated() {
state_ = AttachmentState::kUninitialized;
}
void SurfaceTextureExternalTexture::MarkNewFrameAvailable() {
new_frame_ready_ = true;
}
void SurfaceTextureExternalTexture::Paint(PaintContext& context,
const SkRect& bounds,
bool freeze,
const DlImageSampling sampling) {
if (state_ == AttachmentState::kDetached) {
return;
}
const bool should_process_frame =
(!freeze && new_frame_ready_) || dl_image_ == nullptr;
if (should_process_frame) {
ProcessFrame(context, bounds);
new_frame_ready_ = false;
}
FML_CHECK(state_ == AttachmentState::kAttached);
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(ERROR) << "No DlImage available.";
}
}
void SurfaceTextureExternalTexture::OnGrContextDestroyed() {
if (state_ == AttachmentState::kAttached) {
Detach();
}
state_ = AttachmentState::kDetached;
}
void SurfaceTextureExternalTexture::OnTextureUnregistered() {}
void SurfaceTextureExternalTexture::Detach() {
jni_facade_->SurfaceTextureDetachFromGLContext(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
dl_image_.reset();
}
void SurfaceTextureExternalTexture::Attach(int gl_tex_id) {
jni_facade_->SurfaceTextureAttachToGLContext(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_), gl_tex_id);
state_ = AttachmentState::kAttached;
}
void SurfaceTextureExternalTexture::Update() {
jni_facade_->SurfaceTextureUpdateTexImage(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_));
jni_facade_->SurfaceTextureGetTransformMatrix(
fml::jni::ScopedJavaLocalRef<jobject>(surface_texture_), transform_);
// Android's SurfaceTexture transform matrix works on texture coordinate
// lookups in the range 0.0-1.0, while Skia's Shader transform matrix works on
// the image itself, as if it were inscribed inside a clip rect.
// An Android transform that scales lookup by 0.5 (displaying 50% of the
// texture) is the same as a Skia transform by 2.0 (scaling 50% of the image
// outside of the virtual "clip rect"), so we invert the incoming matrix.
SkMatrix inverted;
if (!transform_.invert(&inverted)) {
FML_LOG(FATAL)
<< "Invalid (not invertable) SurfaceTexture transformation matrix";
}
transform_ = inverted;
}
} // namespace flutter

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_EXTERNAL_TEXTURE_GL_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_EXTERNAL_TEXTURE_GL_H_
#ifndef FLUTTER_SHELL_PLATFORM_SURFACE_TEXTURE_EXTERNAL_TEXTURE_H_
#define FLUTTER_SHELL_PLATFORM_SURFACE_TEXTURE_EXTERNAL_TEXTURE_H_
#include <GLES/gl.h>
@ -12,14 +12,15 @@
namespace flutter {
class AndroidExternalTextureGL : public flutter::Texture {
// External texture peered to an android.graphics.SurfaceTexture.
class SurfaceTextureExternalTexture : public flutter::Texture {
public:
AndroidExternalTextureGL(
SurfaceTextureExternalTexture(
int64_t id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
~AndroidExternalTextureGL() override;
~SurfaceTextureExternalTexture() override;
void Paint(PaintContext& context,
const SkRect& bounds,
@ -34,32 +35,25 @@ class AndroidExternalTextureGL : public flutter::Texture {
void OnTextureUnregistered() override;
private:
void Attach(jint textureName);
protected:
virtual void ProcessFrame(PaintContext& context, const SkRect& bounds) = 0;
virtual void Detach();
void Attach(int gl_tex_id);
void Update();
void Detach();
void UpdateTransform();
enum class AttachmentState { kUninitialized, kAttached, kDetached };
std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
fml::jni::ScopedJavaGlobalRef<jobject> surface_texture_;
AttachmentState state_ = AttachmentState::kUninitialized;
SkMatrix transform_;
bool new_frame_ready_ = false;
sk_sp<flutter::DlImage> dl_image_;
GLuint texture_name_ = 0;
SkMatrix transform;
FML_DISALLOW_COPY_AND_ASSIGN(AndroidExternalTextureGL);
FML_DISALLOW_COPY_AND_ASSIGN(SurfaceTextureExternalTexture);
};
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_EXTERNAL_TEXTURE_GL_H_
#endif // FLUTTER_SHELL_PLATFORM_SURFACE_TEXTURE_EXTERNAL_TEXTURE_H_

View File

@ -0,0 +1,115 @@
// 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/surface_texture_external_texture_gl.h"
#include <utility>
#include "flutter/display_list/effects/dl_color_source.h"
#include "impeller/display_list/dl_image_impeller.h"
#include "shell/platform/android/surface_texture_external_texture.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
namespace flutter {
SurfaceTextureExternalTextureGL::SurfaceTextureExternalTextureGL(
int64_t id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: SurfaceTextureExternalTexture(id, surface_texture, jni_facade) {}
SurfaceTextureExternalTextureGL::~SurfaceTextureExternalTextureGL() {
Detach();
}
void SurfaceTextureExternalTextureGL::ProcessFrame(PaintContext& context,
const SkRect& bounds) {
if (state_ == AttachmentState::kUninitialized) {
// Generate the texture handle.
glGenTextures(1, &texture_name_);
Attach(texture_name_);
}
FML_CHECK(state_ == AttachmentState::kAttached);
// Updates the texture contents and transformation matrix.
Update();
// Create a
GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_,
GL_RGBA8_OES};
auto backendTexture =
GrBackendTextures::MakeGL(1, 1, skgpu::Mipmapped::kNo, textureInfo);
dl_image_ = DlImage::Make(SkImages::BorrowTextureFrom(
context.gr_context, backendTexture, kTopLeft_GrSurfaceOrigin,
kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr));
}
void SurfaceTextureExternalTextureGL::Detach() {
SurfaceTextureExternalTexture::Detach();
if (texture_name_ != 0) {
glDeleteTextures(1, &texture_name_);
texture_name_ = 0;
}
}
SurfaceTextureExternalTextureImpellerGL::
SurfaceTextureExternalTextureImpellerGL(
const std::shared_ptr<impeller::ContextGLES>& context,
int64_t id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: SurfaceTextureExternalTexture(id, surface_texture, jni_facade),
impeller_context_(context) {}
SurfaceTextureExternalTextureImpellerGL::
~SurfaceTextureExternalTextureImpellerGL() {
Detach();
}
void SurfaceTextureExternalTextureImpellerGL::ProcessFrame(
PaintContext& context,
const SkRect& bounds) {
if (state_ == AttachmentState::kUninitialized) {
// Generate the texture handle.
impeller::TextureDescriptor desc;
desc.type = impeller::TextureType::kTextureExternalOES;
desc.storage_mode = impeller::StorageMode::kDevicePrivate;
desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt;
desc.size = {static_cast<int>(bounds.width()),
static_cast<int>(bounds.height())};
desc.mip_count = 1;
texture_ = std::make_shared<impeller::TextureGLES>(
impeller_context_->GetReactor(), desc,
impeller::TextureGLES::IsWrapped::kWrapped);
texture_->SetCoordinateSystem(
impeller::TextureCoordinateSystem::kUploadFromHost);
auto maybe_handle = texture_->GetGLHandle();
if (!maybe_handle.has_value()) {
FML_LOG(ERROR) << "Could not get GL handle from impeller::TextureGLES!";
return;
}
Attach(maybe_handle.value());
}
FML_CHECK(state_ == AttachmentState::kAttached);
// Updates the texture contents and transformation matrix.
Update();
dl_image_ = impeller::DlImageImpeller::Make(texture_);
}
void SurfaceTextureExternalTextureImpellerGL::Detach() {
SurfaceTextureExternalTexture::Detach();
texture_.reset();
}
} // namespace flutter

View File

@ -0,0 +1,64 @@
// 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.
#ifndef FLUTTER_SHELL_PLATFORM_SURFACE_TEXTURE_EXTERNAL_TEXTURE_GL_H_
#define FLUTTER_SHELL_PLATFORM_SURFACE_TEXTURE_EXTERNAL_TEXTURE_GL_H_
#include "flutter/shell/platform/android/surface_texture_external_texture.h"
#include "flutter/impeller/renderer/backend/gles/context_gles.h"
#include "flutter/impeller/renderer/backend/gles/gles.h"
#include "flutter/impeller/renderer/backend/gles/texture_gles.h"
#include "flutter/impeller/toolkit/egl/egl.h"
#include "flutter/impeller/toolkit/egl/image.h"
#include "flutter/impeller/toolkit/gles/texture.h"
#include "flutter/impeller/renderer/backend/gles/context_gles.h"
namespace flutter {
class SurfaceTextureExternalTextureGL : public SurfaceTextureExternalTexture {
public:
SurfaceTextureExternalTextureGL(
int64_t id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
~SurfaceTextureExternalTextureGL() override;
private:
virtual void ProcessFrame(PaintContext& context,
const SkRect& bounds) override;
virtual void Detach() override;
GLuint texture_name_ = 0;
FML_DISALLOW_COPY_AND_ASSIGN(SurfaceTextureExternalTextureGL);
};
class SurfaceTextureExternalTextureImpellerGL
: public SurfaceTextureExternalTexture {
public:
SurfaceTextureExternalTextureImpellerGL(
const std::shared_ptr<impeller::ContextGLES>& context,
int64_t id,
const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
~SurfaceTextureExternalTextureImpellerGL() override;
private:
virtual void ProcessFrame(PaintContext& context,
const SkRect& bounds) override;
virtual void Detach() override;
const std::shared_ptr<impeller::ContextGLES> impeller_context_;
std::shared_ptr<impeller::TextureGLES> texture_;
FML_DISALLOW_COPY_AND_ASSIGN(SurfaceTextureExternalTextureImpellerGL);
};
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_SURFACE_TEXTURE_EXTERNAL_TEXTURE_GL_H_