Skip to content

Commit

Permalink
[Tizen] Support EmbedderExternalTextureGL for impeller (flutter-tizen…
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaowei-guan authored and JSUYA committed Jul 22, 2024
1 parent c5150d3 commit ab84814
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 6 deletions.
2 changes: 2 additions & 0 deletions shell/platform/embedder/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ template("embedder_source_set") {

if (impeller_supports_rendering) {
sources += [
"embedder_external_texture_gl_impeller.cc",
"embedder_external_texture_gl_impeller.h",
"embedder_surface_gl_impeller.cc",
"embedder_surface_gl_impeller.h",
]
Expand Down
4 changes: 2 additions & 2 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2029,8 +2029,8 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
}
return texture;
};
external_texture_resolver =
std::make_unique<ExternalTextureResolver>(external_texture_callback);
external_texture_resolver = std::make_unique<ExternalTextureResolver>(
external_texture_callback, settings.enable_impeller);
}
}
#endif
Expand Down
15 changes: 14 additions & 1 deletion shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ typedef struct {
} FlutterTransformation;

typedef void (*VoidCallback)(void* /* user data */);
typedef bool (*BoolCallback)(void* /* user data */);

typedef enum {
/// Specifies an OpenGL texture target type. Textures are specified using
Expand Down Expand Up @@ -361,6 +362,11 @@ typedef enum {
kFlutterSoftwarePixelFormatNative32,
} FlutterSoftwarePixelFormat;

typedef enum {
kFlutterGLImpellerTexturePixelBuffer,
kFlutterGLImpellerTextureGpuSurface,
} FlutterGLImpellerTextureType;

typedef struct {
/// Target texture of the active texture unit (example GL_TEXTURE_2D or
/// GL_TEXTURE_RECTANGLE).
Expand All @@ -369,6 +375,14 @@ typedef struct {
uint32_t name;
/// The texture format (example GL_RGBA8).
uint32_t format;
/// The pixel data buffer.
const uint8_t* buffer;
/// The size of pixel buffer.
size_t buffer_size;
/// Callback invoked that the gpu surface texture start binding.
BoolCallback bind_callback;
/// The type of the texture.
FlutterGLImpellerTextureType impeller_texture_type;
/// User data to be returned on the invocation of the destruction callback.
void* user_data;
/// Callback invoked (on an engine managed thread) that asks the embedder to
Expand Down Expand Up @@ -401,7 +415,6 @@ typedef struct {
VoidCallback destruction_callback;
} FlutterOpenGLFramebuffer;

typedef bool (*BoolCallback)(void* /* user data */);
typedef FlutterTransformation (*TransformationCallback)(void* /* user data */);
typedef uint32_t (*UIntCallback)(void* /* user data */);
typedef bool (*SoftwareSurfacePresentCallback)(void* /* user data */,
Expand Down
160 changes: 160 additions & 0 deletions shell/platform/embedder/embedder_external_texture_gl_impeller.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// 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/embedder/embedder_external_texture_gl_impeller.h"

#include "flutter/fml/logging.h"
#include "flutter/impeller/display_list/dl_image_impeller.h"
#include "flutter/impeller/renderer/backend/gles/context_gles.h"
#include "flutter/impeller/renderer/backend/gles/texture_gles.h"
#include "impeller/aiks/aiks_context.h"
#include "impeller/renderer/backend/gles/gles.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"

namespace flutter {

EmbedderExternalTextureGLImpeller::EmbedderExternalTextureGLImpeller(
int64_t texture_identifier,
const EmbedderExternalTextureGL::ExternalTextureCallback& callback)
: Texture(texture_identifier), external_texture_callback_(callback) {
FML_DCHECK(external_texture_callback_);
}

EmbedderExternalTextureGLImpeller::~EmbedderExternalTextureGLImpeller() =
default;

// |flutter::Texture|
void EmbedderExternalTextureGLImpeller::Paint(PaintContext& context,
const SkRect& bounds,
bool freeze,
const DlImageSampling sampling) {
if (last_image_ == nullptr) {
last_image_ =
ResolveTexture(Id(), //
context, //
SkISize::Make(bounds.width(), bounds.height()) //
);
}

DlCanvas* canvas = context.canvas;
const DlPaint* paint = context.paint;

if (last_image_) {
SkRect image_bounds = SkRect::Make(last_image_->bounds());
if (bounds != image_bounds) {
canvas->DrawImageRect(last_image_, image_bounds, bounds, sampling, paint);
} else {
canvas->DrawImage(last_image_, {bounds.x(), bounds.y()}, sampling, paint);
}
}
}

// |flutter::Texture|
void EmbedderExternalTextureGLImpeller::OnGrContextCreated() {}

// |flutter::Texture|
void EmbedderExternalTextureGLImpeller::OnGrContextDestroyed() {}

// |flutter::Texture|
void EmbedderExternalTextureGLImpeller::MarkNewFrameAvailable() {
last_image_ = nullptr;
}

// |flutter::Texture|
void EmbedderExternalTextureGLImpeller::OnTextureUnregistered() {}

sk_sp<DlImage> EmbedderExternalTextureGLImpeller::ResolveTexture(
int64_t texture_id,
PaintContext& context,
const SkISize& size) {
std::unique_ptr<FlutterOpenGLTexture> texture =
external_texture_callback_(texture_id, size.width(), size.height());
if (!texture) {
return nullptr;
}
size_t width = size.width();
size_t height = size.height();
if (texture->width != 0 && texture->height != 0) {
width = texture->width;
height = texture->height;
}
if (texture->impeller_texture_type ==
FlutterGLImpellerTextureType::kFlutterGLImpellerTexturePixelBuffer) {
return ResolvePixelBufferTexture(texture.get(), context,
SkISize::Make(width, height));
} else {
return ResolveGpuSurfaceTexture(texture.get(), context,
SkISize::Make(width, height));
}
}

sk_sp<DlImage> EmbedderExternalTextureGLImpeller::ResolvePixelBufferTexture(
FlutterOpenGLTexture* texture,
PaintContext& context,
const SkISize& size) {
impeller::TextureDescriptor desc;
desc.type = impeller::TextureType::kTexture2D;
impeller::AiksContext* aiks_context = context.aiks_context;
const auto& gl_context =
impeller::ContextGLES::Cast(*aiks_context->GetContext());
desc.storage_mode = impeller::StorageMode::kDevicePrivate;
desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt;
desc.size = {static_cast<int>(size.width()), static_cast<int>(size.height())};
desc.mip_count = 1;

auto textureGLES =
std::make_shared<impeller::TextureGLES>(gl_context.GetReactor(), desc);
if (!textureGLES->SetContents(texture->buffer, texture->buffer_size)) {
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
return nullptr;
}
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
return impeller::DlImageImpeller::Make(textureGLES);
}

sk_sp<DlImage> EmbedderExternalTextureGLImpeller::ResolveGpuSurfaceTexture(
FlutterOpenGLTexture* texture,
PaintContext& context,
const SkISize& size) {
impeller::TextureDescriptor desc;
desc.type = impeller::TextureType::kTextureExternalOES;
impeller::AiksContext* aiks_context = context.aiks_context;
const auto& gl_context =
impeller::ContextGLES::Cast(*aiks_context->GetContext());
desc.storage_mode = impeller::StorageMode::kDevicePrivate;
desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt;
desc.size = {static_cast<int>(size.width()), static_cast<int>(size.height())};
desc.mip_count = 1;
auto textureGLES = std::make_shared<impeller::TextureGLES>(
gl_context.GetReactor(), desc,
impeller::TextureGLES::IsWrapped::kWrapped);
textureGLES->SetCoordinateSystem(
impeller::TextureCoordinateSystem::kUploadFromHost);
if (!textureGLES->Bind()) {
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
return nullptr;
}

if (!texture->bind_callback(texture->user_data)) {
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
return nullptr;
}

if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}

return impeller::DlImageImpeller::Make(textureGLES);
}

} // namespace flutter
62 changes: 62 additions & 0 deletions shell/platform/embedder/embedder_external_texture_gl_impeller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_IMPELLER_H_
#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_IMPELLER_H_

#include "flutter/common/graphics/texture.h"
#include "flutter/fml/macros.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/embedder_external_texture_gl.h"
#include "third_party/skia/include/core/SkSize.h"

namespace flutter {

class EmbedderExternalTextureGLImpeller : public flutter::Texture {
public:
EmbedderExternalTextureGLImpeller(
int64_t texture_identifier,
const EmbedderExternalTextureGL::ExternalTextureCallback& callback);

~EmbedderExternalTextureGLImpeller();

private:
const EmbedderExternalTextureGL::ExternalTextureCallback&
external_texture_callback_;
sk_sp<DlImage> last_image_;

sk_sp<DlImage> ResolveTexture(int64_t texture_id,
PaintContext& context,
const SkISize& size);
sk_sp<DlImage> ResolveGpuSurfaceTexture(FlutterOpenGLTexture* texture,
PaintContext& context,
const SkISize& size);
sk_sp<DlImage> ResolvePixelBufferTexture(FlutterOpenGLTexture* texture,
PaintContext& context,
const SkISize& size);

// |flutter::Texture|
void Paint(PaintContext& context,
const SkRect& bounds,
bool freeze,
const DlImageSampling sampling) override;

// |flutter::Texture|
void OnGrContextCreated() override;

// |flutter::Texture|
void OnGrContextDestroyed() override;

// |flutter::Texture|
void MarkNewFrameAvailable() override;

// |flutter::Texture|
void OnTextureUnregistered() override;

FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureGLImpeller);
};

} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_IMPELLER_H_
15 changes: 13 additions & 2 deletions shell/platform/embedder/embedder_external_texture_resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@

#include "flutter/shell/platform/embedder/embedder_external_texture_resolver.h"

#if defined(SHELL_ENABLE_GL) && defined(IMPELLER_SUPPORTS_RENDERING)
#include "flutter/shell/platform/embedder/embedder_external_texture_gl_impeller.h"
#endif

#include <memory>
#include <utility>

namespace flutter {

#ifdef SHELL_ENABLE_GL
EmbedderExternalTextureResolver::EmbedderExternalTextureResolver(
EmbedderExternalTextureGL::ExternalTextureCallback gl_callback)
: gl_callback_(std::move(gl_callback)) {}
EmbedderExternalTextureGL::ExternalTextureCallback gl_callback,
bool enable_impeller)
: gl_callback_(std::move(gl_callback)), enable_impeller_(enable_impeller) {}
#endif

#ifdef SHELL_ENABLE_METAL
Expand All @@ -25,6 +30,12 @@ std::unique_ptr<Texture>
EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) {
#ifdef SHELL_ENABLE_GL
if (gl_callback_) {
#ifdef IMPELLER_SUPPORTS_RENDERING
if (enable_impeller_) {
return std::make_unique<EmbedderExternalTextureGLImpeller>(texture_id,
gl_callback_);
}
#endif
return std::make_unique<EmbedderExternalTextureGL>(texture_id,
gl_callback_);
}
Expand Down
4 changes: 3 additions & 1 deletion shell/platform/embedder/embedder_external_texture_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class EmbedderExternalTextureResolver {

#ifdef SHELL_ENABLE_GL
explicit EmbedderExternalTextureResolver(
EmbedderExternalTextureGL::ExternalTextureCallback gl_callback);
EmbedderExternalTextureGL::ExternalTextureCallback gl_callback,
bool enable_impeller);
#endif

#ifdef SHELL_ENABLE_METAL
Expand All @@ -46,6 +47,7 @@ class EmbedderExternalTextureResolver {
#ifdef SHELL_ENABLE_METAL
EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback_;
#endif
bool enable_impeller_ = false;

FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureResolver);
};
Expand Down

0 comments on commit ab84814

Please sign in to comment.