Skip to content

Commit

Permalink
Add windows plugin texture support
Browse files Browse the repository at this point in the history
  • Loading branch information
jnschulze committed Jun 30, 2020
1 parent ba172c0 commit d5b4626
Show file tree
Hide file tree
Showing 19 changed files with 595 additions and 0 deletions.
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,7 @@ FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registry.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_message_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_method_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/texture_registrar.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_result_functions_unittests.cc
Expand All @@ -853,6 +854,7 @@ FILE: ../../../flutter/shell/platform/common/cpp/path_utils_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_export.h
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_messenger.h
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_plugin_registrar.h
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_texture_registrar.h
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.cc
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.h
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model_unittests.cc
Expand Down Expand Up @@ -1301,6 +1303,8 @@ FILE: ../../../flutter/shell/platform/windows/client_wrapper/plugin_registrar_wi
FILE: ../../../flutter/shell/platform/windows/dpi_utils.cc
FILE: ../../../flutter/shell/platform/windows/dpi_utils.h
FILE: ../../../flutter/shell/platform/windows/dpi_utils_unittests.cc
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.cc
FILE: ../../../flutter/shell/platform/windows/external_texture_gl.h
FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc
FILE: ../../../flutter/shell/platform/windows/key_event_handler.cc
FILE: ../../../flutter/shell/platform/windows/key_event_handler.h
Expand Down
1 change: 1 addition & 0 deletions shell/platform/common/cpp/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ _public_headers = [
"public/flutter_export.h",
"public/flutter_messenger.h",
"public/flutter_plugin_registrar.h",
"public/flutter_texture_registrar.h",
]

# Any files that are built by clients (client_wrapper code, library headers for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ core_cpp_client_wrapper_includes =
"include/flutter/method_result.h",
"include/flutter/plugin_registrar.h",
"include/flutter/plugin_registry.h",
"include/flutter/texture_registrar.h",
"include/flutter/standard_message_codec.h",
"include/flutter/standard_method_codec.h",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <flutter_plugin_registrar.h>

#include "binary_messenger.h"
#include "texture_registrar.h"

namespace flutter {

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

// Returns the texture registrar to use for the plugin to render a pixel
// buffer.
TextureRegistrar* textures() { return textures_.get(); }

// Takes ownership of |plugin|.
//
// Plugins are not required to call this method if they have other lifetime
Expand All @@ -60,6 +65,8 @@ class PluginRegistrar {

std::unique_ptr<BinaryMessenger> messenger_;

std::unique_ptr<TextureRegistrar> textures_;

// Plugins registered for ownership.
std::set<std::unique_ptr<Plugin>> plugins_;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_

#include <flutter_texture_registrar.h>

#include <stdint.h>
#include <memory>

namespace flutter {

// An external texture interface declaration.
class Texture {
public:
virtual ~Texture() {}
// This interface is used to respond to texture copy requests from the Flutter
// engine, Flutter engine will be providing the |height| and |width|
// parameters of bounds. In some cases, the user can be scale the texture to
// the size of the bounds to reduce memory usage.
virtual const PixelBuffer* CopyPixelBuffer(size_t width, size_t height) = 0;
};

class TextureRegistrar {
public:
virtual ~TextureRegistrar() {}

/**
* Registers a |texture| object and returns the ID for that texture.
*/
virtual int64_t RegisterTexture(Texture* texture) = 0;

/**
* Notify the flutter engine that the texture object corresponding
* to |texure_id| needs to render a new texture.
*/
virtual void MarkTextureFrameAvailable(int64_t texture_id) = 0;

/**
* Unregisters an existing Texture object.
*/
virtual void UnregisterTexture(int64_t texture_id) = 0;
};

} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_
40 changes: 40 additions & 0 deletions shell/platform/common/cpp/client_wrapper/plugin_registrar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,52 @@ void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
ForwardToHandler, message_handler);
}

