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

Commit e16603c

Browse files
committed
Add windows plugin texture support
1 parent ba172c0 commit e16603c

19 files changed

+595
-0
lines changed

ci/licenses_golden/licenses_flutter

+4
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/
830830
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registry.h
831831
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_message_codec.h
832832
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_method_codec.h
833+
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/texture_registrar.h
833834
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc
834835
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc
835836
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_result_functions_unittests.cc
@@ -853,6 +854,7 @@ FILE: ../../../flutter/shell/platform/common/cpp/path_utils_unittests.cc
853854
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_export.h
854855
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_messenger.h
855856
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_plugin_registrar.h
857+
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_texture_registrar.h
856858
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.cc
857859
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.h
858860
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model_unittests.cc
@@ -1301,6 +1303,8 @@ FILE: ../../../flutter/shell/platform/windows/client_wrapper/plugin_registrar_wi
13011303
FILE: ../../../flutter/shell/platform/windows/dpi_utils.cc
13021304
FILE: ../../../flutter/shell/platform/windows/dpi_utils.h
13031305
FILE: ../../../flutter/shell/platform/windows/dpi_utils_unittests.cc
1306+
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.cc
1307+
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.h
13041308
FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc
13051309
FILE: ../../../flutter/shell/platform/windows/key_event_handler.cc
13061310
FILE: ../../../flutter/shell/platform/windows/key_event_handler.h

shell/platform/common/cpp/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ _public_headers = [
1212
"public/flutter_export.h",
1313
"public/flutter_messenger.h",
1414
"public/flutter_plugin_registrar.h",
15+
"public/flutter_texture_registrar.h",
1516
]
1617

1718
# Any files that are built by clients (client_wrapper code, library headers for

shell/platform/common/cpp/client_wrapper/core_wrapper_files.gni

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ core_cpp_client_wrapper_includes =
2020
"include/flutter/method_result.h",
2121
"include/flutter/plugin_registrar.h",
2222
"include/flutter/plugin_registry.h",
23+
"include/flutter/texture_registrar.h",
2324
"include/flutter/standard_message_codec.h",
2425
"include/flutter/standard_method_codec.h",
2526
],

shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h

+7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <flutter_plugin_registrar.h>
1414

1515
#include "binary_messenger.h"
16+
#include "texture_registrar.h"
1617

