blob: 081de2e89c12e0db76d850badead1f3f1e54a417 [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.
59 FloatRect rect(0, 0, display.physicalDisplay.width(), display.physicalDisplay.height() - 30);
60 LayerSettings layer{
61 .geometry =
62 Geometry{
63 .boundaries = rect,
64 .roundedCornersCrop = rect,
65 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040066 // drawShadow ignores alpha
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050067 .shadow =
68 ShadowSettings{
69 .ambientColor = vec4(0, 0, 0, 0.00935997f),
70 .spotColor = vec4(0, 0, 0, 0.0455841f),
71 .lightPos = vec3(370.508f, -1527.03f, 1650.f),
72 .lightRadius = 2200.0f,
73 .length = 0.955342f,
74 },
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040075 // important that this matches dest so the general shadow fragment shader doesn't
76 // have color correction added, and important that it be srgb, so the *vertex* shader
77 // doesn't have color correction added.
78 .sourceDataspace = kDestDataSpace,
Nathaniel Nifong490a9472021-06-23 16:44:19 -040079 // setting this is mandatory for shadows and blurs
80 .skipContentDraw = true,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050081 };
82
83 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040084 // The identity matrix will generate the fast shader
Alec Mouria90a5702021-04-16 16:36:21 +000085 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd(),
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040086 nullptr);
87 // This matrix, which has different scales for x and y, will
88 // generate the slower (more general case) version, which has variants for translucent
89 // casters and rounded rects.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -040090 layer.geometry.positionTransform = kScaleAsymmetric;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040091 for (auto translucent : {false, true}) {
92 layer.shadow.casterIsTranslucent = translucent;
Alec Mouria90a5702021-04-16 16:36:21 +000093 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050094 base::unique_fd(), nullptr);
95 }
96}
97
98static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +000099 const std::shared_ptr<ExternalTexture>& dstTexture,
100 const std::shared_ptr<ExternalTexture>& srcTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500101 const Rect& displayRect = display.physicalDisplay;
102 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
103 LayerSettings layer{
104 .geometry =
105 Geometry{
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400106 // The position transform doesn't matter when the reduced shader mode
107 // in in effect. A matrix transform stage is always included.
108 .positionTransform = mat4(),
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500109 .boundaries = rect,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500110 .roundedCornersCrop = rect,
111 },
112 .source = PixelSource{.buffer =
113 Buffer{
Alec Mouria90a5702021-04-16 16:36:21 +0000114 .buffer = srcTexture,
John Reckac09e452021-04-07 16:35:37 -0400115 .maxLuminanceNits = 1000.f,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500116 }},
117 };
118
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500119 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongbf6f7542021-04-27 12:05:16 -0400120 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
121 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400122 // Cache shaders for both rects and round rects.
123 // In reduced shader mode, all non-zero round rect radii get the same code path.
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400124 for (float roundedCornersRadius : {0.0f, 50.0f}) {
125 // roundedCornersCrop is always set, but the radius triggers the behavior
126 layer.geometry.roundedCornersRadius = roundedCornersRadius;
127 for (bool isOpaque : {true, false}) {
128 layer.source.buffer.isOpaque = isOpaque;
129 for (auto alpha : {half(.2f), half(1.0f)}) {
130 layer.alpha = alpha;
131 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
132 base::unique_fd(), nullptr);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500133 }
134 }
135 }
136 }
137}
138
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400139static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000140 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400141 const Rect& displayRect = display.physicalDisplay;
142 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
143 LayerSettings layer{
144 .geometry =
145 Geometry{
146 .boundaries = rect,
147 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400148 .source =
149 PixelSource{
150 .solidColor = half3(0.1f, 0.2f, 0.3f),
151 },
Nathaniel Nifong768693f2021-06-08 14:33:47 -0400152 .alpha = 0.5,
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400153 };
154
155 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400156 for (auto transform : {mat4(), kScaleAndTranslate}) {
157 layer.geometry.positionTransform = transform;
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400158 for (float roundedCornersRadius : {0.0f, 50.f}) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400159 layer.geometry.roundedCornersRadius = roundedCornersRadius;
Alec Mouria90a5702021-04-16 16:36:21 +0000160 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400161 base::unique_fd(), nullptr);
162 }
163 }
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400164}
165
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400166static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000167 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400168 const Rect& displayRect = display.physicalDisplay;
169 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
170 LayerSettings layer{
171 .geometry =
172 Geometry{
173 .boundaries = rect,
174 },
175 .alpha = 1,
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400176 // setting this is mandatory for shadows and blurs
177 .skipContentDraw = true,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400178 };
179
180 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifong490a9472021-06-23 16:44:19 -0400181 // Different blur code is invoked for radii less and greater than 30 pixels
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400182 for (int radius : {9, 60}) {
183 layer.backgroundBlurRadius = radius;
Alec Mouria90a5702021-04-16 16:36:21 +0000184 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400185 base::unique_fd(), nullptr);
186 }
187}
188
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400189// The unique feature of these layers is that the boundary is slightly smaller than the rounded
190// rect crop, so the rounded edges intersect that boundary and require a different clipping method.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400191// For buffers, this is done with a stage that computes coverage and it will differ for round and
192// elliptical corners.
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400193static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
194 const std::shared_ptr<ExternalTexture>& dstTexture,
195 const std::shared_ptr<ExternalTexture>& srcTexture) {
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400196 const Rect& displayRect = display.physicalDisplay;
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400197 FloatRect rect(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller
198
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400199 PixelSource bufferSource{.buffer = Buffer{
200 .buffer = srcTexture,
201 .isOpaque = 0,
202 .maxLuminanceNits = 1000.f,
203 }};
204 PixelSource bufferOpaque{.buffer = Buffer{
205 .buffer = srcTexture,
206 .isOpaque = 1,
207 .maxLuminanceNits = 1000.f,
208 }};
209 PixelSource colorSource{.solidColor = half3(0.1f, 0.2f, 0.3f)};
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400210
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400211 LayerSettings layer{
212 .geometry =
213 Geometry{
214 .boundaries = rect,
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400215 .roundedCornersRadius = 27, // larger than the 20 above.
216 .roundedCornersCrop =
217 FloatRect(0, 0, displayRect.width(), displayRect.height()),
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400218 },
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400219 };
220
221 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400222 for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) {
223 layer.source = pixelSource;
224 for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
225 layer.sourceDataspace = dataspace;
Nathaniel Nifong13491502021-06-30 17:28:29 -0400226 // Produce a CircularRRect clip and an EllipticalRRect clip.
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400227 for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) {
228 layer.geometry.positionTransform = transform;
Nathaniel Nifongafeac5b2021-05-27 10:52:30 -0400229 for (float alpha : {0.5f, 1.f}) {
230 layer.alpha = alpha,
231 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
232 base::unique_fd(), nullptr);
233 }
234 }
Nathaniel Nifong2d91c5e2021-05-13 17:14:00 -0400235 }
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400236 }
237}
238
Nathaniel Nifong13491502021-06-30 17:28:29 -0400239static void drawPIPImageLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
240 const std::shared_ptr<ExternalTexture>& dstTexture,
241 const std::shared_ptr<ExternalTexture>& srcTexture) {
242 const Rect& displayRect = display.physicalDisplay;
243 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
244 LayerSettings layer{
245 .geometry =
246 Geometry{
247 // Note that this flip matrix only makes a difference when clipping,
248 // which happens in this layer because the roundrect crop is just a bit
249 // larger than the layer bounds.
250 .positionTransform = kFlip,
251 .boundaries = rect,
252 .roundedCornersRadius = 94.2551,
253 .roundedCornersCrop = FloatRect(
254 -93.75, 0, displayRect.width() + 93.75, displayRect.height()),
255 },
256 .source = PixelSource{.buffer =
257 Buffer{
258 .buffer = srcTexture,
259 .maxLuminanceNits = 1000.f,
260 .isOpaque = 0,
261 .usePremultipliedAlpha = 1,
262 }},
263 .sourceDataspace = kOtherDataSpace,
264 .alpha = 1,
265
266 };
267
268 auto layers = std::vector<const LayerSettings*>{&layer};
269 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
270 base::unique_fd(), nullptr);
271}
272
273static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
274 const std::shared_ptr<ExternalTexture>& dstTexture) {
275 const Rect& displayRect = display.physicalDisplay;
276 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
277 FloatRect small(0, 0, displayRect.width()-20, displayRect.height()+20);
278 LayerSettings layer{
279 .geometry =
280 Geometry{
281 .positionTransform = kScaleAndTranslate,
282 // the boundaries have to be smaller than the rounded crop so that
283 // clipRRect is used instead of drawRRect
284 .boundaries = small,
285 .roundedCornersRadius = 50.f,
286 .roundedCornersCrop = rect,
287 },
288 .source = PixelSource{
289 .solidColor = half3(0.f, 0.f, 0.f),
290 },
291 .sourceDataspace = kDestDataSpace,
292 .alpha = 0,
293 .disableBlending = true,
294
295 };
296
297 auto layers = std::vector<const LayerSettings*>{&layer};
298 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
299 base::unique_fd(), nullptr);
300}
301
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400302//
303// The collection of shaders cached here were found by using perfetto to record shader compiles
304// during actions that involve RenderEngine, logging the layer settings, and the shader code
305// and reproducing those settings here.
306//
307// It is helpful when debugging this to turn on
308// in SkGLRenderEngine.cpp:
309// kPrintLayerSettings = true
310// kFlushAfterEveryLayer = true
311// in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
312// gPrintSKSL = true
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500313void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400314 const int previousCount = renderengine->reportShadersCompiled();
315 if (previousCount) {
316 ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
317 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500318
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400319 // The loop is beneficial for debugging and should otherwise be optimized out by the compiler.
320 // Adding additional bounds to the loop is useful for verifying that the size of the dst buffer
321 // does not impact the shader compilation counts by triggering different behaviors in RE/Skia.
322 for (SkSize bounds : {SkSize::Make(128, 128), /*SkSize::Make(1080, 2340)*/}) {
323 const nsecs_t timeBefore = systemTime();
324 // The dimensions should not matter, so long as we draw inside them.
325 const Rect displayRect(0, 0, bounds.fWidth, bounds.fHeight);
326 DisplaySettings display{
327 .physicalDisplay = displayRect,
328 .clip = displayRect,
329 .maxLuminance = 500,
330 .outputDataspace = kDestDataSpace,
331 };
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500332
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400333 const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
Alec Mouria90a5702021-04-16 16:36:21 +0000334
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400335 sp<GraphicBuffer> dstBuffer =
336 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
337 1, usage, "primeShaderCache_dst");
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400338
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400339 const auto dstTexture =
340 std::make_shared<ExternalTexture>(dstBuffer, *renderengine,
341 ExternalTexture::Usage::WRITEABLE);
342 // This buffer will be the source for the call to drawImageLayers. Draw
343 // something to it as a placeholder for what an app draws. We should draw
344 // something, but the details are not important. Make use of the shadow layer drawing step
345 // to populate it.
346 sp<GraphicBuffer> srcBuffer =
347 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
348 1, usage, "drawImageLayer_src");
Alec Mouria90a5702021-04-16 16:36:21 +0000349
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400350 const auto srcTexture =
351 std::make_shared<ExternalTexture>(srcBuffer, *renderengine,
352 ExternalTexture::Usage::READABLE |
353 ExternalTexture::Usage::WRITEABLE);
Nathaniel Nifong13491502021-06-30 17:28:29 -0400354 drawHolePunchLayer(renderengine, display, dstTexture);
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400355 drawSolidLayers(renderengine, display, dstTexture);
356 drawShadowLayers(renderengine, display, srcTexture);
Nathaniel Nifongcda45e92021-06-10 15:01:42 -0400357
358 if (renderengine->supportsBackgroundBlur()) {
359 drawBlurLayers(renderengine, display, dstTexture);
360 }
361
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400362 // should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
363 const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400364 sp<GraphicBuffer> externalBuffer =
365 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
366 1, usageExternal, "primeShaderCache_external");
367 const auto externalTexture =
368 std::make_shared<ExternalTexture>(externalBuffer, *renderengine,
369 ExternalTexture::Usage::READABLE);
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400370
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400371 // Another external texture with a different pixel format triggers useIsOpaqueWorkaround
372 sp<GraphicBuffer> f16ExternalBuffer =
373 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_FP16,
374 1, usageExternal, "primeShaderCache_external_f16");
375 const auto f16ExternalTexture =
376 std::make_shared<ExternalTexture>(f16ExternalBuffer, *renderengine,
377 ExternalTexture::Usage::READABLE);
378
379 // The majority of shaders are related to sampling images.
380 // These need to be generated with various source textures
Nathaniel Nifong628feb72021-07-01 14:11:05 -0400381 // The F16 texture may not be usable on all devices, so check first that it was created with
382 // the requested usage bit.
383 auto textures = {srcTexture, externalTexture};
384 auto texturesWithF16 = {srcTexture, externalTexture, f16ExternalTexture};
385 bool canUsef16 = f16ExternalBuffer->getUsage() & GRALLOC_USAGE_HW_TEXTURE;
386
387 for (auto texture : canUsef16 ? texturesWithF16 : textures) {
Nathaniel Nifongf06a45b2021-06-25 17:24:26 -0400388 drawImageLayers(renderengine, display, dstTexture, texture);
389 // Draw layers for b/185569240.
390 drawClippedLayers(renderengine, display, dstTexture, texture);
391 }
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400392
Nathaniel Nifong13491502021-06-30 17:28:29 -0400393 drawPIPImageLayer(renderengine, display, dstTexture, externalTexture);
394
Derek Sollenbergere9a51082021-05-06 14:01:38 -0400395 const nsecs_t timeAfter = systemTime();
396 const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
397 const int shadersCompiled = renderengine->reportShadersCompiled();
398 ALOGD("Shader cache generated %d shaders in %f ms\n", shadersCompiled, compileTimeMs);
399 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500400}
401
402} // namespace android::renderengine::skia