xref: /aosp_15_r20/frameworks/native/libs/renderengine/include/renderengine/RenderEngine.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright 2013 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 #ifndef SF_RENDERENGINE_H_
18 #define SF_RENDERENGINE_H_
19 
20 #include <android-base/unique_fd.h>
21 #include <ftl/future.h>
22 #include <math/mat4.h>
23 #include <renderengine/DisplaySettings.h>
24 #include <renderengine/ExternalTexture.h>
25 #include <renderengine/LayerSettings.h>
26 #include <stdint.h>
27 #include <sys/types.h>
28 #include <ui/FenceResult.h>
29 #include <ui/GraphicTypes.h>
30 #include <ui/Transform.h>
31 
32 #include <future>
33 #include <memory>
34 
35 /**
36  * Allows to override the RenderEngine backend.
37  */
38 #define PROPERTY_DEBUG_RENDERENGINE_BACKEND "debug.renderengine.backend"
39 
40 /**
41  * Allows opting particular devices into an initial preview rollout of RenderEngine on Graphite.
42  *
43  * Only applicable within SurfaceFlinger, and if relevant aconfig flags are enabled.
44  */
45 #define PROPERTY_DEBUG_RENDERENGINE_GRAPHITE_PREVIEW_OPTIN \
46     "debug.renderengine.graphite_preview_optin"
47 
48 /**
49  * Turns on recording of skia commands in SkiaGL version of the RE. This property
50  * defines number of milliseconds for the recording to take place. A non zero value
51  * turns on the recording.
52  */
53 #define PROPERTY_DEBUG_RENDERENGINE_CAPTURE_SKIA_MS "debug.renderengine.capture_skia_ms"
54 
55 /**
56  * Set to the most recently saved file once the capture is finished.
57  */
58 #define PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME "debug.renderengine.capture_filename"
59 
60 /**
61  * Switches the cross-window background blur algorithm.
62  */
63 #define PROPERTY_DEBUG_RENDERENGINE_BLUR_ALGORITHM "debug.renderengine.blur_algorithm"
64 
65 /**
66  * Allows recording of Skia drawing commands with systrace.
67  */
68 #define PROPERTY_SKIA_ATRACE_ENABLED "debug.renderengine.skia_atrace_enabled"
69 
70 struct ANativeWindowBuffer;
71 
72 namespace android {
73 
74 class Rect;
75 class Region;
76 
77 namespace renderengine {
78 
79 class ExternalTexture;
80 class Image;
81 class Mesh;
82 class Texture;
83 struct RenderEngineCreationArgs;
84 
85 namespace threaded {
86 class RenderEngineThreaded;
87 }
88 
89 namespace impl {
90 class RenderEngine;
91 class ExternalTexture;
92 }
93 
94 enum class Protection {
95     UNPROTECTED = 1,
96     PROTECTED = 2,
97 };
98 
99 // Toggles for skipping or enabling priming of particular shaders.
100 struct PrimeCacheConfig {
101     bool cacheHolePunchLayer = true;
102     bool cacheSolidLayers = true;
103     bool cacheSolidDimmedLayers = true;
104     bool cacheImageLayers = true;
105     bool cacheImageDimmedLayers = true;
106     bool cacheClippedLayers = true;
107     bool cacheShadowLayers = true;
108     bool cacheEdgeExtension = true;
109     bool cachePIPImageLayers = true;
110     bool cacheTransparentImageDimmedLayers = true;
111     bool cacheClippedDimmedImageLayers = true;
112     bool cacheUltraHDR = true;
113 };
114 
115 class RenderEngine {
116 public:
117     enum class ContextPriority {
118         LOW = 1,
119         MEDIUM = 2,
120         HIGH = 3,
121         REALTIME = 4,
122     };
123 
124     enum class Threaded {
125         NO,
126         YES,
127     };
128 
129     enum class GraphicsApi {
130         GL,
131         VK,
132     };
133 
134     enum class SkiaBackend {
135         GANESH,
136         GRAPHITE,
137     };
138 
139     enum class BlurAlgorithm {
140         NONE,
141         GAUSSIAN,
142         KAWASE,
143         KAWASE_DUAL_FILTER,
144     };
145 
146     static std::unique_ptr<RenderEngine> create(const RenderEngineCreationArgs& args);
147 
148     // Check if the device supports the given GraphicsApi.
149     //
150     // If called for GraphicsApi::VK then underlying (unprotected) VK resources will be preserved
151     // to optimize subsequent VK initialization, but teardown(GraphicsApi::VK) must be invoked if
152     // the caller subsequently decides to NOT use VK.
153     //
154     // The first call may require significant resource initialization, but subsequent checks are
155     // cached internally.
156     static bool canSupport(GraphicsApi graphicsApi);
157 
158     // Teardown any GPU API resources that were previously initialized but are no longer needed.
159     //
160     // Must be called with GraphicsApi::VK if canSupport(GraphicsApi::VK) was previously invoked but
161     // the caller subsequently decided to not use VK.
162     //
163     // This is safe to call if there is nothing to teardown, but NOT safe to call if a RenderEngine
164     // instance exists. The RenderEngine destructor will handle its own teardown logic.
165     static void teardown(GraphicsApi graphicsApi);
166 
167     virtual ~RenderEngine() = 0;
168 
169     // ----- BEGIN DEPRECATED INTERFACE -----
170     // This interface, while still in use until a suitable replacement is built,
171     // should be considered deprecated, minus some methods which still may be
172     // used to support legacy behavior.
173     virtual std::future<void> primeCache(PrimeCacheConfig config) = 0;
174 
175     // dump the extension strings. always call the base class.
176     virtual void dump(std::string& result) = 0;
177 
178     // queries that are required to be thread safe
179     virtual size_t getMaxTextureSize() const = 0;
180     virtual size_t getMaxViewportDims() const = 0;
181 
182     // ----- END DEPRECATED INTERFACE -----
183 
184     // ----- BEGIN NEW INTERFACE -----
185 
186     // queries that are required to be thread safe
187     virtual bool supportsProtectedContent() const = 0;
188 
189     // Notify RenderEngine of changes to the dimensions of the active display
190     // so that it can configure its internal caches accordingly.
191     virtual void onActiveDisplaySizeChanged(ui::Size size) = 0;
192 
193     // Renders layers for a particular display via GPU composition. This method
194     // should be called for every display that needs to be rendered via the GPU.
195     // @param display The display-wide settings that should be applied prior to
196     // drawing any layers.
197     //
198     // Assumptions when calling this method:
199     // 1. There is exactly one caller - i.e. multi-threading is not supported.
200     // 2. Additional threads may be calling the {bind,cache}ExternalTexture
201     // methods above. But the main thread is responsible for holding resources
202     // such that Image destruction does not occur while this method is called.
203     //
204     // TODO(b/136806342): This should behavior should ideally be fixed since
205     // the above two assumptions are brittle, as conditional thread safetyness
206     // may be insufficient when maximizing rendering performance in the future.
207     //
208     // @param layers The layers to draw onto the display, in Z-order.
209     // @param buffer The buffer which will be drawn to. This buffer will be
210     // ready once drawFence fires.
211     // @param bufferFence Fence signalling that the buffer is ready to be drawn
212     // to.
213     // @return A future object of FenceResult indicating whether drawing was
214     // successful in async mode.
215     virtual ftl::Future<FenceResult> drawLayers(const DisplaySettings& display,
216                                                 const std::vector<LayerSettings>& layers,
217                                                 const std::shared_ptr<ExternalTexture>& buffer,
218                                                 base::unique_fd&& bufferFence);
219 
220     virtual ftl::Future<FenceResult> drawGainmap(const std::shared_ptr<ExternalTexture>& sdr,
221                                                  base::borrowed_fd&& sdrFence,
222                                                  const std::shared_ptr<ExternalTexture>& hdr,
223                                                  base::borrowed_fd&& hdrFence, float hdrSdrRatio,
224                                                  ui::Dataspace dataspace,
225                                                  const std::shared_ptr<ExternalTexture>& gainmap);
226 
227     // Clean-up method that should be called on the main thread after the
228     // drawFence returned by drawLayers fires. This method will free up
229     // resources used by the most recently drawn frame. If the frame is still
230     // being drawn, then the implementation is free to silently ignore this call.
231     virtual void cleanupPostRender() = 0;
232 
233     // Returns the priority this context was actually created with. Note: this
234     // may not be the same as specified at context creation time, due to
235     // implementation limits on the number of contexts that can be created at a
236     // specific priority level in the system.
237     //
238     // This should return a valid EGL context priority enum as described by
239     // https://registry.khronos.org/EGL/extensions/IMG/EGL_IMG_context_priority.txt
240     // or
241     // https://registry.khronos.org/EGL/extensions/NV/EGL_NV_context_priority_realtime.txt
242     virtual int getContextPriority() = 0;
243 
244     // Returns true if blur was requested in the RenderEngineCreationArgs and the implementation
245     // also supports background blur.  If false, no blur will be applied when drawing layers. This
246     // query is required to be thread safe.
247     virtual bool supportsBackgroundBlur() = 0;
248 
249     // TODO(b/180767535): This is only implemented to allow for backend-specific behavior, which
250     // we should not allow in general, so remove this.
isThreaded()251     bool isThreaded() const { return mThreaded == Threaded::YES; }
252 
253     static void validateInputBufferUsage(const sp<GraphicBuffer>&);
254     static void validateOutputBufferUsage(const sp<GraphicBuffer>&);
255 
256     // Allows flinger to get the render engine thread id for power management with ADPF
257     // Returns the tid of the renderengine thread if it's threaded, and std::nullopt otherwise
getRenderEngineTid()258     virtual std::optional<pid_t> getRenderEngineTid() const { return std::nullopt; }
259 
setEnableTracing(bool)260     virtual void setEnableTracing(bool /*tracingEnabled*/) {}
261 
262 protected:
RenderEngine()263     RenderEngine() : RenderEngine(Threaded::NO) {}
264 
RenderEngine(Threaded threaded)265     RenderEngine(Threaded threaded) : mThreaded(threaded) {}
266 
267     // Maps GPU resources for this buffer.
268     // Note that work may be deferred to an additional thread, i.e. this call
269     // is made asynchronously, but the caller can expect that map/unmap calls
270     // are performed in a manner that's conflict serializable, i.e. unmapping
271     // a buffer should never occur before binding the buffer if the caller
272     // called mapExternalTextureBuffer before calling unmap.
273     // Note also that if the buffer contains protected content, then mapping those GPU resources may
274     // be deferred until the buffer is really used for drawing. This is because typical SoCs that
275     // support protected memory only support a limited amount, so optimisitically mapping protected
276     // memory may be too burdensome. If a buffer contains protected content and the RenderEngine
277     // implementation supports protected context, then GPU resources may be mapped into both the
278     // protected and unprotected contexts.
279     // If the buffer may ever be written to by RenderEngine, then isRenderable must be true.
280     virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) = 0;
281     // Unmaps GPU resources used by this buffer. This method should be
282     // invoked when the caller will no longer hold a reference to a GraphicBuffer
283     // and needs to clean up its resources.
284     // Note that if there are multiple callers holding onto the same buffer, then the buffer's
285     // resources may be internally ref-counted to guard against use-after-free errors. Note that
286     // work may be deferred to an additional thread, i.e. this call is expected to be made
287     // asynchronously, but the caller can expect that map/unmap calls are performed in a manner
288     // that's conflict serializable, i.e. unmap a buffer should never occur before binding the
289     // buffer if the caller called mapExternalTextureBuffer before calling unmap.
290     virtual void unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) = 0;
291 
292     // A thread safe query to determine if any post rendering cleanup is necessary.  Returning true
293     // is a signal that calling the postRenderCleanup method would be a no-op and that callers can
294     // avoid any thread synchronization that may be required by directly calling postRenderCleanup.
295     virtual bool canSkipPostRenderCleanup() const = 0;
296 
297     friend class impl::ExternalTexture;
298     friend class threaded::RenderEngineThreaded;
299     friend class RenderEngineTest_cleanupPostRender_cleansUpOnce_Test;
300     const Threaded mThreaded;
301 
302     // Update protectedContext mode depending on whether or not any layer has a protected buffer.
303     void updateProtectedContext(const std::vector<LayerSettings>&,
304                                 std::vector<const ExternalTexture*>);
305     // Attempt to switch RenderEngine into and out of protectedContext mode
306     virtual void useProtectedContext(bool useProtectedContext) = 0;
307 
308     virtual void drawLayersInternal(
309             const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
310             const DisplaySettings& display, const std::vector<LayerSettings>& layers,
311             const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) = 0;
312 
313     virtual void drawGainmapInternal(
314             const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
315             const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence,
316             const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence,
317             float hdrSdrRatio, ui::Dataspace dataspace,
318             const std::shared_ptr<ExternalTexture>& gainmap) = 0;
319 };
320 
321 struct RenderEngineCreationArgs {
322     int pixelFormat;
323     uint32_t imageCacheSize;
324     bool useColorManagement;
325     bool enableProtectedContext;
326     bool precacheToneMapperShaderOnly;
327     RenderEngine::BlurAlgorithm blurAlgorithm;
328     RenderEngine::ContextPriority contextPriority;
329     RenderEngine::Threaded threaded;
330     RenderEngine::GraphicsApi graphicsApi;
331     RenderEngine::SkiaBackend skiaBackend;
332 
333     struct Builder;
334 
335 private:
336     // must be created by Builder via constructor with full argument list
RenderEngineCreationArgsRenderEngineCreationArgs337     RenderEngineCreationArgs(int _pixelFormat, uint32_t _imageCacheSize,
338                              bool _enableProtectedContext, bool _precacheToneMapperShaderOnly,
339                              RenderEngine::BlurAlgorithm _blurAlgorithm,
340                              RenderEngine::ContextPriority _contextPriority,
341                              RenderEngine::Threaded _threaded,
342                              RenderEngine::GraphicsApi _graphicsApi,
343                              RenderEngine::SkiaBackend _skiaBackend)
344           : pixelFormat(_pixelFormat),
345             imageCacheSize(_imageCacheSize),
346             enableProtectedContext(_enableProtectedContext),
347             precacheToneMapperShaderOnly(_precacheToneMapperShaderOnly),
348             blurAlgorithm(_blurAlgorithm),
349             contextPriority(_contextPriority),
350             threaded(_threaded),
351             graphicsApi(_graphicsApi),
352             skiaBackend(_skiaBackend) {}
353     RenderEngineCreationArgs() = delete;
354 };
355 
356 struct RenderEngineCreationArgs::Builder {
BuilderBuilder357     Builder() {}
358 
setPixelFormatBuilder359     Builder& setPixelFormat(int pixelFormat) {
360         this->pixelFormat = pixelFormat;
361         return *this;
362     }
setImageCacheSizeBuilder363     Builder& setImageCacheSize(uint32_t imageCacheSize) {
364         this->imageCacheSize = imageCacheSize;
365         return *this;
366     }
setEnableProtectedContextBuilder367     Builder& setEnableProtectedContext(bool enableProtectedContext) {
368         this->enableProtectedContext = enableProtectedContext;
369         return *this;
370     }
setPrecacheToneMapperShaderOnlyBuilder371     Builder& setPrecacheToneMapperShaderOnly(bool precacheToneMapperShaderOnly) {
372         this->precacheToneMapperShaderOnly = precacheToneMapperShaderOnly;
373         return *this;
374     }
setBlurAlgorithmBuilder375     Builder& setBlurAlgorithm(RenderEngine::BlurAlgorithm blurAlgorithm) {
376         this->blurAlgorithm = blurAlgorithm;
377         return *this;
378     }
setContextPriorityBuilder379     Builder& setContextPriority(RenderEngine::ContextPriority contextPriority) {
380         this->contextPriority = contextPriority;
381         return *this;
382     }
setThreadedBuilder383     Builder& setThreaded(RenderEngine::Threaded threaded) {
384         this->threaded = threaded;
385         return *this;
386     }
setGraphicsApiBuilder387     Builder& setGraphicsApi(RenderEngine::GraphicsApi graphicsApi) {
388         this->graphicsApi = graphicsApi;
389         return *this;
390     }
setSkiaBackendBuilder391     Builder& setSkiaBackend(RenderEngine::SkiaBackend skiaBackend) {
392         this->skiaBackend = skiaBackend;
393         return *this;
394     }
buildBuilder395     RenderEngineCreationArgs build() const {
396         return RenderEngineCreationArgs(pixelFormat, imageCacheSize, enableProtectedContext,
397                                         precacheToneMapperShaderOnly, blurAlgorithm,
398                                         contextPriority, threaded, graphicsApi, skiaBackend);
399     }
400 
401 private:
402     // 1 means RGBA_8888
403     int pixelFormat = 1;
404     uint32_t imageCacheSize = 0;
405     bool enableProtectedContext = false;
406     bool precacheToneMapperShaderOnly = false;
407     RenderEngine::BlurAlgorithm blurAlgorithm = RenderEngine::BlurAlgorithm::NONE;
408     RenderEngine::ContextPriority contextPriority = RenderEngine::ContextPriority::MEDIUM;
409     RenderEngine::Threaded threaded = RenderEngine::Threaded::YES;
410     RenderEngine::GraphicsApi graphicsApi = RenderEngine::GraphicsApi::GL;
411     RenderEngine::SkiaBackend skiaBackend = RenderEngine::SkiaBackend::GANESH;
412 };
413 
414 } // namespace renderengine
415 } // namespace android
416 
417 #endif /* SF_RENDERENGINE_H_ */
418