// Wrapper around a FlutterDesktopTextureRegistrarRef that implements the
// TextureRegistrar API.
class TextureRegistrarImpl : public TextureRegistrar {
public:
explicit TextureRegistrarImpl(
FlutterDesktopTextureRegistrarRef texture_registrar_ref)
: texture_registrar_ref_(texture_registrar_ref) {}

virtual ~TextureRegistrarImpl() = default;

// Prevent copying.
TextureRegistrarImpl(TextureRegistrarImpl const&) = delete;
TextureRegistrarImpl& operator=(TextureRegistrarImpl const&) = delete;

virtual int64_t RegisterTexture(Texture* texture) override {
FlutterTextureCallback callback =
[](size_t width, size_t height, void* user_data) -> const PixelBuffer* {
return static_cast<Texture*>(user_data)->CopyPixelBuffer(width, height);
};
int64_t texture_id = FlutterDesktopRegisterExternalTexture(
texture_registrar_ref_, callback, texture);
return texture_id;
}

virtual void MarkTextureFrameAvailable(int64_t texture_id) override {
FlutterDesktopMarkExternalTextureFrameAvailable(texture_registrar_ref_,
texture_id);
}

virtual void UnregisterTexture(int64_t texture_id) override {
FlutterDesktopUnregisterExternalTexture(texture_registrar_ref_, texture_id);
}

private:
// Handle for interacting with the C API.
FlutterDesktopTextureRegistrarRef texture_registrar_ref_;
};

// ===== PluginRegistrar =====

PluginRegistrar::PluginRegistrar(FlutterDesktopPluginRegistrarRef registrar)
: registrar_(registrar) {
auto core_messenger = FlutterDesktopRegistrarGetMessenger(registrar_);
messenger_ = std::make_unique<BinaryMessengerImpl>(core_messenger);
auto texture_registrar = FlutterDesktopGetTextureRegistrar(registrar_);
textures_ = std::make_unique<TextureRegistrarImpl>(texture_registrar);
}

PluginRegistrar::~PluginRegistrar() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <map>
#include <memory>
#include <vector>

#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h"
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/texture_registrar.h"
#include "flutter/shell/platform/common/cpp/client_wrapper/testing/stub_flutter_api.h"
#include "gtest/gtest.h"

Expand All @@ -15,6 +17,14 @@ namespace {

// Stub implementation to validate calls to the API.
class TestApi : public testing::StubFlutterApi {
public:
struct FakeTexture {
int64_t texture_id;
int32_t mark_count;
FlutterTextureCallback texture_callback;
void* user_data;
};

public:
// |flutter::testing::StubFlutterApi|
bool MessengerSend(const char* channel,
Expand Down Expand Up @@ -52,10 +62,55 @@ class TestApi : public testing::StubFlutterApi {
return last_destruction_callback_set_;
}

int64_t RegisterExternalTexture(FlutterTextureCallback texture_callback,
void* user_data) override {
last_texture_id_++;

auto texture = std::make_unique<FakeTexture>();
texture->texture_callback = texture_callback;
texture->user_data = user_data;
texture->mark_count = 0;
texture->texture_id = last_texture_id_;

textures_[last_texture_id_] = std::move(texture);
return last_texture_id_;
}

bool UnregisterExternalTexture(int64_t texture_id) override {
auto it = textures_.find(texture_id);
if (it != textures_.end()) {
textures_.erase(it);
return true;
}
return false;
}

bool TextureFrameAvailable(int64_t texture_id) override {
auto it = textures_.find(texture_id);
if (it != textures_.end()) {
it->second->mark_count++;
return true;
}
return false;
}

FakeTexture* GetFakeTexture(int64_t texture_id) {
auto it = textures_.find(texture_id);
if (it != textures_.end())
return it->second.get();
return nullptr;
}

int64_t last_texture_id() { return last_texture_id_; }

size_t textures_size() { return textures_.size(); }

private:
const uint8_t* last_data_sent_ = nullptr;
FlutterDesktopMessageCallback last_message_callback_set_ = nullptr;
FlutterDesktopOnRegistrarDestroyed last_destruction_callback_set_ = nullptr;
int64_t last_texture_id_ = -1;
std::map<int64_t, std::unique_ptr<FakeTexture>> textures_;
};

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

// Tests texture register that calls through to the C API.
TEST(MethodCallTest, RegisterTexture) {
testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());

auto dummy_registrar_handle =
reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
PluginRegistrar registrar(dummy_registrar_handle);
TextureRegistrar* textures = registrar.textures();

EXPECT_EQ(test_api->last_texture_id(), -1);
auto texture = test_api->GetFakeTexture(0);
EXPECT_EQ(texture, nullptr);

int64_t texture_id = textures->RegisterTexture(reinterpret_cast<Texture*>(2));
EXPECT_EQ(test_api->last_texture_id(), texture_id);
EXPECT_EQ(test_api->textures_size(), static_cast<size_t>(1));

texture = test_api->GetFakeTexture(texture_id);
EXPECT_EQ(texture->texture_id, texture_id);
EXPECT_EQ(texture->user_data, reinterpret_cast<Texture*>(2));

textures->MarkTextureFrameAvailable(texture_id);
textures->MarkTextureFrameAvailable(texture_id);
textures->MarkTextureFrameAvailable(texture_id);
EXPECT_EQ(texture->mark_count, 3);

textures->UnregisterTexture(texture_id);
texture = test_api->GetFakeTexture(texture_id);
EXPECT_EQ(texture, nullptr);
EXPECT_EQ(test_api->textures_size(), static_cast<size_t>(0));
}

} // namespace flutter
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,40 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
s_stub_implementation->MessengerSetCallback(channel, callback, user_data);
}
}

