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