blob: a3a1969ee7329c1962c7e19693a399d7f832af31 [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"
Vishnu Nairdbbe3852022-01-12 20:22:11 -080022#include "renderengine/impl/ExternalTexture.h"
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050023#include "ui/GraphicBuffer.h"
24#include "ui/GraphicTypes.h"
25#include "ui/PixelFormat.h"
26#include "ui/Rect.h"
27#include "utils/Timers.h"
28
29namespace android::renderengine::skia {
30
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040031namespace {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040032// Warming shader cache, not framebuffer cache.
33constexpr bool kUseFrameBufferCache = false;
34
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040035// clang-format off
36// Any non-identity matrix will do.
37const auto kScaleAndTranslate = mat4(0.7f, 0.f, 0.f, 0.f,
38 0.f, 0.7f, 0.f, 0.f,
39 0.f, 0.f, 1.f, 0.f,
40 67.3f, 52.2f, 0.f, 1.f);
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -040041const auto kScaleAsymmetric = mat4(0.8f, 0.f, 0.f, 0.f,
42 0.f, 1.1f, 0.f, 0.f,
43 0.f, 0.f, 1.f, 0.f,
44 0.f, 0.f, 0.f, 1.f);
Nathaniel Nifong13491502021-06-30 17:28:29 -040045const auto kFlip = mat4(1.1f, -0.1f, 0.f, 0.f,
46 0.1f, 1.1f, 0.f, 0.f,
47 0.f, 0.f, 1.f, 0.f,
48 2.f, 2.f, 0.f, 1.f);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040049// clang-format on
Nathaniel Nifongbf6f7542021-04-27 12:05:16 -040050// When setting layer.sourceDataspace, whether it matches the destination or not determines whether
51// a color correction effect is added to the shader.
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040052constexpr auto kDestDataSpace = ui::Dataspace::SRGB;
Nathaniel Nifong21e021f2021-04-21 13:15:46 -040053constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040054} // namespace
55
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040056static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +000057 const std::shared_ptr<ExternalTexture>& dstTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050058 // Somewhat arbitrary dimensions, but on screen and slightly shorter, based
59 // on actual use.
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040060 const Rect& displayRect = display.physicalDisplay;
61 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
62 FloatRect smallerRect(20, 20, displayRect.width()-20, displayRect.height()-20);
63
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050064 LayerSettings layer{
65 .geometry =
66 Geometry{
67 .boundaries = rect,
68 .roundedCornersCrop = rect,
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040069 .roundedCornersRadius = 50.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050070 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040071 // drawShadow ignores alpha
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050072 .shadow =
73 ShadowSettings{
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040074 .boundaries = rect,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050075 .ambientColor = vec4(0, 0, 0, 0.00935997f),
76 .spotColor = vec4(0, 0, 0, 0.0455841f),
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040077 .lightPos = vec3(500.f, -1500.f, 1500.f),
78 .lightRadius = 2500.0f,
79 .length = 15.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050080 },
Nathaniel Nifong490a9472021-06-23 16:44:19 -040081 // setting this is mandatory for shadows and blurs
82 .skipContentDraw = true,
Nathaniel Nifonga6b54232021-07-02 13:24:32 -040083 .alpha = 1,
84 };
85 LayerSettings caster{
86 .geometry =
87 Geometry{
88 .boundaries = smallerRect,
89 .roundedCornersCrop = rect,
90 .roundedCornersRadius = 50.f,
91 },
92 .source =
93 PixelSource{
94 .solidColor = half3(0.f, 0.f, 0.f),
95 },
96 .alpha = 1,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050097 };
98
Sally Qi59a9f502021-10-12 18:53:23 +000099 auto layers = std::vector<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,
Sally Qi4cabdd02021-08-05 16:45:57 -0700119 base::unique_fd());
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
Sally Qi59a9f502021-10-12 18:53:23 +0000144 auto layers = std::vector<LayerSettings>{layer};
Nathaniel Nifongbf6f7542021-04-27 12:05:16 -0400145 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
146 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400147 // Cache shaders for both rects and round rects.
148 // In reduced shader mode, all non-zero round rect radii get the same code path.
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400149 for (float roundedCornersRadius : {0.0f, 50.0f}) {
150 // roundedCornersCrop is always set, but the radius triggers the behavior
151 layer.geometry.roundedCornersRadius = roundedCornersRadius;
152 for (bool isOpaque : {true, false}) {
153 layer.source.buffer.isOpaque = isOpaque;
154 for (auto alpha : {half(.2f), half(1.0f)}) {
155 layer.alpha = alpha;
156 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700157 base::unique_fd());
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500158 }
159 }
160 }
161 }
162}
163
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400164static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000165 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400166 const Rect& displayRect = display.physicalDisplay;
167 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
168 LayerSettings layer{
169 .geometry =
170 Geometry{
171 .boundaries = rect,
172 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400173 .source =
174 PixelSource{
175 .solidColor = half3(0.1f, 0.2f, 0.3f),
176 },
Nathaniel Nifong768693f2021-06-08 14:33:47 -0400177 .alpha = 0.5,
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400178 };
179
Sally Qi59a9f502021-10-12 18:53:23 +0000180 auto layers = std::vector<LayerSettings>{layer};
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400181 for (auto transform : {mat4(), kScaleAndTranslate}) {
182 layer.geometry.positionTransform = transform;
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400183 for (float roundedCornersRadius : {0.0f, 50.f}) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400184 layer.geometry.roundedCornersRadius = roundedCornersRadius;
Alec Mouria90a5702021-04-16 16:36:21 +0000185 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700186 base::unique_fd());
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400187 }
188 }
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400189}
190
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400191static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000192 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400193 const Rect& displayRect = display.physicalDisplay;
194 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
195 LayerSettings layer{
196 .geometry =
197 Geometry{
198 .boundaries = rect,
199 },
200 .alpha = 1,
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400201 // setting this is mandatory for shadows and blurs
202 .skipContentDraw = true,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400203 };
204
Sally Qi59a9f502021-10-12 18:53:23 +0000205 auto layers = std::vector<LayerSettings>{layer};
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400206 // Different blur code is invoked for radii less and greater than 30 pixels
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400207 for (int radius : {9, 60}) {
208 layer.backgroundBlurRadius = radius;
Alec Mouria90a5702021-04-16 16:36:21 +0000209 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700210 base::unique_fd());
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400211 }
212}
213
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400214// The unique feature of these layers is that the boundary is slightly smaller than the rounded
215// rect crop, so the rounded edges intersect that boundary and require a different clipping method.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400216// For buffers, this is done with a stage that computes coverage and it will differ for round and
217// elliptical corners.
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400218static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
219 const std::shared_ptr<ExternalTexture>& dstTexture,
220 const std::shared_ptr<ExternalTexture>& srcTexture) {
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400221 const Rect& displayRect = display.physicalDisplay;
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400222 FloatRect rect(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller
223
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400224 PixelSource bufferSource{.buffer = Buffer{
225 .buffer = srcTexture,
226 .isOpaque = 0,
227 .maxLuminanceNits = 1000.f,
228 }};
229 PixelSource bufferOpaque{.buffer = Buffer{
230 .buffer = srcTexture,
231 .isOpaque = 1,
232 .maxLuminanceNits = 1000.f,
233 }};
234 PixelSource colorSource{.solidColor = half3(0.1f, 0.2f, 0.3f)};
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400235
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400236 LayerSettings layer{
237 .geometry =
238 Geometry{
239 .boundaries = rect,
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400240 .roundedCornersRadius = 27, // larger than the 20 above.
241 .roundedCornersCrop =
242 FloatRect(0, 0, displayRect.width(), displayRect.height()),
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400243 },
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400244 };
245
Sally Qi59a9f502021-10-12 18:53:23 +0000246 auto layers = std::vector<LayerSettings>{layer};
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400247 for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) {
248 layer.source = pixelSource;
249 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
250 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400251 // Produce a CircularRRect clip and an EllipticalRRect clip.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400252 for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) {
253 layer.geometry.positionTransform = transform;
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400254 for (float alpha : {0.5f, 1.f}) {
255 layer.alpha = alpha,
256 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700257 base::unique_fd());
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400258 }
259 }
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400260 }
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400261 }
262}
263
Nathaniel Nifong13491502021-06-30 17:28:29 -0400264static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
265 const std::shared_ptr<ExternalTexture>& dstTexture,
266 const std::shared_ptr<ExternalTexture>& srcTexture) {
267 const Rect& displayRect = display.physicalDisplay;
268 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
269 LayerSettings layer{
270 .geometry =
271 Geometry{
272 // Note that this flip matrix only makes a difference when clipping,
273 // which happens in this layer because the roundrect crop is just a bit
274 // larger than the layer bounds.
275 .positionTransform = kFlip,
276 .boundaries = rect,
277 .roundedCornersRadius = 94.2551,
278 .roundedCornersCrop = FloatRect(
279 -93.75, 0, displayRect.width() + 93.75, displayRect.height()),
280 },
281 .source = PixelSource{.buffer =
282 Buffer{
283 .buffer = srcTexture,
284 .maxLuminanceNits = 1000.f,
285 .isOpaque = 0,
286 .usePremultipliedAlpha = 1,
287 }},
288 .sourceDataspace = kOtherDataSpace,
289 .alpha = 1,
290
291 };
292
Sally Qi59a9f502021-10-12 18:53:23 +0000293 auto layers = std::vector<LayerSettings>{layer};
Sally Qi4cabdd02021-08-05 16:45:57 -0700294 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd());
Nathaniel Nifong13491502021-06-30 17:28:29 -0400295}
296
297static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
298 const std::shared_ptr<ExternalTexture>& dstTexture) {
299 const Rect& displayRect = display.physicalDisplay;
300 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
301 FloatRect small(0, 0, displayRect.width()-20, displayRect.height()+20);
302 LayerSettings layer{
303 .geometry =
304 Geometry{
305 .positionTransform = kScaleAndTranslate,
306 // the boundaries have to be smaller than the rounded crop so that
307 // clipRRect is used instead of drawRRect
308 .boundaries = small,
309 .roundedCornersRadius = 50.f,
310 .roundedCornersCrop = rect,
311 },
312 .source = PixelSource{
313 .solidColor = half3(0.f, 0.f, 0.f),
314 },
315 .sourceDataspace = kDestDataSpace,
316 .alpha = 0,
317 .disableBlending = true,
318
319 };
320
Sally Qi59a9f502021-10-12 18:53:23 +0000321 auto layers = std::vector<LayerSettings>{layer};
Sally Qi4cabdd02021-08-05 16:45:57 -0700322 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd());
Nathaniel Nifong13491502021-06-30 17:28:29 -0400323}
324
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400325//
326// The collection of shaders cached here were found by using perfetto to record shader compiles
327// during actions that involve RenderEngine, logging the layer settings, and the shader code
328// and reproducing those settings here.
329//
330// It is helpful when debugging this to turn on
331// in SkGLRenderEngine.cpp:
332// kPrintLayerSettings = true
333// kFlushAfterEveryLayer = true
334// in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
335// gPrintSKSL = true
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500336void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400337 const int previousCount = renderengine->reportShadersCompiled();
338 if (previousCount) {
339 ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
340 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500341
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400342 // The loop is beneficial for debugging and should otherwise be optimized out by the compiler.
343 // Adding additional bounds to the loop is useful for verifying that the size of the dst buffer
344 // does not impact the shader compilation counts by triggering different behaviors in RE/Skia.
345 for (SkSize bounds : {SkSize::Make(128, 128), /*SkSize::Make(1080, 2340)*/}) {
346 const nsecs_t timeBefore = systemTime();
347 // The dimensions should not matter, so long as we draw inside them.
348 const Rect displayRect(0, 0, bounds.fWidth, bounds.fHeight);
349 DisplaySettings display{
350 .physicalDisplay = displayRect,
351 .clip = displayRect,
352 .maxLuminance = 500,
353 .outputDataspace = kDestDataSpace,
354 };
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400355 DisplaySettings p3Display{
356 .physicalDisplay = displayRect,
357 .clip = displayRect,
358 .maxLuminance = 500,
359 .outputDataspace = kOtherDataSpace,
360 };
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500361
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400362 const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
Alec Mouria90a5702021-04-16 16:36:21 +0000363
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400364 sp<GraphicBuffer> dstBuffer =
365 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
366 1, usage, "primeShaderCache_dst");
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400367
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400368 const auto dstTexture =
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800369 std::make_shared<impl::ExternalTexture>(dstBuffer, *renderengine,
370 impl::ExternalTexture::Usage::WRITEABLE);
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400371 // This buffer will be the source for the call to drawImageLayers. Draw
372 // something to it as a placeholder for what an app draws. We should draw
373 // something, but the details are not important. Make use of the shadow layer drawing step
374 // to populate it.
375 sp<GraphicBuffer> srcBuffer =
376 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
377 1, usage, "drawImageLayer_src");
Alec Mouria90a5702021-04-16 16:36:21 +0000378
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800379 const auto srcTexture = std::make_shared<
380 impl::ExternalTexture>(srcBuffer, *renderengine,
381 impl::ExternalTexture::Usage::READABLE |
382 impl::ExternalTexture::Usage::WRITEABLE);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400383 drawHolePunchLayer(renderengine, display, dstTexture);
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400384 drawSolidLayers(renderengine, display, dstTexture);
Nathaniel Nifong49a59582021-07-26 19:49:47 -0400385
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400386 drawShadowLayers(renderengine, display, srcTexture);
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400387 drawShadowLayers(renderengine, p3Display, srcTexture);
Nathaniel Nifongcda45e92021-06-10 15:01:42 -0400388
389 if (renderengine->supportsBackgroundBlur()) {
390 drawBlurLayers(renderengine, display, dstTexture);
391 }
392
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400393 // The majority of skia shaders needed by RenderEngine are related to sampling images.
394 // These need to be generated with various source textures.
395 // Make a list of applicable sources.
396 // GRALLOC_USAGE_HW_TEXTURE should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE.
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400397 const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400398 sp<GraphicBuffer> externalBuffer =
399 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
400 1, usageExternal, "primeShaderCache_external");
401 const auto externalTexture =
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800402 std::make_shared<impl::ExternalTexture>(externalBuffer, *renderengine,
403 impl::ExternalTexture::Usage::READABLE);
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400404 std::vector<const std::shared_ptr<ExternalTexture>> textures =
405 {srcTexture, externalTexture};
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400406
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400407 // Another external texture with a different pixel format triggers useIsOpaqueWorkaround.
408 // It doesn't have to be f16, but it can't be the usual 8888.
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400409 sp<GraphicBuffer> f16ExternalBuffer =
410 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_FP16,
411 1, usageExternal, "primeShaderCache_external_f16");
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400412 // The F16 texture may not be usable on all devices, so check first that it was created.
413 status_t error = f16ExternalBuffer->initCheck();
414 if (!error) {
415 const auto f16ExternalTexture =
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800416 std::make_shared<impl::ExternalTexture>(f16ExternalBuffer, *renderengine,
417 impl::ExternalTexture::Usage::READABLE);
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400418 textures.push_back(f16ExternalTexture);
419 }
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400420
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400421 for (auto texture : textures) {
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400422 drawImageLayers(renderengine, display, dstTexture, texture);
423 // Draw layers for b/185569240.
424 drawClippedLayers(renderengine, display, dstTexture, texture);
425 }
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400426
Nathaniel Nifong13491502021-06-30 17:28:29 -0400427 drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
428
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400429 // draw one final layer synchronously to force GL submit
430 LayerSettings layer{
431 .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)},
432 };
Sally Qi59a9f502021-10-12 18:53:23 +0000433 auto layers = std::vector<LayerSettings>{layer};
Sally Qi4cabdd02021-08-05 16:45:57 -0700434 // call get() to make it synchronous
435 renderengine
436 ->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd())
437 .get();
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400438
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400439 const nsecs_t timeAfter = systemTime();
440 const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
441 const int shadersCompiled = renderengine->reportShadersCompiled();
442 ALOGD("Shader cache generated %d shaders in %f ms\n", shadersCompiled, compileTimeMs);
443 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500444}
445
446} // namespace android::renderengine::skia