blob: de793c21420cc6c60baad698cd66e413336698d5 [file] [log] [blame]
Mathias Agopian3f844832013-08-07 21:24:32 -07001/*
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
Peiyong Lin7e219eb2018-12-03 05:40:42 -080017#ifndef SF_GLESRENDERENGINE_H_
18#define SF_GLESRENDERENGINE_H_
Mathias Agopian3f844832013-08-07 21:24:32 -070019
Alec Mouri554d06e2018-12-20 00:15:33 -080020#include <android-base/thread_annotations.h>
Mathias Agopian3f844832013-08-07 21:24:32 -070021#include <stdint.h>
22#include <sys/types.h>
Alec Mouri554d06e2018-12-20 00:15:33 -080023#include <condition_variable>
Alec Mourida4cf3b2019-02-12 15:33:01 -080024#include <deque>
Alec Mouri554d06e2018-12-20 00:15:33 -080025#include <mutex>
26#include <queue>
27#include <thread>
Alec Mourida4cf3b2019-02-12 15:33:01 -080028#include <unordered_map>
Mathias Agopian3f844832013-08-07 21:24:32 -070029
Peiyong Linf11f39b2018-09-05 14:37:41 -070030#include <EGL/egl.h>
31#include <EGL/eglext.h>
Mathias Agopian3f844832013-08-07 21:24:32 -070032#include <GLES2/gl2.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070033#include <renderengine/RenderEngine.h>
Peiyong Lin833074a2018-08-28 11:53:54 -070034#include <renderengine/private/Description.h>
Mathias Agopian3f844832013-08-07 21:24:32 -070035
Peiyong Linf11f39b2018-09-05 14:37:41 -070036#define EGL_NO_CONFIG ((EGLConfig)0)
37
Mathias Agopian3f844832013-08-07 21:24:32 -070038namespace android {
Mathias Agopian3f844832013-08-07 21:24:32 -070039
Peiyong Lin833074a2018-08-28 11:53:54 -070040namespace renderengine {
41
Mathias Agopian3f844832013-08-07 21:24:32 -070042class Mesh;
Mathias Agopian49457ac2013-08-14 18:20:17 -070043class Texture;
Mathias Agopian3f844832013-08-07 21:24:32 -070044
Peiyong Lin833074a2018-08-28 11:53:54 -070045namespace gl {
Lloyd Pique144e1162017-12-20 16:44:52 -080046
Peiyong Linf1bada92018-08-29 09:39:31 -070047class GLImage;
Peiyong Linf1bada92018-08-29 09:39:31 -070048
Peiyong Lin7e219eb2018-12-03 05:40:42 -080049class GLESRenderEngine : public impl::RenderEngine {
Mathias Agopian3f844832013-08-07 21:24:32 -070050public:
Alec Mourida4cf3b2019-02-12 15:33:01 -080051 static std::unique_ptr<GLESRenderEngine> create(int hwcFormat, uint32_t featureFlags,
52 uint32_t imageCacheSize);
Peiyong Linf11f39b2018-09-05 14:37:41 -070053 static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
54
Peiyong Lin7e219eb2018-12-03 05:40:42 -080055 GLESRenderEngine(uint32_t featureFlags, // See RenderEngine::FeatureFlag
Peiyong Linfb530cf2018-12-15 05:07:38 +000056 EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy,
Alec Mourida4cf3b2019-02-12 15:33:01 -080057 EGLContext protectedContext, EGLSurface protectedDummy,
58 uint32_t imageCacheSize);
Alec Mourid43ccab2019-03-13 12:23:45 -070059 ~GLESRenderEngine() override EXCLUDES(mRenderingMutex);
Mathias Agopian3f844832013-08-07 21:24:32 -070060
Peiyong Line5a9a7f2018-08-30 15:32:13 -070061 std::unique_ptr<Framebuffer> createFramebuffer() override;
Peiyong Line5a9a7f2018-08-30 15:32:13 -070062 std::unique_ptr<Image> createImage() override;
Peiyong Linf1bada92018-08-29 09:39:31 -070063
64 void primeCache() const override;
Peiyong Lin60bedb52018-09-05 10:47:31 -070065 bool isCurrent() const override;
Peiyong Lin60bedb52018-09-05 10:47:31 -070066 base::unique_fd flush() override;
67 bool finish() override;
68 bool waitFence(base::unique_fd fenceFd) override;
69 void clearWithColor(float red, float green, float blue, float alpha) override;
Chia-I Wu28e3a252018-09-07 12:05:02 -070070 void fillRegionWithColor(const Region& region, float red, float green, float blue,
71 float alpha) override;
Peiyong Lin60bedb52018-09-05 10:47:31 -070072 void genTextures(size_t count, uint32_t* names) override;
73 void deleteTextures(size_t count, uint32_t const* names) override;
Peiyong Line5a9a7f2018-08-30 15:32:13 -070074 void bindExternalTextureImage(uint32_t texName, const Image& image) override;
Alec Mourid7b3a8b2019-03-21 11:44:18 -070075 status_t bindExternalTextureBuffer(uint32_t texName, const sp<GraphicBuffer>& buffer,
76 const sp<Fence>& fence) EXCLUDES(mRenderingMutex);
77 status_t cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
Alec Mourif0497272019-03-11 15:53:11 -070078 void unbindExternalTextureBuffer(uint64_t bufferId) EXCLUDES(mRenderingMutex);
Peiyong Line5a9a7f2018-08-30 15:32:13 -070079 status_t bindFrameBuffer(Framebuffer* framebuffer) override;
80 void unbindFrameBuffer(Framebuffer* framebuffer) override;
Peiyong Lin60bedb52018-09-05 10:47:31 -070081 void checkErrors() const override;
Peiyong Linf1bada92018-08-29 09:39:31 -070082
Peiyong Linfb530cf2018-12-15 05:07:38 +000083 bool isProtected() const override { return mInProtectedContext; }
84 bool supportsProtectedContent() const override;
85 bool useProtectedContext(bool useProtectedContext) override;
Alec Mouri1089aed2018-10-25 21:33:57 -070086 status_t drawLayers(const DisplaySettings& display, const std::vector<LayerSettings>& layers,
Alec Mourife0d72b2019-03-21 14:05:56 -070087 ANativeWindowBuffer* buffer, const bool useFramebufferCache,
88 base::unique_fd&& bufferFence, base::unique_fd* drawFence)
89 EXCLUDES(mRenderingMutex) override;
Alec Mouri6e57f682018-09-29 20:45:08 -070090
Peiyong Linf11f39b2018-09-05 14:37:41 -070091 // internal to RenderEngine
92 EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
93 EGLConfig getEGLConfig() const { return mEGLConfig; }
Alec Mourida4cf3b2019-02-12 15:33:01 -080094 // Creates an output image for rendering to
Alec Mourife0d72b2019-03-21 14:05:56 -070095 EGLImageKHR createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer, bool isProtected,
96 bool useFramebufferCache);
Peiyong Linf11f39b2018-09-05 14:37:41 -070097
Alec Mourid43ccab2019-03-13 12:23:45 -070098 // Test-only methods
99 // Returns true iff mImageCache contains an image keyed by bufferId
100 bool isImageCachedForTesting(uint64_t bufferId) EXCLUDES(mRenderingMutex);
101 // Returns true iff mFramebufferImageCache contains an image keyed by bufferId
102 bool isFramebufferImageCachedForTesting(uint64_t bufferId) EXCLUDES(mRenderingMutex);
103
Mathias Agopian3f844832013-08-07 21:24:32 -0700104protected:
Alec Mouri820c7402019-01-23 13:02:39 -0800105 Framebuffer* getFramebufferForDrawing() override;
Yiwei Zhang5434a782018-12-05 18:06:32 -0800106 void dump(std::string& result) override;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700107 void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
108 ui::Transform::orientation_flags rotation) override;
109 void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
Lucas Dupin1b6531c2018-07-05 17:18:21 -0700110 const half4& color, float cornerRadius) override;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700111 void setupLayerTexturing(const Texture& texture) override;
112 void setupLayerBlackedOut() override;
113 void setupFillWithColor(float r, float g, float b, float a) override;
Peiyong Lind3788632018-09-18 16:01:31 -0700114 void setColorTransform(const mat4& colorTransform) override;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700115 void disableTexturing() override;
116 void disableBlending() override;
Lucas Dupin1b6531c2018-07-05 17:18:21 -0700117 void setupCornerRadiusCropSize(float width, float height) override;
Mathias Agopian3f844832013-08-07 21:24:32 -0700118
Peiyong Linf11f39b2018-09-05 14:37:41 -0700119 // HDR and color management related functions and state
120 void setSourceY410BT2020(bool enable) override;
121 void setSourceDataSpace(ui::Dataspace source) override;
122 void setOutputDataSpace(ui::Dataspace dataspace) override;
123 void setDisplayMaxLuminance(const float maxLuminance) override;
124
125 // drawing
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700126 void drawMesh(const Mesh& mesh) override;
Mathias Agopian3f844832013-08-07 21:24:32 -0700127
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700128 size_t getMaxTextureSize() const override;
129 size_t getMaxViewportDims() const override;
130
131private:
Peiyong Linf11f39b2018-09-05 14:37:41 -0700132 enum GlesVersion {
133 GLES_VERSION_1_0 = 0x10000,
134 GLES_VERSION_1_1 = 0x10001,
135 GLES_VERSION_2_0 = 0x20000,
136 GLES_VERSION_3_0 = 0x30000,
137 };
138
139 static GlesVersion parseGlesVersion(const char* str);
Peiyong Lina5e9f1b2018-11-27 22:49:37 -0800140 static EGLContext createEglContext(EGLDisplay display, EGLConfig config,
Peiyong Linfb530cf2018-12-15 05:07:38 +0000141 EGLContext shareContext, bool useContextPriority,
142 Protection protection);
Peiyong Lina5e9f1b2018-11-27 22:49:37 -0800143 static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
Peiyong Linfb530cf2018-12-15 05:07:38 +0000144 int hwcFormat, Protection protection);
Peiyong Lin1c097612019-03-22 16:21:46 -0700145 void setScissor(const Rect& region);
146 void disableScissor();
Alec Mouri554d06e2018-12-20 00:15:33 -0800147 bool waitSync(EGLSyncKHR sync, EGLint flags);
Peiyong Linf11f39b2018-09-05 14:37:41 -0700148
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700149 // A data space is considered HDR data space if it has BT2020 color space
150 // with PQ or HLG transfer function.
151 bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
152 bool needsXYZTransformMatrix() const;
Alec Mouri1089aed2018-10-25 21:33:57 -0700153 // Defines the viewport, and sets the projection matrix to the projection
154 // defined by the clip.
155 void setViewportAndProjection(Rect viewport, Rect clip);
Alec Mouri539319f2018-12-19 17:56:23 -0800156 // Evicts stale images from the buffer cache.
157 void evictImages(const std::vector<LayerSettings>& layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -0800158 // Computes the cropping window for the layer and sets up cropping
159 // coordinates for the mesh.
160 FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh);
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700161
Peiyong Lin1c097612019-03-22 16:21:46 -0700162 // We do a special handling for rounded corners when it's possible to turn off blending
163 // for the majority of the layer. The rounded corners needs to turn on blending such that
164 // we can set the alpha value correctly, however, only the corners need this, and since
165 // blending is an expensive operation, we want to turn off blending when it's not necessary.
166 void handleRoundedCorners(const DisplaySettings& display, const LayerSettings& layer,
167 const Mesh& mesh);
168
Peiyong Linf11f39b2018-09-05 14:37:41 -0700169 EGLDisplay mEGLDisplay;
170 EGLConfig mEGLConfig;
171 EGLContext mEGLContext;
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800172 EGLSurface mDummySurface;
Peiyong Linfb530cf2018-12-15 05:07:38 +0000173 EGLContext mProtectedEGLContext;
174 EGLSurface mProtectedDummySurface;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700175 GLuint mProtectedTexName;
176 GLint mMaxViewportDims[2];
177 GLint mMaxTextureSize;
178 GLuint mVpWidth;
179 GLuint mVpHeight;
180 Description mState;
181
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700182 mat4 mSrgbToXyz;
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700183 mat4 mDisplayP3ToXyz;
Valerie Haueb8e0762018-11-06 10:10:42 -0800184 mat4 mBt2020ToXyz;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700185 mat4 mXyzToSrgb;
186 mat4 mXyzToDisplayP3;
187 mat4 mXyzToBt2020;
Valerie Haueb8e0762018-11-06 10:10:42 -0800188 mat4 mSrgbToDisplayP3;
189 mat4 mSrgbToBt2020;
190 mat4 mDisplayP3ToSrgb;
191 mat4 mDisplayP3ToBt2020;
192 mat4 mBt2020ToSrgb;
193 mat4 mBt2020ToDisplayP3;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700194
Peiyong Linfb530cf2018-12-15 05:07:38 +0000195 bool mInProtectedContext = false;
Alec Mouri554d06e2018-12-20 00:15:33 -0800196 // If set to true, then enables tracing flush() and finish() to systrace.
197 bool mTraceGpuCompletion = false;
Alec Mourida4cf3b2019-02-12 15:33:01 -0800198 // Maximum size of mFramebufferImageCache. If more images would be cached, then (approximately)
199 // the last recently used buffer should be kicked out.
200 uint32_t mFramebufferImageCacheSize = 0;
201
202 // Cache of output images, keyed by corresponding GraphicBuffer ID.
203 std::deque<std::pair<uint64_t, EGLImageKHR>> mFramebufferImageCache;
Peiyong Linfb069302018-04-25 14:34:31 -0700204
205 // Current dataspace of layer being rendered
206 ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN;
207
208 // Current output dataspace of the render engine
209 ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN;
210
Peiyong Lin13effd12018-07-24 17:01:47 -0700211 // Whether device supports color management, currently color management
212 // supports sRGB, DisplayP3 color spaces.
213 const bool mUseColorManagement = false;
Alec Mouri554d06e2018-12-20 00:15:33 -0800214
Alec Mouri539319f2018-12-19 17:56:23 -0800215 // Cache of GL images that we'll store per GraphicBuffer ID
Alec Mourif0497272019-03-11 15:53:11 -0700216 std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache GUARDED_BY(mRenderingMutex);
217 // Mutex guarding rendering operations, so that:
218 // 1. GL operations aren't interleaved, and
219 // 2. Internal state related to rendering that is potentially modified by
220 // multiple threads is guaranteed thread-safe.
221 std::mutex mRenderingMutex;
222
223 // See bindExternalTextureBuffer above, but requiring that mRenderingMutex
224 // is held.
Alec Mourid7b3a8b2019-03-21 11:44:18 -0700225 status_t bindExternalTextureBufferLocked(uint32_t texName, const sp<GraphicBuffer>& buffer,
226 const sp<Fence>& fence) REQUIRES(mRenderingMutex);
227 // See cacheExternalTextureBuffer above, but requiring that mRenderingMutex
228 // is held.
229 status_t cacheExternalTextureBufferLocked(const sp<GraphicBuffer>& buffer)
230 REQUIRES(mRenderingMutex);
Alec Mouri539319f2018-12-19 17:56:23 -0800231
Alec Mouri820c7402019-01-23 13:02:39 -0800232 std::unique_ptr<Framebuffer> mDrawingBuffer;
233
Alec Mouri554d06e2018-12-20 00:15:33 -0800234 class FlushTracer {
235 public:
236 FlushTracer(GLESRenderEngine* engine);
237 ~FlushTracer();
238 void queueSync(EGLSyncKHR sync) EXCLUDES(mMutex);
239
240 struct QueueEntry {
241 EGLSyncKHR mSync = nullptr;
242 uint64_t mFrameNum = 0;
243 };
244
245 private:
246 void loop();
247 GLESRenderEngine* const mEngine;
248 std::thread mThread;
249 std::condition_variable_any mCondition;
250 std::mutex mMutex;
251 std::queue<QueueEntry> mQueue GUARDED_BY(mMutex);
252 uint64_t mFramesQueued GUARDED_BY(mMutex) = 0;
253 bool mRunning = true;
254 };
255 friend class FlushTracer;
256 std::unique_ptr<FlushTracer> mFlushTracer;
Mathias Agopian3f844832013-08-07 21:24:32 -0700257};
258
Peiyong Lin46080ef2018-10-26 18:43:14 -0700259} // namespace gl
260} // namespace renderengine
261} // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -0700262
Peiyong Lin7e219eb2018-12-03 05:40:42 -0800263#endif /* SF_GLESRENDERENGINE_H_ */