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 <stdint.h>
21 #include <sys/types.h>
22 #include <memory>
23 
24 #include <android-base/unique_fd.h>
25 #include <math/mat4.h>
26 #include <renderengine/DisplaySettings.h>
27 #include <renderengine/Framebuffer.h>
28 #include <renderengine/Image.h>
29 #include <renderengine/LayerSettings.h>
30 #include <ui/GraphicTypes.h>
31 #include <ui/Transform.h>
32 
33 /**
34  * Allows to set RenderEngine backend to GLES (default) or Vulkan (NOT yet supported).
35  */
36 #define PROPERTY_DEBUG_RENDERENGINE_BACKEND "debug.renderengine.backend"
37 
38 struct ANativeWindowBuffer;
39 
40 namespace android {
41 
42 class Rect;
43 class Region;
44 
45 namespace renderengine {
46 
47 class BindNativeBufferAsFramebuffer;
48 class Image;
49 class Mesh;
50 class Texture;
51 struct RenderEngineCreationArgs;
52 
53 namespace impl {
54 class RenderEngine;
55 }
56 
57 enum class Protection {
58     UNPROTECTED = 1,
59     PROTECTED = 2,
60 };
61 
62 class RenderEngine {
63 public:
64     enum class ContextPriority {
65         LOW = 1,
66         MEDIUM = 2,
67         HIGH = 3,
68     };
69 
70     static std::unique_ptr<impl::RenderEngine> create(const RenderEngineCreationArgs& args);
71 
72     virtual ~RenderEngine() = 0;
73 
74     // ----- BEGIN DEPRECATED INTERFACE -----
75     // This interface, while still in use until a suitable replacement is built,
76     // should be considered deprecated, minus some methods which still may be
77     // used to support legacy behavior.
78     virtual void primeCache() const = 0;
79 
80     // dump the extension strings. always call the base class.
81     virtual void dump(std::string& result) = 0;
82 
83     virtual bool useNativeFenceSync() const = 0;
84     virtual bool useWaitSync() const = 0;
85     virtual void genTextures(size_t count, uint32_t* names) = 0;
86     virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
87     virtual void bindExternalTextureImage(uint32_t texName, const Image& image) = 0;
88     // Legacy public method used by devices that don't support native fence
89     // synchronization in their GPU driver, as this method provides implicit
90     // synchronization for latching buffers.
91     virtual status_t bindExternalTextureBuffer(uint32_t texName, const sp<GraphicBuffer>& buffer,
92                                                const sp<Fence>& fence) = 0;
93     // Caches Image resources for this buffer, but does not bind the buffer to
94     // a particular texture.
95     // Note that work is deferred to an additional thread, i.e. this call
96     // is made asynchronously, but the caller can expect that cache/unbind calls
97     // are performed in a manner that's conflict serializable, i.e. unbinding
98     // a buffer should never occur before binding the buffer if the caller
99     // called {bind, cache}ExternalTextureBuffer before calling unbind.
100     virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0;
101     // Removes internal resources referenced by the bufferId. This method should be
102     // invoked when the caller will no longer hold a reference to a GraphicBuffer
103     // and needs to clean up its resources.
104     // Note that work is deferred to an additional thread, i.e. this call
105     // is made asynchronously, but the caller can expect that cache/unbind calls
106     // are performed in a manner that's conflict serializable, i.e. unbinding
107     // a buffer should never occur before binding the buffer if the caller
108     // called {bind, cache}ExternalTextureBuffer before calling unbind.
109     virtual void unbindExternalTextureBuffer(uint64_t bufferId) = 0;
110     // When binding a native buffer, it must be done before setViewportAndProjection
111     // Returns NO_ERROR when binds successfully, NO_MEMORY when there's no memory for allocation.
112     virtual status_t bindFrameBuffer(Framebuffer* framebuffer) = 0;
113     virtual void unbindFrameBuffer(Framebuffer* framebuffer) = 0;
114     // Clean-up method that should be called on the main thread after the
115     // drawFence returned by drawLayers fires. This method will free up
116     // resources used by the most recently drawn frame. If the frame is still
117     // being drawn, then this call is silently ignored.
118     //
119     // Returns true if resources were cleaned up, and false if we didn't need to
120     // do any work.
121     virtual bool cleanupPostRender() = 0;
122 
123     // queries
124     virtual size_t getMaxTextureSize() const = 0;
125     virtual size_t getMaxViewportDims() const = 0;
126 
127     // ----- END DEPRECATED INTERFACE -----
128 
129     // ----- BEGIN NEW INTERFACE -----
130 
131     virtual bool isProtected() const = 0;
132     virtual bool supportsProtectedContent() const = 0;
133     virtual bool useProtectedContext(bool useProtectedContext) = 0;
134 
135     // Renders layers for a particular display via GPU composition. This method
136     // should be called for every display that needs to be rendered via the GPU.
137     // @param display The display-wide settings that should be applied prior to
138     // drawing any layers.
139     //
140     // Assumptions when calling this method:
141     // 1. There is exactly one caller - i.e. multi-threading is not supported.
142     // 2. Additional threads may be calling the {bind,cache}ExternalTexture
143     // methods above. But the main thread is responsible for holding resources
144     // such that Image destruction does not occur while this method is called.
145     //
146     // TODO(b/136806342): This should behavior should ideally be fixed since
147     // the above two assumptions are brittle, as conditional thread safetyness
148     // may be insufficient when maximizing rendering performance in the future.
149     //
150     // @param layers The layers to draw onto the display, in Z-order.
151     // @param buffer The buffer which will be drawn to. This buffer will be
152     // ready once drawFence fires.
153     // @param useFramebufferCache True if the framebuffer cache should be used.
154     // If an implementation does not cache output framebuffers, then this
155     // parameter does nothing.
156     // @param bufferFence Fence signalling that the buffer is ready to be drawn
157     // to.
158     // @param drawFence A pointer to a fence, which will fire when the buffer
159     // has been drawn to and is ready to be examined. The fence will be
160     // initialized by this method. The caller will be responsible for owning the
161     // fence.
162     // @return An error code indicating whether drawing was successful. For
163     // now, this always returns NO_ERROR.
164     virtual status_t drawLayers(const DisplaySettings& display,
165                                 const std::vector<const LayerSettings*>& layers,
166                                 ANativeWindowBuffer* buffer, const bool useFramebufferCache,
167                                 base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0;
168 
169 protected:
170     // Gets a framebuffer to render to. This framebuffer may or may not be
171     // cached depending on the implementation.
172     //
173     // Note that this method does not transfer ownership, so the caller most not
174     // live longer than RenderEngine.
175     virtual Framebuffer* getFramebufferForDrawing() = 0;
176     friend class BindNativeBufferAsFramebuffer;
177 };
178 
179 struct RenderEngineCreationArgs {
180     int pixelFormat;
181     uint32_t imageCacheSize;
182     bool useColorManagement;
183     bool enableProtectedContext;
184     bool precacheToneMapperShaderOnly;
185     bool supportsBackgroundBlur;
186     RenderEngine::ContextPriority contextPriority;
187 
188     struct Builder;
189 
190 private:
191     // must be created by Builder via constructor with full argument list
RenderEngineCreationArgsRenderEngineCreationArgs192     RenderEngineCreationArgs(
193             int _pixelFormat,
194             uint32_t _imageCacheSize,
195             bool _useColorManagement,
196             bool _enableProtectedContext,
197             bool _precacheToneMapperShaderOnly,
198             bool _supportsBackgroundBlur,
199             RenderEngine::ContextPriority _contextPriority)
200         : pixelFormat(_pixelFormat)
201         , imageCacheSize(_imageCacheSize)
202         , useColorManagement(_useColorManagement)
203         , enableProtectedContext(_enableProtectedContext)
204         , precacheToneMapperShaderOnly(_precacheToneMapperShaderOnly)
205         , supportsBackgroundBlur(_supportsBackgroundBlur)
206         , contextPriority(_contextPriority) {}
207     RenderEngineCreationArgs() = delete;
208 };
209 
210 struct RenderEngineCreationArgs::Builder {
BuilderBuilder211     Builder() {}
212 
setPixelFormatBuilder213     Builder& setPixelFormat(int pixelFormat) {
214         this->pixelFormat = pixelFormat;
215         return *this;
216     }
setImageCacheSizeBuilder217     Builder& setImageCacheSize(uint32_t imageCacheSize) {
218         this->imageCacheSize = imageCacheSize;
219         return *this;
220     }
setUseColorManagermentBuilder221     Builder& setUseColorManagerment(bool useColorManagement) {
222         this->useColorManagement = useColorManagement;
223         return *this;
224     }
setEnableProtectedContextBuilder225     Builder& setEnableProtectedContext(bool enableProtectedContext) {
226         this->enableProtectedContext = enableProtectedContext;
227         return *this;
228     }
setPrecacheToneMapperShaderOnlyBuilder229     Builder& setPrecacheToneMapperShaderOnly(bool precacheToneMapperShaderOnly) {
230         this->precacheToneMapperShaderOnly = precacheToneMapperShaderOnly;
231         return *this;
232     }
setSupportsBackgroundBlurBuilder233     Builder& setSupportsBackgroundBlur(bool supportsBackgroundBlur) {
234         this->supportsBackgroundBlur = supportsBackgroundBlur;
235         return *this;
236     }
setContextPriorityBuilder237     Builder& setContextPriority(RenderEngine::ContextPriority contextPriority) {
238         this->contextPriority = contextPriority;
239         return *this;
240     }
buildBuilder241     RenderEngineCreationArgs build() const {
242         return RenderEngineCreationArgs(pixelFormat, imageCacheSize, useColorManagement,
243                                         enableProtectedContext, precacheToneMapperShaderOnly,
244                                         supportsBackgroundBlur, contextPriority);
245     }
246 
247 private:
248     // 1 means RGBA_8888
249     int pixelFormat = 1;
250     uint32_t imageCacheSize = 0;
251     bool useColorManagement = true;
252     bool enableProtectedContext = false;
253     bool precacheToneMapperShaderOnly = false;
254     bool supportsBackgroundBlur = false;
255     RenderEngine::ContextPriority contextPriority = RenderEngine::ContextPriority::MEDIUM;
256 };
257 
258 class BindNativeBufferAsFramebuffer {
259 public:
BindNativeBufferAsFramebuffer(RenderEngine & engine,ANativeWindowBuffer * buffer,const bool useFramebufferCache)260     BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer,
261                                   const bool useFramebufferCache)
262           : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) {
263         mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected(),
264                                                       useFramebufferCache)
265                 ? mEngine.bindFrameBuffer(mFramebuffer)
266                 : NO_MEMORY;
267     }
~BindNativeBufferAsFramebuffer()268     ~BindNativeBufferAsFramebuffer() {
269         mFramebuffer->setNativeWindowBuffer(nullptr, false, /*arbitrary*/ true);
270         mEngine.unbindFrameBuffer(mFramebuffer);
271     }
getStatus()272     status_t getStatus() const { return mStatus; }
273 
274 private:
275     RenderEngine& mEngine;
276     Framebuffer* mFramebuffer;
277     status_t mStatus;
278 };
279 
280 namespace impl {
281 
282 // impl::RenderEngine contains common implementation that is graphics back-end agnostic.
283 class RenderEngine : public renderengine::RenderEngine {
284 public:
285     virtual ~RenderEngine() = 0;
286 
287     bool useNativeFenceSync() const override;
288     bool useWaitSync() const override;
289 
290 protected:
291     RenderEngine(const RenderEngineCreationArgs& args);
292     const RenderEngineCreationArgs mArgs;
293 };
294 
295 } // namespace impl
296 } // namespace renderengine
297 } // namespace android
298 
299 #endif /* SF_RENDERENGINE_H_ */
300