Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 409e92d

Browse files
committed
Windows: Add D3D texture interoperability support
1 parent e6b9442 commit 409e92d

16 files changed

Lines changed: 462 additions & 130 deletions

ci/licenses_golden/licenses_flutter

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,8 +1697,11 @@ FILE: ../../../flutter/shell/platform/windows/display_helper_winuwp.h
16971697
FILE: ../../../flutter/shell/platform/windows/dpi_utils_win32.cc
16981698
FILE: ../../../flutter/shell/platform/windows/dpi_utils_win32.h
16991699
FILE: ../../../flutter/shell/platform/windows/dpi_utils_win32_unittests.cc
1700-
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.cc
1701-
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.h
1700+
FILE: ../../../flutter/shell/platform/windows/external_texture.h
1701+
FILE: ../../../flutter/shell/platform/windows/external_texture_d3d.cc
1702+
FILE: ../../../flutter/shell/platform/windows/external_texture_d3d.h
1703+
FILE: ../../../flutter/shell/platform/windows/external_texture_pixelbuffer.cc
1704+
FILE: ../../../flutter/shell/platform/windows/external_texture_pixelbuffer.h
17021705
FILE: ../../../flutter/shell/platform/windows/flutter_key_map.cc
17031706
FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle.cc
17041707
FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle.h

shell/platform/common/client_wrapper/core_implementations.cc

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,25 +157,35 @@ TextureRegistrarImpl::TextureRegistrarImpl(
157157
TextureRegistrarImpl::~TextureRegistrarImpl() = default;
158158

159159
int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) {
160+
FlutterDesktopTextureInfo info = {};
160161
if (auto pixel_buffer_texture = std::get_if<PixelBufferTexture>(texture)) {
161-
FlutterDesktopTextureInfo info = {};
162162
info.type = kFlutterDesktopPixelBufferTexture;
163163
info.pixel_buffer_config.user_data = pixel_buffer_texture;
164164
info.pixel_buffer_config.callback =
165165
[](size_t width, size_t height,
166166
void* user_data) -> const FlutterDesktopPixelBuffer* {
167167
auto texture = static_cast<PixelBufferTexture*>(user_data);
168-
auto buffer = texture->CopyPixelBuffer(width, height);
169-
return buffer;
168+
return texture->CopyPixelBuffer(width, height);
170169
};
171-
172-
int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture(
173-
texture_registrar_ref_, &info);
174-
return texture_id;
170+
} else if (auto gpu_surface_texture =
171+
std::get_if<GpuSurfaceTexture>(texture)) {
172+
info.type = kFlutterDesktopGpuSurfaceTexture;
173+
info.gpu_surface_config.type = gpu_surface_texture->surface_type();
174+
info.gpu_surface_config.user_data = gpu_surface_texture;
175+
info.gpu_surface_config.callback =
176+
[](size_t width, size_t height,
177+
void* user_data) -> const FlutterDesktopGpuSurfaceDescriptor* {
178+
auto texture = static_cast<GpuSurfaceTexture*>(user_data);
179+
return texture->ObtainDescriptor(width, height);
180+
};
181+
} else {
182+
std::cerr << "Attempting to register unknown texture variant." << std::endl;
183+
return -1;
175184
}
176185

177-
std::cerr << "Attempting to register unknown texture variant." << std::endl;
178-
return -1;
186+
int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture(
187+
texture_registrar_ref_, &info);
188+
return texture_id;
179189
} // namespace flutter
180190

