1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2021 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker #include "Cache.h"
17*38e8c45fSAndroid Build Coastguard Worker #include "AutoBackendTexture.h"
18*38e8c45fSAndroid Build Coastguard Worker #include "SkiaRenderEngine.h"
19*38e8c45fSAndroid Build Coastguard Worker #include "android-base/unique_fd.h"
20*38e8c45fSAndroid Build Coastguard Worker #include "cutils/properties.h"
21*38e8c45fSAndroid Build Coastguard Worker #include "renderengine/DisplaySettings.h"
22*38e8c45fSAndroid Build Coastguard Worker #include "renderengine/LayerSettings.h"
23*38e8c45fSAndroid Build Coastguard Worker #include "renderengine/impl/ExternalTexture.h"
24*38e8c45fSAndroid Build Coastguard Worker #include "ui/GraphicBuffer.h"
25*38e8c45fSAndroid Build Coastguard Worker #include "ui/GraphicTypes.h"
26*38e8c45fSAndroid Build Coastguard Worker #include "ui/PixelFormat.h"
27*38e8c45fSAndroid Build Coastguard Worker #include "ui/Rect.h"
28*38e8c45fSAndroid Build Coastguard Worker #include "utils/Timers.h"
29*38e8c45fSAndroid Build Coastguard Worker
30*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libgui_flags.h>
31*38e8c45fSAndroid Build Coastguard Worker
32*38e8c45fSAndroid Build Coastguard Worker namespace android::renderengine::skia {
33*38e8c45fSAndroid Build Coastguard Worker
34*38e8c45fSAndroid Build Coastguard Worker namespace {
35*38e8c45fSAndroid Build Coastguard Worker
36*38e8c45fSAndroid Build Coastguard Worker // clang-format off
37*38e8c45fSAndroid Build Coastguard Worker // Any non-identity matrix will do.
38*38e8c45fSAndroid Build Coastguard Worker const auto kScaleAndTranslate = mat4(0.7f, 0.f, 0.f, 0.f,
39*38e8c45fSAndroid Build Coastguard Worker 0.f, 0.7f, 0.f, 0.f,
40*38e8c45fSAndroid Build Coastguard Worker 0.f, 0.f, 1.f, 0.f,
41*38e8c45fSAndroid Build Coastguard Worker 67.3f, 52.2f, 0.f, 1.f);
42*38e8c45fSAndroid Build Coastguard Worker const auto kScaleAsymmetric = mat4(0.8f, 0.f, 0.f, 0.f,
43*38e8c45fSAndroid Build Coastguard Worker 0.f, 1.1f, 0.f, 0.f,
44*38e8c45fSAndroid Build Coastguard Worker 0.f, 0.f, 1.f, 0.f,
45*38e8c45fSAndroid Build Coastguard Worker 0.f, 0.f, 0.f, 1.f);
46*38e8c45fSAndroid Build Coastguard Worker const auto kFlip = mat4(1.1f, -0.1f, 0.f, 0.f,
47*38e8c45fSAndroid Build Coastguard Worker 0.1f, 1.1f, 0.f, 0.f,
48*38e8c45fSAndroid Build Coastguard Worker 0.f, 0.f, 1.f, 0.f,
49*38e8c45fSAndroid Build Coastguard Worker 2.f, 2.f, 0.f, 1.f);
50*38e8c45fSAndroid Build Coastguard Worker // clang-format on
51*38e8c45fSAndroid Build Coastguard Worker // When setting layer.sourceDataspace, whether it matches the destination or not determines whether
52*38e8c45fSAndroid Build Coastguard Worker // a color correction effect is added to the shader.
53*38e8c45fSAndroid Build Coastguard Worker constexpr auto kDestDataSpace = ui::Dataspace::SRGB;
54*38e8c45fSAndroid Build Coastguard Worker constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3;
55*38e8c45fSAndroid Build Coastguard Worker constexpr auto kBT2020DataSpace = ui::Dataspace::BT2020_ITU_PQ;
56*38e8c45fSAndroid Build Coastguard Worker constexpr auto kExtendedHdrDataSpce =
57*38e8c45fSAndroid Build Coastguard Worker static_cast<ui::Dataspace>(ui::Dataspace::RANGE_EXTENDED | ui::Dataspace::TRANSFER_SRGB |
58*38e8c45fSAndroid Build Coastguard Worker ui::Dataspace::STANDARD_DCI_P3);
59*38e8c45fSAndroid Build Coastguard Worker // Dimming is needed to trigger linear effects for some dataspace pairs
60*38e8c45fSAndroid Build Coastguard Worker const std::array<float, 3> kLayerWhitePoints = {
61*38e8c45fSAndroid Build Coastguard Worker 1000.0f, 500.0f,
62*38e8c45fSAndroid Build Coastguard Worker 100.0f, // trigger dithering by dimming below 20%
63*38e8c45fSAndroid Build Coastguard Worker };
64*38e8c45fSAndroid Build Coastguard Worker } // namespace
65*38e8c45fSAndroid Build Coastguard Worker
drawShadowLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture)66*38e8c45fSAndroid Build Coastguard Worker static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
67*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture) {
68*38e8c45fSAndroid Build Coastguard Worker // Somewhat arbitrary dimensions, but on screen and slightly shorter, based
69*38e8c45fSAndroid Build Coastguard Worker // on actual use.
70*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
71*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
72*38e8c45fSAndroid Build Coastguard Worker FloatRect smallerRect(20, 20, displayRect.width()-20, displayRect.height()-20);
73*38e8c45fSAndroid Build Coastguard Worker
74*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
75*38e8c45fSAndroid Build Coastguard Worker .geometry =
76*38e8c45fSAndroid Build Coastguard Worker Geometry{
77*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
78*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {50.f, 50.f},
79*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
80*38e8c45fSAndroid Build Coastguard Worker },
81*38e8c45fSAndroid Build Coastguard Worker .alpha = 1,
82*38e8c45fSAndroid Build Coastguard Worker // setting this is mandatory for shadows and blurs
83*38e8c45fSAndroid Build Coastguard Worker .skipContentDraw = true,
84*38e8c45fSAndroid Build Coastguard Worker // drawShadow ignores alpha
85*38e8c45fSAndroid Build Coastguard Worker .shadow =
86*38e8c45fSAndroid Build Coastguard Worker ShadowSettings{
87*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
88*38e8c45fSAndroid Build Coastguard Worker .ambientColor = vec4(0, 0, 0, 0.00935997f),
89*38e8c45fSAndroid Build Coastguard Worker .spotColor = vec4(0, 0, 0, 0.0455841f),
90*38e8c45fSAndroid Build Coastguard Worker .lightPos = vec3(500.f, -1500.f, 1500.f),
91*38e8c45fSAndroid Build Coastguard Worker .lightRadius = 2500.0f,
92*38e8c45fSAndroid Build Coastguard Worker .length = 15.f,
93*38e8c45fSAndroid Build Coastguard Worker },
94*38e8c45fSAndroid Build Coastguard Worker };
95*38e8c45fSAndroid Build Coastguard Worker LayerSettings caster{
96*38e8c45fSAndroid Build Coastguard Worker .geometry =
97*38e8c45fSAndroid Build Coastguard Worker Geometry{
98*38e8c45fSAndroid Build Coastguard Worker .boundaries = smallerRect,
99*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {50.f, 50.f},
100*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
101*38e8c45fSAndroid Build Coastguard Worker },
102*38e8c45fSAndroid Build Coastguard Worker .source =
103*38e8c45fSAndroid Build Coastguard Worker PixelSource{
104*38e8c45fSAndroid Build Coastguard Worker .solidColor = half3(0.f, 0.f, 0.f),
105*38e8c45fSAndroid Build Coastguard Worker },
106*38e8c45fSAndroid Build Coastguard Worker .alpha = 1,
107*38e8c45fSAndroid Build Coastguard Worker };
108*38e8c45fSAndroid Build Coastguard Worker
109*38e8c45fSAndroid Build Coastguard Worker // Four combinations of settings are used (two transforms here, and drawShadowLayers is
110*38e8c45fSAndroid Build Coastguard Worker // called with two different destination data spaces) They're all rounded rect.
111*38e8c45fSAndroid Build Coastguard Worker // Three of these are cache misses that generate new shaders.
112*38e8c45fSAndroid Build Coastguard Worker // The first combination generates a short and simple shadow shader.
113*38e8c45fSAndroid Build Coastguard Worker // The second combination, flip transform, generates two shaders. The first appears to involve
114*38e8c45fSAndroid Build Coastguard Worker // gaussian_fp. The second is a long and general purpose shadow shader with a device space
115*38e8c45fSAndroid Build Coastguard Worker // transformation stage.
116*38e8c45fSAndroid Build Coastguard Worker // The third combination is a cache hit, nothing new.
117*38e8c45fSAndroid Build Coastguard Worker // The fourth combination, flip transform with a non-SRGB destination dataspace, is new.
118*38e8c45fSAndroid Build Coastguard Worker // It is unique in that nearly everything is done in the vertex shader, and that vertex shader
119*38e8c45fSAndroid Build Coastguard Worker // requires color correction. This is triggered differently from every other instance of color
120*38e8c45fSAndroid Build Coastguard Worker // correction. All other instances are triggered when src and dst dataspaces differ, while
121*38e8c45fSAndroid Build Coastguard Worker // this one is triggered by the destination being non-srgb. Apparently since the third
122*38e8c45fSAndroid Build Coastguard Worker // combination is a cache hit, this color correction is only added when the vertex shader is
123*38e8c45fSAndroid Build Coastguard Worker // doing something non-trivial.
124*38e8c45fSAndroid Build Coastguard Worker for (auto transform : {mat4(), kFlip}) {
125*38e8c45fSAndroid Build Coastguard Worker layer.geometry.positionTransform = transform;
126*38e8c45fSAndroid Build Coastguard Worker caster.geometry.positionTransform = transform;
127*38e8c45fSAndroid Build Coastguard Worker
128*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer, caster};
129*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
130*38e8c45fSAndroid Build Coastguard Worker }
131*38e8c45fSAndroid Build Coastguard Worker }
132*38e8c45fSAndroid Build Coastguard Worker
drawImageLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)133*38e8c45fSAndroid Build Coastguard Worker static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
134*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
135*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
136*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
137*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
138*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
139*38e8c45fSAndroid Build Coastguard Worker .geometry =
140*38e8c45fSAndroid Build Coastguard Worker Geometry{
141*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
142*38e8c45fSAndroid Build Coastguard Worker // The position transform doesn't matter when the reduced shader mode
143*38e8c45fSAndroid Build Coastguard Worker // in in effect. A matrix transform stage is always included.
144*38e8c45fSAndroid Build Coastguard Worker .positionTransform = mat4(),
145*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
146*38e8c45fSAndroid Build Coastguard Worker },
147*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer =
148*38e8c45fSAndroid Build Coastguard Worker Buffer{
149*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
150*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
151*38e8c45fSAndroid Build Coastguard Worker }},
152*38e8c45fSAndroid Build Coastguard Worker };
153*38e8c45fSAndroid Build Coastguard Worker
154*38e8c45fSAndroid Build Coastguard Worker for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
155*38e8c45fSAndroid Build Coastguard Worker layer.sourceDataspace = dataspace;
156*38e8c45fSAndroid Build Coastguard Worker // Cache shaders for both rects and round rects.
157*38e8c45fSAndroid Build Coastguard Worker // In reduced shader mode, all non-zero round rect radii get the same code path.
158*38e8c45fSAndroid Build Coastguard Worker for (float roundedCornersRadius : {0.0f, 50.0f}) {
159*38e8c45fSAndroid Build Coastguard Worker // roundedCornersCrop is always set, but the radius triggers the behavior
160*38e8c45fSAndroid Build Coastguard Worker layer.geometry.roundedCornersRadius = {roundedCornersRadius, roundedCornersRadius};
161*38e8c45fSAndroid Build Coastguard Worker for (bool isOpaque : {true, false}) {
162*38e8c45fSAndroid Build Coastguard Worker layer.source.buffer.isOpaque = isOpaque;
163*38e8c45fSAndroid Build Coastguard Worker for (auto alpha : {half(.2f), half(1.0f)}) {
164*38e8c45fSAndroid Build Coastguard Worker layer.alpha = alpha;
165*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
166*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
167*38e8c45fSAndroid Build Coastguard Worker }
168*38e8c45fSAndroid Build Coastguard Worker }
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker }
171*38e8c45fSAndroid Build Coastguard Worker }
172*38e8c45fSAndroid Build Coastguard Worker
drawSolidLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture)173*38e8c45fSAndroid Build Coastguard Worker static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
174*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture) {
175*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
176*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
177*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
178*38e8c45fSAndroid Build Coastguard Worker .geometry =
179*38e8c45fSAndroid Build Coastguard Worker Geometry{
180*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
181*38e8c45fSAndroid Build Coastguard Worker },
182*38e8c45fSAndroid Build Coastguard Worker .source =
183*38e8c45fSAndroid Build Coastguard Worker PixelSource{
184*38e8c45fSAndroid Build Coastguard Worker .solidColor = half3(0.1f, 0.2f, 0.3f),
185*38e8c45fSAndroid Build Coastguard Worker },
186*38e8c45fSAndroid Build Coastguard Worker .alpha = 0.5,
187*38e8c45fSAndroid Build Coastguard Worker };
188*38e8c45fSAndroid Build Coastguard Worker
189*38e8c45fSAndroid Build Coastguard Worker for (auto transform : {mat4(), kScaleAndTranslate}) {
190*38e8c45fSAndroid Build Coastguard Worker layer.geometry.positionTransform = transform;
191*38e8c45fSAndroid Build Coastguard Worker for (float roundedCornersRadius : {0.0f, 50.f}) {
192*38e8c45fSAndroid Build Coastguard Worker layer.geometry.roundedCornersRadius = {roundedCornersRadius, roundedCornersRadius};
193*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
194*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
195*38e8c45fSAndroid Build Coastguard Worker }
196*38e8c45fSAndroid Build Coastguard Worker }
197*38e8c45fSAndroid Build Coastguard Worker }
198*38e8c45fSAndroid Build Coastguard Worker
drawBlurLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture)199*38e8c45fSAndroid Build Coastguard Worker static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
200*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture) {
201*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
202*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
203*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
204*38e8c45fSAndroid Build Coastguard Worker .geometry =
205*38e8c45fSAndroid Build Coastguard Worker Geometry{
206*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
207*38e8c45fSAndroid Build Coastguard Worker },
208*38e8c45fSAndroid Build Coastguard Worker .alpha = 1,
209*38e8c45fSAndroid Build Coastguard Worker // setting this is mandatory for shadows and blurs
210*38e8c45fSAndroid Build Coastguard Worker .skipContentDraw = true,
211*38e8c45fSAndroid Build Coastguard Worker };
212*38e8c45fSAndroid Build Coastguard Worker
213*38e8c45fSAndroid Build Coastguard Worker // Different blur code is invoked for radii less and greater than 30 pixels
214*38e8c45fSAndroid Build Coastguard Worker for (int radius : {9, 60}) {
215*38e8c45fSAndroid Build Coastguard Worker layer.backgroundBlurRadius = radius;
216*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
217*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
218*38e8c45fSAndroid Build Coastguard Worker }
219*38e8c45fSAndroid Build Coastguard Worker }
220*38e8c45fSAndroid Build Coastguard Worker
221*38e8c45fSAndroid Build Coastguard Worker // The unique feature of these layers is that the boundary is slightly smaller than the rounded
222*38e8c45fSAndroid Build Coastguard Worker // rect crop, so the rounded edges intersect that boundary and require a different clipping method.
223*38e8c45fSAndroid Build Coastguard Worker // For buffers, this is done with a stage that computes coverage and it will differ for round and
224*38e8c45fSAndroid Build Coastguard Worker // elliptical corners.
drawClippedLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)225*38e8c45fSAndroid Build Coastguard Worker static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
226*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
227*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
228*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
229*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller
230*38e8c45fSAndroid Build Coastguard Worker
231*38e8c45fSAndroid Build Coastguard Worker PixelSource bufferSource{.buffer = Buffer{
232*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
233*38e8c45fSAndroid Build Coastguard Worker .isOpaque = 0,
234*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
235*38e8c45fSAndroid Build Coastguard Worker }};
236*38e8c45fSAndroid Build Coastguard Worker PixelSource bufferOpaque{.buffer = Buffer{
237*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
238*38e8c45fSAndroid Build Coastguard Worker .isOpaque = 1,
239*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
240*38e8c45fSAndroid Build Coastguard Worker }};
241*38e8c45fSAndroid Build Coastguard Worker PixelSource colorSource{.solidColor = half3(0.1f, 0.2f, 0.3f)};
242*38e8c45fSAndroid Build Coastguard Worker
243*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
244*38e8c45fSAndroid Build Coastguard Worker .geometry =
245*38e8c45fSAndroid Build Coastguard Worker Geometry{
246*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
247*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {27.f, 27.f},
248*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop =
249*38e8c45fSAndroid Build Coastguard Worker FloatRect(0, 0, displayRect.width(), displayRect.height()),
250*38e8c45fSAndroid Build Coastguard Worker },
251*38e8c45fSAndroid Build Coastguard Worker };
252*38e8c45fSAndroid Build Coastguard Worker
253*38e8c45fSAndroid Build Coastguard Worker for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) {
254*38e8c45fSAndroid Build Coastguard Worker layer.source = pixelSource;
255*38e8c45fSAndroid Build Coastguard Worker for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
256*38e8c45fSAndroid Build Coastguard Worker layer.sourceDataspace = dataspace;
257*38e8c45fSAndroid Build Coastguard Worker // Produce a CircularRRect clip and an EllipticalRRect clip.
258*38e8c45fSAndroid Build Coastguard Worker for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) {
259*38e8c45fSAndroid Build Coastguard Worker layer.geometry.positionTransform = transform;
260*38e8c45fSAndroid Build Coastguard Worker for (float alpha : {0.5f, 1.f}) {
261*38e8c45fSAndroid Build Coastguard Worker layer.alpha = alpha;
262*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
263*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
264*38e8c45fSAndroid Build Coastguard Worker }
265*38e8c45fSAndroid Build Coastguard Worker }
266*38e8c45fSAndroid Build Coastguard Worker }
267*38e8c45fSAndroid Build Coastguard Worker }
268*38e8c45fSAndroid Build Coastguard Worker }
269*38e8c45fSAndroid Build Coastguard Worker
drawPIPImageLayer(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)270*38e8c45fSAndroid Build Coastguard Worker static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
271*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
272*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
273*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
274*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
275*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
276*38e8c45fSAndroid Build Coastguard Worker .geometry =
277*38e8c45fSAndroid Build Coastguard Worker Geometry{
278*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
279*38e8c45fSAndroid Build Coastguard Worker // Note that this flip matrix only makes a difference when clipping,
280*38e8c45fSAndroid Build Coastguard Worker // which happens in this layer because the roundrect crop is just a bit
281*38e8c45fSAndroid Build Coastguard Worker // larger than the layer bounds.
282*38e8c45fSAndroid Build Coastguard Worker .positionTransform = kFlip,
283*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {94.2551f, 94.2551f},
284*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = FloatRect(-93.75, 0, displayRect.width() + 93.75,
285*38e8c45fSAndroid Build Coastguard Worker displayRect.height()),
286*38e8c45fSAndroid Build Coastguard Worker },
287*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer =
288*38e8c45fSAndroid Build Coastguard Worker Buffer{
289*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
290*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = 1,
291*38e8c45fSAndroid Build Coastguard Worker .isOpaque = 0,
292*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
293*38e8c45fSAndroid Build Coastguard Worker }},
294*38e8c45fSAndroid Build Coastguard Worker .alpha = 1,
295*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kOtherDataSpace,
296*38e8c45fSAndroid Build Coastguard Worker
297*38e8c45fSAndroid Build Coastguard Worker };
298*38e8c45fSAndroid Build Coastguard Worker
299*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
300*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
301*38e8c45fSAndroid Build Coastguard Worker }
302*38e8c45fSAndroid Build Coastguard Worker
drawHolePunchLayer(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture)303*38e8c45fSAndroid Build Coastguard Worker static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
304*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture) {
305*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
306*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
307*38e8c45fSAndroid Build Coastguard Worker FloatRect small(0, 0, displayRect.width()-20, displayRect.height()+20);
308*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
309*38e8c45fSAndroid Build Coastguard Worker .geometry =
310*38e8c45fSAndroid Build Coastguard Worker Geometry{
311*38e8c45fSAndroid Build Coastguard Worker // the boundaries have to be smaller than the rounded crop so that
312*38e8c45fSAndroid Build Coastguard Worker // clipRRect is used instead of drawRRect
313*38e8c45fSAndroid Build Coastguard Worker .boundaries = small,
314*38e8c45fSAndroid Build Coastguard Worker .positionTransform = kScaleAndTranslate,
315*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {50.f, 50.f},
316*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
317*38e8c45fSAndroid Build Coastguard Worker },
318*38e8c45fSAndroid Build Coastguard Worker .source =
319*38e8c45fSAndroid Build Coastguard Worker PixelSource{
320*38e8c45fSAndroid Build Coastguard Worker .solidColor = half3(0.f, 0.f, 0.f),
321*38e8c45fSAndroid Build Coastguard Worker },
322*38e8c45fSAndroid Build Coastguard Worker .alpha = 0,
323*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kDestDataSpace,
324*38e8c45fSAndroid Build Coastguard Worker .disableBlending = true,
325*38e8c45fSAndroid Build Coastguard Worker
326*38e8c45fSAndroid Build Coastguard Worker };
327*38e8c45fSAndroid Build Coastguard Worker
328*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
329*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
330*38e8c45fSAndroid Build Coastguard Worker }
331*38e8c45fSAndroid Build Coastguard Worker
drawImageDimmedLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)332*38e8c45fSAndroid Build Coastguard Worker static void drawImageDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
333*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
334*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
335*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
336*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
337*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
338*38e8c45fSAndroid Build Coastguard Worker .geometry =
339*38e8c45fSAndroid Build Coastguard Worker Geometry{
340*38e8c45fSAndroid Build Coastguard Worker // The position transform doesn't matter when the reduced shader mode
341*38e8c45fSAndroid Build Coastguard Worker // in in effect. A matrix transform stage is always included.
342*38e8c45fSAndroid Build Coastguard Worker .positionTransform = mat4(),
343*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
344*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
345*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {0.f, 0.f},
346*38e8c45fSAndroid Build Coastguard Worker },
347*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
348*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
349*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = true,
350*38e8c45fSAndroid Build Coastguard Worker .isOpaque = true}},
351*38e8c45fSAndroid Build Coastguard Worker .alpha = 1.f,
352*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kDestDataSpace,
353*38e8c45fSAndroid Build Coastguard Worker };
354*38e8c45fSAndroid Build Coastguard Worker
355*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers;
356*38e8c45fSAndroid Build Coastguard Worker
357*38e8c45fSAndroid Build Coastguard Worker for (auto layerWhitePoint : kLayerWhitePoints) {
358*38e8c45fSAndroid Build Coastguard Worker layer.whitePointNits = layerWhitePoint;
359*38e8c45fSAndroid Build Coastguard Worker layers.push_back(layer);
360*38e8c45fSAndroid Build Coastguard Worker }
361*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
362*38e8c45fSAndroid Build Coastguard Worker }
363*38e8c45fSAndroid Build Coastguard Worker
drawTransparentImageDimmedLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)364*38e8c45fSAndroid Build Coastguard Worker static void drawTransparentImageDimmedLayers(SkiaRenderEngine* renderengine,
365*38e8c45fSAndroid Build Coastguard Worker const DisplaySettings& display,
366*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
367*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
368*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
369*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
370*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
371*38e8c45fSAndroid Build Coastguard Worker .geometry =
372*38e8c45fSAndroid Build Coastguard Worker Geometry{
373*38e8c45fSAndroid Build Coastguard Worker .positionTransform = mat4(),
374*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
375*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
376*38e8c45fSAndroid Build Coastguard Worker },
377*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer =
378*38e8c45fSAndroid Build Coastguard Worker Buffer{
379*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
380*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
381*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = true,
382*38e8c45fSAndroid Build Coastguard Worker .isOpaque = false,
383*38e8c45fSAndroid Build Coastguard Worker }},
384*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kDestDataSpace,
385*38e8c45fSAndroid Build Coastguard Worker };
386*38e8c45fSAndroid Build Coastguard Worker
387*38e8c45fSAndroid Build Coastguard Worker for (auto roundedCornerRadius : {0.f, 50.f}) {
388*38e8c45fSAndroid Build Coastguard Worker layer.geometry.roundedCornersRadius = {roundedCornerRadius, roundedCornerRadius};
389*38e8c45fSAndroid Build Coastguard Worker for (auto alpha : {0.5f, 1.0f}) {
390*38e8c45fSAndroid Build Coastguard Worker layer.alpha = alpha;
391*38e8c45fSAndroid Build Coastguard Worker for (auto isOpaque : {true, false}) {
392*38e8c45fSAndroid Build Coastguard Worker if (roundedCornerRadius == 0.f && isOpaque) {
393*38e8c45fSAndroid Build Coastguard Worker // already covered in drawImageDimmedLayers
394*38e8c45fSAndroid Build Coastguard Worker continue;
395*38e8c45fSAndroid Build Coastguard Worker }
396*38e8c45fSAndroid Build Coastguard Worker
397*38e8c45fSAndroid Build Coastguard Worker layer.source.buffer.isOpaque = isOpaque;
398*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers;
399*38e8c45fSAndroid Build Coastguard Worker
400*38e8c45fSAndroid Build Coastguard Worker for (auto layerWhitePoint : kLayerWhitePoints) {
401*38e8c45fSAndroid Build Coastguard Worker layer.whitePointNits = layerWhitePoint;
402*38e8c45fSAndroid Build Coastguard Worker layers.push_back(layer);
403*38e8c45fSAndroid Build Coastguard Worker }
404*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
405*38e8c45fSAndroid Build Coastguard Worker }
406*38e8c45fSAndroid Build Coastguard Worker }
407*38e8c45fSAndroid Build Coastguard Worker }
408*38e8c45fSAndroid Build Coastguard Worker }
409*38e8c45fSAndroid Build Coastguard Worker
drawClippedDimmedImageLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)410*38e8c45fSAndroid Build Coastguard Worker static void drawClippedDimmedImageLayers(SkiaRenderEngine* renderengine,
411*38e8c45fSAndroid Build Coastguard Worker const DisplaySettings& display,
412*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
413*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
414*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
415*38e8c45fSAndroid Build Coastguard Worker
416*38e8c45fSAndroid Build Coastguard Worker // If rect and boundary is too small compared to roundedCornersRadius, Skia will switch to
417*38e8c45fSAndroid Build Coastguard Worker // blending instead of EllipticalRRect, so enlarge them a bit.
418*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
419*38e8c45fSAndroid Build Coastguard Worker FloatRect boundary(0, 0, displayRect.width(),
420*38e8c45fSAndroid Build Coastguard Worker displayRect.height() - 20); // boundary is smaller
421*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
422*38e8c45fSAndroid Build Coastguard Worker .geometry =
423*38e8c45fSAndroid Build Coastguard Worker Geometry{
424*38e8c45fSAndroid Build Coastguard Worker .positionTransform = mat4(),
425*38e8c45fSAndroid Build Coastguard Worker .boundaries = boundary,
426*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
427*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {27.f, 27.f},
428*38e8c45fSAndroid Build Coastguard Worker },
429*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer =
430*38e8c45fSAndroid Build Coastguard Worker Buffer{
431*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
432*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
433*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = true,
434*38e8c45fSAndroid Build Coastguard Worker .isOpaque = false,
435*38e8c45fSAndroid Build Coastguard Worker }},
436*38e8c45fSAndroid Build Coastguard Worker .alpha = 1.f,
437*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kDestDataSpace,
438*38e8c45fSAndroid Build Coastguard Worker };
439*38e8c45fSAndroid Build Coastguard Worker
440*38e8c45fSAndroid Build Coastguard Worker std::array<mat4, 2> transforms = {kScaleAndTranslate, kScaleAsymmetric};
441*38e8c45fSAndroid Build Coastguard Worker
442*38e8c45fSAndroid Build Coastguard Worker constexpr float radius = 27.f;
443*38e8c45fSAndroid Build Coastguard Worker
444*38e8c45fSAndroid Build Coastguard Worker for (size_t i = 0; i < transforms.size(); i++) {
445*38e8c45fSAndroid Build Coastguard Worker layer.geometry.positionTransform = transforms[i];
446*38e8c45fSAndroid Build Coastguard Worker layer.geometry.roundedCornersRadius = {radius, radius};
447*38e8c45fSAndroid Build Coastguard Worker
448*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers;
449*38e8c45fSAndroid Build Coastguard Worker
450*38e8c45fSAndroid Build Coastguard Worker for (auto layerWhitePoint : kLayerWhitePoints) {
451*38e8c45fSAndroid Build Coastguard Worker layer.whitePointNits = layerWhitePoint;
452*38e8c45fSAndroid Build Coastguard Worker layers.push_back(layer);
453*38e8c45fSAndroid Build Coastguard Worker }
454*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
455*38e8c45fSAndroid Build Coastguard Worker }
456*38e8c45fSAndroid Build Coastguard Worker }
457*38e8c45fSAndroid Build Coastguard Worker
drawSolidDimmedLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture)458*38e8c45fSAndroid Build Coastguard Worker static void drawSolidDimmedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
459*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture) {
460*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
461*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
462*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
463*38e8c45fSAndroid Build Coastguard Worker .geometry =
464*38e8c45fSAndroid Build Coastguard Worker Geometry{
465*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
466*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
467*38e8c45fSAndroid Build Coastguard Worker },
468*38e8c45fSAndroid Build Coastguard Worker .source =
469*38e8c45fSAndroid Build Coastguard Worker PixelSource{
470*38e8c45fSAndroid Build Coastguard Worker .solidColor = half3(0.1f, 0.2f, 0.3f),
471*38e8c45fSAndroid Build Coastguard Worker },
472*38e8c45fSAndroid Build Coastguard Worker .alpha = 1.f,
473*38e8c45fSAndroid Build Coastguard Worker };
474*38e8c45fSAndroid Build Coastguard Worker
475*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers;
476*38e8c45fSAndroid Build Coastguard Worker
477*38e8c45fSAndroid Build Coastguard Worker for (auto layerWhitePoint : kLayerWhitePoints) {
478*38e8c45fSAndroid Build Coastguard Worker layer.whitePointNits = layerWhitePoint;
479*38e8c45fSAndroid Build Coastguard Worker layers.push_back(layer);
480*38e8c45fSAndroid Build Coastguard Worker }
481*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
482*38e8c45fSAndroid Build Coastguard Worker }
483*38e8c45fSAndroid Build Coastguard Worker
drawBT2020ImageLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)484*38e8c45fSAndroid Build Coastguard Worker static void drawBT2020ImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
485*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
486*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
487*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
488*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
489*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
490*38e8c45fSAndroid Build Coastguard Worker .geometry =
491*38e8c45fSAndroid Build Coastguard Worker Geometry{
492*38e8c45fSAndroid Build Coastguard Worker // The position transform doesn't matter when the reduced shader mode
493*38e8c45fSAndroid Build Coastguard Worker // in in effect. A matrix transform stage is always included.
494*38e8c45fSAndroid Build Coastguard Worker .positionTransform = mat4(),
495*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
496*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
497*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {0.f, 0.f},
498*38e8c45fSAndroid Build Coastguard Worker },
499*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
500*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
501*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = true,
502*38e8c45fSAndroid Build Coastguard Worker .isOpaque = true}},
503*38e8c45fSAndroid Build Coastguard Worker .alpha = 1.f,
504*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kBT2020DataSpace,
505*38e8c45fSAndroid Build Coastguard Worker };
506*38e8c45fSAndroid Build Coastguard Worker
507*38e8c45fSAndroid Build Coastguard Worker for (auto alpha : {0.5f, 1.f}) {
508*38e8c45fSAndroid Build Coastguard Worker layer.alpha = alpha;
509*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers;
510*38e8c45fSAndroid Build Coastguard Worker layer.whitePointNits = -1.f;
511*38e8c45fSAndroid Build Coastguard Worker layers.push_back(layer);
512*38e8c45fSAndroid Build Coastguard Worker
513*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
514*38e8c45fSAndroid Build Coastguard Worker }
515*38e8c45fSAndroid Build Coastguard Worker }
drawBT2020ClippedImageLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)516*38e8c45fSAndroid Build Coastguard Worker static void drawBT2020ClippedImageLayers(SkiaRenderEngine* renderengine,
517*38e8c45fSAndroid Build Coastguard Worker const DisplaySettings& display,
518*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
519*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
520*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
521*38e8c45fSAndroid Build Coastguard Worker
522*38e8c45fSAndroid Build Coastguard Worker // If rect and boundary is too small compared to roundedCornersRadius, Skia will switch to
523*38e8c45fSAndroid Build Coastguard Worker // blending instead of EllipticalRRect, so enlarge them a bit.
524*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
525*38e8c45fSAndroid Build Coastguard Worker FloatRect boundary(0, 0, displayRect.width(),
526*38e8c45fSAndroid Build Coastguard Worker displayRect.height() - 10); // boundary is smaller
527*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
528*38e8c45fSAndroid Build Coastguard Worker .geometry =
529*38e8c45fSAndroid Build Coastguard Worker Geometry{
530*38e8c45fSAndroid Build Coastguard Worker .positionTransform = kScaleAsymmetric,
531*38e8c45fSAndroid Build Coastguard Worker .boundaries = boundary,
532*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
533*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {64.1f, 64.1f},
534*38e8c45fSAndroid Build Coastguard Worker },
535*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer =
536*38e8c45fSAndroid Build Coastguard Worker Buffer{
537*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
538*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
539*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = true,
540*38e8c45fSAndroid Build Coastguard Worker .isOpaque = true,
541*38e8c45fSAndroid Build Coastguard Worker }},
542*38e8c45fSAndroid Build Coastguard Worker .alpha = 0.5f,
543*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kBT2020DataSpace,
544*38e8c45fSAndroid Build Coastguard Worker };
545*38e8c45fSAndroid Build Coastguard Worker
546*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers = {layer};
547*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
548*38e8c45fSAndroid Build Coastguard Worker }
549*38e8c45fSAndroid Build Coastguard Worker
drawExtendedHDRImageLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)550*38e8c45fSAndroid Build Coastguard Worker static void drawExtendedHDRImageLayers(SkiaRenderEngine* renderengine,
551*38e8c45fSAndroid Build Coastguard Worker const DisplaySettings& display,
552*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
553*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
554*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
555*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
556*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
557*38e8c45fSAndroid Build Coastguard Worker .geometry =
558*38e8c45fSAndroid Build Coastguard Worker Geometry{
559*38e8c45fSAndroid Build Coastguard Worker // The position transform doesn't matter when the reduced shader mode
560*38e8c45fSAndroid Build Coastguard Worker // in in effect. A matrix transform stage is always included.
561*38e8c45fSAndroid Build Coastguard Worker .positionTransform = mat4(),
562*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
563*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
564*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {50.f, 50.f},
565*38e8c45fSAndroid Build Coastguard Worker },
566*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
567*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
568*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = true,
569*38e8c45fSAndroid Build Coastguard Worker .isOpaque = true}},
570*38e8c45fSAndroid Build Coastguard Worker .alpha = 0.5f,
571*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kExtendedHdrDataSpce,
572*38e8c45fSAndroid Build Coastguard Worker };
573*38e8c45fSAndroid Build Coastguard Worker
574*38e8c45fSAndroid Build Coastguard Worker for (auto roundedCornerRadius : {0.f, 50.f}) {
575*38e8c45fSAndroid Build Coastguard Worker layer.geometry.roundedCornersRadius = {roundedCornerRadius, roundedCornerRadius};
576*38e8c45fSAndroid Build Coastguard Worker for (auto alpha : {0.5f, 1.f}) {
577*38e8c45fSAndroid Build Coastguard Worker layer.alpha = alpha;
578*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers;
579*38e8c45fSAndroid Build Coastguard Worker
580*38e8c45fSAndroid Build Coastguard Worker for (auto layerWhitePoint : kLayerWhitePoints) {
581*38e8c45fSAndroid Build Coastguard Worker layer.whitePointNits = layerWhitePoint;
582*38e8c45fSAndroid Build Coastguard Worker layers.push_back(layer);
583*38e8c45fSAndroid Build Coastguard Worker }
584*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
585*38e8c45fSAndroid Build Coastguard Worker }
586*38e8c45fSAndroid Build Coastguard Worker }
587*38e8c45fSAndroid Build Coastguard Worker }
588*38e8c45fSAndroid Build Coastguard Worker
drawP3ImageLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)589*38e8c45fSAndroid Build Coastguard Worker static void drawP3ImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
590*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
591*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
592*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
593*38e8c45fSAndroid Build Coastguard Worker FloatRect rect(0, 0, displayRect.width(), displayRect.height());
594*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
595*38e8c45fSAndroid Build Coastguard Worker .geometry =
596*38e8c45fSAndroid Build Coastguard Worker Geometry{
597*38e8c45fSAndroid Build Coastguard Worker // The position transform doesn't matter when the reduced shader mode
598*38e8c45fSAndroid Build Coastguard Worker // in in effect. A matrix transform stage is always included.
599*38e8c45fSAndroid Build Coastguard Worker .positionTransform = mat4(),
600*38e8c45fSAndroid Build Coastguard Worker .boundaries = rect,
601*38e8c45fSAndroid Build Coastguard Worker .roundedCornersCrop = rect,
602*38e8c45fSAndroid Build Coastguard Worker .roundedCornersRadius = {50.f, 50.f},
603*38e8c45fSAndroid Build Coastguard Worker },
604*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
605*38e8c45fSAndroid Build Coastguard Worker .maxLuminanceNits = 1000.f,
606*38e8c45fSAndroid Build Coastguard Worker .usePremultipliedAlpha = true,
607*38e8c45fSAndroid Build Coastguard Worker .isOpaque = false}},
608*38e8c45fSAndroid Build Coastguard Worker .alpha = 0.5f,
609*38e8c45fSAndroid Build Coastguard Worker .sourceDataspace = kOtherDataSpace,
610*38e8c45fSAndroid Build Coastguard Worker };
611*38e8c45fSAndroid Build Coastguard Worker
612*38e8c45fSAndroid Build Coastguard Worker for (auto alpha : {0.5f, 1.f}) {
613*38e8c45fSAndroid Build Coastguard Worker layer.alpha = alpha;
614*38e8c45fSAndroid Build Coastguard Worker std::vector<LayerSettings> layers;
615*38e8c45fSAndroid Build Coastguard Worker
616*38e8c45fSAndroid Build Coastguard Worker for (auto layerWhitePoint : kLayerWhitePoints) {
617*38e8c45fSAndroid Build Coastguard Worker layer.whitePointNits = layerWhitePoint;
618*38e8c45fSAndroid Build Coastguard Worker layers.push_back(layer);
619*38e8c45fSAndroid Build Coastguard Worker }
620*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
621*38e8c45fSAndroid Build Coastguard Worker }
622*38e8c45fSAndroid Build Coastguard Worker }
623*38e8c45fSAndroid Build Coastguard Worker
drawEdgeExtensionLayers(SkiaRenderEngine * renderengine,const DisplaySettings & display,const std::shared_ptr<ExternalTexture> & dstTexture,const std::shared_ptr<ExternalTexture> & srcTexture)624*38e8c45fSAndroid Build Coastguard Worker static void drawEdgeExtensionLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
625*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& dstTexture,
626*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& srcTexture) {
627*38e8c45fSAndroid Build Coastguard Worker const Rect& displayRect = display.physicalDisplay;
628*38e8c45fSAndroid Build Coastguard Worker // Make the layer
629*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
630*38e8c45fSAndroid Build Coastguard Worker // Make the layer bigger than the texture
631*38e8c45fSAndroid Build Coastguard Worker .geometry = Geometry{.boundaries = FloatRect(0, 0, displayRect.width(),
632*38e8c45fSAndroid Build Coastguard Worker displayRect.height())},
633*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.buffer =
634*38e8c45fSAndroid Build Coastguard Worker Buffer{
635*38e8c45fSAndroid Build Coastguard Worker .buffer = srcTexture,
636*38e8c45fSAndroid Build Coastguard Worker .isOpaque = 1,
637*38e8c45fSAndroid Build Coastguard Worker }},
638*38e8c45fSAndroid Build Coastguard Worker // The type of effect does not affect the shader's uniforms, but the layer must have a
639*38e8c45fSAndroid Build Coastguard Worker // valid EdgeExtensionEffect to apply the shader
640*38e8c45fSAndroid Build Coastguard Worker .edgeExtensionEffect =
641*38e8c45fSAndroid Build Coastguard Worker EdgeExtensionEffect(true /* left */, false, false, true /* bottom */),
642*38e8c45fSAndroid Build Coastguard Worker };
643*38e8c45fSAndroid Build Coastguard Worker for (float alpha : {0.5, 0.0, 1.0}) {
644*38e8c45fSAndroid Build Coastguard Worker layer.alpha = alpha;
645*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
646*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd());
647*38e8c45fSAndroid Build Coastguard Worker }
648*38e8c45fSAndroid Build Coastguard Worker }
649*38e8c45fSAndroid Build Coastguard Worker
650*38e8c45fSAndroid Build Coastguard Worker //
651*38e8c45fSAndroid Build Coastguard Worker // The collection of shaders cached here were found by using perfetto to record shader compiles
652*38e8c45fSAndroid Build Coastguard Worker // during actions that involve RenderEngine, logging the layer settings, and the shader code
653*38e8c45fSAndroid Build Coastguard Worker // and reproducing those settings here.
654*38e8c45fSAndroid Build Coastguard Worker //
655*38e8c45fSAndroid Build Coastguard Worker // It is helpful when debugging this to turn on
656*38e8c45fSAndroid Build Coastguard Worker // in SkGLRenderEngine.cpp:
657*38e8c45fSAndroid Build Coastguard Worker // kPrintLayerSettings = true
658*38e8c45fSAndroid Build Coastguard Worker // kFlushAfterEveryLayer = true
659*38e8c45fSAndroid Build Coastguard Worker // in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
660*38e8c45fSAndroid Build Coastguard Worker // gPrintSKSL = true
primeShaderCache(SkiaRenderEngine * renderengine,PrimeCacheConfig config)661*38e8c45fSAndroid Build Coastguard Worker void Cache::primeShaderCache(SkiaRenderEngine* renderengine, PrimeCacheConfig config) {
662*38e8c45fSAndroid Build Coastguard Worker const int previousCount = renderengine->reportShadersCompiled();
663*38e8c45fSAndroid Build Coastguard Worker if (previousCount) {
664*38e8c45fSAndroid Build Coastguard Worker ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
665*38e8c45fSAndroid Build Coastguard Worker }
666*38e8c45fSAndroid Build Coastguard Worker
667*38e8c45fSAndroid Build Coastguard Worker // The loop is beneficial for debugging and should otherwise be optimized out by the compiler.
668*38e8c45fSAndroid Build Coastguard Worker // Adding additional bounds to the loop is useful for verifying that the size of the dst buffer
669*38e8c45fSAndroid Build Coastguard Worker // does not impact the shader compilation counts by triggering different behaviors in RE/Skia.
670*38e8c45fSAndroid Build Coastguard Worker for (SkSize bounds : {SkSize::Make(128, 128), /*SkSize::Make(1080, 2340)*/}) {
671*38e8c45fSAndroid Build Coastguard Worker const nsecs_t timeBefore = systemTime();
672*38e8c45fSAndroid Build Coastguard Worker // The dimensions should not matter, so long as we draw inside them.
673*38e8c45fSAndroid Build Coastguard Worker const Rect displayRect(0, 0, bounds.fWidth, bounds.fHeight);
674*38e8c45fSAndroid Build Coastguard Worker DisplaySettings display{
675*38e8c45fSAndroid Build Coastguard Worker .physicalDisplay = displayRect,
676*38e8c45fSAndroid Build Coastguard Worker .clip = displayRect,
677*38e8c45fSAndroid Build Coastguard Worker .maxLuminance = 500,
678*38e8c45fSAndroid Build Coastguard Worker .outputDataspace = kDestDataSpace,
679*38e8c45fSAndroid Build Coastguard Worker };
680*38e8c45fSAndroid Build Coastguard Worker DisplaySettings p3Display{
681*38e8c45fSAndroid Build Coastguard Worker .physicalDisplay = displayRect,
682*38e8c45fSAndroid Build Coastguard Worker .clip = displayRect,
683*38e8c45fSAndroid Build Coastguard Worker .maxLuminance = 500,
684*38e8c45fSAndroid Build Coastguard Worker .outputDataspace = kOtherDataSpace,
685*38e8c45fSAndroid Build Coastguard Worker };
686*38e8c45fSAndroid Build Coastguard Worker DisplaySettings p3DisplayEnhance{.physicalDisplay = displayRect,
687*38e8c45fSAndroid Build Coastguard Worker .clip = displayRect,
688*38e8c45fSAndroid Build Coastguard Worker .maxLuminance = 500,
689*38e8c45fSAndroid Build Coastguard Worker .outputDataspace = kOtherDataSpace,
690*38e8c45fSAndroid Build Coastguard Worker .dimmingStage = aidl::android::hardware::graphics::
691*38e8c45fSAndroid Build Coastguard Worker composer3::DimmingStage::GAMMA_OETF,
692*38e8c45fSAndroid Build Coastguard Worker .renderIntent = aidl::android::hardware::graphics::
693*38e8c45fSAndroid Build Coastguard Worker composer3::RenderIntent::ENHANCE};
694*38e8c45fSAndroid Build Coastguard Worker DisplaySettings bt2020Display{.physicalDisplay = displayRect,
695*38e8c45fSAndroid Build Coastguard Worker .clip = displayRect,
696*38e8c45fSAndroid Build Coastguard Worker .maxLuminance = 500,
697*38e8c45fSAndroid Build Coastguard Worker .outputDataspace = ui::Dataspace::BT2020,
698*38e8c45fSAndroid Build Coastguard Worker .deviceHandlesColorTransform = true,
699*38e8c45fSAndroid Build Coastguard Worker .dimmingStage = aidl::android::hardware::graphics::composer3::
700*38e8c45fSAndroid Build Coastguard Worker DimmingStage::GAMMA_OETF,
701*38e8c45fSAndroid Build Coastguard Worker .renderIntent = aidl::android::hardware::graphics::composer3::
702*38e8c45fSAndroid Build Coastguard Worker RenderIntent::TONE_MAP_ENHANCE};
703*38e8c45fSAndroid Build Coastguard Worker
704*38e8c45fSAndroid Build Coastguard Worker const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
705*38e8c45fSAndroid Build Coastguard Worker
706*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> dstBuffer =
707*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>::make(displayRect.width(), displayRect.height(),
708*38e8c45fSAndroid Build Coastguard Worker PIXEL_FORMAT_RGBA_8888, 1, usage, "primeShaderCache_dst");
709*38e8c45fSAndroid Build Coastguard Worker
710*38e8c45fSAndroid Build Coastguard Worker const auto dstTexture =
711*38e8c45fSAndroid Build Coastguard Worker std::make_shared<impl::ExternalTexture>(dstBuffer, *renderengine,
712*38e8c45fSAndroid Build Coastguard Worker impl::ExternalTexture::Usage::WRITEABLE);
713*38e8c45fSAndroid Build Coastguard Worker // This buffer will be the source for the call to drawImageLayers. Draw
714*38e8c45fSAndroid Build Coastguard Worker // something to it as a placeholder for what an app draws. We should draw
715*38e8c45fSAndroid Build Coastguard Worker // something, but the details are not important. Make use of the shadow layer drawing step
716*38e8c45fSAndroid Build Coastguard Worker // to populate it.
717*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> srcBuffer =
718*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>::make(displayRect.width(), displayRect.height(),
719*38e8c45fSAndroid Build Coastguard Worker PIXEL_FORMAT_RGBA_8888, 1, usage, "drawImageLayer_src");
720*38e8c45fSAndroid Build Coastguard Worker
721*38e8c45fSAndroid Build Coastguard Worker const auto srcTexture = std::make_shared<
722*38e8c45fSAndroid Build Coastguard Worker impl::ExternalTexture>(srcBuffer, *renderengine,
723*38e8c45fSAndroid Build Coastguard Worker impl::ExternalTexture::Usage::READABLE |
724*38e8c45fSAndroid Build Coastguard Worker impl::ExternalTexture::Usage::WRITEABLE);
725*38e8c45fSAndroid Build Coastguard Worker
726*38e8c45fSAndroid Build Coastguard Worker if (config.cacheHolePunchLayer) {
727*38e8c45fSAndroid Build Coastguard Worker drawHolePunchLayer(renderengine, display, dstTexture);
728*38e8c45fSAndroid Build Coastguard Worker }
729*38e8c45fSAndroid Build Coastguard Worker
730*38e8c45fSAndroid Build Coastguard Worker if (config.cacheSolidLayers) {
731*38e8c45fSAndroid Build Coastguard Worker drawSolidLayers(renderengine, display, dstTexture);
732*38e8c45fSAndroid Build Coastguard Worker drawSolidLayers(renderengine, p3Display, dstTexture);
733*38e8c45fSAndroid Build Coastguard Worker }
734*38e8c45fSAndroid Build Coastguard Worker
735*38e8c45fSAndroid Build Coastguard Worker if (config.cacheSolidDimmedLayers) {
736*38e8c45fSAndroid Build Coastguard Worker drawSolidDimmedLayers(renderengine, display, dstTexture);
737*38e8c45fSAndroid Build Coastguard Worker }
738*38e8c45fSAndroid Build Coastguard Worker
739*38e8c45fSAndroid Build Coastguard Worker if (config.cacheShadowLayers) {
740*38e8c45fSAndroid Build Coastguard Worker drawShadowLayers(renderengine, display, srcTexture);
741*38e8c45fSAndroid Build Coastguard Worker drawShadowLayers(renderengine, p3Display, srcTexture);
742*38e8c45fSAndroid Build Coastguard Worker }
743*38e8c45fSAndroid Build Coastguard Worker
744*38e8c45fSAndroid Build Coastguard Worker if (renderengine->supportsBackgroundBlur()) {
745*38e8c45fSAndroid Build Coastguard Worker drawBlurLayers(renderengine, display, dstTexture);
746*38e8c45fSAndroid Build Coastguard Worker }
747*38e8c45fSAndroid Build Coastguard Worker
748*38e8c45fSAndroid Build Coastguard Worker // The majority of skia shaders needed by RenderEngine are related to sampling images.
749*38e8c45fSAndroid Build Coastguard Worker // These need to be generated with various source textures.
750*38e8c45fSAndroid Build Coastguard Worker // Make a list of applicable sources.
751*38e8c45fSAndroid Build Coastguard Worker // GRALLOC_USAGE_HW_TEXTURE should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE.
752*38e8c45fSAndroid Build Coastguard Worker const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
753*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> externalBuffer =
754*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>::make(displayRect.width(), displayRect.height(),
755*38e8c45fSAndroid Build Coastguard Worker PIXEL_FORMAT_RGBA_8888, 1, usageExternal,
756*38e8c45fSAndroid Build Coastguard Worker "primeShaderCache_external");
757*38e8c45fSAndroid Build Coastguard Worker const auto externalTexture =
758*38e8c45fSAndroid Build Coastguard Worker std::make_shared<impl::ExternalTexture>(externalBuffer, *renderengine,
759*38e8c45fSAndroid Build Coastguard Worker impl::ExternalTexture::Usage::READABLE);
760*38e8c45fSAndroid Build Coastguard Worker std::vector<std::shared_ptr<ExternalTexture>> textures = {srcTexture, externalTexture};
761*38e8c45fSAndroid Build Coastguard Worker
762*38e8c45fSAndroid Build Coastguard Worker // Another external texture with a different pixel format triggers useIsOpaqueWorkaround.
763*38e8c45fSAndroid Build Coastguard Worker // It doesn't have to be f16, but it can't be the usual 8888.
764*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> f16ExternalBuffer =
765*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer>::make(displayRect.width(), displayRect.height(),
766*38e8c45fSAndroid Build Coastguard Worker PIXEL_FORMAT_RGBA_FP16, 1, usageExternal,
767*38e8c45fSAndroid Build Coastguard Worker "primeShaderCache_external_f16");
768*38e8c45fSAndroid Build Coastguard Worker // The F16 texture may not be usable on all devices, so check first that it was created.
769*38e8c45fSAndroid Build Coastguard Worker status_t error = f16ExternalBuffer->initCheck();
770*38e8c45fSAndroid Build Coastguard Worker if (!error) {
771*38e8c45fSAndroid Build Coastguard Worker const auto f16ExternalTexture =
772*38e8c45fSAndroid Build Coastguard Worker std::make_shared<impl::ExternalTexture>(f16ExternalBuffer, *renderengine,
773*38e8c45fSAndroid Build Coastguard Worker impl::ExternalTexture::Usage::READABLE);
774*38e8c45fSAndroid Build Coastguard Worker textures.push_back(f16ExternalTexture);
775*38e8c45fSAndroid Build Coastguard Worker }
776*38e8c45fSAndroid Build Coastguard Worker
777*38e8c45fSAndroid Build Coastguard Worker for (auto texture : textures) {
778*38e8c45fSAndroid Build Coastguard Worker if (config.cacheImageLayers) {
779*38e8c45fSAndroid Build Coastguard Worker drawImageLayers(renderengine, display, dstTexture, texture);
780*38e8c45fSAndroid Build Coastguard Worker }
781*38e8c45fSAndroid Build Coastguard Worker
782*38e8c45fSAndroid Build Coastguard Worker if (config.cacheImageDimmedLayers) {
783*38e8c45fSAndroid Build Coastguard Worker drawImageDimmedLayers(renderengine, display, dstTexture, texture);
784*38e8c45fSAndroid Build Coastguard Worker drawImageDimmedLayers(renderengine, p3Display, dstTexture, texture);
785*38e8c45fSAndroid Build Coastguard Worker drawImageDimmedLayers(renderengine, bt2020Display, dstTexture, texture);
786*38e8c45fSAndroid Build Coastguard Worker }
787*38e8c45fSAndroid Build Coastguard Worker
788*38e8c45fSAndroid Build Coastguard Worker if (config.cacheClippedLayers) {
789*38e8c45fSAndroid Build Coastguard Worker // Draw layers for b/185569240.
790*38e8c45fSAndroid Build Coastguard Worker drawClippedLayers(renderengine, display, dstTexture, texture);
791*38e8c45fSAndroid Build Coastguard Worker }
792*38e8c45fSAndroid Build Coastguard Worker
793*38e8c45fSAndroid Build Coastguard Worker if (com::android::graphics::libgui::flags::edge_extension_shader() &&
794*38e8c45fSAndroid Build Coastguard Worker config.cacheEdgeExtension) {
795*38e8c45fSAndroid Build Coastguard Worker drawEdgeExtensionLayers(renderengine, display, dstTexture, texture);
796*38e8c45fSAndroid Build Coastguard Worker drawEdgeExtensionLayers(renderengine, p3Display, dstTexture, texture);
797*38e8c45fSAndroid Build Coastguard Worker }
798*38e8c45fSAndroid Build Coastguard Worker }
799*38e8c45fSAndroid Build Coastguard Worker
800*38e8c45fSAndroid Build Coastguard Worker if (config.cachePIPImageLayers) {
801*38e8c45fSAndroid Build Coastguard Worker drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
802*38e8c45fSAndroid Build Coastguard Worker }
803*38e8c45fSAndroid Build Coastguard Worker
804*38e8c45fSAndroid Build Coastguard Worker if (config.cacheTransparentImageDimmedLayers) {
805*38e8c45fSAndroid Build Coastguard Worker drawTransparentImageDimmedLayers(renderengine, bt2020Display, dstTexture,
806*38e8c45fSAndroid Build Coastguard Worker externalTexture);
807*38e8c45fSAndroid Build Coastguard Worker drawTransparentImageDimmedLayers(renderengine, display, dstTexture, externalTexture);
808*38e8c45fSAndroid Build Coastguard Worker drawTransparentImageDimmedLayers(renderengine, p3Display, dstTexture, externalTexture);
809*38e8c45fSAndroid Build Coastguard Worker drawTransparentImageDimmedLayers(renderengine, p3DisplayEnhance, dstTexture,
810*38e8c45fSAndroid Build Coastguard Worker externalTexture);
811*38e8c45fSAndroid Build Coastguard Worker }
812*38e8c45fSAndroid Build Coastguard Worker
813*38e8c45fSAndroid Build Coastguard Worker if (config.cacheClippedDimmedImageLayers) {
814*38e8c45fSAndroid Build Coastguard Worker drawClippedDimmedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
815*38e8c45fSAndroid Build Coastguard Worker }
816*38e8c45fSAndroid Build Coastguard Worker
817*38e8c45fSAndroid Build Coastguard Worker if (config.cacheUltraHDR) {
818*38e8c45fSAndroid Build Coastguard Worker drawBT2020ClippedImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
819*38e8c45fSAndroid Build Coastguard Worker
820*38e8c45fSAndroid Build Coastguard Worker drawBT2020ImageLayers(renderengine, bt2020Display, dstTexture, externalTexture);
821*38e8c45fSAndroid Build Coastguard Worker drawBT2020ImageLayers(renderengine, p3Display, dstTexture, externalTexture);
822*38e8c45fSAndroid Build Coastguard Worker
823*38e8c45fSAndroid Build Coastguard Worker drawExtendedHDRImageLayers(renderengine, display, dstTexture, externalTexture);
824*38e8c45fSAndroid Build Coastguard Worker drawExtendedHDRImageLayers(renderengine, p3Display, dstTexture, externalTexture);
825*38e8c45fSAndroid Build Coastguard Worker drawExtendedHDRImageLayers(renderengine, p3DisplayEnhance, dstTexture, externalTexture);
826*38e8c45fSAndroid Build Coastguard Worker
827*38e8c45fSAndroid Build Coastguard Worker drawP3ImageLayers(renderengine, p3DisplayEnhance, dstTexture, externalTexture);
828*38e8c45fSAndroid Build Coastguard Worker }
829*38e8c45fSAndroid Build Coastguard Worker
830*38e8c45fSAndroid Build Coastguard Worker // draw one final layer synchronously to force GL submit
831*38e8c45fSAndroid Build Coastguard Worker LayerSettings layer{
832*38e8c45fSAndroid Build Coastguard Worker .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)},
833*38e8c45fSAndroid Build Coastguard Worker };
834*38e8c45fSAndroid Build Coastguard Worker auto layers = std::vector<LayerSettings>{layer};
835*38e8c45fSAndroid Build Coastguard Worker // call get() to make it synchronous
836*38e8c45fSAndroid Build Coastguard Worker renderengine->drawLayers(display, layers, dstTexture, base::unique_fd()).get();
837*38e8c45fSAndroid Build Coastguard Worker
838*38e8c45fSAndroid Build Coastguard Worker const nsecs_t timeAfter = systemTime();
839*38e8c45fSAndroid Build Coastguard Worker const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
840*38e8c45fSAndroid Build Coastguard Worker const int shadersCompiled = renderengine->reportShadersCompiled() - previousCount;
841*38e8c45fSAndroid Build Coastguard Worker ALOGD("Shader cache generated %d shaders in %f ms\n", shadersCompiled, compileTimeMs);
842*38e8c45fSAndroid Build Coastguard Worker }
843*38e8c45fSAndroid Build Coastguard Worker }
844*38e8c45fSAndroid Build Coastguard Worker
845*38e8c45fSAndroid Build Coastguard Worker } // namespace android::renderengine::skia
846