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