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 
52 namespace impl {
53 class RenderEngine;
54 }
55 
56 enum class Protection {
57     UNPROTECTED = 1,
58     PROTECTED = 2,
59 };
60 
61 class RenderEngine {
62 public:
63     enum FeatureFlag {
64         USE_COLOR_MANAGEMENT = 1 << 0,      // Device manages color
65         USE_HIGH_PRIORITY_CONTEXT = 1 << 1, // Use high priority context
66 
67         // Create a protected context when if possible
68         ENABLE_PROTECTED_CONTEXT = 1 << 2,
69     };
70 
71     static std::unique_ptr<impl::RenderEngine> create(int hwcFormat, uint32_t featureFlags,
72                                                       uint32_t imageCacheSize);
73 
74     virtual ~RenderEngine() = 0;
75 
76     // ----- BEGIN DEPRECATED INTERFACE -----
77     // This interface, while still in use until a suitable replacement is built,
78     // should be considered deprecated, minus some methods which still may be
79     // used to support legacy behavior.
80 
81     virtual std::unique_ptr<Framebuffer> createFramebuffer() = 0;
82     virtual std::unique_ptr<Image> createImage() = 0;
83 
84     virtual void primeCache() const = 0;
85 
86     // dump the extension strings. always call the base class.
87     virtual void dump(std::string& result) = 0;
88 
89     virtual bool useNativeFenceSync() const = 0;
90     virtual bool useWaitSync() const = 0;
91 
92     virtual bool isCurrent() const = 0;
93 
94     // helpers
95     // flush submits RenderEngine command stream for execution and returns a
96     // native fence fd that is signaled when the execution has completed.  It
97     // returns -1 on errors.
98     virtual base::unique_fd flush() = 0;
99     // finish waits until RenderEngine command stream has been executed.  It
100     // returns false on errors.
101     virtual bool finish() = 0;
102     // waitFence inserts a wait on an external fence fd to RenderEngine
103     // command stream.  It returns false on errors.
104     virtual bool waitFence(base::unique_fd fenceFd) = 0;
105 
106     virtual void clearWithColor(float red, float green, float blue, float alpha) = 0;
107     virtual void fillRegionWithColor(const Region& region, float red, float green, float blue,
108                                      float alpha) = 0;
109     virtual void genTextures(size_t count, uint32_t* names) = 0;
110     virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
111     virtual void bindExternalTextureImage(uint32_t texName, const Image& image) = 0;
112     // Legacy public method used by devices that don't support native fence
113     // synchronization in their GPU driver, as this method provides implicit
114     // synchronization for latching buffers.
115     virtual status_t bindExternalTextureBuffer(uint32_t texName, const sp<GraphicBuffer>& buffer,
116                                                const sp<Fence>& fence) = 0;
117     // Caches Image resources for this buffer, but does not bind the buffer to
118     // a particular texture.
119     // Note that work is deferred to an additional thread, i.e. this call
120     // is made asynchronously, but the caller can expect that cache/unbind calls
121     // are performed in a manner that's conflict serializable, i.e. unbinding
122     // a buffer should never occur before binding the buffer if the caller
123     // called {bind, cache}ExternalTextureBuffer before calling unbind.
124     virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0;
125     // Removes internal resources referenced by the bufferId. This method should be
126     // invoked when the caller will no longer hold a reference to a GraphicBuffer
127     // and needs to clean up its resources.
128     // Note that work is deferred to an additional thread, i.e. this call
129     // is made asynchronously, but the caller can expect that cache/unbind calls
130     // are performed in a manner that's conflict serializable, i.e. unbinding
131     // a buffer should never occur before binding the buffer if the caller
132     // called {bind, cache}ExternalTextureBuffer before calling unbind.
133     virtual void unbindExternalTextureBuffer(uint64_t bufferId) = 0;
134     // When binding a native buffer, it must be done before setViewportAndProjection
135     // Returns NO_ERROR when binds successfully, NO_MEMORY when there's no memory for allocation.
136     virtual status_t bindFrameBuffer(Framebuffer* framebuffer) = 0;
137     virtual void unbindFrameBuffer(Framebuffer* framebuffer) = 0;
138 
139     // set-up
140     virtual void checkErrors() const = 0;
141     virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
142                                           ui::Transform::orientation_flags rotation) = 0;
143     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
144                                     const half4& color, float cornerRadius) = 0;
145     virtual void setupLayerTexturing(const Texture& texture) = 0;
146     virtual void setupLayerBlackedOut() = 0;
147     virtual void setupFillWithColor(float r, float g, float b, float a) = 0;
148     // Sets up the crop size for corner radius clipping.
149     //
150     // Having corner radius will force GPU composition on the layer and its children, drawing it
151     // with a special shader. The shader will receive the radius and the crop rectangle as input,
152     // modifying the opacity of the destination texture, multiplying it by a number between 0 and 1.
153     // We query Layer#getRoundedCornerState() to retrieve the radius as well as the rounded crop
154     // rectangle to figure out how to apply the radius for this layer. The crop rectangle will be
155     // in local layer coordinate space, so we have to take the layer transform into account when
156     // walking up the tree.
157     virtual void setupCornerRadiusCropSize(float width, float height) = 0;
158 
159     // Set a color transform matrix that is applied in linear space right before OETF.
160     virtual void setColorTransform(const mat4& /* colorTransform */) = 0;
161     virtual void disableTexturing() = 0;
162     virtual void disableBlending() = 0;
163 
164     // HDR and color management support
165     virtual void setSourceY410BT2020(bool enable) = 0;
166     virtual void setSourceDataSpace(ui::Dataspace source) = 0;
167     virtual void setOutputDataSpace(ui::Dataspace dataspace) = 0;
168     virtual void setDisplayMaxLuminance(const float maxLuminance) = 0;
169 
170     // drawing
171     virtual void drawMesh(const Mesh& mesh) = 0;
172 
173     // queries
174     virtual size_t getMaxTextureSize() const = 0;
175     virtual size_t getMaxViewportDims() const = 0;
176 
177     // ----- END DEPRECATED INTERFACE -----
178 
179     // ----- BEGIN NEW INTERFACE -----
180 
181     virtual bool isProtected() const = 0;
182     virtual bool supportsProtectedContent() const = 0;
183     virtual bool useProtectedContext(bool useProtectedContext) = 0;
184 
185     // Renders layers for a particular display via GPU composition. This method
186     // should be called for every display that needs to be rendered via the GPU.
187     // @param display The display-wide settings that should be applied prior to
188     // drawing any layers.
189     //
190     // Assumptions when calling this method:
191     // 1. There is exactly one caller - i.e. multi-threading is not supported.
192     // 2. Additional threads may be calling the {bind,cache}ExternalTexture
193     // methods above. But the main thread is responsible for holding resources
194     // such that Image destruction does not occur while this method is called.
195     //
196     // TODO(b/136806342): This should behavior should ideally be fixed since
197     // the above two assumptions are brittle, as conditional thread safetyness
198     // may be insufficient when maximizing rendering performance in the future.
199     //
200     // @param layers The layers to draw onto the display, in Z-order.
201     // @param buffer The buffer which will be drawn to. This buffer will be
202     // ready once drawFence fires.
203     // @param useFramebufferCache True if the framebuffer cache should be used.
204     // If an implementation does not cache output framebuffers, then this
205     // parameter does nothing.
206     // @param bufferFence Fence signalling that the buffer is ready to be drawn
207     // to.
208     // @param drawFence A pointer to a fence, which will fire when the buffer
209     // has been drawn to and is ready to be examined. The fence will be
210     // initialized by this method. The caller will be responsible for owning the
211     // fence.
212     // @return An error code indicating whether drawing was successful. For
213     // now, this always returns NO_ERROR.
214     virtual status_t drawLayers(const DisplaySettings& display,
215                                 const std::vector<LayerSettings>& layers,
216                                 ANativeWindowBuffer* buffer, const bool useFramebufferCache,
217                                 base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0;
218 
219 protected:
220     // Gets a framebuffer to render to. This framebuffer may or may not be
221     // cached depending on the implementation.
222     //
223     // Note that this method does not transfer ownership, so the caller most not
224     // live longer than RenderEngine.
225     virtual Framebuffer* getFramebufferForDrawing() = 0;
226     friend class BindNativeBufferAsFramebuffer;
227 };
228 
229 class BindNativeBufferAsFramebuffer {
230 public:
BindNativeBufferAsFramebuffer(RenderEngine & engine,ANativeWindowBuffer * buffer,const bool useFramebufferCache)231     BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer,
232                                   const bool useFramebufferCache)
233           : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) {
234         mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected(),
235                                                       useFramebufferCache)
236                 ? mEngine.bindFrameBuffer(mFramebuffer)
237                 : NO_MEMORY;
238     }
~BindNativeBufferAsFramebuffer()239     ~BindNativeBufferAsFramebuffer() {
240         mFramebuffer->setNativeWindowBuffer(nullptr, false, /*arbitrary*/ true);
241         mEngine.unbindFrameBuffer(mFramebuffer);
242     }
getStatus()243     status_t getStatus() const { return mStatus; }
244 
245 private:
246     RenderEngine& mEngine;
247     Framebuffer* mFramebuffer;
248     status_t mStatus;
249 };
250 
251 namespace impl {
252 
253 // impl::RenderEngine contains common implementation that is graphics back-end agnostic.
254 class RenderEngine : public renderengine::RenderEngine {
255 public:
256     virtual ~RenderEngine() = 0;
257 
258     bool useNativeFenceSync() const override;
259     bool useWaitSync() const override;
260 
261 protected:
262     RenderEngine(uint32_t featureFlags);
263     const uint32_t mFeatureFlags;
264 };
265 
266 } // namespace impl
267 } // namespace renderengine
268 } // namespace android
269 
270 #endif /* SF_RENDERENGINE_H_ */
271