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_GLESRENDERENGINE_H_ 18 #define SF_GLESRENDERENGINE_H_ 19 20 #include <condition_variable> 21 #include <deque> 22 #include <mutex> 23 #include <queue> 24 #include <thread> 25 #include <unordered_map> 26 27 #include <EGL/egl.h> 28 #include <EGL/eglext.h> 29 #include <GLES2/gl2.h> 30 #include <android-base/thread_annotations.h> 31 #include <renderengine/RenderEngine.h> 32 #include <renderengine/private/Description.h> 33 #include <sys/types.h> 34 #include "GLShadowTexture.h" 35 #include "ImageManager.h" 36 37 #define EGL_NO_CONFIG ((EGLConfig)0) 38 39 namespace android { 40 41 namespace renderengine { 42 43 class Mesh; 44 class Texture; 45 46 namespace gl { 47 48 class GLImage; 49 class BlurFilter; 50 51 class GLESRenderEngine : public RenderEngine { 52 public: 53 static std::unique_ptr<GLESRenderEngine> create(const RenderEngineCreationArgs& args); 54 55 GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display, EGLConfig config, 56 EGLContext ctxt, EGLSurface stub, EGLContext protectedContext, 57 EGLSurface protectedStub); 58 ~GLESRenderEngine() override EXCLUDES(mRenderingMutex); 59 60 std::future<void> primeCache() override; 61 void genTextures(size_t count, uint32_t* names) override; 62 void deleteTextures(size_t count, uint32_t const* names) override; isProtected()63 bool isProtected() const override { return mInProtectedContext; } 64 bool supportsProtectedContent() const override; 65 void useProtectedContext(bool useProtectedContext) override; 66 status_t drawLayers(const DisplaySettings& display, 67 const std::vector<const LayerSettings*>& layers, 68 const std::shared_ptr<ExternalTexture>& buffer, 69 const bool useFramebufferCache, base::unique_fd&& bufferFence, 70 base::unique_fd* drawFence) override; 71 void cleanupPostRender() override; 72 int getContextPriority() override; supportsBackgroundBlur()73 bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; } onActiveDisplaySizeChanged(ui::Size size)74 void onActiveDisplaySizeChanged(ui::Size size) override {} 75 getEGLDisplay()76 EGLDisplay getEGLDisplay() const { return mEGLDisplay; } 77 // Creates an output image for rendering to 78 EGLImageKHR createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer, bool isProtected, 79 bool useFramebufferCache) 80 EXCLUDES(mFramebufferImageCacheMutex); 81 82 // Test-only methods 83 // Returns true iff mImageCache contains an image keyed by bufferId 84 bool isImageCachedForTesting(uint64_t bufferId) EXCLUDES(mRenderingMutex); 85 // Returns true iff texName was previously generated by RenderEngine and was 86 // not destroyed. 87 bool isTextureNameKnownForTesting(uint32_t texName); 88 // Returns the buffer ID of the content bound to texName, or nullopt if no 89 // such mapping exists. 90 std::optional<uint64_t> getBufferIdForTextureNameForTesting(uint32_t texName); 91 // Returns true iff mFramebufferImageCache contains an image keyed by bufferId 92 bool isFramebufferImageCachedForTesting(uint64_t bufferId) 93 EXCLUDES(mFramebufferImageCacheMutex); 94 // These are wrappers around public methods above, but exposing Barrier 95 // objects so that tests can block. 96 std::shared_ptr<ImageManager::Barrier> cacheExternalTextureBufferForTesting( 97 const sp<GraphicBuffer>& buffer); 98 std::shared_ptr<ImageManager::Barrier> unbindExternalTextureBufferForTesting(uint64_t bufferId); 99 100 protected: 101 Framebuffer* getFramebufferForDrawing(); 102 void dump(std::string& result) override EXCLUDES(mRenderingMutex) 103 EXCLUDES(mFramebufferImageCacheMutex); 104 size_t getMaxTextureSize() const override; 105 size_t getMaxViewportDims() const override; 106 void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) 107 EXCLUDES(mRenderingMutex); 108 void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex); 109 bool canSkipPostRenderCleanup() const override; 110 111 private: 112 friend class BindNativeBufferAsFramebuffer; 113 114 enum GlesVersion { 115 GLES_VERSION_1_0 = 0x10000, 116 GLES_VERSION_1_1 = 0x10001, 117 GLES_VERSION_2_0 = 0x20000, 118 GLES_VERSION_3_0 = 0x30000, 119 }; 120 121 static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig); 122 static GlesVersion parseGlesVersion(const char* str); 123 static EGLContext createEglContext(EGLDisplay display, EGLConfig config, 124 EGLContext shareContext, 125 std::optional<ContextPriority> contextPriority, 126 Protection protection); 127 static std::optional<RenderEngine::ContextPriority> createContextPriority( 128 const RenderEngineCreationArgs& args); 129 static EGLSurface createStubEglPbufferSurface(EGLDisplay display, EGLConfig config, 130 int hwcFormat, Protection protection); 131 std::unique_ptr<Framebuffer> createFramebuffer(); 132 std::unique_ptr<Image> createImage(); 133 void checkErrors() const; 134 void checkErrors(const char* tag) const; 135 void setScissor(const Rect& region); 136 void disableScissor(); 137 bool waitSync(EGLSyncKHR sync, EGLint flags); 138 status_t cacheExternalTextureBufferInternal(const sp<GraphicBuffer>& buffer) 139 EXCLUDES(mRenderingMutex); 140 void unbindExternalTextureBufferInternal(uint64_t bufferId) EXCLUDES(mRenderingMutex); 141 status_t bindFrameBuffer(Framebuffer* framebuffer); 142 void unbindFrameBuffer(Framebuffer* framebuffer); 143 void bindExternalTextureImage(uint32_t texName, const Image& image); 144 void bindExternalTextureBuffer(uint32_t texName, const sp<GraphicBuffer>& buffer, 145 const sp<Fence>& fence) EXCLUDES(mRenderingMutex); 146 void cleanFramebufferCache() EXCLUDES(mFramebufferImageCacheMutex) override; 147 148 // A data space is considered HDR data space if it has BT2020 color space 149 // with PQ or HLG transfer function. 150 bool isHdrDataSpace(const ui::Dataspace dataSpace) const; 151 bool needsXYZTransformMatrix() const; 152 // Defines the viewport, and sets the projection matrix to the projection 153 // defined by the clip. 154 void setViewportAndProjection(Rect viewport, Rect clip); 155 // Evicts stale images from the buffer cache. 156 void evictImages(const std::vector<LayerSettings>& layers); 157 // Computes the cropping window for the layer and sets up cropping 158 // coordinates for the mesh. 159 FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh); 160 161 // We do a special handling for rounded corners when it's possible to turn off blending 162 // for the majority of the layer. The rounded corners needs to turn on blending such that 163 // we can set the alpha value correctly, however, only the corners need this, and since 164 // blending is an expensive operation, we want to turn off blending when it's not necessary. 165 void handleRoundedCorners(const DisplaySettings& display, const LayerSettings& layer, 166 const Mesh& mesh); 167 base::unique_fd flush(); 168 bool finish(); 169 bool waitFence(base::unique_fd fenceFd); 170 void clearWithColor(float red, float green, float blue, float alpha); 171 void fillRegionWithColor(const Region& region, float red, float green, float blue, float alpha); 172 void handleShadow(const FloatRect& casterRect, float casterCornerRadius, 173 const ShadowSettings& shadowSettings); 174 void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture, 175 const half4& color, float cornerRadius); 176 void setupLayerTexturing(const Texture& texture); 177 void setupFillWithColor(float r, float g, float b, float a); 178 void setColorTransform(const mat4& colorTransform); 179 void setDisplayColorTransform(const mat4& colorTransform); 180 void disableTexturing(); 181 void disableBlending(); 182 void setupCornerRadiusCropSize(float width, float height); 183 184 // HDR and color management related functions and state 185 void setSourceY410BT2020(bool enable); 186 void setSourceDataSpace(ui::Dataspace source); 187 void setOutputDataSpace(ui::Dataspace dataspace); 188 void setDisplayMaxLuminance(const float maxLuminance); 189 190 // drawing 191 void drawMesh(const Mesh& mesh); 192 193 EGLDisplay mEGLDisplay; 194 EGLConfig mEGLConfig; 195 EGLContext mEGLContext; 196 EGLSurface mStubSurface; 197 EGLContext mProtectedEGLContext; 198 EGLSurface mProtectedStubSurface; 199 GLint mMaxViewportDims[2]; 200 GLint mMaxTextureSize; 201 GLuint mVpWidth; 202 GLuint mVpHeight; 203 Description mState; 204 std::unique_ptr<GLShadowTexture> mShadowTexture = nullptr; 205 206 mat4 mSrgbToXyz; 207 mat4 mDisplayP3ToXyz; 208 mat4 mBt2020ToXyz; 209 mat4 mXyzToSrgb; 210 mat4 mXyzToDisplayP3; 211 mat4 mXyzToBt2020; 212 mat4 mSrgbToDisplayP3; 213 mat4 mSrgbToBt2020; 214 mat4 mDisplayP3ToSrgb; 215 mat4 mDisplayP3ToBt2020; 216 mat4 mBt2020ToSrgb; 217 mat4 mBt2020ToDisplayP3; 218 219 bool mInProtectedContext = false; 220 // If set to true, then enables tracing flush() and finish() to systrace. 221 bool mTraceGpuCompletion = false; 222 // Maximum size of mFramebufferImageCache. If more images would be cached, then (approximately) 223 // the last recently used buffer should be kicked out. 224 uint32_t mFramebufferImageCacheSize = 0; 225 226 // Cache of output images, keyed by corresponding GraphicBuffer ID. 227 std::deque<std::pair<uint64_t, EGLImageKHR>> mFramebufferImageCache 228 GUARDED_BY(mFramebufferImageCacheMutex); 229 // The only reason why we have this mutex is so that we don't segfault when 230 // dumping info. 231 std::mutex mFramebufferImageCacheMutex; 232 233 // Current dataspace of layer being rendered 234 ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN; 235 236 // Current output dataspace of the render engine 237 ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN; 238 239 // Whether device supports color management, currently color management 240 // supports sRGB, DisplayP3 color spaces. 241 const bool mUseColorManagement = false; 242 243 // Whether only shaders performing tone mapping from HDR to SDR will be generated on 244 // primeCache(). 245 const bool mPrecacheToneMapperShaderOnly = false; 246 247 // Cache of GL images that we'll store per GraphicBuffer ID 248 std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache GUARDED_BY(mRenderingMutex); 249 std::unordered_map<uint32_t, std::optional<uint64_t>> mTextureView; 250 251 // Mutex guarding rendering operations, so that: 252 // 1. GL operations aren't interleaved, and 253 // 2. Internal state related to rendering that is potentially modified by 254 // multiple threads is guaranteed thread-safe. 255 std::mutex mRenderingMutex; 256 257 std::unique_ptr<Framebuffer> mDrawingBuffer; 258 // this is a 1x1 RGB buffer, but over-allocate in case a driver wants more 259 // memory or if it needs to satisfy alignment requirements. In this case: 260 // assume that each channel requires 4 bytes, and add 3 additional bytes to 261 // ensure that we align on a word. Allocating 16 bytes will provide a 262 // guarantee that we don't clobber memory. 263 uint32_t mPlaceholderDrawBuffer[4]; 264 // Placeholder buffer and image, similar to mPlaceholderDrawBuffer, but 265 // instead these are intended for cleaning up texture memory with the 266 // GL_TEXTURE_EXTERNAL_OES target. 267 ANativeWindowBuffer* mPlaceholderBuffer = nullptr; 268 EGLImage mPlaceholderImage = EGL_NO_IMAGE_KHR; 269 sp<Fence> mLastDrawFence; 270 // Store a separate boolean checking if prior resources were cleaned up, as 271 // devices that don't support native sync fences can't rely on a last draw 272 // fence that doesn't exist. 273 bool mPriorResourcesCleaned = true; 274 275 // Blur effect processor, only instantiated when a layer requests it. 276 BlurFilter* mBlurFilter = nullptr; 277 278 class FlushTracer { 279 public: 280 FlushTracer(GLESRenderEngine* engine); 281 ~FlushTracer(); 282 void queueSync(EGLSyncKHR sync) EXCLUDES(mMutex); 283 284 struct QueueEntry { 285 EGLSyncKHR mSync = nullptr; 286 uint64_t mFrameNum = 0; 287 }; 288 289 private: 290 void loop(); 291 GLESRenderEngine* const mEngine; 292 std::thread mThread; 293 std::condition_variable_any mCondition; 294 std::mutex mMutex; 295 std::queue<QueueEntry> mQueue GUARDED_BY(mMutex); 296 uint64_t mFramesQueued GUARDED_BY(mMutex) = 0; 297 bool mRunning = true; 298 }; 299 friend class FlushTracer; 300 friend class ImageManager; 301 friend class GLFramebuffer; 302 friend class BlurFilter; 303 friend class GenericProgram; 304 std::unique_ptr<FlushTracer> mFlushTracer; 305 std::unique_ptr<ImageManager> mImageManager; 306 }; 307 308 } // namespace gl 309 } // namespace renderengine 310 } // namespace android 311 312 #endif /* SF_GLESRENDERENGINE_H_ */ 313