blob: 0c5dd0a7e5b9e0f28962de85b45c61dccea2741f [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};
100 // When sourceDataspace matches dest, the general shadow fragment shader doesn't
101 // have color correction added.
102 // independently, when it is not srgb, the *vertex* shader has color correction added.
103 // This may be a bug, but the shader still needs to be cached as it is triggered
104 // during youtube pip.
105 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
106 layer.sourceDataspace = dataspace;
107 // The 2nd matrix, which has different scales for x and y, will
108 // generate the slower (more general case) shadow shader
109 for (auto transform : {mat4(), kScaleAndTranslate, kFlip}) {
110 layer.geometry.positionTransform = transform;
111 caster.geometry.positionTransform = transform;
112 for (bool translucent : {false, true}){
113 layer.shadow.casterIsTranslucent = translucent;
114 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400115 base::unique_fd(), &drawFence);
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400116 }
117 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500118 }
119}
120
121static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000122 const std::shared_ptr<ExternalTexture>& dstTexture,
123 const std::shared_ptr<ExternalTexture>& srcTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500124 const Rect& displayRect = display.physicalDisplay;
125 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
126 LayerSettings layer{
127 .geometry =
128 Geometry{
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400129 // The position transform doesn't matter when the reduced shader mode
130 // in in effect. A matrix transform stage is always included.
131 .positionTransform = mat4(),
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500132 .boundaries = rect,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500133 .roundedCornersCrop = rect,
134 },
135 .source = PixelSource{.buffer =
136 Buffer{
Alec Mouria90a5702021-04-16 16:36:21 +0000137 .buffer = srcTexture,
John Reckac09e452021-04-07 16:35:37 -0400138 .maxLuminanceNits = 1000.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500139 }},
140 };
141
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400142 base::unique_fd drawFence;
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500143 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongbf6f7542021-04-27 12:05:16 -0400144 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
145 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400146 // Cache shaders for both rects and round rects.
147 // In reduced shader mode, all non-zero round rect radii get the same code path.
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400148 for (float roundedCornersRadius : {0.0f, 50.0f}) {
149 // roundedCornersCrop is always set, but the radius triggers the behavior
150 layer.geometry.roundedCornersRadius = roundedCornersRadius;
151 for (bool isOpaque : {true, false}) {
152 layer.source.buffer.isOpaque = isOpaque;
153 for (auto alpha : {half(.2f), half(1.0f)}) {
154 layer.alpha = alpha;
155 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400156 base::unique_fd(), &drawFence);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500157 }
158 }
159 }
160 }
161}
162
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400163static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000164 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400165 const Rect& displayRect = display.physicalDisplay;
166 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
167 LayerSettings layer{
168 .geometry =
169 Geometry{
170 .boundaries = rect,
171 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400172 .source =
173 PixelSource{
174 .solidColor = half3(0.1f, 0.2f, 0.3f),
175 },
Nathaniel Nifong768693f2021-06-08 14:33:47 -0400176 .alpha = 0.5,
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400177 };
178
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400179 base::unique_fd drawFence;
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400180 auto layers = std::vector<const 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,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400186 base::unique_fd(), &drawFence);
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
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400205 base::unique_fd drawFence;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400206 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400207 // Different blur code is invoked for radii less and greater than 30 pixels
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400208 for (int radius : {9, 60}) {
209 layer.backgroundBlurRadius = radius;
Alec Mouria90a5702021-04-16 16:36:21 +0000210 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400211 base::unique_fd(), &drawFence);
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 Nifong2d2f4322021-07-22 15:17:36 -0400247 base::unique_fd drawFence;
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400248 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400249 for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) {
250 layer.source = pixelSource;
251 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
252 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400253 // Produce a CircularRRect clip and an EllipticalRRect clip.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400254 for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) {
255 layer.geometry.positionTransform = transform;
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400256 for (float alpha : {0.5f, 1.f}) {
257 layer.alpha = alpha,
258 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400259 base::unique_fd(), &drawFence);
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400260 }
261 }
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400262 }
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400263 }
264}
265
Nathaniel Nifong13491502021-06-30 17:28:29 -0400266static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
267 const std::shared_ptr<ExternalTexture>& dstTexture,
268 const std::shared_ptr<ExternalTexture>& srcTexture) {
269 const Rect& displayRect = display.physicalDisplay;
270 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
271 LayerSettings layer{
272 .geometry =
273 Geometry{
274 // Note that this flip matrix only makes a difference when clipping,
275 // which happens in this layer because the roundrect crop is just a bit
276 // larger than the layer bounds.
277 .positionTransform = kFlip,
278 .boundaries = rect,
279 .roundedCornersRadius = 94.2551,
280 .roundedCornersCrop = FloatRect(
281 -93.75, 0, displayRect.width() + 93.75, displayRect.height()),
282 },
283 .source = PixelSource{.buffer =
284 Buffer{
285 .buffer = srcTexture,
286 .maxLuminanceNits = 1000.f,
287 .isOpaque = 0,
288 .usePremultipliedAlpha = 1,
289 }},
290 .sourceDataspace = kOtherDataSpace,
291 .alpha = 1,
292
293 };
294
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400295 base::unique_fd drawFence;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400296 auto layers = std::vector<const LayerSettings*>{&layer};
297 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400298 base::unique_fd(), &drawFence);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400299}
300
301static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
302 const std::shared_ptr<ExternalTexture>& dstTexture) {
303 const Rect& displayRect = display.physicalDisplay;
304 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
305 FloatRect small(0, 0, displayRect.width()-20, displayRect.height()+20);
306 LayerSettings layer{
307 .geometry =
308 Geometry{
309 .positionTransform = kScaleAndTranslate,
310 // the boundaries have to be smaller than the rounded crop so that
311 // clipRRect is used instead of drawRRect
312 .boundaries = small,
313 .roundedCornersRadius = 50.f,
314 .roundedCornersCrop = rect,
315 },
316 .source = PixelSource{
317 .solidColor = half3(0.f, 0.f, 0.f),
318 },
319 .sourceDataspace = kDestDataSpace,
320 .alpha = 0,
321 .disableBlending = true,
322
323 };
324
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400325 base::unique_fd drawFence;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400326 auto layers = std::vector<const LayerSettings*>{&layer};
327 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400328 base::unique_fd(), &drawFence);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400329}
330
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400331//
332// The collection of shaders cached here were found by using perfetto to record shader compiles
333// during actions that involve RenderEngine, logging the layer settings, and the shader code
334// and reproducing those settings here.
335//
336// It is helpful when debugging this to turn on
337// in SkGLRenderEngine.cpp:
338// kPrintLayerSettings = true
339// kFlushAfterEveryLayer = true
340// in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
341// gPrintSKSL = true
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500342void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400343 const int previousCount = renderengine->reportShadersCompiled();
344 if (previousCount) {
345 ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
346 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500347
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400348 // The loop is beneficial for debugging and should otherwise be optimized out by the compiler.
349 // Adding additional bounds to the loop is useful for verifying that the size of the dst buffer
350 // does not impact the shader compilation counts by triggering different behaviors in RE/Skia.
351 for (SkSize bounds : {SkSize::Make(128, 128), /*SkSize::Make(1080, 2340)*/}) {
352 const nsecs_t timeBefore = systemTime();
353 // The dimensions should not matter, so long as we draw inside them.
354 const Rect displayRect(0, 0, bounds.fWidth, bounds.fHeight);
355 DisplaySettings display{
356 .physicalDisplay = displayRect,
357 .clip = displayRect,
358 .maxLuminance = 500,
359 .outputDataspace = kDestDataSpace,
360 };
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400361 DisplaySettings p3Display{
362 .physicalDisplay = displayRect,
363 .clip = displayRect,
364 .maxLuminance = 500,
365 .outputDataspace = kOtherDataSpace,
366 };
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500367
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400368 const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
Alec Mouria90a5702021-04-16 16:36:21 +0000369
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400370 sp<GraphicBuffer> dstBuffer =
371 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
372 1, usage, "primeShaderCache_dst");
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400373
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400374 const auto dstTexture =
375 std::make_shared<ExternalTexture>(dstBuffer, *renderengine,
376 ExternalTexture::Usage::WRITEABLE);
377 // This buffer will be the source for the call to drawImageLayers. Draw
378 // something to it as a placeholder for what an app draws. We should draw
379 // something, but the details are not important. Make use of the shadow layer drawing step
380 // to populate it.
381 sp<GraphicBuffer> srcBuffer =
382 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
383 1, usage, "drawImageLayer_src");
Alec Mouria90a5702021-04-16 16:36:21 +0000384
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400385 const auto srcTexture =
386 std::make_shared<ExternalTexture>(srcBuffer, *renderengine,
387 ExternalTexture::Usage::READABLE |
388 ExternalTexture::Usage::WRITEABLE);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400389 drawHolePunchLayer(renderengine, display, dstTexture);
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400390 drawSolidLayers(renderengine, display, dstTexture);
391 drawShadowLayers(renderengine, display, srcTexture);
Nathaniel Nifonga6b54232021-07-02 13:24:32 -0400392 drawShadowLayers(renderengine, p3Display, srcTexture);
Nathaniel Nifongcda45e92021-06-10 15:01:42 -0400393
394 if (renderengine->supportsBackgroundBlur()) {
395 drawBlurLayers(renderengine, display, dstTexture);
396 }
397
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400398 // should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
399 const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400400 sp<GraphicBuffer> externalBuffer =
401 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
402 1, usageExternal, "primeShaderCache_external");
403 const auto externalTexture =
404 std::make_shared<ExternalTexture>(externalBuffer, *renderengine,
405 ExternalTexture::Usage::READABLE);
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400406
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400407 // Another external texture with a different pixel format triggers useIsOpaqueWorkaround
408 sp<GraphicBuffer> f16ExternalBuffer =
409 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_FP16,
410 1, usageExternal, "primeShaderCache_external_f16");
411 const auto f16ExternalTexture =
412 std::make_shared<ExternalTexture>(f16ExternalBuffer, *renderengine,
413 ExternalTexture::Usage::READABLE);
414
415 // The majority of shaders are related to sampling images.
416 // These need to be generated with various source textures
Nathaniel Nifong628feb72021-07-01 14:11:05 -0400417 // The F16 texture may not be usable on all devices, so check first that it was created with
418 // the requested usage bit.
419 auto textures = {srcTexture, externalTexture};
420 auto texturesWithF16 = {srcTexture, externalTexture, f16ExternalTexture};
421 bool canUsef16 = f16ExternalBuffer->getUsage() & GRALLOC_USAGE_HW_TEXTURE;
422
423 for (auto texture : canUsef16 ? texturesWithF16 : textures) {
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400424 drawImageLayers(renderengine, display, dstTexture, texture);
425 // Draw layers for b/185569240.
426 drawClippedLayers(renderengine, display, dstTexture, texture);
427 }
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400428
Nathaniel Nifong13491502021-06-30 17:28:29 -0400429 drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
430
Nathaniel Nifong2d2f4322021-07-22 15:17:36 -0400431 // draw one final layer synchronously to force GL submit
432 LayerSettings layer{
433 .source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)},
434 };
435 auto layers = std::vector<const LayerSettings*>{&layer};
436 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
437 base::unique_fd(), nullptr); // null drawFence makes it synchronous
438
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