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

Commit 21614f6

Browse files
committed
Windows: Add Direct3D texture interopability support
1 parent b9616ca commit 21614f6

16 files changed

+447
-177
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,8 +1578,12 @@ FILE: ../../../flutter/shell/platform/windows/display_helper_winuwp.h
15781578
FILE: ../../../flutter/shell/platform/windows/dpi_utils_win32.cc
15791579
FILE: ../../../flutter/shell/platform/windows/dpi_utils_win32.h
15801580
FILE: ../../../flutter/shell/platform/windows/dpi_utils_win32_unittests.cc
1581-
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.cc
1582-
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.h
1581+
FILE: ../../../flutter/shell/platform/windows/external_texture.cc
1582+
FILE: ../../../flutter/shell/platform/windows/external_texture.h
1583+
FILE: ../../../flutter/shell/platform/windows/external_texture_d3d.cc
1584+
FILE: ../../../flutter/shell/platform/windows/external_texture_d3d.h
1585+
FILE: ../../../flutter/shell/platform/windows/external_texture_pixelbuffer.cc
1586+
FILE: ../../../flutter/shell/platform/windows/external_texture_pixelbuffer.h
15831587
FILE: ../../../flutter/shell/platform/windows/flutter_key_map.cc
15841588
FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle.cc
15851589
FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle.h

shell/platform/common/client_wrapper/core_implementations.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,20 @@ int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) {
174174
return texture_id;
175175
}
176176

177+
if (auto gpu_surface_texture = std::get_if<GpuSurfaceTexture>(texture)) {
178+
FlutterDesktopTextureInfo info = {};
179+
info.type = kFlutterDesktopGpuSurfaceTexture;
180+
auto& desc = info.gpu_surface_descriptor;
181+
desc.handle = gpu_surface_texture->handle();
182+
desc.width = gpu_surface_texture->width();
183+
desc.height = gpu_surface_texture->height();
184+
desc.format = gpu_surface_texture->format();
185+
186+
int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture(
187+
texture_registrar_ref_, &info);
188+
return texture_id;
189+
}
190+
177191
std::cerr << "Attempting to register unknown texture variant." << std::endl;
178192
return -1;
179193
} // namespace flutter

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,29 @@ class PixelBufferTexture {
4242
const CopyBufferCallback copy_buffer_callback_;
4343
};
4444

45+
class GpuSurfaceTexture {
46+
public:
47+
GpuSurfaceTexture(
48+
void* handle,
49+
size_t width,
50+
size_t height,
51+
FlutterDesktopPixelFormat format = kFlutterDesktopPixelFormatNone)
52+
: handle_(handle), width_(width), height_(height), format_(format) {}
53+
54+
constexpr size_t width() const { return width_; }
55+
constexpr size_t height() const { return height_; }
56+
constexpr void* handle() const { return handle_; }
57+
constexpr FlutterDesktopPixelFormat format() const { return format_; }
58+
59+
private:
60+
const size_t width_;
61+
const size_t height_;
62+
void* const handle_;
63+
const FlutterDesktopPixelFormat format_;
64+
};
65+
4566
// The available texture variants.
46-
// Only PixelBufferTexture is currently implemented.
47-
// Other variants are expected to be added in the future.
48-
typedef std::variant<PixelBufferTexture> TextureVariant;
67+
typedef std::variant<PixelBufferTexture, GpuSurfaceTexture> TextureVariant;
4968

5069
// An object keeping track of external textures.
5170
//

shell/platform/common/public/flutter_texture_registrar.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,24 @@ typedef struct FlutterDesktopTextureRegistrar*
2222
// Possible values for the type specified in FlutterDesktopTextureInfo.
2323
// Additional types may be added in the future.
2424
typedef enum {
25-
// A Pixel buffer-based texture.
26-
kFlutterDesktopPixelBufferTexture
25+
// A generic pixel buffer-based texture.
26+
kFlutterDesktopPixelBufferTexture,
27+
// A platform-specific GPU surface-backed texture.
28+
kFlutterDesktopGpuSurfaceTexture
2729
} FlutterDesktopTextureType;
2830

