mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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:
parent
4beaef6a06
commit
50190fcaa6
@ -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
|
||||
|
||||
@ -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",
|
||||
]
|
||||
|
||||
@ -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
|
||||
@ -14,6 +14,8 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
// External texture peered to a sequence of android.hardware.HardwareBuffers.
|
||||
//
|
||||
class HardwareBufferExternalTexture : public flutter::Texture {
|
||||
public:
|
||||
explicit HardwareBufferExternalTexture(
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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>(
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
Loading…
x
Reference in New Issue
Block a user