Skip to content

Commit d7750d3

Browse files
WIP: external-texture: add kFlutterDesktopGpuSurfaceTexture support
Signed-off-by: Hidenori Matsubayashi <[email protected]>
1 parent ac2a2c6 commit d7750d3

9 files changed

+208
-8
lines changed

cmake/build.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ set(ELINUX_COMMON_SRC
146146
"src/flutter/shell/platform/linux_embedded/task_runner.cc"
147147
"src/flutter/shell/platform/linux_embedded/system_utils.cc"
148148
"src/flutter/shell/platform/linux_embedded/logger.cc"
149+
"src/flutter/shell/platform/linux_embedded/external_texture_d3d.cc"
149150
"src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.cc"
150151
"src/flutter/shell/platform/linux_embedded/external_texture_egl_image.cc"
151152
"src/flutter/shell/platform/linux_embedded/vsync_waiter.cc"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/shell/platform/linux_embedded/external_texture_d3d.h"
6+
7+
#include "flutter/shell/platform/embedder/embedder_struct_macros.h"
8+
#include "flutter/shell/platform/linux_embedded/logger.h"
9+
10+
namespace flutter {
11+
12+
ExternalTextureD3d::ExternalTextureD3d(
13+
const FlutterDesktopGpuSurfaceTextureCallback texture_callback,
14+
void* user_data,
15+
const ELinuxRenderSurfaceTarget* surface_manager,
16+
const GlProcs& gl_procs)
17+
: texture_callback_(texture_callback),
18+
user_data_(user_data),
19+
surface_manager_(surface_manager),
20+
gl_(gl_procs) {}
21+
22+
ExternalTextureD3d::~ExternalTextureD3d() {
23+
ReleaseImage();
24+
25+
if (gl_texture_ != 0) {
26+
gl_.glDeleteTextures(1, &gl_texture_);
27+
}
28+
}
29+
30+
bool ExternalTextureD3d::PopulateTexture(size_t width,
31+
size_t height,
32+
FlutterOpenGLTexture* opengl_texture) {
33+
const FlutterDesktopGpuSurfaceDescriptor* descriptor =
34+
texture_callback_(width, height, user_data_);
35+
36+
if (!CreateOrUpdateTexture(descriptor)) {
37+
return false;
38+
}
39+
40+
// Populate the texture object used by the engine.
41+
opengl_texture->target = GL_TEXTURE_2D;
42+
opengl_texture->name = gl_texture_;
43+
opengl_texture->format = GL_RGBA8_OES;
44+
opengl_texture->destruction_callback = nullptr;
45+
opengl_texture->user_data = nullptr;
46+
opengl_texture->width = SAFE_ACCESS(descriptor, visible_width, 0);
47+
opengl_texture->height = SAFE_ACCESS(descriptor, visible_height, 0);
48+
49+
return true;
50+
}
51+
52+
void ExternalTextureD3d::ReleaseImage() {
53+
if (egl_surface_ != EGL_NO_SURFACE) {
54+
eglReleaseTexImage(surface_manager_->EglDisplay(), egl_surface_,
55+
EGL_BACK_BUFFER);
56+
eglDestroySurface(surface_manager_->EglDisplay(), egl_surface_);
57+
egl_surface_ = EGL_NO_SURFACE;
58+
}
59+
}
60+
61+
bool ExternalTextureD3d::CreateOrUpdateTexture(
62+
const FlutterDesktopGpuSurfaceDescriptor* descriptor) {
63+
if (descriptor == nullptr ||
64+
SAFE_ACCESS(descriptor, handle, nullptr) == nullptr) {
65+
ReleaseImage();
66+
return false;
67+
}
68+
69+
if (gl_texture_ == 0) {
70+
gl_.glGenTextures(1, &gl_texture_);
71+
72+
gl_.glBindTexture(GL_TEXTURE_2D, gl_texture_);
73+
gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
74+
gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
75+
gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
76+
gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
77+
} else {
78+
gl_.glBindTexture(GL_TEXTURE_2D, gl_texture_);
79+
}
80+
81+
auto handle = SAFE_ACCESS(descriptor, handle, nullptr);
82+
if (handle != last_surface_handle_) {
83+
ReleaseImage();
84+
85+
EGLint attributes[] = {
86+
EGL_WIDTH,
87+
static_cast<EGLint>(SAFE_ACCESS(descriptor, width, 0)),
88+
EGL_HEIGHT,
89+
static_cast<EGLint>(SAFE_ACCESS(descriptor, height, 0)),
90+
EGL_TEXTURE_TARGET,
91+
EGL_TEXTURE_2D,
92+
EGL_TEXTURE_FORMAT,
93+
EGL_TEXTURE_RGBA, // always EGL_TEXTURE_RGBA
94+
EGL_NONE};
95+
96+
egl_surface_ = surface_manager_->CreateSurfaceFromHandle(
97+
EGL_OPENVG_IMAGE, handle, attributes);
98+
99+
if (egl_surface_ == EGL_NO_SURFACE ||
100+
eglBindTexImage(surface_manager_->EglDisplay(), egl_surface_,
101+
EGL_BACK_BUFFER) == EGL_FALSE) {
102+
ELINUX_LOG(ERROR) << "Binding D3D surface failed.";
103+
}
104+
last_surface_handle_ = handle;
105+
}
106+
107+
auto release_callback = SAFE_ACCESS(descriptor, release_callback, nullptr);
108+
if (release_callback) {
109+
release_callback(SAFE_ACCESS(descriptor, release_context, nullptr));
110+
}
111+
return egl_surface_ != EGL_NO_SURFACE;
112+
}
113+
114+
} // namespace flutter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_D3D_H_
6+
#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_D3D_H_
7+
8+
#include "flutter/shell/platform/common/public/flutter_texture_registrar.h"
9+
10+
#include "flutter/shell/platform/linux_embedded/external_texture.h"
11+
12+
#include "flutter/shell/platform/linux_embedded/window_binding_handler.h"
13+
14+
namespace flutter {
15+
16+
// An external texture that is backed by a DXGI surface.
17+
class ExternalTextureD3d : public ExternalTexture {
18+
public:
19+
ExternalTextureD3d(
20+
const FlutterDesktopGpuSurfaceTextureCallback texture_callback,
21+
void* user_data,
22+
const ELinuxRenderSurfaceTarget* surface_manager,
23+
const GlProcs& gl_procs);
24+
virtual ~ExternalTextureD3d();
25+
26+
// |ExternalTexture|
27+
bool PopulateTexture(size_t width,
28+
size_t height,
29+
FlutterOpenGLTexture* opengl_texture) override;
30+
31+
private:
32+
// Creates or updates the backing texture and associates it with the provided
33+
// surface.
34+
bool CreateOrUpdateTexture(
35+
const FlutterDesktopGpuSurfaceDescriptor* descriptor);
36+
// Detaches the previously attached surface, if any.
37+
void ReleaseImage();
38+
39+
const FlutterDesktopGpuSurfaceTextureCallback texture_callback_;
40+
void* const user_data_;
41+
const ELinuxRenderSurfaceTarget* surface_manager_;
42+
const GlProcs& gl_;
43+
GLuint gl_texture_ = 0;
44+
EGLSurface egl_surface_ = EGL_NO_SURFACE;
45+
void* last_surface_handle_ = nullptr;
46+
};
47+
48+
} // namespace flutter
49+
50+
#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_D3D_H_

src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project)
160160
std::make_unique<IncomingMessageDispatcher>(messenger_.get());
161161

