Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
9 changes: 1 addition & 8 deletions engine/src/flutter/shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,6 @@ 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 @@ -513,13 +512,6 @@ 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;

/// 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 @@ -613,6 +605,7 @@ typedef struct {
uint32_t format;
} FlutterOpenGLSurface;

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
Original file line number Diff line number Diff line change
Expand Up @@ -129,107 +129,136 @@ sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureSkia(
return DlImage::Make(std::move(image));
}

sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpeller(
int64_t texture_id,
impeller::AiksContext* aiks_context,
const SkISize& size) {
std::unique_ptr<FlutterOpenGLTexture> texture =
external_texture_callback_(texture_id, size.width(), size.height());
bool EmbedderExternalTextureGL::IsExternalTextureChanged(
FlutterOpenGLTexture* texture) {
if (static_cast<int64_t>(texture->width) != desc_.size.width ||
static_cast<int64_t>(texture->height) != desc_.size.height) {
return true;
}

if (!texture) {
return nullptr;
if (!texture_image_) {
return true;
}

if (texture->bind_callback != nullptr) {
return ResolveTextureImpellerSurface(aiks_context, std::move(texture));
} else {
return ResolveTextureImpellerPixelbuffer(aiks_context, std::move(texture));
auto handle = texture_image_->GetGLHandle();
if (!handle.has_value()) {
return true;
}

if (handle.value() != texture->name) {
return true;
}

return false;
}

sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpellerPixelbuffer(
std::shared_ptr<impeller::TextureGLES>
EmbedderExternalTextureGL::CreateImpellerTexture(
impeller::AiksContext* aiks_context,
std::unique_ptr<FlutterOpenGLTexture> texture) {
FlutterOpenGLTexture* texture) {
impeller::TextureDescriptor desc;
desc.size = impeller::ISize(texture->width, texture->height);
desc.type = impeller::TextureType::kTexture2D;
desc.storage_mode = impeller::StorageMode::kDevicePrivate;
desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt;
if (texture->target == GL_TEXTURE_EXTERNAL_OES) {
desc.type = impeller::TextureType::kTextureExternalOES;
} else {
desc.type = impeller::TextureType::kTexture2D;
}

impeller::ContextGLES& context =
impeller::ContextGLES::Cast(*aiks_context->GetContext());
std::shared_ptr<impeller::TextureGLES> image =
std::make_shared<impeller::TextureGLES>(context.GetReactor(), desc);
impeller::HandleGLES handle = context.GetReactor()->CreateHandle(
impeller::HandleType::kTexture, texture->name);

image->MarkContentsInitialized();
if (!image->SetContents(texture->buffer, texture->buffer_size)) {
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
return nullptr;
}
std::shared_ptr<impeller::TextureGLES> texture_image =
impeller::TextureGLES::WrapTexture(context.GetReactor(), desc, handle);

if (!image) {
// In case Skia rejects the image, call the release proc so that
// embedders can perform collection of intermediates.
if (!texture_image) {
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
FML_LOG(ERROR) << "Could not create external texture";
FML_LOG(ERROR) << "Could not create external texture with name: "
<< texture->name << ", size: " << texture->width << "x"
<< texture->height;
return nullptr;
}

texture_image->SetCoordinateSystem(
impeller::TextureCoordinateSystem::kUploadFromHost);

if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
if (!context.GetReactor()->RegisterCleanupCallback(
handle,
[callback = texture->destruction_callback,
user_data = texture->user_data]() { callback(user_data); })) {
FML_LOG(ERROR) << "Could not register destruction callback for texture: "
<< texture->name;
texture_image.reset();
return nullptr;
}
}

return impeller::DlImageImpeller::Make(image);
desc_ = desc;
return texture_image;
}

sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpellerSurface(
impeller::AiksContext* aiks_context,
std::unique_ptr<FlutterOpenGLTexture> texture) {
impeller::TextureDescriptor desc;
desc.size = impeller::ISize(texture->width, texture->height);
desc.storage_mode = impeller::StorageMode::kDevicePrivate;
desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt;
desc.type = impeller::TextureType::kTextureExternalOES;
impeller::ContextGLES& context =
impeller::ContextGLES::Cast(*aiks_context->GetContext());
std::shared_ptr<impeller::TextureGLES> image =
std::make_shared<impeller::TextureGLES>(context.GetReactor(), desc);
image->MarkContentsInitialized();
image->SetCoordinateSystem(
impeller::TextureCoordinateSystem::kUploadFromHost);
if (!image->Bind()) {
bool EmbedderExternalTextureGL::ValidateTextureParameters(
FlutterOpenGLTexture* texture,
const SkISize& size) {
if (size.width() <= 0 || size.height() <= 0) {
FML_LOG(ERROR) << "Invalid texture size: " << size.width() << "x"
<< size.height();
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
FML_LOG(ERROR) << "Could not bind texture";
return nullptr;
return false;
}

if (!image) {
// In case Skia rejects the image, call the release proc so that
// embedders can perform collection of intermediates.
if (texture->name == 0) {
FML_LOG(ERROR) << "Invalid texture name (0)";
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
FML_LOG(ERROR) << "Could not create external texture";
return false;
}

return true;
}

sk_sp<DlImage> EmbedderExternalTextureGL::ResolveTextureImpeller(
int64_t texture_id,
impeller::AiksContext* aiks_context,
const SkISize& size) {
std::unique_ptr<FlutterOpenGLTexture> texture =
external_texture_callback_(texture_id, size.width(), size.height());

if (!texture) {
FML_LOG(ERROR) << "External texture callback returned null for texture_id: "
<< texture_id;
return nullptr;
}

if (!texture->bind_callback(texture->user_data)) {
if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
}
if (!ValidateTextureParameters(texture.get(), size)) {
return nullptr;
}

if (texture->destruction_callback) {
texture->destruction_callback(texture->user_data);
if (!texture_image_) {
texture_image_ = CreateImpellerTexture(aiks_context, texture.get());
} else {
if (IsExternalTextureChanged(texture.get())) {
texture_image_.reset();
texture_image_ = CreateImpellerTexture(aiks_context, texture.get());
}
}

if (texture_image_ == nullptr) {
FML_LOG(ERROR) << "Failed to create Impeller texture for texture_id: "
<< texture_id;
return nullptr;
}

return impeller::DlImageImpeller::Make(image);
return impeller::DlImageImpeller::Make(texture_image_);
}

// |flutter::Texture|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "flutter/common/graphics/texture.h"
#include "flutter/fml/macros.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "impeller/renderer/backend/gles/texture_gles.h"
#include "third_party/skia/include/core/SkSize.h"

namespace flutter {
Expand All @@ -25,7 +26,8 @@ class EmbedderExternalTextureGL : public flutter::Texture {
private:
const ExternalTextureCallback& external_texture_callback_;
sk_sp<DlImage> last_image_;

std::shared_ptr<impeller::TextureGLES> texture_image_ = nullptr;
impeller::TextureDescriptor desc_;
sk_sp<DlImage> ResolveTexture(int64_t texture_id,
GrDirectContext* context,
impeller::AiksContext* aiks_context,
Expand All @@ -39,13 +41,14 @@ class EmbedderExternalTextureGL : public flutter::Texture {
impeller::AiksContext* aiks_context,
const SkISize& size);

sk_sp<DlImage> ResolveTextureImpellerPixelbuffer(
impeller::AiksContext* aiks_context,
std::unique_ptr<FlutterOpenGLTexture> texture);
bool ValidateTextureParameters(FlutterOpenGLTexture* texture,
const SkISize& size);

bool IsExternalTextureChanged(FlutterOpenGLTexture* texture);

sk_sp<DlImage> ResolveTextureImpellerSurface(
std::shared_ptr<impeller::TextureGLES> CreateImpellerTexture(
impeller::AiksContext* aiks_context,
std::unique_ptr<FlutterOpenGLTexture> texture);
FlutterOpenGLTexture* texture);

// |flutter::Texture|
void Paint(PaintContext& context,
Expand Down
Loading