未验证 提交 26e02aaa 编写于 作者: C Chinmay Garde 提交者: GitHub

Wire up support for external OpenGL textures for the embedder. (#7087)

上级 20d70d2b
......@@ -555,6 +555,8 @@ FILE: ../../../flutter/shell/platform/embedder/embedder.cc
FILE: ../../../flutter/shell/platform/embedder/embedder.h
FILE: ../../../flutter/shell/platform/embedder/embedder_engine.cc
FILE: ../../../flutter/shell/platform/embedder/embedder_engine.h
FILE: ../../../flutter/shell/platform/embedder/embedder_external_texture_gl.cc
FILE: ../../../flutter/shell/platform/embedder/embedder_external_texture_gl.h
FILE: ../../../flutter/shell/platform/embedder/embedder_include.c
FILE: ../../../flutter/shell/platform/embedder/embedder_surface.cc
FILE: ../../../flutter/shell/platform/embedder/embedder_surface.h
......
......@@ -18,6 +18,8 @@ source_set("embedder") {
"embedder.h",
"embedder_engine.cc",
"embedder_engine.h",
"embedder_external_texture_gl.cc",
"embedder_external_texture_gl.h",
"embedder_include.c",
"embedder_surface.cc",
"embedder_surface.h",
......@@ -33,6 +35,7 @@ source_set("embedder") {
":embedder_gpu_configuration",
"$flutter_root/assets",
"$flutter_root/common",
"$flutter_root/flow",
"$flutter_root/fml",
"$flutter_root/lib/snapshot",
"$flutter_root/shell/common",
......
......@@ -356,13 +356,65 @@ FlutterResult FlutterEngineRun(size_t version,
return std::make_unique<shell::Rasterizer>(shell.GetTaskRunners());
};
// TODO(chinmaygarde): This is the wrong spot for this. It belongs in the
// platform view jump table.
shell::EmbedderExternalTextureGL::ExternalTextureCallback
external_texture_callback;
if (config->type == kOpenGL) {
const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
if (SAFE_ACCESS(open_gl_config, gl_external_texture_frame_callback,
nullptr) != nullptr) {
external_texture_callback =
[ptr = open_gl_config->gl_external_texture_frame_callback, user_data](
int64_t texture_identifier, GrContext* context,
const SkISize& size) -> sk_sp<SkImage> {
FlutterOpenGLTexture texture = {};
if (!ptr(user_data, texture_identifier, size.width(), size.height(),
&texture)) {
return nullptr;
}
GrGLTextureInfo gr_texture_info = {texture.target, texture.name,
texture.format};
GrBackendTexture gr_backend_texture(size.width(), size.height(),
GrMipMapped::kNo, gr_texture_info);
SkImage::TextureReleaseProc release_proc = texture.destruction_callback;
auto image = SkImage::MakeFromTexture(
context, // context
gr_backend_texture, // texture handle
kTopLeft_GrSurfaceOrigin, // origin
kRGBA_8888_SkColorType, // color type
kPremul_SkAlphaType, // alpha type
nullptr, // colorspace
release_proc, // texture release proc
texture.user_data // texture release context
);
if (!image) {
// In case Skia rejects the image, call the release proc so that
// embedders can perform collection of intermediates.
if (release_proc) {
release_proc(texture.user_data);
}
FML_LOG(ERROR) << "Could not create external texture.";
return nullptr;
}
return image;
};
}
}
// Step 1: Create the engine.
auto embedder_engine =
std::make_unique<shell::EmbedderEngine>(std::move(thread_host), //
std::move(task_runners), //
settings, //
on_create_platform_view, //
on_create_rasterizer //
std::make_unique<shell::EmbedderEngine>(std::move(thread_host), //
std::move(task_runners), //
settings, //
on_create_platform_view, //
on_create_rasterizer, //
external_texture_callback //
);
if (!embedder_engine->IsValid()) {
......@@ -524,3 +576,43 @@ FlutterResult __FlutterEngineFlushPendingTasksNow() {
fml::MessageLoop::GetCurrent().RunExpiredTasksNow();
return kSuccess;
}
FlutterResult FlutterEngineRegisterExternalTexture(FlutterEngine engine,
int64_t texture_identifier) {
if (engine == nullptr || texture_identifier == 0) {
return kInvalidArguments;
}
if (!reinterpret_cast<shell::EmbedderEngine*>(engine)->RegisterTexture(
texture_identifier)) {
return kInternalInconsistency;
}
return kSuccess;
}
FlutterResult FlutterEngineUnregisterExternalTexture(
FlutterEngine engine,
int64_t texture_identifier) {
if (engine == nullptr || texture_identifier == 0) {
return kInvalidArguments;
}
if (!reinterpret_cast<shell::EmbedderEngine*>(engine)->UnregisterTexture(
texture_identifier)) {
return kInternalInconsistency;
}
return kSuccess;
}
FlutterResult FlutterEngineMarkExternalTextureFrameAvailable(
FlutterEngine engine,
int64_t texture_identifier) {
if (engine == nullptr || texture_identifier == 0) {
return kInvalidArguments;
}
if (!reinterpret_cast<shell::EmbedderEngine*>(engine)
->MarkTextureFrameAvailable(texture_identifier)) {
return kInternalInconsistency;
}
return kSuccess;
}
......@@ -23,6 +23,7 @@ typedef enum {
kSuccess = 0,
kInvalidLibraryVersion,
kInvalidArguments,
kInternalInconsistency,
} FlutterResult;
typedef enum {
......@@ -53,6 +54,22 @@ typedef struct {
double pers2;
} FlutterTransformation;
typedef void (*VoidCallback)(void* /* user data */);
typedef struct {
// Target texture of the active texture unit (example GL_TEXTURE_2D).
uint32_t target;
// The name of the texture.
uint32_t name;
// The texture format (example GL_RGBA8).
uint32_t format;
// 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
// collect the texture.
VoidCallback destruction_callback;
} FlutterOpenGLTexture;
typedef bool (*BoolCallback)(void* /* user data */);
typedef FlutterTransformation (*TransformationCallback)(void* /* user data */);
typedef uint32_t (*UIntCallback)(void* /* user data */);
......@@ -61,6 +78,11 @@ typedef bool (*SoftwareSurfacePresentCallback)(void* /* user data */,
size_t /* row bytes */,
size_t /* height */);
typedef void* (*ProcResolver)(void* /* user data */, const char* /* name */);
typedef bool (*TextureFrameCallback)(void* /* user data */,
int64_t /* texture identifier */,
size_t /* width */,
size_t /* height */,
FlutterOpenGLTexture* /* texture out */);
typedef struct {
// The size of this struct. Must be sizeof(FlutterOpenGLRendererConfig).
......@@ -79,6 +101,11 @@ typedef struct {
// operations. This callback is optional.
TransformationCallback surface_transformation;
ProcResolver gl_proc_resolver;
// When the embedder specifies that a texture has a frame available, the
// engine will call this method (on an internal engine managed thread) so that
// external texture details can be suppplied to the engine for subsequent
// composition.
TextureFrameCallback gl_external_texture_frame_callback;
} FlutterOpenGLRendererConfig;
typedef struct {
......@@ -220,6 +247,27 @@ FlutterResult FlutterEngineSendPlatformMessageResponse(
FLUTTER_EXPORT
FlutterResult __FlutterEngineFlushPendingTasksNow();
// Register an external texture with a unique (per engine) identifier. Only
// rendering backends that support external textures accept external texture
// registrations. After the external texture is registered, the application can
// mark that a frame is available by calling
// |FlutterEngineMarkExternalTextureFrameAvailable|.
FLUTTER_EXPORT
FlutterResult FlutterEngineRegisterExternalTexture(FlutterEngine engine,
int64_t texture_identifier);
// Unregister a previous texture registration.
FLUTTER_EXPORT
FlutterResult FlutterEngineUnregisterExternalTexture(
FlutterEngine engine,
int64_t texture_identifier);
// Mark that a new texture frame is available for a given texture identifier.
FLUTTER_EXPORT
FlutterResult FlutterEngineMarkExternalTextureFrameAvailable(
FlutterEngine engine,
int64_t texture_identifier);
#if defined(__cplusplus)
} // extern "C"
#endif
......
......@@ -13,12 +13,15 @@ EmbedderEngine::EmbedderEngine(
blink::TaskRunners task_runners,
blink::Settings settings,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer)
Shell::CreateCallback<Rasterizer> on_create_rasterizer,
EmbedderExternalTextureGL::ExternalTextureCallback
external_texture_callback)
: thread_host_(std::move(thread_host)),
shell_(Shell::Create(std::move(task_runners),
std::move(settings),
on_create_platform_view,
on_create_rasterizer)) {
on_create_rasterizer)),
external_texture_callback_(external_texture_callback) {
is_valid_ = shell_ != nullptr;
}
......@@ -112,4 +115,30 @@ bool EmbedderEngine::SendPlatformMessage(
return true;
}
bool EmbedderEngine::RegisterTexture(int64_t texture) {
if (!IsValid() || !external_texture_callback_) {
return false;
}
shell_->GetPlatformView()->RegisterTexture(
std::make_unique<EmbedderExternalTextureGL>(texture,
external_texture_callback_));
return true;
}
bool EmbedderEngine::UnregisterTexture(int64_t texture) {
if (!IsValid() || !external_texture_callback_) {
return false;
}
shell_->GetPlatformView()->UnregisterTexture(texture);
return true;
}
bool EmbedderEngine::MarkTextureFrameAvailable(int64_t texture) {
if (!IsValid() || !external_texture_callback_) {
return false;
}
shell_->GetPlatformView()->MarkTextureFrameAvailable(texture);
return true;
}
} // namespace shell
......@@ -11,6 +11,7 @@
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/embedder_external_texture_gl.h"
namespace shell {
......@@ -22,7 +23,9 @@ class EmbedderEngine {
blink::TaskRunners task_runners,
blink::Settings settings,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer);
Shell::CreateCallback<Rasterizer> on_create_rasterizer,
EmbedderExternalTextureGL::ExternalTextureCallback
external_texture_callback);
~EmbedderEngine();
......@@ -41,9 +44,17 @@ class EmbedderEngine {
bool SendPlatformMessage(fml::RefPtr<blink::PlatformMessage> message);
bool RegisterTexture(int64_t texture);
bool UnregisterTexture(int64_t texture);
bool MarkTextureFrameAvailable(int64_t texture);
private:
const ThreadHost thread_host_;
std::unique_ptr<Shell> shell_;
const EmbedderExternalTextureGL::ExternalTextureCallback
external_texture_callback_;
bool is_valid_ = false;
FML_DISALLOW_COPY_AND_ASSIGN(EmbedderEngine);
......
// 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.h"
#include "flutter/fml/logging.h"
namespace shell {
EmbedderExternalTextureGL::EmbedderExternalTextureGL(
int64_t texture_identifier,
ExternalTextureCallback callback)
: Texture(texture_identifier), external_texture_callback_(callback) {
FML_DCHECK(external_texture_callback_);
}
EmbedderExternalTextureGL::~EmbedderExternalTextureGL() = default;
// |flow::Texture|
void EmbedderExternalTextureGL::Paint(SkCanvas& canvas,
const SkRect& bounds,
bool freeze) {
if (auto image = external_texture_callback_(
Id(), //
canvas.getGrContext(), //
SkISize::Make(bounds.width(), bounds.height()) //
)) {
last_image_ = image;
}
if (last_image_) {
canvas.drawImage(last_image_, bounds.x(), bounds.y());
}
}
// |flow::Texture|
void EmbedderExternalTextureGL::OnGrContextCreated() {}
// |flow::Texture|
void EmbedderExternalTextureGL::OnGrContextDestroyed() {}
// |flow::Texture|
void EmbedderExternalTextureGL::MarkNewFrameAvailable() {}
} // namespace shell
// 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_H_
#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_H_
#include "flutter/flow/texture.h"
#include "flutter/fml/macros.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSize.h"
namespace shell {
class EmbedderExternalTextureGL : public flow::Texture {
public:
using ExternalTextureCallback = std::function<
sk_sp<SkImage>(int64_t texture_identifier, GrContext*, const SkISize&)>;
EmbedderExternalTextureGL(int64_t texture_identifier,
ExternalTextureCallback callback);
~EmbedderExternalTextureGL();
private:
ExternalTextureCallback external_texture_callback_;
sk_sp<SkImage> last_image_;
// |flow::Texture|
void Paint(SkCanvas& canvas, const SkRect& bounds, bool freeze) override;
// |flow::Texture|
void OnGrContextCreated() override;
// |flow::Texture|
void OnGrContextDestroyed() override;
// |flow::Texture|
void MarkNewFrameAvailable() override;
FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureGL);
};
} // namespace shell
#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册