Flutter Windows Embedder
compositor_software_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 <memory>
6 #include <vector>
7 
10 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
11 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
12 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
13 #include "flutter/shell/platform/windows/testing/windows_test.h"
14 #include "gmock/gmock.h"
15 #include "gtest/gtest.h"
16 
17 namespace flutter {
18 namespace testing {
19 
20 namespace {
21 using ::testing::Return;
22 
23 class MockFlutterWindowsView : public FlutterWindowsView {
24  public:
25  MockFlutterWindowsView(FlutterWindowsEngine* engine,
26  std::unique_ptr<WindowBindingHandler> window)
28  engine,
29  std::move(window),
30  false,
31  BoxConstraints()) {}
32  virtual ~MockFlutterWindowsView() = default;
33 
34  MOCK_METHOD(bool,
35  PresentSoftwareBitmap,
36  (const void* allocation, size_t row_bytes, size_t height),
37  (override));
38  MOCK_METHOD(bool, ClearSoftwareBitmap, (), (override));
39 
40  private:
41  FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView);
42 };
43 
44 class CompositorSoftwareTest : public WindowsTest {
45  public:
46  CompositorSoftwareTest() = default;
47  virtual ~CompositorSoftwareTest() = default;
48 
49  protected:
50  FlutterWindowsEngine* engine() { return engine_.get(); }
51  MockFlutterWindowsView* view() { return view_.get(); }
52 
53  void UseEngineWithView() {
54  FlutterWindowsEngineBuilder builder{GetContext()};
55 
56  auto window = std::make_unique<MockWindowBindingHandler>();
57  EXPECT_CALL(*window.get(), SetView).Times(1);
58  EXPECT_CALL(*window.get(), GetWindowHandle).WillRepeatedly(Return(nullptr));
59 
60  engine_ = builder.Build();
61  view_ = std::make_unique<MockFlutterWindowsView>(engine_.get(),
62  std::move(window));
63  }
64 
65  private:
66  std::unique_ptr<FlutterWindowsEngine> engine_;
67  std::unique_ptr<MockFlutterWindowsView> view_;
68 
69  FML_DISALLOW_COPY_AND_ASSIGN(CompositorSoftwareTest);
70 };
71 
72 } // namespace
73 
74 TEST_F(CompositorSoftwareTest, CreateBackingStore) {
75  CompositorSoftware compositor;
76 
77  FlutterBackingStoreConfig config = {};
78  FlutterBackingStore backing_store = {};
79 
80  ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
81  ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
82 }
83 
84 TEST_F(CompositorSoftwareTest, Present) {
85  UseEngineWithView();
86 
87  CompositorSoftware compositor;
88 
89  FlutterBackingStoreConfig config = {};
90  FlutterBackingStore backing_store = {};
91 
92  ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store));
93 
94  FlutterLayer layer = {};
95  layer.type = kFlutterLayerContentTypeBackingStore;
96  layer.backing_store = &backing_store;
97  const FlutterLayer* layer_ptr = &layer;
98 
99  EXPECT_CALL(*view(), PresentSoftwareBitmap).WillOnce(Return(true));
100  EXPECT_TRUE(compositor.Present(view(), &layer_ptr, 1));
101 
102  ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
103 }
104 
105 TEST_F(CompositorSoftwareTest, PresentEmpty) {
106  UseEngineWithView();
107 
108  CompositorSoftware compositor;
109 
110  EXPECT_CALL(*view(), ClearSoftwareBitmap).WillOnce(Return(true));
111  EXPECT_TRUE(compositor.Present(view(), nullptr, 0));
112 }
113 
114 // Test compositing an upper layer on a base layer, each 2x2 pixels.
115 // Base layer has opaque pixel values:
116 // BLACK RED
117 // GREEN WHITE
118 // Overlay layer has pixel values:
119 // RED: 127 WHITE: 0
120 // BLUE: 127 BLACK: 255
121 TEST_F(CompositorSoftwareTest, PresentMultiLayers) {
122  UseEngineWithView();
123 
124  CompositorSoftware compositor;
125 
126  FlutterBackingStoreConfig config = {sizeof(config), {2, 2}};
127  FlutterBackingStore backing_store0 = {sizeof(FlutterBackingStore), nullptr};
128  FlutterBackingStore backing_store1 = {sizeof(FlutterBackingStore), nullptr};
129 
130  ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store0));
131  ASSERT_TRUE(compositor.CreateBackingStore(config, &backing_store1));
132 
133  uint32_t pixels0[4] = {0xff000000, 0xff0000ff, 0xff00ff00, 0xffffffff};
134  uint32_t pixels1[4] = {0x7f0000ff, 0x00ffffff, 0x7fff0000, 0xff000000};
135 
136  std::memcpy(const_cast<void*>(backing_store0.software.allocation), pixels0,
137  sizeof(uint32_t) * 4);
138  std::memcpy(const_cast<void*>(backing_store1.software.allocation), pixels1,
139  sizeof(uint32_t) * 4);
140 
141  FlutterLayer layer0 = {};
142  layer0.type = kFlutterLayerContentTypeBackingStore;
143  layer0.backing_store = &backing_store0;
144  layer0.offset = {0, 0};
145  layer0.size = {2, 2};
146 
147  FlutterLayer layer1 = layer0;
148  layer1.backing_store = &backing_store1;
149  const FlutterLayer* layer_ptr[2] = {&layer0, &layer1};
150 
151  EXPECT_CALL(*view(), PresentSoftwareBitmap)
152  .WillOnce([&](const void* allocation, size_t row_bytes, size_t height) {
153  auto pixel_data = static_cast<const uint32_t*>(allocation);
154  EXPECT_EQ(row_bytes, 2 * sizeof(uint32_t));
155  EXPECT_EQ(height, 2);
156  EXPECT_EQ(pixel_data[0], 0xff00007f);
157  EXPECT_EQ(pixel_data[1], 0xff0000ff);
158  EXPECT_EQ(pixel_data[2], 0xff7f8000);
159  EXPECT_EQ(pixel_data[3], 0xff000000);
160  return true;
161  });
162  EXPECT_TRUE(compositor.Present(view(), layer_ptr, 2));
163 
164  ASSERT_TRUE(compositor.CollectBackingStore(&backing_store0));
165  ASSERT_TRUE(compositor.CollectBackingStore(&backing_store1));
166 }
167 
168 // Test compositing layers with offsets.
169 // 0th layer is a single red pixel in the top-left.
170 // 1st layer is a row of two blue pixels on the second row.
171 TEST_F(CompositorSoftwareTest, PresentOffsetLayers) {
172  UseEngineWithView();
173 
174  CompositorSoftware compositor;
175 
176  FlutterBackingStoreConfig config0 = {sizeof(FlutterBackingStoreConfig),
177  {1, 1}};
178  FlutterBackingStore backing_store0 = {sizeof(FlutterBackingStore), nullptr};
179  FlutterBackingStoreConfig config1 = {sizeof(FlutterBackingStoreConfig),
180  {2, 1}};
181  FlutterBackingStore backing_store1 = {sizeof(FlutterBackingStore), nullptr};
182 
183  ASSERT_TRUE(compositor.CreateBackingStore(config0, &backing_store0));
184  ASSERT_TRUE(compositor.CreateBackingStore(config1, &backing_store1));
185 
186  uint32_t pixels0 = 0xff0000ff;
187  uint32_t pixels1[2] = {0xffff0000, 0xffff0000};
188 
189  std::memcpy(const_cast<void*>(backing_store0.software.allocation), &pixels0,
190  sizeof(uint32_t) * 1);
191  std::memcpy(const_cast<void*>(backing_store1.software.allocation), pixels1,
192  sizeof(uint32_t) * 2);
193 
194  FlutterLayer layer0 = {};
195  layer0.type = kFlutterLayerContentTypeBackingStore;
196  layer0.backing_store = &backing_store0;
197  layer0.offset = {0, 0};
198  layer0.size = {1, 1};
199 
200  FlutterLayer layer1 = layer0;
201  layer1.backing_store = &backing_store1;
202  layer1.offset = {0, 1};
203  layer1.size = {2, 1};
204  const FlutterLayer* layer_ptr[2] = {&layer0, &layer1};
205 
206  EXPECT_CALL(*view(), PresentSoftwareBitmap)
207  .WillOnce([&](const void* allocation, size_t row_bytes, size_t height) {
208  auto pixel_data = static_cast<const uint32_t*>(allocation);
209  EXPECT_EQ(row_bytes, 2 * sizeof(uint32_t));
210  EXPECT_EQ(height, 2);
211  EXPECT_EQ(pixel_data[0], 0xff0000ff);
212  EXPECT_EQ(pixel_data[1], 0xff000000);
213  EXPECT_EQ(pixel_data[2], 0xffff0000);
214  EXPECT_EQ(pixel_data[3], 0xffff0000);
215  return true;
216  });
217  EXPECT_TRUE(compositor.Present(view(), layer_ptr, 2));
218 
219  ASSERT_TRUE(compositor.CollectBackingStore(&backing_store0));
220  ASSERT_TRUE(compositor.CollectBackingStore(&backing_store1));
221 }
222 
223 } // namespace testing
224 } // namespace flutter
bool CollectBackingStore(const FlutterBackingStore *store) override
|Compositor|
bool Present(FlutterWindowsView *view, const FlutterLayer **layers, size_t layers_count) override
|Compositor|
bool CreateBackingStore(const FlutterBackingStoreConfig &config, FlutterBackingStore *result) override
|Compositor|
FlutterWindowsView(FlutterViewId view_id, FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > window_binding, bool is_sized_to_content, const BoxConstraints &box_constraints, FlutterWindowsViewSizingDelegate *sizing_delegate=nullptr, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
TEST_F(AccessibilityPluginTest, DirectAnnounceCall)
constexpr FlutterViewId kImplicitViewId