blob: a0da888a81ec5f927e52a236d1980e0804bec1c0 [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 Nifong21e021f2021-04-21 13:15:46 -040040const auto kScaleYOnly = mat4(1.f, 0.f, 0.f, 0.f,
41 0.f, 0.7f, 0.f, 0.f,
42 0.f, 0.f, 1.f, 0.f,
43 0.f, 0.f, 0.f, 1.f);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040044// clang-format on
45// When choosing dataspaces below, whether the match the destination or not determined whether
46// a color correction effect is added to the shader. There may be other additional shader details
47// for particular color spaces.
48// TODO(b/184842383) figure out which color related shaders are necessary
49constexpr auto kDestDataSpace = ui::Dataspace::SRGB;
Nathaniel Nifong21e021f2021-04-21 13:15:46 -040050constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040051} // namespace
52
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040053static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +000054 const std::shared_ptr<ExternalTexture>& dstTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050055 // Somewhat arbitrary dimensions, but on screen and slightly shorter, based
56 // on actual use.
57 FloatRect rect(0, 0, display.physicalDisplay.width(), display.physicalDisplay.height() - 30);
58 LayerSettings layer{
59 .geometry =
60 Geometry{
61 .boundaries = rect,
62 .roundedCornersCrop = rect,
63 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -040064 // drawShadow ignores alpha
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050065 .shadow =
66 ShadowSettings{
67 .ambientColor = vec4(0, 0, 0, 0.00935997f),
68 .spotColor = vec4(0, 0, 0, 0.0455841f),
69 .lightPos = vec3(370.508f, -1527.03f, 1650.f),
70 .lightRadius = 2200.0f,
71 .length = 0.955342f,
72 },
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040073 // important that this matches dest so the general shadow fragment shader doesn't
74 // have color correction added, and important that it be srgb, so the *vertex* shader
75 // doesn't have color correction added.
76 .sourceDataspace = kDestDataSpace,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050077 };
78
79 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040080 // The identity matrix will generate the fast shader
Alec Mouria90a5702021-04-16 16:36:21 +000081 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd(),
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -040082 nullptr);
83 // This matrix, which has different scales for x and y, will
84 // generate the slower (more general case) version, which has variants for translucent
85 // casters and rounded rects.
86 // clang-format off
87 layer.geometry.positionTransform = mat4(0.7f, 0.f, 0.f, 0.f,
88 0.f, 0.8f, 0.f, 0.f,
89 0.f, 0.f, 1.f, 0.f,
90 0.f, 0.f, 0.f, 1.f);
91 // clang-format on
92 for (auto translucent : {false, true}) {
93 layer.shadow.casterIsTranslucent = translucent;
Alec Mouria90a5702021-04-16 16:36:21 +000094 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050095 base::unique_fd(), nullptr);
96 }
97}
98
99static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000100 const std::shared_ptr<ExternalTexture>& dstTexture,
101 const std::shared_ptr<ExternalTexture>& srcTexture) {
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500102 const Rect& displayRect = display.physicalDisplay;
103 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
104 LayerSettings layer{
105 .geometry =
106 Geometry{
107 .boundaries = rect,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500108 .roundedCornersCrop = rect,
109 },
110 .source = PixelSource{.buffer =
111 Buffer{
Alec Mouria90a5702021-04-16 16:36:21 +0000112 .buffer = srcTexture,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500113 .maxMasteringLuminance = 1000.f,
114 .maxContentLuminance = 1000.f,
115 }},
116 };
117
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400118 auto threeCornerRadii = {0.0f, 0.05f, 50.f};
119 auto oneCornerRadius = {50.f};
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400120
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500121 // Test both drawRect and drawRRect
122 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400123 for (bool identity : {true, false}) {
124 layer.geometry.positionTransform = identity ? mat4() : kScaleAndTranslate;
125 // Corner radii less than 0.5 creates a special shader. This likely occurs in real usage
126 // due to animating corner radius.
127 // For the non-idenity matrix, only the large corner radius will create a new shader.
128 for (float roundedCornersRadius : identity ? threeCornerRadii : oneCornerRadius) {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400129 // roundedCornersCrop is always set, but it is this radius that triggers the behavior
130 layer.geometry.roundedCornersRadius = roundedCornersRadius;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400131 for (bool isOpaque : {true, false}) {
132 layer.source.buffer.isOpaque = isOpaque;
133 for (auto alpha : {half(.23999f), half(1.0f)}) {
134 layer.alpha = alpha;
Alec Mouria90a5702021-04-16 16:36:21 +0000135 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400136 base::unique_fd(), nullptr);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500137 }
138 }
139 }
140 }
141}
142
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400143static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000144 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400145 const Rect& displayRect = display.physicalDisplay;
146 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
147 LayerSettings layer{
148 .geometry =
149 Geometry{
150 .boundaries = rect,
151 },
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400152 .source =
153 PixelSource{
154 .solidColor = half3(0.1f, 0.2f, 0.3f),
155 },
Alec Mouria90a5702021-04-16 16:36:21 +0000156 .alpha = 1,
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400157 };
158
159 auto layers = std::vector<const LayerSettings*>{&layer};
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400160 for (auto transform : {mat4(), kScaleAndTranslate}) {
161 layer.geometry.positionTransform = transform;
162 for (float roundedCornersRadius : {0.0f, 0.05f, 50.f}) {
163 layer.geometry.roundedCornersRadius = roundedCornersRadius;
Alec Mouria90a5702021-04-16 16:36:21 +0000164 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400165 base::unique_fd(), nullptr);
166 }
167 }
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400168}
169
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400170static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
Alec Mouria90a5702021-04-16 16:36:21 +0000171 const std::shared_ptr<ExternalTexture>& dstTexture) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400172 const Rect& displayRect = display.physicalDisplay;
173 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
174 LayerSettings layer{
175 .geometry =
176 Geometry{
177 .boundaries = rect,
178 },
179 .alpha = 1,
180 };
181
182 auto layers = std::vector<const LayerSettings*>{&layer};
183 for (int radius : {9, 60}) {
184 layer.backgroundBlurRadius = radius;
Alec Mouria90a5702021-04-16 16:36:21 +0000185 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400186 base::unique_fd(), nullptr);
187 }
188}
189
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400190static void drawTextureScaleLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
191 const std::shared_ptr<ExternalTexture>& dstTexture,
192 const std::shared_ptr<ExternalTexture>& srcTexture) {
193 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 .roundedCornersCrop = rect,
200 .positionTransform = kScaleAndTranslate,
201 .roundedCornersRadius = 300,
202 },
203 .source = PixelSource{.buffer =
204 Buffer{
205 .buffer = srcTexture,
206 .maxMasteringLuminance = 1000.f,
207 .maxContentLuminance = 1000.f,
208 .textureTransform = kScaleYOnly,
209 }},
210 .sourceDataspace = kOtherDataSpace,
211 };
212
213 auto layers = std::vector<const LayerSettings*>{&layer};
214 for (float alpha : {0.5f, 1.f}) {
215 layer.alpha = alpha,
216 renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
217 base::unique_fd(), nullptr);
218 }
219}
220
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400221//
222// The collection of shaders cached here were found by using perfetto to record shader compiles
223// during actions that involve RenderEngine, logging the layer settings, and the shader code
224// and reproducing those settings here.
225//
226// It is helpful when debugging this to turn on
227// in SkGLRenderEngine.cpp:
228// kPrintLayerSettings = true
229// kFlushAfterEveryLayer = true
230// in external/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
231// gPrintSKSL = true
232//
233// TODO(b/184631553) cache the shader involved in youtube pip return.
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500234void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400235 const int previousCount = renderengine->reportShadersCompiled();
236 if (previousCount) {
237 ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount);
238 }
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500239 const nsecs_t timeBefore = systemTime();
240 // The dimensions should not matter, so long as we draw inside them.
241 const Rect displayRect(0, 0, 1080, 2340);
242 DisplaySettings display{
243 .physicalDisplay = displayRect,
244 .clip = displayRect,
245 .maxLuminance = 500,
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400246 .outputDataspace = kDestDataSpace,
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500247 };
248
249 const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
250
251 sp<GraphicBuffer> dstBuffer =
252 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
253 usage, "primeShaderCache_dst");
Alec Mouria90a5702021-04-16 16:36:21 +0000254
255 const auto dstTexture = std::make_shared<ExternalTexture>(dstBuffer, *renderengine,
256 ExternalTexture::Usage::WRITEABLE);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500257 // This buffer will be the source for the call to drawImageLayers. Draw
258 // something to it as a placeholder for what an app draws. We should draw
Nathaniel Nifong4fc750d2021-03-19 11:37:36 -0400259 // something, but the details are not important. Make use of the shadow layer drawing step
260 // to populate it.
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500261 sp<GraphicBuffer> srcBuffer =
262 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
263 usage, "drawImageLayer_src");
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400264
Alec Mouria90a5702021-04-16 16:36:21 +0000265 const auto srcTexture =
266 std::make_shared<ExternalTexture>(srcBuffer, *renderengine,
267 ExternalTexture::Usage::READABLE |
268 ExternalTexture::Usage::WRITEABLE);
269
270 drawSolidLayers(renderengine, display, dstTexture);
271 drawShadowLayers(renderengine, display, srcTexture);
272 drawBlurLayers(renderengine, display, dstTexture);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400273 // The majority of shaders are related to sampling images.
Alec Mouria90a5702021-04-16 16:36:21 +0000274 drawImageLayers(renderengine, display, dstTexture, srcTexture);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400275
Nathaniel Nifongf4362402021-04-12 11:41:05 -0400276 // should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
277 const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
278
279 sp<GraphicBuffer> externalBuffer =
280 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
281 usageExternal, "primeShaderCache_external");
Alec Mouria90a5702021-04-16 16:36:21 +0000282 const auto externalTexture =
283 std::make_shared<ExternalTexture>(externalBuffer, *renderengine,
284 ExternalTexture::Usage::READABLE);
Nathaniel Nifongf4362402021-04-12 11:41:05 -0400285 // TODO(b/184665179) doubles number of image shader compilations, but only somewhere
286 // between 6 and 8 will occur in real uses.
Alec Mouria90a5702021-04-16 16:36:21 +0000287 drawImageLayers(renderengine, display, dstTexture, externalTexture);
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400288
Nathaniel Nifong21e021f2021-04-21 13:15:46 -0400289 // Draw layers for b/185569240.
290 drawTextureScaleLayers(renderengine, display, dstTexture, externalTexture);
291
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500292 const nsecs_t timeAfter = systemTime();
293 const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
Nathaniel Nifongb9f27ef2021-04-01 16:44:12 -0400294 const int shadersCompiled = renderengine->reportShadersCompiled();
295 ALOGD("Shader cache generated %d shaders in %f ms\n", shadersCompiled, compileTimeMs);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500296}
297
298} // namespace android::renderengine::skia