blob: 03af3100a5a980087e2ec1c9bfd014d3a24d1ab2 [file] [log] [blame]
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -05001/*
2 * Copyright 2021 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 */
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050016#include "Cache.h"
17#include "AutoBackendTexture.h"
18#include "SkiaRenderEngine.h"
19#include "android-base/unique_fd.h"
20#include "renderengine/DisplaySettings.h"
21#include "renderengine/LayerSettings.h"
22#include "ui/GraphicBuffer.h"
23#include "ui/GraphicTypes.h"
24#include "ui/PixelFormat.h"
25#include "ui/Rect.h"
26#include "utils/Timers.h"
27
28namespace android::renderengine::skia {
29
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040030namespace {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040031// Warming shader cache, not framebuffer cache.
32constexpr bool kUseFrameBufferCache = false;
33
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040034// clang-format off
35// Any non-identity matrix will do.
36const auto kScaleAndTranslate = mat4(0.7f, 0.f, 0.f, 0.f,
37 0.f, 0.7f, 0.f, 0.f,
38 0.f, 0.f, 1.f, 0.f,
39 67.3f, 52.2f, 0.f, 1.f);
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -040040const auto kScaleAsymmetric = mat4(0.8f, 0.f, 0.f, 0.f,
41 0.f, 1.1f, 0.f, 0.f,
42 0.f, 0.f, 1.f, 0.f,
43 0.f, 0.f, 0.f, 1.f);
Nathaniel Nifong13491502021-06-30 17:28:29 -040044const auto kFlip = mat4(1.1f, -0.1f, 0.f, 0.f,
45 0.1f, 1.1f, 0.f, 0.f,
46 0.f, 0.f, 1.f, 0.f,
47 2.f, 2.f, 0.f, 1.f);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040048// clang-format on
Nathaniel Nifongbf6f7542021-04-27 12:05:16 -040049// When setting layer.sourceDataspace, whether it matches the destination or not determines whether
50// a color correction effect is added to the shader.
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040051constexpr auto kDestDataSpace = ui::Dataspace::SRGB;
Nathaniel Nifong21e021f2021-04-21 13:15:46 -040052constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040053} // namespace
54
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040055static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +000056 const std::shared_ptr<ExternalTexture>& dstTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050057 // Somewhat arbitrary dimensions, but on screen and slightly shorter, based
58 // on actual use.
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040059 const Rect& displayRect = display.physicalDisplay;
60 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
61 FloatRect smallerRect(20, 20, displayRect.width()-20, displayRect.height()-20);
62
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050063 LayerSettings layer{
64 .geometry =
65 Geometry{
66 .boundaries = rect,
67 .roundedCornersCrop = rect,
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040068 .roundedCornersRadius = 50.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050069 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040070 // drawShadow ignores alpha
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050071 .shadow =
72 ShadowSettings{
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040073 .boundaries = rect,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050074 .ambientColor = vec4(0, 0, 0, 0.00935997f),
75 .spotColor = vec4(0, 0, 0, 0.0455841f),
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040076 .lightPos = vec3(500.f, -1500.f, 1500.f),
77 .lightRadius = 2500.0f,
78 .length = 15.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050079 },
Nathaniel Nifong490a9472021-06-23 16:44:19 -040080 // setting this is mandatory for shadows and blurs
81 .skipContentDraw = true,
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040082 .alpha = 1,
83 };
84 LayerSettings caster{
85 .geometry =
86 Geometry{
87 .boundaries = smallerRect,
88 .roundedCornersCrop = rect,
89 .roundedCornersRadius = 50.f,
90 },
91 .source =
92 PixelSource{
93 .solidColor = half3(0.f, 0.f, 0.f),
94 },
95 .alpha = 1,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050096 };
97
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -040098 base::unique_fd drawFence;
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040099 auto layers = std::vector<const LayerSettings*>{&layer, &caster};
Nathaniel Nifong49a59582021-07-26 19:49:47 -0400100 // Four combinations of settings are used (two transforms here, and drawShadowLayers is
101 // called with two different destination data spaces) They're all rounded rect.
102 // Three of these are cache misses that generate new shaders.
103 // The first combination generates a short and simple shadow shader.
104 // The second combination, flip transform, generates two shaders. The first appears to involve
105 // gaussian_fp. The second is a long and general purpose shadow shader with a device space
106 // transformation stage.
107 // The third combination is a cache hit, nothing new.
108 // The fourth combination, flip transform with a non-SRGB destination dataspace, is new.
109 // It is unique in that nearly everything is done in the vertex shader, and that vertex shader
110 // requires color correction. This is triggered differently from every other instance of color
111 // correction. All other instances are triggered when src and dst dataspaces differ, while
112 // this one is triggered by the destination being non-srgb. Apparently since the third
113 // combination is a cache hit, this color correction is only added when the vertex shader is
114 // doing something non-trivial.
115 for (auto transform : {mat4(), kFlip}) {
116 layer.geometry.positionTransform = transform;
117 caster.geometry.positionTransform = transform;
118 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
119 base::unique_fd(), &drawFence);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500120 }
121}
122
123static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000124 const std::shared_ptr<ExternalTexture>& dstTexture,
125 const std::shared_ptr<ExternalTexture>& srcTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500126 const Rect& displayRect = display.physicalDisplay;
127 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
128 LayerSettings layer{
129 .geometry =
130 Geometry{
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400131 // The position transform doesn't matter when the reduced shader mode
132 // in in effect. A matrix transform stage is always included.
133 .positionTransform = mat4(),
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500134 .boundaries = rect,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500135 .roundedCornersCrop = rect,
136 },
137 .source = PixelSource{.buffer =
138 Buffer{
Alec Mouria90a5702021-04-16 16:36:21 +0000139 .buffer = srcTexture,
John Reckac09e452021-04-07 16:35:37 -0400140 .maxLuminanceNits = 1000.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500141 }},
142 };
143
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400144 base::unique_fd drawFence;
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500145 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongbf6f7542021-04-27 12:05:16 -0400146 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
147 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400148 // Cache shaders for both rects and round rects.
149 // In reduced shader mode, all non-zero round rect radii get the same code path.
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400150 for (float roundedCornersRadius : {0.0f, 50.0f}) {
151 // roundedCornersCrop is always set, but the radius triggers the behavior
152 layer.geometry.roundedCornersRadius = roundedCornersRadius;
153 for (bool isOpaque : {true, false}) {
154 layer.source.buffer.isOpaque = isOpaque;
155 for (auto alpha : {half(.2f), half(1.0f)}) {
156 layer.alpha = alpha;
157 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400158 base::unique_fd(), &drawFence);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500159 }
160 }
161 }
162 }
163}
164
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400165static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000166 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400167 const Rect& displayRect = display.physicalDisplay;
168 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
169 LayerSettings layer{
170 .geometry =
171 Geometry{
172 .boundaries = rect,
173 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400174 .source =
175 PixelSource{
176 .solidColor = half3(0.1f, 0.2f, 0.3f),
177 },
Nathaniel Nifong768693f2021-06-08 14:33:47 -0400178 .alpha = 0.5,
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400179 };
180
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400181 base::unique_fd drawFence;
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400182 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400183 for (auto transform : {mat4(), kScaleAndTranslate}) {
184 layer.geometry.positionTransform = transform;
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400185 for (float roundedCornersRadius : {0.0f, 50.f}) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400186 layer.geometry.roundedCornersRadius = roundedCornersRadius;
Alec Mouria90a5702021-04-16 16:36:21 +0000187 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400188 base::unique_fd(), &drawFence);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400189 }
190 }
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400191}
192
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400193static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000194 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400195 const Rect& displayRect = display.physicalDisplay;
196 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
197 LayerSettings layer{
198 .geometry =
199 Geometry{
200 .boundaries = rect,
201 },
202 .alpha = 1,
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400203 // setting this is mandatory for shadows and blurs
204 .skipContentDraw = true,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400205 };
206
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400207 base::unique_fd drawFence;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400208 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400209 // Different blur code is invoked for radii less and greater than 30 pixels
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400210 for (int radius : {9, 60}) {
211 layer.backgroundBlurRadius = radius;
Alec Mouria90a5702021-04-16 16:36:21 +0000212 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400213 base::unique_fd(), &drawFence);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400214 }
215}
216
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400217// The unique feature of these layers is that the boundary is slightly smaller than the rounded
218// rect crop, so the rounded edges intersect that boundary and require a different clipping method.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400219// For buffers, this is done with a stage that computes coverage and it will differ for round and
220// elliptical corners.
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400221static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
222 const std::shared_ptr<ExternalTexture>& dstTexture,
223 const std::shared_ptr<ExternalTexture>& srcTexture) {
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400224 const Rect& displayRect = display.physicalDisplay;
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400225 FloatRect rect(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller
226
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400227 PixelSource bufferSource{.buffer = Buffer{
228 .buffer = srcTexture,
229 .isOpaque = 0,
230 .maxLuminanceNits = 1000.f,
231 }};
232 PixelSource bufferOpaque{.buffer = Buffer{
233 .buffer = srcTexture,
234 .isOpaque = 1,
235 .maxLuminanceNits = 1000.f,
236 }};
237 PixelSource colorSource{.solidColor = half3(0.1f, 0.2f, 0.3f)};
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400238
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400239 LayerSettings layer{
240 .geometry =
241 Geometry{
242 .boundaries = rect,
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400243 .roundedCornersRadius = 27, // larger than the 20 above.
244 .roundedCornersCrop =
245 FloatRect(0, 0, displayRect.width(), displayRect.height()),
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400246 },
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400247 };
248
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400249 base::unique_fd drawFence;
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400250 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400251 for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) {
252 layer.source = pixelSource;
253 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
254 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400255 // Produce a CircularRRect clip and an EllipticalRRect clip.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400256 for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) {
257 layer.geometry.positionTransform = transform;
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400258 for (float alpha : {0.5f, 1.f}) {
259 layer.alpha = alpha,
260 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400261 base::unique_fd(), &drawFence);
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400262 }
263 }
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400264 }
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400265 }
266}
267
Nathaniel Nifong13491502021-06-30 17:28:29 -0400268static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
269 const std::shared_ptr<ExternalTexture>& dstTexture,
270 const std::shared_ptr<ExternalTexture>& srcTexture) {
271 const Rect& displayRect = display.physicalDisplay;
272 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
273 LayerSettings layer{
274 .geometry =
275 Geometry{
276 // Note that this flip matrix only makes a difference when clipping,
277 // which happens in this layer because the roundrect crop is just a bit
278 // larger than the layer bounds.
279 .positionTransform = kFlip,
280 .boundaries = rect,
281 .roundedCornersRadius = 94.2551,
282 .roundedCornersCrop = FloatRect(
283 -93.75, 0, displayRect.width() + 93.75, displayRect.height()),
284 },
285 .source = PixelSource{.buffer =
286 Buffer{
287 .buffer = srcTexture,
288 .maxLuminanceNits = 1000.f,
289 .isOpaque = 0,
290 .usePremultipliedAlpha = 1,
291 }},
292 .sourceDataspace = kOtherDataSpace,
293 .alpha = 1,
294
295 };
296
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400297 base::unique_fd drawFence;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400298 auto layers = std::vector<const LayerSettings*>{&layer};
299 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400300 base::unique_fd(), &drawFence);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400301}
302
303static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
304 const std::shared_ptr<ExternalTexture>& dstTexture) {
305 const Rect& displayRect = display.physicalDisplay;
306 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
307 FloatRect small(0, 0, displayRect.width()-20, displayRect.height()+20);
308 LayerSettings layer{
309 .geometry =
310 Geometry{
311 .positionTransform = kScaleAndTranslate,
312 // the boundaries have to be smaller than the rounded crop so that
313 // clipRRect is used instead of drawRRect
314 .boundaries = small,
315 .roundedCornersRadius = 50.f,
316 .roundedCornersCrop = rect,
317 },
318 .source = PixelSource{
319 .solidColor = half3(0.f, 0.f, 0.f),
320 },
321 .sourceDataspace = kDestDataSpace,
322 .alpha = 0,
323 .disableBlending = true,
324
325 };
326
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400327 base::unique_fd drawFence;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400328 auto layers = std::vector<const LayerSettings*>{&layer};
329 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400330 base::unique_fd(), &drawFence);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400331}
332
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400333//
334// The collection of shaders cached here were found by using perfetto to record shader compiles
335// during actions that involve RenderEngine, logging the layer settings, and the shader code
336// and reproducing those settings here.
337//
338// It is helpful when debugging this to turn on
339// in SkGLRenderEngine.cpp:
340// kPrintLayerSettings = true
341// kFlushAfterEveryLayer = true
342// in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
343// gPrintSKSL = true
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500344void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400345 const int previousCount = renderengine->reportShadersCompiled();
346 if (previousCount) {
347 ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
348 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500349
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400350 // The loop is beneficial for debugging and should otherwise be optimized out by the compiler.
351 // Adding additional bounds to the loop is useful for verifying that the size of the dst buffer
352 // does not impact the shader compilation counts by triggering different behaviors in RE/Skia.
353 for (SkSize bounds : {SkSize::Make(128, 128), /*SkSize::Make(1080, 2340)*/}) {
354 const nsecs_t timeBefore = systemTime();
355 // The dimensions should not matter, so long as we draw inside them.
356 const Rect displayRect(0, 0, bounds.fWidth, bounds.fHeight);
357 DisplaySettings display{
358 .physicalDisplay = displayRect,
359 .clip = displayRect,
360 .maxLuminance = 500,
361 .outputDataspace = kDestDataSpace,
362 };
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400363 DisplaySettings p3Display{
364 .physicalDisplay = displayRect,
365 .clip = displayRect,
366 .maxLuminance = 500,
367 .outputDataspace = kOtherDataSpace,
368 };
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500369
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400370 const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
Alec Mouria90a5702021-04-16 16:36:21 +0000371
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400372 sp<GraphicBuffer> dstBuffer =
373 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
374 1, usage, "primeShaderCache_dst");
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400375
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400376 const auto dstTexture =
377 std::make_shared<ExternalTexture>(dstBuffer, *renderengine,
378 ExternalTexture::Usage::WRITEABLE);
379 // This buffer will be the source for the call to drawImageLayers. Draw
380 // something to it as a placeholder for what an app draws. We should draw
381 // something, but the details are not important. Make use of the shadow layer drawing step
382 // to populate it.
383 sp<GraphicBuffer> srcBuffer =
384 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
385 1, usage, "drawImageLayer_src");
Alec Mouria90a5702021-04-16 16:36:21 +0000386
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400387 const auto srcTexture =
388 std::make_shared<ExternalTexture>(srcBuffer, *renderengine,
389 ExternalTexture::Usage::READABLE |
390 ExternalTexture::Usage::WRITEABLE);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400391 drawHolePunchLayer(renderengine, display, dstTexture);
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400392 drawSolidLayers(renderengine, display, dstTexture);
Nathaniel Nifong49a59582021-07-26 19:49:47 -0400393
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400394 drawShadowLayers(renderengine, display, srcTexture);
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400395 drawShadowLayers(renderengine, p3Display, srcTexture);
Nathaniel Nifongcda45e92021-06-10 15:01:42 -0400396
397 if (renderengine->supportsBackgroundBlur()) {
398 drawBlurLayers(renderengine, display, dstTexture);
399 }
400
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400401 // The majority of skia shaders needed by RenderEngine are related to sampling images.
402 // These need to be generated with various source textures.
403 // Make a list of applicable sources.
404 // GRALLOC_USAGE_HW_TEXTURE should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE.
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400405 const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400406 sp<GraphicBuffer> externalBuffer =
407 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
408 1, usageExternal, "primeShaderCache_external");
409 const auto externalTexture =
410 std::make_shared<ExternalTexture>(externalBuffer, *renderengine,
411 ExternalTexture::Usage::READABLE);
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400412 std::vector<const std::shared_ptr<ExternalTexture>> textures =
413 {srcTexture, externalTexture};
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400414
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400415 // Another external texture with a different pixel format triggers useIsOpaqueWorkaround.
416 // It doesn't have to be f16, but it can't be the usual 8888.
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400417 sp<GraphicBuffer> f16ExternalBuffer =
418 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_FP16,
419 1, usageExternal, "primeShaderCache_external_f16");
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400420 // The F16 texture may not be usable on all devices, so check first that it was created.
421 status_t error = f16ExternalBuffer->initCheck();
422 if (!error) {
423 const auto f16ExternalTexture =
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400424 std::make_shared<ExternalTexture>(f16ExternalBuffer, *renderengine,
425 ExternalTexture::Usage::READABLE);
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400426 textures.push_back(f16ExternalTexture);
427 }
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400428
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400429 for (auto texture : textures) {
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400430 drawImageLayers(renderengine, display, dstTexture, texture);
431 // Draw layers for b/185569240.
432 drawClippedLayers(renderengine, display, dstTexture, texture);
433 }
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400434
Nathaniel Nifong13491502021-06-30 17:28:29 -0400435 drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
436
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400437 // draw one final layer synchronously to force GL submit
438 LayerSettings layer{
439 .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)},
440 };
441 auto layers = std::vector<const LayerSettings*>{&layer};
442 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
443 base::unique_fd(), nullptr); // null drawFence makes it synchronous
444
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400445 const nsecs_t timeAfter = systemTime();
446 const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
447 const int shadersCompiled = renderengine->reportShadersCompiled();
448 ALOGD("Shader cache generated %d shaders in %f ms\n", shadersCompiled, compileTimeMs);
449 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500450}
451
452} // namespace android::renderengine::skia