| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 1 | /* | 
 | 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 III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 16 | #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 Nair | dbbe385 | 2022-01-12 20:22:11 -0800 | [diff] [blame] | 22 | #include "renderengine/impl/ExternalTexture.h" | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 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 |  | 
 | 29 | namespace android::renderengine::skia { | 
 | 30 |  | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 31 | namespace { | 
| Nathaniel Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 32 | // Warming shader cache, not framebuffer cache. | 
 | 33 | constexpr bool kUseFrameBufferCache = false; | 
 | 34 |  | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 35 | // clang-format off | 
 | 36 | // Any non-identity matrix will do. | 
 | 37 | const 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 Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 41 | const 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 Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 45 | const 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 Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 49 | // clang-format on | 
| Nathaniel Nifong | bf6f754 | 2021-04-27 12:05:16 -0400 | [diff] [blame] | 50 | // When setting layer.sourceDataspace, whether it matches the destination or not determines whether | 
 | 51 | // a color correction effect is added to the shader. | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 52 | constexpr auto kDestDataSpace = ui::Dataspace::SRGB; | 
| Nathaniel Nifong | 21e021f | 2021-04-21 13:15:46 -0400 | [diff] [blame] | 53 | constexpr auto kOtherDataSpace = ui::Dataspace::DISPLAY_P3; | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 54 | } // namespace | 
 | 55 |  | 
| Nathaniel Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 56 | static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 57 |                              const std::shared_ptr<ExternalTexture>& dstTexture) { | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 58 |     // Somewhat arbitrary dimensions, but on screen and slightly shorter, based | 
 | 59 |     // on actual use. | 
| Nathaniel Nifong | a6b5423 | 2021-07-02 13:24:32 -0400 | [diff] [blame] | 60 |     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 III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 64 |     LayerSettings layer{ | 
 | 65 |             .geometry = | 
 | 66 |                     Geometry{ | 
 | 67 |                             .boundaries = rect, | 
 | 68 |                             .roundedCornersCrop = rect, | 
| Nathaniel Nifong | a6b5423 | 2021-07-02 13:24:32 -0400 | [diff] [blame] | 69 |                             .roundedCornersRadius = 50.f, | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 70 |                     }, | 
| Nathaniel Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 71 |             // drawShadow ignores alpha | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 72 |             .shadow = | 
 | 73 |                     ShadowSettings{ | 
| Nathaniel Nifong | a6b5423 | 2021-07-02 13:24:32 -0400 | [diff] [blame] | 74 |                             .boundaries = rect, | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 75 |                             .ambientColor = vec4(0, 0, 0, 0.00935997f), | 
 | 76 |                             .spotColor = vec4(0, 0, 0, 0.0455841f), | 
| Nathaniel Nifong | a6b5423 | 2021-07-02 13:24:32 -0400 | [diff] [blame] | 77 |                             .lightPos = vec3(500.f, -1500.f, 1500.f), | 
 | 78 |                             .lightRadius = 2500.0f, | 
 | 79 |                             .length = 15.f, | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 80 |                     }, | 
| Nathaniel Nifong | 490a947 | 2021-06-23 16:44:19 -0400 | [diff] [blame] | 81 |             // setting this is mandatory for shadows and blurs | 
 | 82 |             .skipContentDraw = true, | 
| Nathaniel Nifong | a6b5423 | 2021-07-02 13:24:32 -0400 | [diff] [blame] | 83 |             .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 III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 97 |     }; | 
 | 98 |  | 
| Nathaniel Nifong | 49a5958 | 2021-07-26 19:49:47 -0400 | [diff] [blame] | 99 |     // 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 III | ae07fe5 | 2022-04-26 15:23:55 -0400 | [diff] [blame] | 117 |  | 
 | 118 |         auto layers = std::vector<LayerSettings>{layer, caster}; | 
| Nathaniel Nifong | 49a5958 | 2021-07-26 19:49:47 -0400 | [diff] [blame] | 119 |         renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 120 |                                  base::unique_fd()); | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 121 |     } | 
 | 122 | } | 
 | 123 |  | 
 | 124 | static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 125 |                             const std::shared_ptr<ExternalTexture>& dstTexture, | 
 | 126 |                             const std::shared_ptr<ExternalTexture>& srcTexture) { | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 127 |     const Rect& displayRect = display.physicalDisplay; | 
 | 128 |     FloatRect rect(0, 0, displayRect.width(), displayRect.height()); | 
 | 129 |     LayerSettings layer{ | 
 | 130 |             .geometry = | 
 | 131 |                     Geometry{ | 
| Nathaniel Nifong | f06a45b | 2021-06-25 17:24:26 -0400 | [diff] [blame] | 132 |                             // 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 III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 135 |                             .boundaries = rect, | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 136 |                             .roundedCornersCrop = rect, | 
 | 137 |                     }, | 
 | 138 |             .source = PixelSource{.buffer = | 
 | 139 |                                           Buffer{ | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 140 |                                                   .buffer = srcTexture, | 
| John Reck | ac09e45 | 2021-04-07 16:35:37 -0400 | [diff] [blame] | 141 |                                                   .maxLuminanceNits = 1000.f, | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 142 |                                           }}, | 
 | 143 |     }; | 
 | 144 |  | 
| Nathaniel Nifong | bf6f754 | 2021-04-27 12:05:16 -0400 | [diff] [blame] | 145 |     for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { | 
 | 146 |         layer.sourceDataspace = dataspace; | 
| Nathaniel Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 147 |         // 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 Nifong | f06a45b | 2021-06-25 17:24:26 -0400 | [diff] [blame] | 149 |         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 III | ae07fe5 | 2022-04-26 15:23:55 -0400 | [diff] [blame] | 156 |                     auto layers = std::vector<LayerSettings>{layer}; | 
| Nathaniel Nifong | f06a45b | 2021-06-25 17:24:26 -0400 | [diff] [blame] | 157 |                     renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 158 |                                              base::unique_fd()); | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 159 |                 } | 
 | 160 |             } | 
 | 161 |         } | 
 | 162 |     } | 
 | 163 | } | 
 | 164 |  | 
| Nathaniel Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 165 | static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 166 |                             const std::shared_ptr<ExternalTexture>& dstTexture) { | 
| Nathaniel Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 167 |     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 Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 174 |             .source = | 
 | 175 |                     PixelSource{ | 
 | 176 |                             .solidColor = half3(0.1f, 0.2f, 0.3f), | 
 | 177 |                     }, | 
| Nathaniel Nifong | 768693f | 2021-06-08 14:33:47 -0400 | [diff] [blame] | 178 |             .alpha = 0.5, | 
| Nathaniel Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 179 |     }; | 
 | 180 |  | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 181 |     for (auto transform : {mat4(), kScaleAndTranslate}) { | 
 | 182 |         layer.geometry.positionTransform = transform; | 
| Nathaniel Nifong | f06a45b | 2021-06-25 17:24:26 -0400 | [diff] [blame] | 183 |         for (float roundedCornersRadius : {0.0f, 50.f}) { | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 184 |             layer.geometry.roundedCornersRadius = roundedCornersRadius; | 
| Leon Scroggins III | ae07fe5 | 2022-04-26 15:23:55 -0400 | [diff] [blame] | 185 |             auto layers = std::vector<LayerSettings>{layer}; | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 186 |             renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 187 |                                      base::unique_fd()); | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 188 |         } | 
 | 189 |     } | 
| Nathaniel Nifong | 4fc750d | 2021-03-19 11:37:36 -0400 | [diff] [blame] | 190 | } | 
 | 191 |  | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 192 | static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 193 |                            const std::shared_ptr<ExternalTexture>& dstTexture) { | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 194 |     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 Nifong | 490a947 | 2021-06-23 16:44:19 -0400 | [diff] [blame] | 202 |             // setting this is mandatory for shadows and blurs | 
 | 203 |             .skipContentDraw = true, | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 204 |     }; | 
 | 205 |  | 
| Nathaniel Nifong | 490a947 | 2021-06-23 16:44:19 -0400 | [diff] [blame] | 206 |     // Different blur code is invoked for radii less and greater than 30 pixels | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 207 |     for (int radius : {9, 60}) { | 
 | 208 |         layer.backgroundBlurRadius = radius; | 
| Leon Scroggins III | ae07fe5 | 2022-04-26 15:23:55 -0400 | [diff] [blame] | 209 |         auto layers = std::vector<LayerSettings>{layer}; | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 210 |         renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 211 |                                  base::unique_fd()); | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 212 |     } | 
 | 213 | } | 
 | 214 |  | 
| Nathaniel Nifong | 2d91c5e | 2021-05-13 17:14:00 -0400 | [diff] [blame] | 215 | // 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 Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 217 | // For buffers, this is done with a stage that computes coverage and it will differ for round and | 
 | 218 | // elliptical corners. | 
| Nathaniel Nifong | 2d91c5e | 2021-05-13 17:14:00 -0400 | [diff] [blame] | 219 | static void drawClippedLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, | 
 | 220 |                               const std::shared_ptr<ExternalTexture>& dstTexture, | 
 | 221 |                               const std::shared_ptr<ExternalTexture>& srcTexture) { | 
| Nathaniel Nifong | 21e021f | 2021-04-21 13:15:46 -0400 | [diff] [blame] | 222 |     const Rect& displayRect = display.physicalDisplay; | 
| Nathaniel Nifong | 2d91c5e | 2021-05-13 17:14:00 -0400 | [diff] [blame] | 223 |     FloatRect rect(0, 0, displayRect.width(), displayRect.height() - 20); // boundary is smaller | 
 | 224 |  | 
| Nathaniel Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 225 |     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 Nifong | 2d91c5e | 2021-05-13 17:14:00 -0400 | [diff] [blame] | 236 |  | 
| Nathaniel Nifong | 21e021f | 2021-04-21 13:15:46 -0400 | [diff] [blame] | 237 |     LayerSettings layer{ | 
 | 238 |             .geometry = | 
 | 239 |                     Geometry{ | 
 | 240 |                             .boundaries = rect, | 
| Nathaniel Nifong | 2d91c5e | 2021-05-13 17:14:00 -0400 | [diff] [blame] | 241 |                             .roundedCornersRadius = 27, // larger than the 20 above. | 
 | 242 |                             .roundedCornersCrop = | 
 | 243 |                                     FloatRect(0, 0, displayRect.width(), displayRect.height()), | 
| Nathaniel Nifong | 21e021f | 2021-04-21 13:15:46 -0400 | [diff] [blame] | 244 |                     }, | 
| Nathaniel Nifong | 21e021f | 2021-04-21 13:15:46 -0400 | [diff] [blame] | 245 |     }; | 
 | 246 |  | 
| Nathaniel Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 247 |     for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) { | 
 | 248 |         layer.source = pixelSource; | 
 | 249 |         for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) { | 
 | 250 |             layer.sourceDataspace = dataspace; | 
| Nathaniel Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 251 |             // Produce a CircularRRect clip and an EllipticalRRect clip. | 
| Nathaniel Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 252 |             for (auto transform : {kScaleAndTranslate, kScaleAsymmetric}) { | 
 | 253 |                 layer.geometry.positionTransform = transform; | 
| Nathaniel Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 254 |                 for (float alpha : {0.5f, 1.f}) { | 
| Leon Scroggins III | ae07fe5 | 2022-04-26 15:23:55 -0400 | [diff] [blame] | 255 |                     layer.alpha = alpha; | 
 | 256 |                     auto layers = std::vector<LayerSettings>{layer}; | 
| Nathaniel Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 257 |                     renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 258 |                                              base::unique_fd()); | 
| Nathaniel Nifong | afeac5b | 2021-05-27 10:52:30 -0400 | [diff] [blame] | 259 |                 } | 
 | 260 |             } | 
| Nathaniel Nifong | 2d91c5e | 2021-05-13 17:14:00 -0400 | [diff] [blame] | 261 |         } | 
| Nathaniel Nifong | 21e021f | 2021-04-21 13:15:46 -0400 | [diff] [blame] | 262 |     } | 
 | 263 | } | 
 | 264 |  | 
| Nathaniel Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 265 | static 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 Qi | 59a9f50 | 2021-10-12 18:53:23 +0000 | [diff] [blame] | 294 |     auto layers = std::vector<LayerSettings>{layer}; | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 295 |     renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); | 
| Nathaniel Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 296 | } | 
 | 297 |  | 
 | 298 | static 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 Qi | 59a9f50 | 2021-10-12 18:53:23 +0000 | [diff] [blame] | 322 |     auto layers = std::vector<LayerSettings>{layer}; | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 323 |     renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()); | 
| Nathaniel Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 324 | } | 
 | 325 |  | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 326 | // | 
 | 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 III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 337 | void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 338 |     const int previousCount = renderengine->reportShadersCompiled(); | 
 | 339 |     if (previousCount) { | 
 | 340 |         ALOGD("%d Shaders already compiled before Cache::primeShaderCache ran\n", previousCount); | 
 | 341 |     } | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 342 |  | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 343 |     // 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 Nifong | a6b5423 | 2021-07-02 13:24:32 -0400 | [diff] [blame] | 356 |         DisplaySettings p3Display{ | 
 | 357 |                 .physicalDisplay = displayRect, | 
 | 358 |                 .clip = displayRect, | 
 | 359 |                 .maxLuminance = 500, | 
 | 360 |                 .outputDataspace = kOtherDataSpace, | 
 | 361 |         }; | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 362 |  | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 363 |         const int64_t usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 364 |  | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 365 |         sp<GraphicBuffer> dstBuffer = | 
 | 366 |                 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, | 
 | 367 |                                   1, usage, "primeShaderCache_dst"); | 
| Nathaniel Nifong | b9f27ef | 2021-04-01 16:44:12 -0400 | [diff] [blame] | 368 |  | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 369 |         const auto dstTexture = | 
| Vishnu Nair | dbbe385 | 2022-01-12 20:22:11 -0800 | [diff] [blame] | 370 |                 std::make_shared<impl::ExternalTexture>(dstBuffer, *renderengine, | 
 | 371 |                                                         impl::ExternalTexture::Usage::WRITEABLE); | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 372 |         // 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 Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 379 |  | 
| Vishnu Nair | dbbe385 | 2022-01-12 20:22:11 -0800 | [diff] [blame] | 380 |         const auto srcTexture = std::make_shared< | 
 | 381 |                 impl::ExternalTexture>(srcBuffer, *renderengine, | 
 | 382 |                                        impl::ExternalTexture::Usage::READABLE | | 
 | 383 |                                                impl::ExternalTexture::Usage::WRITEABLE); | 
| Nathaniel Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 384 |         drawHolePunchLayer(renderengine, display, dstTexture); | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 385 |         drawSolidLayers(renderengine, display, dstTexture); | 
| Nathaniel Nifong | 49a5958 | 2021-07-26 19:49:47 -0400 | [diff] [blame] | 386 |  | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 387 |         drawShadowLayers(renderengine, display, srcTexture); | 
| Nathaniel Nifong | a6b5423 | 2021-07-02 13:24:32 -0400 | [diff] [blame] | 388 |         drawShadowLayers(renderengine, p3Display, srcTexture); | 
| Nathaniel Nifong | cda45e9 | 2021-06-10 15:01:42 -0400 | [diff] [blame] | 389 |  | 
 | 390 |         if (renderengine->supportsBackgroundBlur()) { | 
 | 391 |             drawBlurLayers(renderengine, display, dstTexture); | 
 | 392 |         } | 
 | 393 |  | 
| Nathaniel Nifong | 73537a3 | 2021-08-06 15:07:26 -0400 | [diff] [blame] | 394 |         // 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 Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 398 |         const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE; | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 399 |         sp<GraphicBuffer> externalBuffer = | 
 | 400 |                 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, | 
 | 401 |                                   1, usageExternal, "primeShaderCache_external"); | 
 | 402 |         const auto externalTexture = | 
| Vishnu Nair | dbbe385 | 2022-01-12 20:22:11 -0800 | [diff] [blame] | 403 |                 std::make_shared<impl::ExternalTexture>(externalBuffer, *renderengine, | 
 | 404 |                                                         impl::ExternalTexture::Usage::READABLE); | 
| Nathaniel Nifong | 73537a3 | 2021-08-06 15:07:26 -0400 | [diff] [blame] | 405 |         std::vector<const std::shared_ptr<ExternalTexture>> textures = | 
 | 406 |             {srcTexture, externalTexture}; | 
| Nathaniel Nifong | 21e021f | 2021-04-21 13:15:46 -0400 | [diff] [blame] | 407 |  | 
| Nathaniel Nifong | 73537a3 | 2021-08-06 15:07:26 -0400 | [diff] [blame] | 408 |         // 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 Nifong | f06a45b | 2021-06-25 17:24:26 -0400 | [diff] [blame] | 410 |         sp<GraphicBuffer> f16ExternalBuffer = | 
 | 411 |                 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_FP16, | 
 | 412 |                                   1, usageExternal, "primeShaderCache_external_f16"); | 
| Nathaniel Nifong | 73537a3 | 2021-08-06 15:07:26 -0400 | [diff] [blame] | 413 |         // 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 Nair | dbbe385 | 2022-01-12 20:22:11 -0800 | [diff] [blame] | 417 |                     std::make_shared<impl::ExternalTexture>(f16ExternalBuffer, *renderengine, | 
 | 418 |                                                             impl::ExternalTexture::Usage::READABLE); | 
| Nathaniel Nifong | 73537a3 | 2021-08-06 15:07:26 -0400 | [diff] [blame] | 419 |             textures.push_back(f16ExternalTexture); | 
 | 420 |         } | 
| Nathaniel Nifong | f06a45b | 2021-06-25 17:24:26 -0400 | [diff] [blame] | 421 |  | 
| Nathaniel Nifong | 73537a3 | 2021-08-06 15:07:26 -0400 | [diff] [blame] | 422 |         for (auto texture : textures) { | 
| Nathaniel Nifong | f06a45b | 2021-06-25 17:24:26 -0400 | [diff] [blame] | 423 |             drawImageLayers(renderengine, display, dstTexture, texture); | 
 | 424 |             // Draw layers for b/185569240. | 
 | 425 |             drawClippedLayers(renderengine, display, dstTexture, texture); | 
 | 426 |         } | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 427 |  | 
| Nathaniel Nifong | 1349150 | 2021-06-30 17:28:29 -0400 | [diff] [blame] | 428 |         drawPIPImageLayer(renderengine, display, dstTexture, externalTexture); | 
 | 429 |  | 
| Nathaniel Nifong | 2d2f432 | 2021-07-22 15:17:36 -0400 | [diff] [blame] | 430 |         // 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 Qi | 59a9f50 | 2021-10-12 18:53:23 +0000 | [diff] [blame] | 434 |         auto layers = std::vector<LayerSettings>{layer}; | 
| Sally Qi | 4cabdd0 | 2021-08-05 16:45:57 -0700 | [diff] [blame] | 435 |         // call get() to make it synchronous | 
 | 436 |         renderengine | 
 | 437 |                 ->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd()) | 
 | 438 |                 .get(); | 
| Nathaniel Nifong | 2d2f432 | 2021-07-22 15:17:36 -0400 | [diff] [blame] | 439 |  | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 440 |         const nsecs_t timeAfter = systemTime(); | 
 | 441 |         const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6; | 
| Leon Scroggins III | 45be918 | 2022-04-27 10:37:11 -0400 | [diff] [blame] | 442 |         const int shadersCompiled = renderengine->reportShadersCompiled() - previousCount; | 
| Derek Sollenberger | e9a5108 | 2021-05-06 14:01:38 -0400 | [diff] [blame] | 443 |         ALOGD("Shader cache generated %d shaders in %f ms\n", shadersCompiled, compileTimeMs); | 
 | 444 |     } | 
| Leon Scroggins III | b9216dc | 2021-03-08 17:19:01 -0500 | [diff] [blame] | 445 | } | 
 | 446 |  | 
 | 447 | } // namespace android::renderengine::skia |