blob: f8dd7f52e05214d8325fa9d8b429673bc51ba5af [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 */
16
17#include "Cache.h"
18#include "AutoBackendTexture.h"
19#include "SkiaRenderEngine.h"
20#include "android-base/unique_fd.h"
21#include "renderengine/DisplaySettings.h"
22#include "renderengine/LayerSettings.h"
23#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
31static void drawShadowLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
32 sp<GraphicBuffer> dstBuffer) {
33 // Somewhat arbitrary dimensions, but on screen and slightly shorter, based
34 // on actual use.
35 FloatRect rect(0, 0, display.physicalDisplay.width(), display.physicalDisplay.height() - 30);
36 LayerSettings layer{
37 .geometry =
38 Geometry{
39 .boundaries = rect,
40 .roundedCornersCrop = rect,
41 },
42 .shadow =
43 ShadowSettings{
44 .ambientColor = vec4(0, 0, 0, 0.00935997f),
45 .spotColor = vec4(0, 0, 0, 0.0455841f),
46 .lightPos = vec3(370.508f, -1527.03f, 1650.f),
47 .lightRadius = 2200.0f,
48 .length = 0.955342f,
49 },
50 };
51
52 auto layers = std::vector<const LayerSettings*>{&layer};
53 // The identity matrix will generate the fast shaders, and the second matrix
54 // (based on one seen while going from dialer to the home screen) will
55 // generate the slower (more general case) version. If we also need a
56 // slow version without color correction, we should use this matrix with
57 // display.outputDataspace set to SRGB.
Leon Scroggins III9f3072c2021-03-22 10:42:47 -040058 bool identity = true;
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050059 for (const mat4 transform : { mat4(), mat4(0.728872f, 0.f, 0.f, 0.f,
60 0.f, 0.727627f, 0.f, 0.f,
61 0.f, 0.f, 1.f, 0.f,
62 167.355743f, 1852.257812f, 0.f, 1.f) }) {
63 layer.geometry.positionTransform = transform;
64 renderengine->drawLayers(display, layers, dstBuffer, false /* useFrameBufferCache*/,
65 base::unique_fd(), nullptr);
Leon Scroggins III9f3072c2021-03-22 10:42:47 -040066 renderengine->assertShadersCompiled(identity ? 1 : 2);
67 identity = false;
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -050068 }
69}
70
71static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
72 sp<GraphicBuffer> dstBuffer, sp<GraphicBuffer> srcBuffer) {
73 const Rect& displayRect = display.physicalDisplay;
74 FloatRect rect(0, 0, displayRect.width(), displayRect.height());
75 LayerSettings layer{
76 .geometry =
77 Geometry{
78 .boundaries = rect,
79 // This matrix is based on actual data seen when opening the dialer.
80 // What seems to be important in matching the actual use cases are:
81 // - it is not identity
82 // - the layer will be drawn (not clipped out etc)
83 .positionTransform = mat4(.19f, .0f, .0f, .0f,
84 .0f, .19f, .0f, .0f,
85 .0f, .0f, 1.f, .0f,
86 169.f, 1527.f, .0f, 1.f),
87 .roundedCornersCrop = rect,
88 },
89 .source = PixelSource{.buffer =
90 Buffer{
91 .buffer = srcBuffer,
92 .maxMasteringLuminance = 1000.f,
93 .maxContentLuminance = 1000.f,
94 }},
95 };
96
97 // Test both drawRect and drawRRect
98 auto layers = std::vector<const LayerSettings*>{&layer};
99 for (float roundedCornersRadius : {0.0f, 500.f}) {
100 layer.geometry.roundedCornersRadius = roundedCornersRadius;
101 // No need to check UNKNOWN, which is treated as SRGB.
102 for (auto dataspace : {ui::Dataspace::SRGB, ui::Dataspace::DISPLAY_P3}) {
103 layer.sourceDataspace = dataspace;
104 for (bool isOpaque : {true, false}) {
105 layer.source.buffer.isOpaque = isOpaque;
106 for (auto alpha : {half(.23999f), half(1.0f)}) {
107 layer.alpha = alpha;
108 renderengine->drawLayers(display, layers, dstBuffer,
109 false /* useFrameBufferCache*/, base::unique_fd(),
110 nullptr);
Leon Scroggins III9f3072c2021-03-22 10:42:47 -0400111 renderengine->assertShadersCompiled(1);
Leon Scroggins IIIb9216dc2021-03-08 17:19:01 -0500112 }
113 }
114 }
115 }
116}
117
118void Cache::primeShaderCache(SkiaRenderEngine* renderengine) {
119 const nsecs_t timeBefore = systemTime();
120 // The dimensions should not matter, so long as we draw inside them.
121 const Rect displayRect(0, 0, 1080, 2340);
122 DisplaySettings display{
123 .physicalDisplay = displayRect,
124 .clip = displayRect,
125 .maxLuminance = 500,
126 .outputDataspace = ui::Dataspace::DISPLAY_P3,
127 };
128
129 const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
130
131 sp<GraphicBuffer> dstBuffer =
132 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
133 usage, "primeShaderCache_dst");
134 // This buffer will be the source for the call to drawImageLayers. Draw
135 // something to it as a placeholder for what an app draws. We should draw
136 // something, but the details are not important. We only need one version of
137 // the shadow's SkSL, so draw it here, giving us both a placeholder image
138 // and a chance to compile the shadow's SkSL.
139 sp<GraphicBuffer> srcBuffer =
140 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
141 usage, "drawImageLayer_src");
142 drawShadowLayer(renderengine, display, srcBuffer);
143
144 drawImageLayers(renderengine, display, dstBuffer, srcBuffer);
145 const nsecs_t timeAfter = systemTime();
146 const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
147 ALOGD("shader cache generated in %f ms\n", compileTimeMs);
148}
149
150} // namespace android::renderengine::skia