1718
namespace flutter {
1819

@@ -41,6 +42,10 @@ class PluginRegistrar {
4142
// This pointer will remain valid for the lifetime of this instance.
4243
BinaryMessenger* messenger() { return messenger_.get(); }
4344

45+
// Returns the texture registrar to use for the plugin to render a pixel
46+
// buffer.
47+
TextureRegistrar* textures() { return textures_.get(); }
48+
4449
// Takes ownership of |plugin|.
4550
//
4651
// Plugins are not required to call this method if they have other lifetime
@@ -60,6 +65,8 @@ class PluginRegistrar {
6065

6166
std::unique_ptr<BinaryMessenger> messenger_;
6267

68+
std::unique_ptr<TextureRegistrar> textures_;
69+
6370
// Plugins registered for ownership.
6471
std::set<std::unique_ptr<Plugin>> plugins_;
6572
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_
6+
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_
7+
8+
#include <flutter_texture_registrar.h>
9+
10+
#include <stdint.h>
11+
#include <memory>
12+
13+
namespace flutter {
14+
15+
// An external texture interface declaration.
16+
class Texture {
17+
public:
18+
virtual ~Texture() {}
19+
// This interface is used to respond to texture copy requests from the Flutter
20+
// engine, Flutter engine will be providing the |height| and |width|
21+
// parameters of bounds. In some cases, the user can be scale the texture to
22+
// the size of the bounds to reduce memory usage.
23+
virtual const PixelBuffer* CopyPixelBuffer(size_t width, size_t height) = 0;
24+
};
25+
26+
class TextureRegistrar {
27+
public:
28+
virtual ~TextureRegistrar() {}
29+
30+
/**
31+
* Registers a |texture| object and returns the ID for that texture.
32+
*/
33+
virtual int64_t RegisterTexture(Texture* texture) = 0;
34+
35+
/**
36+
* Notify the flutter engine that the texture object corresponding
37+
* to |texure_id| needs to render a new texture.
38+
*/
39+
virtual void MarkTextureFrameAvailable(int64_t texture_id) = 0;
40+
41+
/**
42+
* Unregisters an existing Texture object.
43+
*/
44+
virtual void UnregisterTexture(int64_t texture_id) = 0;
45+
};
46+
47+
} // namespace flutter
48+
49+
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_

shell/platform/common/cpp/client_wrapper/plugin_registrar.cc

+40
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,52 @@ void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
126126
ForwardToHandler, message_handler);
127127
}
128128

129+
// Wrapper around a FlutterDesktopTextureRegistrarRef that implements the
130+
// TextureRegistrar API.
131+
class TextureRegistrarImpl : public TextureRegistrar {
132+
public:
133+
explicit TextureRegistrarImpl(
134+
FlutterDesktopTextureRegistrarRef texture_registrar_ref)
135+
: texture_registrar_ref_(texture_registrar_ref) {}
136+
137+
virtual ~TextureRegistrarImpl() = default;
138+
139+
// Prevent copying.
140+
TextureRegistrarImpl(TextureRegistrarImpl const&) = delete;
141+
TextureRegistrarImpl& operator=(TextureRegistrarImpl const&) = delete;
142+
143+
virtual int64_t RegisterTexture(Texture* texture) override {
144+
FlutterTextureCallback callback =
145+
[](size_t width, size_t height, void* user_data) -> const PixelBuffer* {
146+
return static_cast<Texture*>(user_data)->CopyPixelBuffer(width, height);
147+
};
148+
int64_t texture_id = FlutterDesktopRegisterExternalTexture(
149+
texture_registrar_ref_, callback, texture);
150+
return texture_id;
151+
}
152+
153+
virtual void MarkTextureFrameAvailable(int64_t texture_id) override {
154+
FlutterDesktopMarkExternalTextureFrameAvailable(texture_registrar_ref_,
155+
texture_id);
156+
}
157+
158+
virtual void UnregisterTexture(int64_t texture_id) override {
159+
FlutterDesktopUnregisterExternalTexture(texture_registrar_ref_, texture_id);
160+
}
161+
162+
private:
163+
// Handle for interacting with the C API.
164+
FlutterDesktopTextureRegistrarRef texture_registrar_ref_;
165+
};
166+
129167
// ===== PluginRegistrar =====
130168

131169
PluginRegistrar::PluginRegistrar(FlutterDesktopPluginRegistrarRef registrar)
132170
: registrar_(registrar) {
133171
auto core_messenger = FlutterDesktopRegistrarGetMessenger(registrar_);
134172
messenger_ = std::make_unique<BinaryMessengerImpl>(core_messenger);
173+
auto texture_registrar = FlutterDesktopGetTextureRegistrar(registrar_);
174+
textures_ = std::make_unique<TextureRegistrarImpl>(texture_registrar);
135175
}
136176

137177
PluginRegistrar::~PluginRegistrar() {}

shell/platform/common/cpp/client_wrapper/plugin_registrar_unittests.cc

+88
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
#include <map>
56
#include <memory>
67
#include <vector>
78

89
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h"
10+
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/texture_registrar.h"
911
#include "flutter/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.h"
1012
#include "gtest/gtest.h"
1113

@@ -15,6 +17,14 @@ namespace {
1517

1618
// Stub implementation to validate calls to the API.
1719
class TestApi : public testing::StubFlutterApi {
20+
public:
21+
struct FakeTexture {
22+
int64_t texture_id;
23+
int32_t mark_count;
24+
FlutterTextureCallback texture_callback;
25+
void* user_data;
26+
};
27+
1828
public:
1929
// |flutter::testing::StubFlutterApi|
2030
bool MessengerSend(const char* channel,
@@ -52,10 +62,55 @@ class TestApi : public testing::StubFlutterApi {
5262
return last_destruction_callback_set_;
5363
}
5464

65+
int64_t RegisterExternalTexture(FlutterTextureCallback texture_callback,
66+
void* user_data) override {
67+
last_texture_id_++;
68+
69+
auto texture = std::make_unique<FakeTexture>();
70+
texture->texture_callback = texture_callback;
71+
texture->user_data = user_data;
72+
texture->mark_count = 0;
73+
texture->texture_id = last_texture_id_;
74+
75+
textures_[last_texture_id_] = std::move(texture);
76+
return last_texture_id_;
77+
}
78+
79+
bool UnregisterExternalTexture(int64_t texture_id) override {
80+
auto it = textures_.find(texture_id);
81+
if (it != textures_.end()) {
82+
textures_.erase(it);
83+
return true;
84+
}
85+
return false;
86+
}
87+
88+
bool TextureFrameAvailable(int64_t texture_id) override {
89+
auto it = textures_.find(texture_id);
90+
if (it != textures_.end()) {
91+
it->second->mark_count++;
92+
return true;
93+
}
94+
return false;
95+
}
96+
97+
FakeTexture* GetFakeTexture(int64_t texture_id) {
98+
auto it = textures_.find(texture_id);
99+
if (it != textures_.end())
100+
return it->second.get();
101+
return nullptr;
102+
}
103+
104+
int64_t last_texture_id() { return last_texture_id_; }
105+
106+
size_t textures_size() { return textures_.size(); }
107+
55108
private:
56109
const uint8_t* last_data_sent_ = nullptr;
57110
FlutterDesktopMessageCallback last_message_callback_set_ = nullptr;
58111
FlutterDesktopOnRegistrarDestroyed last_destruction_callback_set_ = nullptr;
112+
int64_t last_texture_id_ = -1;
113+
std::map<int64_t, std::unique_ptr<FakeTexture>> textures_;
59114
};
60115

61116
// A PluginRegistrar whose destruction can be watched for by tests.
@@ -179,4 +234,37 @@ TEST(PluginRegistrarTest, ManagerRemovesOnDestruction) {
179234
nullptr);
180235
}
181236

237+
// Tests texture register that calls through to the C API.
238+
TEST(MethodCallTest, RegisterTexture) {
239+
testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
240+
auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());
241+
242+
auto dummy_registrar_handle =
243+
reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
244+
PluginRegistrar registrar(dummy_registrar_handle);
245+
TextureRegistrar* textures = registrar.textures();
246+
247+
EXPECT_EQ(test_api->last_texture_id(), -1);
248+
auto texture = test_api->GetFakeTexture(0);
249+
EXPECT_EQ(texture, nullptr);
250+
251+
int64_t texture_id = textures->RegisterTexture(reinterpret_cast<Texture*>(2));
252+
EXPECT_EQ(test_api->last_texture_id(), texture_id);
253+
EXPECT_EQ(test_api->textures_size(), static_cast<size_t>(1));
254+
255+
texture = test_api->GetFakeTexture(texture_id);
256+
EXPECT_EQ(texture->texture_id, texture_id);
257+
EXPECT_EQ(texture->user_data, reinterpret_cast<Texture*>(2));
258+
259+
textures->MarkTextureFrameAvailable(texture_id);
260+
textures->MarkTextureFrameAvailable(texture_id);
261+
textures->MarkTextureFrameAvailable(texture_id);
262+
EXPECT_EQ(texture->mark_count, 3);
263+
264+
textures->UnregisterTexture(texture_id);
265+
texture = test_api->GetFakeTexture(texture_id);
266+
EXPECT_EQ(texture, nullptr);
267+
EXPECT_EQ(test_api->textures_size(), static_cast<size_t>(0));
268+
}
269+
182270
} // namespace flutter

shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.cc

+37
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,40 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
104104
s_stub_implementation->MessengerSetCallback(channel, callback, user_data);
105105
}
106106
}
107+
108+
FlutterDesktopTextureRegistrarRef FlutterDesktopGetTextureRegistrar(
109+
FlutterDesktopPluginRegistrarRef registrar) {
110+
return reinterpret_cast<FlutterDesktopTextureRegistrarRef>(1);
111+
}
112+
113+
int64_t FlutterDesktopRegisterExternalTexture(
114+
FlutterDesktopTextureRegistrarRef texture_registrar,
115+
FlutterTextureCallback texture_callback,
116+
void* user_data) {
117+
uint64_t result = -1;
118+
if (s_stub_implementation) {
119+
result = s_stub_implementation->RegisterExternalTexture(texture_callback,
120+
user_data);
121+
}
122+
return result;
123+
}
124+
125+
bool FlutterDesktopUnregisterExternalTexture(
126+
FlutterDesktopTextureRegistrarRef texture_registrar,
127+
int64_t texture_id) {
128+
bool result = false;
129+
if (s_stub_implementation) {
130+
result = s_stub_implementation->UnregisterExternalTexture(texture_id);
131+
}
132+
return result;
133+
}
134+
135+
bool FlutterDesktopMarkExternalTextureFrameAvailable(
136+
FlutterDesktopTextureRegistrarRef texture_registrar,
137+
int64_t texture_id) {
138+
bool result = false;
139+
if (s_stub_implementation) {
140+
result = s_stub_implementation->TextureFrameAvailable(texture_id);
141+
}
142+
return result;
143+
}

shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.h

+13
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,19 @@ class StubFlutterApi {
6767
virtual void MessengerSetCallback(const char* channel,
6868
FlutterDesktopMessageCallback callback,
6969
void* user_data) {}
70+
71+
// Called for FlutterDesktopRegisterExternalTexture.
72+
virtual int64_t RegisterExternalTexture(
73+
FlutterTextureCallback texture_callback,
74+
void* user_data) {
75+
return -1;
76+
}
77+
78+
// Called for FlutterDesktopUnregisterExternalTexture.
79+
virtual bool UnregisterExternalTexture(int64_t texture_id) { return false; }
80+
81+
// Called for FlutterDesktopMarkExternalTextureFrameAvailable.
82+
virtual bool TextureFrameAvailable(int64_t texture_id) { return false; }
7083
};
7184

7285
// A test helper that owns a stub implementation, making it the test stub for

shell/platform/common/cpp/public/flutter_plugin_registrar.h

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "flutter_export.h"
1212
#include "flutter_messenger.h"
13+
#include "flutter_texture_registrar.h"
1314

1415
#if defined(__cplusplus)
1516
extern "C" {
@@ -26,6 +27,10 @@ typedef void (*FlutterDesktopOnRegistrarDestroyed)(
2627
FLUTTER_EXPORT FlutterDesktopMessengerRef
2728
FlutterDesktopRegistrarGetMessenger(FlutterDesktopPluginRegistrarRef registrar);
2829

30+
// Returns the texture registrar associated with this registrar.
31+
FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef
32+
FlutterDesktopGetTextureRegistrar(FlutterDesktopPluginRegistrarRef registrar);
33+
2934
// Registers a callback to be called when the plugin registrar is destroyed.
3035
FLUTTER_EXPORT void FlutterDesktopRegistrarSetDestructionHandler(
3136
FlutterDesktopPluginRegistrarRef registrar,

0 commit comments

Comments
 (0)