162162
FlutterELinuxTextureRegistrar::ResolveGlFunctions(gl_procs_);
163-
texture_registrar_ =
164-
std::make_unique<FlutterELinuxTextureRegistrar>(this, gl_procs_);
163+
texture_registrar_ = std::make_unique<FlutterELinuxTextureRegistrar>(
164+
this, view_->GetRenderSurfaceTarget(), gl_procs_);
165165

166166
vsync_waiter_ = std::make_unique<VsyncWaiter>();
167167
}

src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc

+12-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
#include "flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h"
66

77
#include <iostream>
8-
#include <mutex>
98

109
#include "flutter/shell/platform/embedder/embedder_struct_macros.h"
10+
#include "flutter/shell/platform/linux_embedded/external_texture_d3d.h"
1111
#include "flutter/shell/platform/linux_embedded/external_texture_egl_image.h"
1212
#include "flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h"
1313
#include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h"
@@ -21,8 +21,9 @@ namespace flutter {
2121

2222
FlutterELinuxTextureRegistrar::FlutterELinuxTextureRegistrar(
2323
FlutterELinuxEngine* engine,
24+
const ELinuxRenderSurfaceTarget* surface_manager,
2425
const GlProcs& gl_procs)
25-
: engine_(engine), gl_procs_(gl_procs) {}
26+
: engine_(engine), surface_manager_(surface_manager), gl_procs_(gl_procs) {}
2627

2728
int64_t FlutterELinuxTextureRegistrar::RegisterTexture(
2829
const FlutterDesktopTextureInfo* texture_info) {
@@ -49,8 +50,15 @@ int64_t FlutterELinuxTextureRegistrar::RegisterTexture(
4950
texture_info->egl_image_config.callback,
5051
texture_info->egl_image_config.user_data, gl_procs_));
5152
} else if (texture_info->type == kFlutterDesktopGpuSurfaceTexture) {
52-
std::cerr << "GpuSurfaceTexture is not yet supported." << std::endl;
53-
return kInvalidTexture;
53+
if (!texture_info->gpu_surface_config.callback) {
54+
std::cerr << "Invalid gpu surface texture callback." << std::endl;
55+
return kInvalidTexture;
56+
}
57+
58+
return EmplaceTexture(std::make_unique<flutter::ExternalTextureD3d>(
59+
texture_info->gpu_surface_config.callback,
60+
texture_info->gpu_surface_config.user_data, surface_manager_,
61+
gl_procs_));
5462
}
5563