181191
bool TextureRegistrarImpl::MarkTextureFrameAvailable(int64_t texture_id) {

shell/platform/common/client_wrapper/include/flutter/texture_registrar.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,40 @@ class PixelBufferTexture {
4242
const CopyBufferCallback copy_buffer_callback_;
4343
};
4444

45+
// A GPU surface-based texture.
46+
class GpuSurfaceTexture {
47+
public:
48+
// A callback used for retrieving surface descriptors.
49+
typedef std::function<
50+
const FlutterDesktopGpuSurfaceDescriptor*(size_t width, size_t height)>
51+
ObtainDescriptorCallback;
52+
53+
GpuSurfaceTexture(FlutterDesktopGpuSurfaceType surface_type,
54+
ObtainDescriptorCallback obtain_descriptor_callback)
55+
: surface_type_(surface_type),
56+
obtain_descriptor_callback_(obtain_descriptor_callback) {}
57+
58+
// Returns the callback-provided FlutterDesktopGpuSurfaceDescriptor that
59+
// contains the surface handle. The intended surface size is specified by
60+
// |width| and |height|.
61+
const FlutterDesktopGpuSurfaceDescriptor* ObtainDescriptor(
62+
size_t width,
63+
size_t height) const {
64+
return obtain_descriptor_callback_(width, height);
65+
}
66+
67+
// Gets the surface type.
68+
FlutterDesktopGpuSurfaceType surface_type() const { return surface_type_; }
69+
70+
private:
71+
const FlutterDesktopGpuSurfaceType surface_type_;
72+
const ObtainDescriptorCallback obtain_descriptor_callback_;
73+
};
74+
4575
// The available texture variants.
4676
// Only PixelBufferTexture is currently implemented.
4777
// Other variants are expected to be added in the future.
48-
typedef std::variant<PixelBufferTexture> TextureVariant;
78+
typedef std::variant<PixelBufferTexture, GpuSurfaceTexture> TextureVariant;
4979

5080
// An object keeping track of external textures.
5181
//

shell/platform/common/public/flutter_texture_registrar.h

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,31 @@ typedef struct FlutterDesktopTextureRegistrar*
2323
// Additional types may be added in the future.
2424
typedef enum {
2525
// A Pixel buffer-based texture.
26-
kFlutterDesktopPixelBufferTexture
26+
kFlutterDesktopPixelBufferTexture,
27+
// A platform-specific GPU surface-backed texture.
28+
kFlutterDesktopGpuSurfaceTexture
2729
} FlutterDesktopTextureType;
2830

31+
// Supported GPU surface types.
32+
typedef enum {
33+
// Uninitialized.
34+
kFlutterDesktopGpuSurfaceTypeNone,
35+
// A D3D/DXGI-based surface.
36+
kFlutterDesktopGpuSurfaceTypeDxgi
37+
} FlutterDesktopGpuSurfaceType;
38+
39+
// Supported pixel formats.
40+
typedef enum {
41+
// Uninitialized.
42+
kFlutterDesktopPixelFormatNone,
43+
// Represents a 32-bit RGBA color format with 8 bits each for red, green, blue
44+
// and alpha.
45+
kFlutterDesktopPixelFormatRGBA8888,
46+
// Represents a 32-bit BGRA color format with 8 bits each for blue, green, red
47+
// and alpha.
48+
kFlutterDesktopPixelFormatBGRA8888
49+
} FlutterDesktopPixelFormat;
50+
2951
// An image buffer object.
3052
typedef struct {
3153
// The pixel data buffer.
@@ -40,6 +62,26 @@ typedef struct {
4062
void* release_context;
4163
} FlutterDesktopPixelBuffer;
4264

65+
// A GPU surface descriptor.
66+
typedef struct {
67+
// The surface handle.
68+
// For DirectX textures (kFlutterDesktopGpuSurfaceTypeDxgi), this is the
69+
// shared handle of an IDXGIResource.
70+
void* handle;
71+
// The physical width.
72+
size_t width;
73+
// The physical height.
74+
size_t height;
75+
// The visible width.
76+
// It might be less or equal to the physical |width|.
77+
size_t visible_width;
78+
// The visible height.
79+
// It might be less or equal to the physical |height|.
80+
size_t visible_height;
81+
// The pixel format which might by optional depending on the surface type.
82+
FlutterDesktopPixelFormat format;
83+
} FlutterDesktopGpuSurfaceDescriptor;
84+
4385
// The pixel buffer copy callback definition provided to
4486
// the Flutter engine to copy the texture.
4587
// It is invoked with the intended surface size specified by |width| and
@@ -54,6 +96,11 @@ typedef const FlutterDesktopPixelBuffer* (
5496
size_t height,
5597
void* user_data);
5698

99+
typedef const FlutterDesktopGpuSurfaceDescriptor* (
100+
*FlutterDesktopGpuSurfaceTextureCallback)(size_t width,
101+
size_t height,
102+
void* user_data);
103+
57104
// An object used to configure pixel buffer textures.
58105
typedef struct {
59106
// The callback used by the engine to copy the pixel buffer object.
@@ -62,10 +109,21 @@ typedef struct {
62109
void* user_data;
63110
} FlutterDesktopPixelBufferTextureConfig;
64111

112+
// An object used to configure GPU-surface textures.
113+
typedef struct {
114+
// The concrete surface type (e.g. kFlutterDesktopGpuSurfaceTypeDxgi)
115+
FlutterDesktopGpuSurfaceType type;
116+
// The callback used by the engine to obtain the surface descriptor.
117+
FlutterDesktopGpuSurfaceTextureCallback callback;
118+
// Opaque data that will get passed to the provided |callback|.
119+
void* user_data;
120+
} FlutterDesktopGpuSurfaceTextureConfig;
121+
65122
typedef struct {
66123
FlutterDesktopTextureType type;
67124
union {
68125
FlutterDesktopPixelBufferTextureConfig pixel_buffer_config;
126+
FlutterDesktopGpuSurfaceTextureConfig gpu_surface_config;
69127
};
70128
} FlutterDesktopTextureInfo;
71129

shell/platform/windows/BUILD.gn

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@ source_set("flutter_windows_source") {
5353
"angle_surface_manager.h",
5454
"cursor_handler.cc",
5555
"cursor_handler.h",
56-
"external_texture_gl.cc",
57-
"external_texture_gl.h",
56+
"external_texture.h",
57+
"external_texture_d3d.cc",
58+
"external_texture_d3d.h",
59+
"external_texture_pixelbuffer.cc",
60+
"external_texture_pixelbuffer.h",
5861
"flutter_key_map.cc",
5962
"flutter_project_bundle.cc",
6063
"flutter_project_bundle.h",

shell/platform/windows/angle_surface_manager.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,4 +326,12 @@ EGLBoolean AngleSurfaceManager::SwapBuffers() {
326326
return (eglSwapBuffers(egl_display_, render_surface_));
327327
}
328328

329+
EGLSurface AngleSurfaceManager::CreateSurfaceFromHandle(
330+
EGLenum handle_type,
331+
EGLClientBuffer handle,
332+
const EGLint* attributes) const {
333+
return eglCreatePbufferFromClientBuffer(egl_display_, handle_type, handle,
334+
egl_config_, attributes);
335+
}
336+
329337
} // namespace flutter

shell/platform/windows/angle_surface_manager.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ class AngleSurfaceManager {
6969
// not null.
7070
EGLBoolean SwapBuffers();
7171

72+
// Creates a |EGLSurface| from the provided handle.
73+
EGLSurface CreateSurfaceFromHandle(EGLenum handle_type,
74+
EGLClientBuffer handle,
75+
const EGLint* attributes) const;
76+
77+
// Gets the |EGLDisplay|.
78+
EGLDisplay egl_display() const { return egl_display_; };
79+
7280
private:
7381
bool Initialize();
7482
void CleanUp();
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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_WINDOWS_EXTERNAL_TEXTURE_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_H_
7+
8+
#include "flutter/shell/platform/embedder/embedder.h"
9+
10+
#include <GLES2/gl2.h>
11+
#include <GLES2/gl2ext.h>
12+
13+
namespace flutter {
14+
15+
typedef void (*glGenTexturesProc)(GLsizei n, GLuint* textures);
16+
typedef void (*glDeleteTexturesProc)(GLsizei n, const GLuint* textures);
17+
typedef void (*glBindTextureProc)(GLenum target, GLuint texture);
18+
typedef void (*glTexParameteriProc)(GLenum target, GLenum pname, GLint param);
19+
typedef void (*glTexImage2DProc)(GLenum target,
20+
GLint level,
21+
GLint internalformat,
22+
GLsizei width,
23+
GLsizei height,
24+
GLint border,
25+
GLenum format,
26+
GLenum type,
27+
const void* data);
28+
29+
// A struct containing pointers to resolved gl* functions.
30+
struct GlProcs {
31+
glGenTexturesProc glGenTextures;
32+
glDeleteTexturesProc glDeleteTextures;
33+
glBindTextureProc glBindTexture;
34+
glTexParameteriProc glTexParameteri;
35+
glTexImage2DProc glTexImage2D;
36+
bool valid;
37+
};
38+
39+
// Abstract external texture.
40+
class ExternalTexture {
41+
public:
42+
virtual ~ExternalTexture() = default;
43+
44+
// Returns the unique id of this texture.
45+
int64_t texture_id() const { return reinterpret_cast<int64_t>(this); };
46+
47+
// Attempts to populate the specified |opengl_texture| with texture details
48+
// such as the name, width, height and the pixel format.
49+
// Returns true on success.
50+
virtual bool PopulateTexture(size_t width,
51+
size_t height,
52+
FlutterOpenGLTexture* opengl_texture) = 0;
53+
};
54+
55+
} // namespace flutter
56+
57+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_H_

0 commit comments

Comments
 (0)