Flutter Engine
The Flutter Engine
texture_registrar_unittests.cc
Go to the documentation of this file.
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/common/client_wrapper/include/flutter/texture_registrar.h"
6
7#include <map>
8#include <memory>
9#include <vector>
10
11#include "flutter/fml/synchronization/waitable_event.h"
12#include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h"
13#include "flutter/shell/platform/common/client_wrapper/testing/stub_flutter_api.h"
14#include "gtest/gtest.h"
15
16namespace flutter {
17
18namespace {
19
20// Stub implementation to validate calls to the API.
21class TestApi : public testing::StubFlutterApi {
22 public:
23 struct FakePixelBufferTexture {
24 int64_t texture_id;
25 int32_t mark_count;
27 void* user_data;
28 };
29
30 public:
31 int64_t TextureRegistrarRegisterExternalTexture(
32 const FlutterDesktopTextureInfo* info) override {
33 last_texture_id_++;
34
35 auto texture = std::make_unique<FakePixelBufferTexture>();
36 texture->texture_callback = info->pixel_buffer_config.callback;
37 texture->user_data = info->pixel_buffer_config.user_data;
38 texture->mark_count = 0;
39 texture->texture_id = last_texture_id_;
40
41 textures_[last_texture_id_] = std::move(texture);
42 return last_texture_id_;
43 }
44
45 void TextureRegistrarUnregisterExternalTexture(
46 int64_t texture_id,
47 void (*callback)(void* user_data),
48 void* user_data) override {
49 auto it = textures_.find(texture_id);
50 if (it != textures_.end()) {
51 textures_.erase(it);
52 }
53 if (callback) {
55 }
56 }
57
58 bool TextureRegistrarMarkTextureFrameAvailable(int64_t texture_id) override {
59 auto it = textures_.find(texture_id);
60 if (it != textures_.end()) {
61 it->second->mark_count++;
62 return true;
63 }
64 return false;
65 }
66
67 FakePixelBufferTexture* GetFakeTexture(int64_t texture_id) {
68 auto it = textures_.find(texture_id);
69 if (it != textures_.end()) {
70 return it->second.get();
71 }
72 return nullptr;
73 }
74
75 int64_t last_texture_id() { return last_texture_id_; }
76
77 size_t textures_size() { return textures_.size(); }
78
79 private:
80 int64_t last_texture_id_ = -1;
81 std::map<int64_t, std::unique_ptr<FakePixelBufferTexture>> textures_;
82};
83
84} // namespace
85
86// Tests thats textures can be registered and unregistered.
87TEST(TextureRegistrarTest, RegisterUnregisterTexture) {
88 testing::ScopedStubFlutterApi scoped_api_stub(std::make_unique<TestApi>());
89 auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());
90
91 auto dummy_registrar_handle =
92 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
93 PluginRegistrar registrar(dummy_registrar_handle);
94 TextureRegistrar* textures = registrar.texture_registrar();
95 ASSERT_NE(textures, nullptr);
96
97 EXPECT_EQ(test_api->last_texture_id(), -1);
98 auto texture = test_api->GetFakeTexture(0);
99 EXPECT_EQ(texture, nullptr);
100
101 auto pixel_buffer_texture = std::make_unique<TextureVariant>(
102 PixelBufferTexture([](size_t width, size_t height) { return nullptr; }));
103 int64_t texture_id = textures->RegisterTexture(pixel_buffer_texture.get());
104 EXPECT_EQ(test_api->last_texture_id(), texture_id);
105 EXPECT_EQ(test_api->textures_size(), static_cast<size_t>(1));
106
107 texture = test_api->GetFakeTexture(texture_id);
108 EXPECT_EQ(texture->texture_id, texture_id);
109 EXPECT_EQ(texture->user_data,
110 std::get_if<PixelBufferTexture>(pixel_buffer_texture.get()));
111
114 bool success = textures->MarkTextureFrameAvailable(texture_id);
115 EXPECT_TRUE(success);
116 EXPECT_EQ(texture->mark_count, 3);
117
118 fml::AutoResetWaitableEvent unregister_latch;
119 textures->UnregisterTexture(texture_id, [&]() { unregister_latch.Signal(); });
120 unregister_latch.Wait();
121
122 texture = test_api->GetFakeTexture(texture_id);
123 EXPECT_EQ(texture, nullptr);
124 EXPECT_EQ(test_api->textures_size(), static_cast<size_t>(0));
125}
126
127// Tests that the unregister callback gets also invoked when attempting to
128// unregister a texture with an unknown id.
129TEST(TextureRegistrarTest, UnregisterInvalidTexture) {
130 auto dummy_registrar_handle =
131 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
132 PluginRegistrar registrar(dummy_registrar_handle);
133
134 TextureRegistrar* textures = registrar.texture_registrar();
135
137 textures->UnregisterTexture(42, [&]() { latch.Signal(); });
138 latch.Wait();
139}
140
141// Tests that claiming a new frame being available for an unknown texture
142// returns false.
143TEST(TextureRegistrarTest, MarkFrameAvailableInvalidTexture) {
144 auto dummy_registrar_handle =
145 reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
146 PluginRegistrar registrar(dummy_registrar_handle);
147
148 TextureRegistrar* textures = registrar.texture_registrar();
149
150 bool success = textures->MarkTextureFrameAvailable(42);
151 EXPECT_FALSE(success);
152}
153
154} // namespace flutter
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
TextureRegistrar * texture_registrar()
virtual void UnregisterTexture(int64_t texture_id, std::function< void()> callback)=0
virtual bool MarkTextureFrameAvailable(int64_t texture_id)=0
virtual int64_t RegisterTexture(TextureVariant *texture)=0
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const FlutterDesktopPixelBuffer *(* FlutterDesktopPixelBufferTextureCallback)(size_t width, size_t height, void *user_data)
FlTexture * texture
TEST(FrameTimingsRecorderTest, RecordVsync)
int32_t height
int32_t width
void * user_data
int64_t texture_id
FlutterDesktopPixelBufferTextureCallback texture_callback
int32_t mark_count
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678