5664
std::cerr << "Attempted to register texture of unsupport type." << std::endl;

src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "flutter/shell/platform/common/public/flutter_texture_registrar.h"
1313
#include "flutter/shell/platform/linux_embedded/external_texture.h"
14+
#include "flutter/shell/platform/linux_embedded/window_binding_handler.h"
1415

1516
namespace flutter {
1617

@@ -20,8 +21,10 @@ class FlutterELinuxEngine;
2021
// Thread safety: All member methods are thread safe.
2122
class FlutterELinuxTextureRegistrar {
2223
public:
23-
explicit FlutterELinuxTextureRegistrar(FlutterELinuxEngine* engine,
24-
const GlProcs& gl_procs);
24+
explicit FlutterELinuxTextureRegistrar(
25+
FlutterELinuxEngine* engine,
26+
const ELinuxRenderSurfaceTarget* surface_manager,
27+
const GlProcs& gl_procs);
2528

2629
// Registers a texture described by the given |texture_info| object.
2730
// Returns the non-zero, positive texture id or -1 on error.
@@ -48,6 +51,7 @@ class FlutterELinuxTextureRegistrar {
4851

4952
private:
5053
FlutterELinuxEngine* engine_ = nullptr;
54+
const ELinuxRenderSurfaceTarget* surface_manager_;
5155
const GlProcs& gl_procs_;
5256

5357
// All registered textures, keyed by their IDs.

src/flutter/shell/platform/linux_embedded/surface/context_egl.cc

+7
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,11 @@ EGLint ContextEgl::GetAttrib(EGLint attribute) {
187187
return value;
188188
}
189189

190+
EGLSurface ContextEgl::CreateSurfaceFromHandle(EGLenum handle_type,
191+
EGLClientBuffer handle,
192+
const EGLint* attributes) const {
193+
return eglCreatePbufferFromClientBuffer(environment_->Display(), handle_type,
194+
handle, config_, attributes);
195+
}
196+
190197
} // namespace flutter

src/flutter/shell/platform/linux_embedded/surface/context_egl.h

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ class ContextEgl {
3636

3737
EGLint GetAttrib(EGLint attribute);
3838

39+
EGLDisplay Display() const { return environment_->Display(); }
40+
41+
EGLSurface CreateSurfaceFromHandle(EGLenum handle_type,
42+
EGLClientBuffer handle,
43+
const EGLint* attributes) const;
44+
3945
protected:
4046
std::unique_ptr<EnvironmentEgl> environment_;
4147
EGLConfig config_;

src/flutter/shell/platform/linux_embedded/surface/surface_gl.h

+10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ class SurfaceGl final : public SurfaceBase, public SurfaceGlDelegate {
3939

4040
// |SurfaceGlDelegate|
4141
void* GlProcResolver(const char* name) const override;
42+
43+
// Gets a EGL display.
44+
EGLDisplay EglDisplay() const { return context_->Display(); }
45+
46+
// Creates a EGLSurface for external GPU texture views.
47+
EGLSurface CreateSurfaceFromHandle(EGLenum handle_type,
48+
EGLClientBuffer handle,
49+
const EGLint* attributes) const {
50+
return context_->CreateSurfaceFromHandle(handle_type, handle, attributes);
51+
}
4252
};
4353

4454
} // namespace flutter

0 commit comments

Comments
 (0)