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