1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <math/mat4.h>
20 #include <math/vec3.h>
21 #include <renderengine/ExternalTexture.h>
22 #include <renderengine/PrintMatrix.h>
23 #include <ui/BlurRegion.h>
24 #include <ui/DebugUtils.h>
25 #include <ui/Fence.h>
26 #include <ui/FloatRect.h>
27 #include <ui/GraphicBuffer.h>
28 #include <ui/GraphicTypes.h>
29 #include <ui/Rect.h>
30 #include <ui/Region.h>
31 #include <ui/ShadowSettings.h>
32 #include <ui/StretchEffect.h>
33 #include <ui/Transform.h>
34
35 #include <iosfwd>
36
37 namespace android {
38 namespace renderengine {
39
40 // Metadata describing the input buffer to render from.
41 struct Buffer {
42 // Buffer containing the image that we will render.
43 // If buffer == nullptr, then the rest of the fields in this struct will be
44 // ignored.
45 std::shared_ptr<ExternalTexture> buffer = nullptr;
46
47 // Fence that will fire when the buffer is ready to be bound.
48 sp<Fence> fence = nullptr;
49
50 // Whether to use filtering when rendering the texture.
51 bool useTextureFiltering = false;
52
53 // Transform matrix to apply to texture coordinates.
54 mat4 textureTransform = mat4();
55
56 // Whether to use pre-multiplied alpha.
57 bool usePremultipliedAlpha = true;
58
59 // Override flag that alpha for each pixel in the buffer *must* be 1.0.
60 // LayerSettings::alpha is still used if isOpaque==true - this flag only
61 // overrides the alpha channel of the buffer.
62 bool isOpaque = false;
63
64 float maxLuminanceNits = 0.0;
65 };
66
67 // Metadata describing the layer geometry.
68 struct Geometry {
69 // Boundaries of the layer.
70 FloatRect boundaries = FloatRect();
71
72 // Transform matrix to apply to mesh coordinates.
73 mat4 positionTransform = mat4();
74
75 // Radius of rounded corners, if greater than 0. Otherwise, this layer's
76 // corners are not rounded.
77 // Having corner radius will force GPU composition on the layer and its children, drawing it
78 // with a special shader. The shader will receive the radius and the crop rectangle as input,
79 // modifying the opacity of the destination texture, multiplying it by a number between 0 and 1.
80 // We query Layer#getRoundedCornerState() to retrieve the radius as well as the rounded crop
81 // rectangle to figure out how to apply the radius for this layer. The crop rectangle will be
82 // in local layer coordinate space, so we have to take the layer transform into account when
83 // walking up the tree.
84 vec2 roundedCornersRadius = vec2(0.0f, 0.0f);
85
86 // Rectangle within which corners will be rounded.
87 FloatRect roundedCornersCrop = FloatRect();
88 };
89
90 // Descriptor of the source pixels for this layer.
91 struct PixelSource {
92 // Source buffer
93 Buffer buffer = Buffer();
94
95 // The solid color with which to fill the layer.
96 // This should only be populated if we don't render from an application
97 // buffer.
98 half3 solidColor = half3(0.0f, 0.0f, 0.0f);
99 };
100
101 // The settings that RenderEngine requires for correctly rendering a Layer.
102 struct LayerSettings {
103 // Geometry information
104 Geometry geometry = Geometry();
105
106 // Source pixels for this layer.
107 PixelSource source = PixelSource();
108
109 // Alpha option to blend with the source pixels
110 half alpha = half(0.0);
111
112 // Color space describing how the source pixels should be interpreted.
113 ui::Dataspace sourceDataspace = ui::Dataspace::UNKNOWN;
114
115 // Additional layer-specific color transform to be applied before the global
116 // transform.
117 mat4 colorTransform = mat4();
118
119 // True if blending will be forced to be disabled.
120 bool disableBlending = false;
121
122 // If true, then this layer casts a shadow and/or blurs behind it, but it does
123 // not otherwise draw any of the layer's other contents.
124 bool skipContentDraw = false;
125
126 ShadowSettings shadow;
127
128 int backgroundBlurRadius = 0;
129
130 std::vector<BlurRegion> blurRegions;
131
132 // Transform matrix used to convert the blurRegions geometry into the same
133 // coordinate space as LayerSettings.geometry
134 mat4 blurRegionTransform = mat4();
135
136 StretchEffect stretchEffect;
137
138 // Name associated with the layer for debugging purposes.
139 std::string name;
140
141 // Luminance of the white point for this layer. Used for linear dimming.
142 // Individual layers will be dimmed by (whitePointNits / maxWhitePoint).
143 // If white point nits are unknown, then this layer is assumed to have the
144 // same luminance as the brightest layer in the scene.
145 float whitePointNits = -1.f;
146 };
147
148 // Keep in sync with custom comparison function in
149 // compositionengine/impl/ClientCompositionRequestCache.cpp
150 static inline bool operator==(const Buffer& lhs, const Buffer& rhs) {
151 return lhs.buffer == rhs.buffer && lhs.fence == rhs.fence &&
152 lhs.useTextureFiltering == rhs.useTextureFiltering &&
153 lhs.textureTransform == rhs.textureTransform &&
154 lhs.usePremultipliedAlpha == rhs.usePremultipliedAlpha &&
155 lhs.isOpaque == rhs.isOpaque && lhs.maxLuminanceNits == rhs.maxLuminanceNits;
156 }
157
158 static inline bool operator==(const Geometry& lhs, const Geometry& rhs) {
159 return lhs.boundaries == rhs.boundaries && lhs.positionTransform == rhs.positionTransform &&
160 lhs.roundedCornersRadius == rhs.roundedCornersRadius &&
161 lhs.roundedCornersCrop == rhs.roundedCornersCrop;
162 }
163
164 static inline bool operator==(const PixelSource& lhs, const PixelSource& rhs) {
165 return lhs.buffer == rhs.buffer && lhs.solidColor == rhs.solidColor;
166 }
167
168 static inline bool operator==(const LayerSettings& lhs, const LayerSettings& rhs) {
169 if (lhs.blurRegions.size() != rhs.blurRegions.size()) {
170 return false;
171 }
172 const auto size = lhs.blurRegions.size();
173 for (size_t i = 0; i < size; i++) {
174 if (lhs.blurRegions[i] != rhs.blurRegions[i]) {
175 return false;
176 }
177 }
178
179 return lhs.geometry == rhs.geometry && lhs.source == rhs.source && lhs.alpha == rhs.alpha &&
180 lhs.sourceDataspace == rhs.sourceDataspace &&
181 lhs.colorTransform == rhs.colorTransform &&
182 lhs.disableBlending == rhs.disableBlending &&
183 lhs.skipContentDraw == rhs.skipContentDraw && lhs.shadow == rhs.shadow &&
184 lhs.backgroundBlurRadius == rhs.backgroundBlurRadius &&
185 lhs.blurRegionTransform == rhs.blurRegionTransform &&
186 lhs.stretchEffect == rhs.stretchEffect && lhs.whitePointNits == rhs.whitePointNits;
187 }
188
PrintTo(const Buffer & settings,::std::ostream * os)189 static inline void PrintTo(const Buffer& settings, ::std::ostream* os) {
190 *os << "Buffer {";
191 *os << "\n .buffer = " << settings.buffer.get() << " "
192 << (settings.buffer.get() ? decodePixelFormat(settings.buffer->getPixelFormat()).c_str()
193 : "");
194 *os << "\n .fence = " << settings.fence.get();
195 *os << "\n .useTextureFiltering = " << settings.useTextureFiltering;
196 *os << "\n .textureTransform = ";
197 PrintMatrix(settings.textureTransform, os);
198 *os << "\n .usePremultipliedAlpha = " << settings.usePremultipliedAlpha;
199 *os << "\n .isOpaque = " << settings.isOpaque;
200 *os << "\n .maxLuminanceNits = " << settings.maxLuminanceNits;
201 *os << "\n}";
202 }
203
PrintTo(const Geometry & settings,::std::ostream * os)204 static inline void PrintTo(const Geometry& settings, ::std::ostream* os) {
205 *os << "Geometry {";
206 *os << "\n .boundaries = ";
207 PrintTo(settings.boundaries, os);
208 *os << "\n .positionTransform = ";
209 PrintMatrix(settings.positionTransform, os);
210 *os << "\n .roundedCornersRadiusX = " << settings.roundedCornersRadius.x;
211 *os << "\n .roundedCornersRadiusY = " << settings.roundedCornersRadius.y;
212 *os << "\n .roundedCornersCrop = ";
213 PrintTo(settings.roundedCornersCrop, os);
214 *os << "\n}";
215 }
216
PrintTo(const PixelSource & settings,::std::ostream * os)217 static inline void PrintTo(const PixelSource& settings, ::std::ostream* os) {
218 *os << "PixelSource {";
219 if (settings.buffer.buffer) {
220 *os << "\n .buffer = ";
221 PrintTo(settings.buffer, os);
222 *os << "\n}";
223 } else {
224 *os << "\n .solidColor = " << settings.solidColor;
225 *os << "\n}";
226 }
227 }
228
PrintTo(const ShadowSettings & settings,::std::ostream * os)229 static inline void PrintTo(const ShadowSettings& settings, ::std::ostream* os) {
230 *os << "ShadowSettings {";
231 *os << "\n .boundaries = ";
232 PrintTo(settings.boundaries, os);
233 *os << "\n .ambientColor = " << settings.ambientColor;
234 *os << "\n .spotColor = " << settings.spotColor;
235 *os << "\n .lightPos = " << settings.lightPos;
236 *os << "\n .lightRadius = " << settings.lightRadius;
237 *os << "\n .length = " << settings.length;
238 *os << "\n .casterIsTranslucent = " << settings.casterIsTranslucent;
239 *os << "\n}";
240 }
241
PrintTo(const StretchEffect & effect,::std::ostream * os)242 static inline void PrintTo(const StretchEffect& effect, ::std::ostream* os) {
243 *os << "StretchEffect {";
244 *os << "\n .width = " << effect.width;
245 *os << "\n .height = " << effect.height;
246 *os << "\n .vectorX = " << effect.vectorX;
247 *os << "\n .vectorY = " << effect.vectorY;
248 *os << "\n .maxAmountX = " << effect.maxAmountX;
249 *os << "\n .maxAmountY = " << effect.maxAmountY;
250 *os << "\n .mappedLeft = " << effect.mappedChildBounds.left;
251 *os << "\n .mappedTop = " << effect.mappedChildBounds.top;
252 *os << "\n .mappedRight = " << effect.mappedChildBounds.right;
253 *os << "\n .mappedBottom = " << effect.mappedChildBounds.bottom;
254 *os << "\n}";
255 }
256
PrintTo(const LayerSettings & settings,::std::ostream * os)257 static inline void PrintTo(const LayerSettings& settings, ::std::ostream* os) {
258 *os << "LayerSettings for '" << settings.name.c_str() << "' {";
259 *os << "\n .geometry = ";
260 PrintTo(settings.geometry, os);
261 *os << "\n .source = ";
262 PrintTo(settings.source, os);
263 *os << "\n .alpha = " << settings.alpha;
264 *os << "\n .sourceDataspace = ";
265 PrintTo(settings.sourceDataspace, os);
266 *os << "\n .colorTransform = ";
267 PrintMatrix(settings.colorTransform, os);
268 *os << "\n .disableBlending = " << settings.disableBlending;
269 *os << "\n .skipContentDraw = " << settings.skipContentDraw;
270 if (settings.shadow != ShadowSettings()) {
271 *os << "\n .shadow = ";
272 PrintTo(settings.shadow, os);
273 }
274 *os << "\n .backgroundBlurRadius = " << settings.backgroundBlurRadius;
275 if (settings.blurRegions.size()) {
276 *os << "\n .blurRegions =";
277 for (auto blurRegion : settings.blurRegions) {
278 *os << "\n";
279 PrintTo(blurRegion, os);
280 }
281 }
282 *os << "\n .blurRegionTransform = ";
283 PrintMatrix(settings.blurRegionTransform, os);
284 if (settings.stretchEffect != StretchEffect()) {
285 *os << "\n .stretchEffect = ";
286 PrintTo(settings.stretchEffect, os);
287 }
288 *os << "\n .whitePointNits = " << settings.whitePointNits;
289 *os << "\n}";
290 }
291
292 } // namespace renderengine
293 } // namespace android
294