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