FlutterDesktopTextureRegistrarRef FlutterDesktopGetTextureRegistrar(
FlutterDesktopPluginRegistrarRef registrar) {
return reinterpret_cast<FlutterDesktopTextureRegistrarRef>(1);
}

int64_t FlutterDesktopRegisterExternalTexture(
FlutterDesktopTextureRegistrarRef texture_registrar,
FlutterTextureCallback texture_callback,
void* user_data) {
uint64_t result = -1;
if (s_stub_implementation) {
result = s_stub_implementation->RegisterExternalTexture(texture_callback,
user_data);
}
return result;
}

bool FlutterDesktopUnregisterExternalTexture(
FlutterDesktopTextureRegistrarRef texture_registrar,
int64_t texture_id) {
bool result = false;
if (s_stub_implementation) {
result = s_stub_implementation->UnregisterExternalTexture(texture_id);
}
return result;
}

bool FlutterDesktopMarkExternalTextureFrameAvailable(
FlutterDesktopTextureRegistrarRef texture_registrar,
int64_t texture_id) {
bool result = false;
if (s_stub_implementation) {
result = s_stub_implementation->TextureFrameAvailable(texture_id);
}
return result;
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ class StubFlutterApi {
virtual void MessengerSetCallback(const char* channel,
FlutterDesktopMessageCallback callback,
void* user_data) {}

// Called for FlutterDesktopRegisterExternalTexture.
virtual int64_t RegisterExternalTexture(
FlutterTextureCallback texture_callback,
void* user_data) {
return -1;
}

// Called for FlutterDesktopUnregisterExternalTexture.
virtual bool UnregisterExternalTexture(int64_t texture_id) { return false; }

// Called for FlutterDesktopMarkExternalTextureFrameAvailable.
virtual bool TextureFrameAvailable(int64_t texture_id) { return false; }
};

// A test helper that owns a stub implementation, making it the test stub for
Expand Down
5 changes: 5 additions & 0 deletions shell/platform/common/cpp/public/flutter_plugin_registrar.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "flutter_export.h"
#include "flutter_messenger.h"
#include "flutter_texture_registrar.h"

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

// Returns the texture registrar associated with this registrar.
FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef
FlutterDesktopGetTextureRegistrar(FlutterDesktopPluginRegistrarRef registrar);

// Registers a callback to be called when the plugin registrar is destroyed.
FLUTTER_EXPORT void FlutterDesktopRegistrarSetDestructionHandler(
FlutterDesktopPluginRegistrarRef registrar,
Expand Down
Loading

0 comments on commit d5b4626

Please sign in to comment.