Flutter Engine
The Flutter Engine
compositor_software.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/windows/compositor_software.h"
6
7#include "flutter/shell/platform/windows/flutter_windows_engine.h"
8#include "flutter/shell/platform/windows/flutter_windows_view.h"
9
10namespace flutter {
11
12constexpr int kOpaqueBlack = 0xff000000;
13
14namespace {
15
16/// Calculate the minimum and maximum x and y coordinates to enclose all layers.
17FlutterRect CalculateBounds(const FlutterLayer** layers, size_t layers_count) {
18 double x_min = HUGE_VAL;
19 double x_max = -HUGE_VAL;
20 double y_min = HUGE_VAL;
21 double y_max = -HUGE_VAL;
22 for (const FlutterLayer** layer = layers; layer < layers + layers_count;
23 layer++) {
24 const FlutterPoint& offset = (*layer)->offset;
25 const FlutterSize& size = (*layer)->size;
26 x_min = std::min(x_min, offset.x);
27 y_min = std::min(y_min, offset.y);
28 x_max = std::max(x_max, offset.x + size.width);
29 y_max = std::max(y_max, offset.y + size.height);
30 }
31 return FlutterRect{x_min, y_min, x_max, y_max};
32}
33
34/// Blend layer in-place onto allocation, which already holds the previous
35/// results of composition.
36void BlendLayer(std::vector<uint32_t>& allocation,
37 const FlutterLayer& layer,
38 int x_min,
39 int y_min,
40 int width,
41 int height) {
43 auto& backing_store = *layer.backing_store;
44 FML_DCHECK(backing_store.type == kFlutterBackingStoreTypeSoftware);
45 auto src_data =
46 static_cast<const uint32_t*>(backing_store.software.allocation);
47 const FlutterPoint& offset = layer.offset;
48 const FlutterSize& size = layer.size;
49
50 // Bounds for iteration to prevent out-of-bounds destination coordinates.
51 int y_src_min = std::max(0., y_min - offset.y);
52 int y_src_max = std::min(size.height, height + y_min - offset.y);
53 int x_src_min = std::max(0., x_min - offset.x);
54 int x_src_max = std::min(size.width, width + x_min - offset.x);
55 for (int y_src = y_src_min; y_src < y_src_max; y_src++) {
56 int y_dst = y_src + offset.y - y_min;
57 for (int x_src = x_src_min; x_src < x_src_max; x_src++) {
58 int x_dst = x_src + offset.x + x_min;
59 size_t i_src = y_src * size.width + x_src;
60 size_t i_dst = y_dst * width + x_dst;
61 uint32_t src = src_data[i_src];
62 uint32_t dst = allocation[i_dst];
63
64 int r_src = (src >> 0) & 0xff;
65 int g_src = (src >> 8) & 0xff;
66 int b_src = (src >> 16) & 0xff;
67 int a_src = (src >> 24) & 0xff;
68
69 int r_dst = (dst >> 0) & 0xff;
70 int g_dst = (dst >> 8) & 0xff;
71 int b_dst = (dst >> 16) & 0xff;
72
73 int r = (r_dst * 255 + (r_src - r_dst) * a_src) / 255;
74 int g = (g_dst * 255 + (g_src - g_dst) * a_src) / 255;
75 int b = (b_dst * 255 + (b_src - b_dst) * a_src) / 255;
76
77 allocation[i_dst] = (r << 0) | (g << 8) | (b << 16) | (0xff << 24);
78 }
79 }
80}
81
82} // namespace
83
85
87 const FlutterBackingStoreConfig& config,
89 size_t size = config.size.width * config.size.height * 4;
90 void* allocation = std::calloc(size, sizeof(uint8_t));
91 if (!allocation) {
92 return false;
93 }
94
96 result->software.allocation = allocation;
97 result->software.height = config.size.height;
98 result->software.row_bytes = config.size.width * 4;
99 result->software.user_data = nullptr;
100 result->software.destruction_callback = [](void* user_data) {
101 // Backing store destroyed in `CompositorSoftware::CollectBackingStore`, set
102 // on FlutterCompositor.collect_backing_store_callback during engine start.
103 };
104 return true;
105}
106
108 std::free(const_cast<void*>(store->software.allocation));
109 return true;
110}
111
113 const FlutterLayer** layers,
114 size_t layers_count) {
115 FML_DCHECK(view != nullptr);
116
117 // Clear the view if there are no layers to present.
118 if (layers_count == 0) {
119 return view->ClearSoftwareBitmap();
120 }
121
122 // Bypass composition logic if there is only one layer.
123 if (layers_count == 1) {
124 const FlutterLayer* layer = layers[0];
125 FML_DCHECK(layer != nullptr);
127 layer->offset.x == 0 && layer->offset.y == 0) {
128 auto& backing_store = *layer->backing_store;
129 FML_DCHECK(backing_store.type == kFlutterBackingStoreTypeSoftware);
130 auto& software = backing_store.software;
131 return view->PresentSoftwareBitmap(software.allocation,
132 software.row_bytes, software.height);
133 }
134 }
135
136 // Composite many layers.
137 FlutterRect bounds = CalculateBounds(layers, layers_count);
138 // Truncate from double to integer to represent whole pixels.
139 int x_min = static_cast<int>(bounds.left);
140 int x_max = static_cast<int>(bounds.right);
141 int y_min = static_cast<int>(bounds.top);
142 int y_max = static_cast<int>(bounds.bottom);
143
144 int width = x_max - x_min;
145 int height = y_max - y_min;
146 std::vector<uint32_t> allocation(width * height, kOpaqueBlack);
147
148 for (const FlutterLayer** layer = layers; layer < layers + layers_count;
149 layer++) {
150 // TODO(schectman): handle platform view type layers.
151 // https://github.com/flutter/flutter/issues/143375
152 if ((*layer)->type == kFlutterLayerContentTypeBackingStore) {
153 BlendLayer(allocation, **layer, x_min, y_min, width, height);
154 } else {
156 return false;
157 }
158 }
159
160 return view->PresentSoftwareBitmap(static_cast<void*>(allocation.data()),
161 width * sizeof(uint32_t), height);
162}
163
164} // namespace flutter
SI void store(P *ptr, const T &val)
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|
virtual bool PresentSoftwareBitmap(const void *allocation, size_t row_bytes, size_t height)
@ kFlutterLayerContentTypeBackingStore
Definition: embedder.h:1793
@ kFlutterBackingStoreTypeSoftware
Specified an software allocation for Flutter to render into using the CPU.
Definition: embedder.h:1744
static bool b
GAsyncResult * result
#define FML_UNREACHABLE()
Definition: logging.h:109
#define FML_DCHECK(condition)
Definition: logging.h:103
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
Optional< SkRect > bounds
Definition: SkRecords.h:189
void * calloc(size_t n, size_t size)
Definition: allocation.cc:11
constexpr int kOpaqueBlack
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
int32_t height
int32_t width
SeparatedVector2 offset
FlutterSize size
The size of the render target the engine expects to render into.
Definition: embedder.h:1784
FlutterPoint offset
Definition: embedder.h:1835
FlutterLayerContentType type
Definition: embedder.h:1824
const FlutterBackingStore * backing_store
Definition: embedder.h:1828
FlutterSize size
The size of the layer (in physical pixels).
Definition: embedder.h:1837
A structure to represent a 2D point.
Definition: embedder.h:445
double y
Definition: embedder.h:447
double x
Definition: embedder.h:446
A structure to represent a rectangle.
Definition: embedder.h:437
A structure to represent the width and height.
Definition: embedder.h:423
double height
Definition: embedder.h:425
double width
Definition: embedder.h:424
void * user_data