blob: f3064f3c695d8be89bf2f6a6f17ca6823f31e703 [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
Nathaniel Nifong49a59582021-07-26 19:49:47 -040099 // Four combinations of settings are used (two transforms here, and drawShadowLayers is
100 // called with two different destination data spaces) They're all rounded rect.
101 // Three of these are cache misses that generate new shaders.
102 // The first combination generates a short and simple shadow shader.
103 // The second combination, flip transform, generates two shaders. The first appears to involve
104 // gaussian_fp. The second is a long and general purpose shadow shader with a device space
105 // transformation stage.
106 // The third combination is a cache hit, nothing new.
107 // The fourth combination, flip transform with a non-SRGB destination dataspace, is new.
108 // It is unique in that nearly everything is done in the vertex shader, and that vertex shader
109 // requires color correction. This is triggered differently from every other instance of color
110 // correction. All other instances are triggered when src and dst dataspaces differ, while
111 // this one is triggered by the destination being non-srgb. Apparently since the third
112 // combination is a cache hit, this color correction is only added when the vertex shader is
113 // doing something non-trivial.
114 for (auto transform : {mat4(), kFlip}) {
115 layer.geometry.positionTransform = transform;
116 caster.geometry.positionTransform = transform;
Leon Scroggins IIIae07fe52022-04-26 15:23:55 -0400117
118 auto layers = std::vector<LayerSettings>{layer, caster};
Nathaniel Nifong49a59582021-07-26 19:49:47 -0400119 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700120 base::unique_fd());
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500121 }
122}
123
124static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000125 const std::shared_ptr<ExternalTexture>& dstTexture,
126 const std::shared_ptr<ExternalTexture>& srcTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500127 const Rect& displayRect = display.physicalDisplay;
128 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
129 LayerSettings layer{
130 .geometry =
131 Geometry{
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400132 // The position transform doesn't matter when the reduced shader mode
133 // in in effect. A matrix transform stage is always included.
134 .positionTransform = mat4(),
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500135 .boundaries = rect,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500136 .roundedCornersCrop = rect,
137 },
138 .source = PixelSource{.buffer =
139 Buffer{
Alec Mouria90a5702021-04-16 16:36:21 +0000140 .buffer = srcTexture,
John Reckac09e452021-04-07 16:35:37 -0400141 .maxLuminanceNits = 1000.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500142 }},
143 };
144
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;
Leon Scroggins IIIae07fe52022-04-26 15:23:55 -0400156 auto layers = std::vector<LayerSettings>{layer};
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400157 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700158 base::unique_fd());
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 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;
Leon Scroggins IIIae07fe52022-04-26 15:23:55 -0400185 auto layers = std::vector<LayerSettings>{layer};
Alec Mouria90a5702021-04-16 16:36:21 +0000186 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700187 base::unique_fd());
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400188 }
189 }
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400190}
191
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400192static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000193 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400194 const Rect& displayRect = display.physicalDisplay;
195 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
196 LayerSettings layer{
197 .geometry =
198 Geometry{
199 .boundaries = rect,
200 },
201 .alpha = 1,
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400202 // setting this is mandatory for shadows and blurs
203 .skipContentDraw = true,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400204 };
205
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;
Leon Scroggins IIIae07fe52022-04-26 15:23:55 -0400209 auto layers = std::vector<LayerSettings>{layer};
Alec Mouria90a5702021-04-16 16:36:21 +0000210 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700211 base::unique_fd());
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400212 }
213}
214
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400215// The unique feature of these layers is that the boundary is slightly smaller than the rounded
216// rect crop, so the rounded edges intersect that boundary and require a different clipping method.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400217// For buffers, this is done with a stage that computes coverage and it will differ for round and
218// elliptical corners.
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400219static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
220 const std::shared_ptr<ExternalTexture>& dstTexture,
221 const std::shared_ptr<ExternalTexture>& srcTexture) {
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400222 const Rect& displayRect = display.physicalDisplay;
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400223 FloatRect rect(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller
224
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400225 PixelSource bufferSource{.buffer = Buffer{
226 .buffer = srcTexture,
227 .isOpaque = 0,
228 .maxLuminanceNits = 1000.f,
229 }};
230 PixelSource bufferOpaque{.buffer = Buffer{
231 .buffer = srcTexture,
232 .isOpaque = 1,
233 .maxLuminanceNits = 1000.f,
234 }};
235 PixelSource colorSource{.solidColor = half3(0.1f, 0.2f, 0.3f)};
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400236
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400237 LayerSettings layer{
238 .geometry =
239 Geometry{
240 .boundaries = rect,
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400241 .roundedCornersRadius = 27, // larger than the 20 above.
242 .roundedCornersCrop =
243 FloatRect(0, 0, displayRect.width(), displayRect.height()),
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400244 },
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400245 };
246
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}) {
Leon Scroggins IIIae07fe52022-04-26 15:23:55 -0400255 layer.alpha = alpha;
256 auto layers = std::vector<LayerSettings>{layer};
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400257 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Sally Qi4cabdd02021-08-05 16:45:57 -0700258 base::unique_fd());
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400259 }
260 }
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400261 }
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400262 }
263}
264
Nathaniel Nifong13491502021-06-30 17:28:29 -0400265static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
266 const std::shared_ptr<ExternalTexture>& dstTexture,
267 const std::shared_ptr<ExternalTexture>& srcTexture) {
268 const Rect& displayRect = display.physicalDisplay;
269 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
270 LayerSettings layer{
271 .geometry =
272 Geometry{
273 // Note that this flip matrix only makes a difference when clipping,
274 // which happens in this layer because the roundrect crop is just a bit
275 // larger than the layer bounds.
276 .positionTransform = kFlip,
277 .boundaries = rect,
278 .roundedCornersRadius = 94.2551,
279 .roundedCornersCrop = FloatRect(
280 -93.75, 0, displayRect.width() + 93.75, displayRect.height()),
281 },
282 .source = PixelSource{.buffer =
283 Buffer{
284 .buffer = srcTexture,
285 .maxLuminanceNits = 1000.f,
286 .isOpaque = 0,
287 .usePremultipliedAlpha = 1,
288 }},
289 .sourceDataspace = kOtherDataSpace,
290 .alpha = 1,
291
292 };
293
Sally Qi59a9f502021-10-12 18:53:23 +0000294 auto layers = std::vector<LayerSettings>{layer};
Sally Qi4cabdd02021-08-05 16:45:57 -0700295 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd());
Nathaniel Nifong13491502021-06-30 17:28:29 -0400296}
297
298static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
299 const std::shared_ptr<ExternalTexture>& dstTexture) {
300 const Rect& displayRect = display.physicalDisplay;
301 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
302 FloatRect small(0, 0, displayRect.width()-20, displayRect.height()+20);
303 LayerSettings layer{
304 .geometry =
305 Geometry{
306 .positionTransform = kScaleAndTranslate,
307 // the boundaries have to be smaller than the rounded crop so that
308 // clipRRect is used instead of drawRRect
309 .boundaries = small,
310 .roundedCornersRadius = 50.f,
311 .roundedCornersCrop = rect,
312 },
313 .source = PixelSource{
314 .solidColor = half3(0.f, 0.f, 0.f),
315 },
316 .sourceDataspace = kDestDataSpace,
317 .alpha = 0,
318 .disableBlending = true,
319
320 };
321
Sally Qi59a9f502021-10-12 18:53:23 +0000322 auto layers = std::vector<LayerSettings>{layer};
Sally Qi4cabdd02021-08-05 16:45:57 -0700323 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd());
Nathaniel Nifong13491502021-06-30 17:28:29 -0400324}
325
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400326//
327// The collection of shaders cached here were found by using perfetto to record shader compiles
328// during actions that involve RenderEngine, logging the layer settings, and the shader code
329// and reproducing those settings here.
330//
331// It is helpful when debugging this to turn on
332// in SkGLRenderEngine.cpp:
333// kPrintLayerSettings = true
334// kFlushAfterEveryLayer = true
335// in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
336// gPrintSKSL = true
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500337void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400338 const int previousCount = renderengine->reportShadersCompiled();
339 if (previousCount) {
340 ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
341 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500342
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400343 // The loop is beneficial for debugging and should otherwise be optimized out by the compiler.
344 // Adding additional bounds to the loop is useful for verifying that the size of the dst buffer
345 // does not impact the shader compilation counts by triggering different behaviors in RE/Skia.
346 for (SkSize bounds : {SkSize::Make(128, 128), /*SkSize::Make(1080, 2340)*/}) {
347 const nsecs_t timeBefore = systemTime();
348 // The dimensions should not matter, so long as we draw inside them.
349 const Rect displayRect(0, 0, bounds.fWidth, bounds.fHeight);
350 DisplaySettings display{
351 .physicalDisplay = displayRect,
352 .clip = displayRect,
353 .maxLuminance = 500,
354 .outputDataspace = kDestDataSpace,
355 };
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400356 DisplaySettings p3Display{
357 .physicalDisplay = displayRect,
358 .clip = displayRect,
359 .maxLuminance = 500,
360 .outputDataspace = kOtherDataSpace,
361 };
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500362
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400363 const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
Alec Mouria90a5702021-04-16 16:36:21 +0000364
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400365 sp<GraphicBuffer> dstBuffer =
366 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
367 1, usage, "primeShaderCache_dst");
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400368
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400369 const auto dstTexture =
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800370 std::make_shared<impl::ExternalTexture>(dstBuffer, *renderengine,
371 impl::ExternalTexture::Usage::WRITEABLE);
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400372 // This buffer will be the source for the call to drawImageLayers. Draw
373 // something to it as a placeholder for what an app draws. We should draw
374 // something, but the details are not important. Make use of the shadow layer drawing step
375 // to populate it.
376 sp<GraphicBuffer> srcBuffer =
377 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
378 1, usage, "drawImageLayer_src");
Alec Mouria90a5702021-04-16 16:36:21 +0000379
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800380 const auto srcTexture = std::make_shared<
381 impl::ExternalTexture>(srcBuffer, *renderengine,
382 impl::ExternalTexture::Usage::READABLE |
383 impl::ExternalTexture::Usage::WRITEABLE);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400384 drawHolePunchLayer(renderengine, display, dstTexture);
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400385 drawSolidLayers(renderengine, display, dstTexture);
Nathaniel Nifong49a59582021-07-26 19:49:47 -0400386
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400387 drawShadowLayers(renderengine, display, srcTexture);
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400388 drawShadowLayers(renderengine, p3Display, srcTexture);
Nathaniel Nifongcda45e92021-06-10 15:01:42 -0400389
390 if (renderengine->supportsBackgroundBlur()) {
391 drawBlurLayers(renderengine, display, dstTexture);
392 }
393
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400394 // The majority of skia shaders needed by RenderEngine are related to sampling images.
395 // These need to be generated with various source textures.
396 // Make a list of applicable sources.
397 // GRALLOC_USAGE_HW_TEXTURE should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE.
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400398 const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400399 sp<GraphicBuffer> externalBuffer =
400 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
401 1, usageExternal, "primeShaderCache_external");
402 const auto externalTexture =
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800403 std::make_shared<impl::ExternalTexture>(externalBuffer, *renderengine,
404 impl::ExternalTexture::Usage::READABLE);
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400405 std::vector<const std::shared_ptr<ExternalTexture>> textures =
406 {srcTexture, externalTexture};
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400407
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400408 // Another external texture with a different pixel format triggers useIsOpaqueWorkaround.
409 // It doesn't have to be f16, but it can't be the usual 8888.
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400410 sp<GraphicBuffer> f16ExternalBuffer =
411 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_FP16,
412 1, usageExternal, "primeShaderCache_external_f16");
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400413 // The F16 texture may not be usable on all devices, so check first that it was created.
414 status_t error = f16ExternalBuffer->initCheck();
415 if (!error) {
416 const auto f16ExternalTexture =
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800417 std::make_shared<impl::ExternalTexture>(f16ExternalBuffer, *renderengine,
418 impl::ExternalTexture::Usage::READABLE);
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400419 textures.push_back(f16ExternalTexture);
420 }
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400421
Nathaniel Nifong73537a32021-08-06 15:07:26 -0400422 for (auto texture : textures) {
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400423 drawImageLayers(renderengine, display, dstTexture, texture);
424 // Draw layers for b/185569240.
425 drawClippedLayers(renderengine, display, dstTexture, texture);
426 }
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400427
Nathaniel Nifong13491502021-06-30 17:28:29 -0400428 drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
429
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400430 // draw one final layer synchronously to force GL submit
431 LayerSettings layer{
432 .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)},
433 };
Sally Qi59a9f502021-10-12 18:53:23 +0000434 auto layers = std::vector<LayerSettings>{layer};
Sally Qi4cabdd02021-08-05 16:45:57 -0700435 // call get() to make it synchronous
436 renderengine
437 ->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd())
438 .get();
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400439
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400440 const nsecs_t timeAfter = systemTime();
441 const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
Leon Scroggins III45be9182022-04-27 10:37:11 -0400442 const int shadersCompiled = renderengine->reportShadersCompiled() - previousCount;
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400443 ALOGD("Shader cache generated %d shaders in %f ms\n", shadersCompiled, compileTimeMs);
444 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500445}
446
447} // namespace android::renderengine::skia