Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tizen] Support EmbedderExternalTextureGL for impeller #368

Merged
merged 5 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions shell/platform/embedder/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ template("embedder_source_set") {
sources += [
"embedder_external_texture_gl.cc",
"embedder_external_texture_gl.h",
"embedder_external_texture_gl_impeller.cc",
"embedder_external_texture_gl_impeller.h",
JSUYA marked this conversation as resolved.
Show resolved Hide resolved
"embedder_surface_gl.cc",
"embedder_surface_gl.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;
JSUYA marked this conversation as resolved.
Show resolved Hide resolved
/// User data to be returned on the invocation of the destruction callback.
void* user_data;
JSUYA marked this conversation as resolved.
Show resolved Hide resolved
/// 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;
}
JSUYA marked this conversation as resolved.
Show resolved Hide resolved

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_
18 changes: 14 additions & 4 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"

#ifdef SHELL_ENABLE_GL
#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,8 +30,13 @@ std::unique_ptr<Texture>
EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) {
#ifdef SHELL_ENABLE_GL
if (gl_callback_) {
return std::make_unique<EmbedderExternalTextureGL>(texture_id,
gl_callback_);
if (enable_impeller_) {
return std::make_unique<EmbedderExternalTextureGLImpeller>(texture_id,
gl_callback_);
} else {
return std::make_unique<EmbedderExternalTextureGL>(texture_id,
gl_callback_);
}
}
#endif

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