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