31+
// Supported pixel formats.
32+
typedef enum {
33+
// Uninitialized.
34+
kFlutterDesktopPixelFormatNone,
35+
// Represents a 32-bit RGBA color format with 8 bits each for red, green, blue
36+
// and alpha.
37+
kFlutterDesktopPixelFormatRGBA8888,
38+
// Represents a 32-bit BGRA color format with 8 bits each for blue, green, red
39+
// and alpha.
40+
kFlutterDesktopPixelFormatBGRA8888
41+
} FlutterDesktopPixelFormat;
42+
2943
// An image buffer object.
3044
typedef struct {
3145
// The pixel data buffer.
@@ -36,6 +50,19 @@ typedef struct {
3650
size_t height;
3751
} FlutterDesktopPixelBuffer;
3852

53+
// A GPU surface descriptor.
54+
typedef struct {
55+
// The surface handle.
56+
// For DirectX textures, this is the shared handle of an IDXGIResource.
57+
void* handle;
58+
// The width of the surface.
59+
size_t width;
60+
// The height of the surface.
61+
size_t height;
62+
// The pixel format which might by optional depending on the surface type.
63+
FlutterDesktopPixelFormat format;
64+
} FlutterDesktopGpuSurfaceDescriptor;
65+
3966
// The pixel buffer copy callback definition provided to
4067
// the Flutter engine to copy the texture.
4168
// It is invoked with the intended surface size specified by |width| and
@@ -62,6 +89,7 @@ typedef struct {
6289
FlutterDesktopTextureType type;
6390
union {
6491
FlutterDesktopPixelBufferTextureConfig pixel_buffer_config;
92+
FlutterDesktopGpuSurfaceDescriptor gpu_surface_descriptor;
6593
};
6694
} FlutterDesktopTextureInfo;
6795

shell/platform/windows/BUILD.gn

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,12 @@ 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.cc",
57+
"external_texture.h",
58+
"external_texture_d3d.cc",
59+
"external_texture_d3d.h",
60+
"external_texture_pixelbuffer.cc",
61+
"external_texture_pixelbuffer.h",
5862
"flutter_key_map.cc",
5963
"flutter_project_bundle.cc",
6064
"flutter_project_bundle.h",

shell/platform/windows/angle_surface_manager.h

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

72+
EGLDisplay egl_display() const { return egl_display_; };
73+
74+
EGLConfig egl_config() const { return egl_config_; }
75+
7276
private:
7377
bool Initialize();
7478
void CleanUp();
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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/windows/external_texture.h"
6+
7+
namespace flutter {
8+
9+
const GlProcs& ResolveGlFunctions() {
10+
static struct GlProcs procs = {};
11+
static bool initialized = false;
12+
13+
if (!initialized) {
14+
procs.glGenTextures =
15+
reinterpret_cast<glGenTexturesProc>(eglGetProcAddress("glGenTextures"));
16+
procs.glDeleteTextures = reinterpret_cast<glDeleteTexturesProc>(
17+
eglGetProcAddress("glDeleteTextures"));
18+
procs.glBindTexture =
19+
reinterpret_cast<glBindTextureProc>(eglGetProcAddress("glBindTexture"));
20+
procs.glTexParameteri = reinterpret_cast<glTexParameteriProc>(
21+
eglGetProcAddress("glTexParameteri"));
22+
procs.glTexImage2D =
23+
reinterpret_cast<glTexImage2DProc>(eglGetProcAddress("glTexImage2D"));
24+
25+
procs.valid = procs.glGenTextures && procs.glDeleteTextures &&
26+
procs.glBindTexture && procs.glTexParameteri &&
27+
procs.glTexImage2D;
28+
initialized = true;
29+
}
30+
return procs;
31+
}
32+
33+
} // namespace flutter
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 <EGL/egl.h>
11+
#include <EGL/eglext.h>
12+
#include <GLES2/gl2.h>
13+
#include <GLES2/gl2ext.h>
14+
15+
namespace flutter {
16+
17+
typedef void (*glGenTexturesProc)(GLsizei n, GLuint* textures);
18+
typedef void (*glDeleteTexturesProc)(GLsizei n, const GLuint* textures);
19+
typedef void (*glBindTextureProc)(GLenum target, GLuint texture);
20+
typedef void (*glTexParameteriProc)(GLenum target, GLenum pname, GLint param);
21+
typedef void (*glTexImage2DProc)(GLenum target,
22+
GLint level,
23+
GLint internalformat,
24+
GLsizei width,
25+
GLsizei height,
26+
GLint border,
27+
GLenum format,
28+
GLenum type,
29+
const void* data);
30+
31+
// A struct containing pointers to resolved gl* functions.
32+
struct GlProcs {
33+
glGenTexturesProc glGenTextures;
34+
glDeleteTexturesProc glDeleteTextures;
35+
glBindTextureProc glBindTexture;
36+
glTexParameteriProc glTexParameteri;
37+
glTexImage2DProc glTexImage2D;
38+
bool valid;
39+
};
40+
41+
const GlProcs& ResolveGlFunctions();
42+
43+
// Abstract external texture.
44+
class ExternalTexture {
45+
public:
46+
virtual ~ExternalTexture() = default;
47+
48+
// Returns the unique id of this texture.
49+
int64_t texture_id() const { return reinterpret_cast<int64_t>(this); };
50+
51+
// Attempts to populate the specified |opengl_texture| with texture details
52+
// such as the name, width, height and the pixel format.
53+
// Returns true on success.
54+
virtual bool PopulateTexture(size_t width,
55+
size_t height,
56+
FlutterOpenGLTexture* opengl_texture) = 0;
57+
};
58+
59+
} // namespace flutter
60+
61+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_H_
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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/windows/external_texture_d3d.h"
6+
7+
namespace flutter {
8+
9+
std::unique_ptr<ExternalTextureD3D>
10+
ExternalTextureD3D::MakeFromSurfaceDescriptor(
11+
const FlutterDesktopGpuSurfaceDescriptor* descriptor,
12+
AngleSurfaceManager* surface_manager) {
13+
EGLSurface surface = EGL_NO_SURFACE;
14+
EGLint attributes[] = {EGL_WIDTH,
15+
static_cast<EGLint>(descriptor->width),
16+
EGL_HEIGHT,
17+
static_cast<EGLint>(descriptor->height),
18+
EGL_TEXTURE_TARGET,
19+
EGL_TEXTURE_2D,
20+
EGL_TEXTURE_FORMAT,
21+
EGL_TEXTURE_RGBA, // always EGL_TEXTURE_RGBA
22+
EGL_NONE};
23+
24+
surface = eglCreatePbufferFromClientBuffer(
25+
surface_manager->egl_display(), EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
26+
descriptor->handle, surface_manager->egl_config(), attributes);
27+
28+
if (surface == EGL_NO_SURFACE) {
29+
return {};
30+
}
31+
32+
return std::unique_ptr<ExternalTextureD3D>(
33+
new ExternalTextureD3D(surface_manager->egl_display(), surface,
34+
descriptor->width, descriptor->height));
35+
}
36+
37+
ExternalTextureD3D::ExternalTextureD3D(EGLDisplay egl_display,
38+
EGLSurface surface,
39+
size_t width,
40+
size_t height)
41+
: egl_surface_(surface),
42+
width_(width),
43+
height_(height),
44+
egl_display_(egl_display) {}
45+
46+
ExternalTextureD3D::~ExternalTextureD3D() {
47+
if (egl_surface_) {
48+
eglDestroySurface(egl_display_, egl_surface_);
49+
}
50+
51+
const auto& gl = ResolveGlFunctions();
52+
if (gl.valid && gl_texture_ != 0) {
53+
gl.glDeleteTextures(1, &gl_texture_);
54+
}
55+
}
56+
57+
bool ExternalTextureD3D::PopulateTexture(size_t width,
58+
size_t height,
59+
FlutterOpenGLTexture* opengl_texture) {
60+
const auto& gl = ResolveGlFunctions();
61+
62+
if (gl_texture_ == 0) {
63+
gl.glGenTextures(1, &gl_texture_);
64+
65+
gl.glBindTexture(GL_TEXTURE_2D, gl_texture_);
66+
67+
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
68+
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
69+
70+
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
71+
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
72+
73+
if (eglBindTexImage(egl_display_, egl_surface_, EGL_BACK_BUFFER) !=
74+
EGL_TRUE) {
75+
gl.glDeleteTextures(1, &gl_texture_);
76+
gl_texture_ = 0;
77+
return false;
78+
}
79+
} else {
80+
gl.glBindTexture(GL_TEXTURE_2D, gl_texture_);
81+
}
82+
83+
opengl_texture->target = GL_TEXTURE_2D;
84+
opengl_texture->name = gl_texture_;
85+
opengl_texture->format = GL_RGBA8;
86+
opengl_texture->destruction_callback = nullptr;
87+
opengl_texture->user_data = nullptr;
88+
opengl_texture->width = width_;
89+
opengl_texture->height = height_;
90+
91+
return true;
92+
}
93+
94+
} // namespace flutter
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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_D3D_H_
6+
#define FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_D3D_H_
7+
8+
#include <stdint.h>
9+
10+
#include <memory>
11+
12+
#include "flutter/shell/platform/common/public/flutter_texture_registrar.h"
13+
#include "flutter/shell/platform/windows/angle_surface_manager.h"
14+
#include "flutter/shell/platform/windows/external_texture.h"
15+
16+
namespace flutter {
17+
18+
// An external texture that is backed by a DXGI surface.
19+
class ExternalTextureD3D : public ExternalTexture {
20+
public:
21+
// Creates a texture using the provided FlutterDesktopGpuSurfaceDescriptor.
22+
static std::unique_ptr<ExternalTextureD3D> MakeFromSurfaceDescriptor(
23+
const FlutterDesktopGpuSurfaceDescriptor* descriptor,
24+
AngleSurfaceManager* surface_manager);
25+
26+
bool PopulateTexture(size_t width,
27+
size_t height,
28+
FlutterOpenGLTexture* opengl_texture) override;
29+
30+
virtual ~ExternalTextureD3D();
31+
32+
private:
33+
EGLDisplay egl_display_;
34+
EGLSurface egl_surface_;
35+
GLuint gl_texture_ = 0;
36+
size_t width_;
37+
size_t height_;
38+
39+
ExternalTextureD3D(EGLDisplay egl_display,
40+
EGLSurface egl_surface,
41+
size_t width,
42+
size_t height);
43+
};
44+
45+
} // namespace flutter
46+
47+
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_D3D_H_

0 commit comments

Comments
 (0)