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