blob: 1b3492154b31f6e1e4301685a35d24a58141a4d0 [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 <condition_variable>
Alec Mourida4cf3b2019-02-12 15:33:01 -080021#include <deque>
Alec Mouri554d06e2018-12-20 00:15:33 -080022#include <mutex>
23#include <queue>
24#include <thread>
Alec Mourida4cf3b2019-02-12 15:33:01 -080025#include <unordered_map>
Mathias Agopian3f844832013-08-07 21:24:32 -070026
Peiyong Linf11f39b2018-09-05 14:37:41 -070027#include <EGL/egl.h>
28#include <EGL/eglext.h>
Mathias Agopian3f844832013-08-07 21:24:32 -070029#include <GLES2/gl2.h>
Alec Mouri16a99402019-07-29 16:37:30 -070030#include <android-base/thread_annotations.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070031#include <renderengine/RenderEngine.h>
Peiyong Lin833074a2018-08-28 11:53:54 -070032#include <renderengine/private/Description.h>
Alec Mouri16a99402019-07-29 16:37:30 -070033#include <sys/types.h>
Patrick Williams2e9748f2022-08-09 22:48:18 +000034#include <ui/FenceResult.h>
Vishnu Nairf19544f2020-02-03 11:23:26 -080035#include "GLShadowTexture.h"
Alec Mouri16a99402019-07-29 16:37:30 -070036#include "ImageManager.h"
Mathias Agopian3f844832013-08-07 21:24:32 -070037
Peiyong Linf11f39b2018-09-05 14:37:41 -070038#define EGL_NO_CONFIG ((EGLConfig)0)
39
Mathias Agopian3f844832013-08-07 21:24:32 -070040namespace android {
Mathias Agopian3f844832013-08-07 21:24:32 -070041
Peiyong Lin833074a2018-08-28 11:53:54 -070042namespace renderengine {
43
Mathias Agopian3f844832013-08-07 21:24:32 -070044class Mesh;
Mathias Agopian49457ac2013-08-14 18:20:17 -070045class Texture;
Mathias Agopian3f844832013-08-07 21:24:32 -070046
Peiyong Lin833074a2018-08-28 11:53:54 -070047namespace gl {
Lloyd Pique144e1162017-12-20 16:44:52 -080048
Peiyong Linf1bada92018-08-29 09:39:31 -070049class GLImage;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -080050class BlurFilter;
Peiyong Linf1bada92018-08-29 09:39:31 -070051
Alec Mouri081be4c2020-09-16 10:24:47 -070052class GLESRenderEngine : public RenderEngine {
Mathias Agopian3f844832013-08-07 21:24:32 -070053public:
Peiyong Lin4137a1d2019-10-09 10:39:09 -070054 static std::unique_ptr<GLESRenderEngine> create(const RenderEngineCreationArgs& args);
Peiyong Linf11f39b2018-09-05 14:37:41 -070055
Peiyong Lin4137a1d2019-10-09 10:39:09 -070056 GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display, EGLConfig config,
Peiyong Lind8460c82020-07-28 16:04:22 -070057 EGLContext ctxt, EGLSurface stub, EGLContext protectedContext,
58 EGLSurface protectedStub);
Alec Mourid43ccab2019-03-13 12:23:45 -070059 ~GLESRenderEngine() override EXCLUDES(mRenderingMutex);
Mathias Agopian3f844832013-08-07 21:24:32 -070060
Ady Abrahamfe2a6db2021-06-09 15:41:37 -070061 std::future<void> primeCache() override;
Peiyong Lin60bedb52018-09-05 10:47:31 -070062 void genTextures(size_t count, uint32_t* names) override;
63 void deleteTextures(size_t count, uint32_t const* names) override;
Patrick Williams8aed5d22022-10-31 22:18:10 +000064 bool isProtected() const { return mInProtectedContext; }
Peiyong Linfb530cf2018-12-15 05:07:38 +000065 bool supportsProtectedContent() const override;
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -040066 void useProtectedContext(bool useProtectedContext) override;
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040067 void cleanupPostRender() override;
Alec Mourid6f09462020-12-07 11:18:17 -080068 int getContextPriority() override;
Derek Sollenbergerb3998372021-02-16 15:16:56 -050069 bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
Ady Abrahamed3290f2021-05-17 15:12:14 -070070 void onActiveDisplaySizeChanged(ui::Size size) override {}
Alec Mouri6e57f682018-09-29 20:45:08 -070071
Peiyong Linf11f39b2018-09-05 14:37:41 -070072 EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
Alec Mourida4cf3b2019-02-12 15:33:01 -080073 // Creates an output image for rendering to
Alec Mourife0d72b2019-03-21 14:05:56 -070074 EGLImageKHR createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer, bool isProtected,
Alec Mourief44c2d2019-07-15 15:27:22 -070075 bool useFramebufferCache)
76 EXCLUDES(mFramebufferImageCacheMutex);
Peiyong Linf11f39b2018-09-05 14:37:41 -070077
Alec Mourid43ccab2019-03-13 12:23:45 -070078 // Test-only methods
79 // Returns true iff mImageCache contains an image keyed by bufferId
80 bool isImageCachedForTesting(uint64_t bufferId) EXCLUDES(mRenderingMutex);
Alec Mouri368e1582020-08-13 10:14:29 -070081 // Returns true iff texName was previously generated by RenderEngine and was
82 // not destroyed.
83 bool isTextureNameKnownForTesting(uint32_t texName);
84 // Returns the buffer ID of the content bound to texName, or nullopt if no
85 // such mapping exists.
86 std::optional<uint64_t> getBufferIdForTextureNameForTesting(uint32_t texName);
Alec Mourid43ccab2019-03-13 12:23:45 -070087 // Returns true iff mFramebufferImageCache contains an image keyed by bufferId
Alec Mourief44c2d2019-07-15 15:27:22 -070088 bool isFramebufferImageCachedForTesting(uint64_t bufferId)
89 EXCLUDES(mFramebufferImageCacheMutex);
Alec Mouri16a99402019-07-29 16:37:30 -070090 // These are wrappers around public methods above, but exposing Barrier
91 // objects so that tests can block.
92 std::shared_ptr<ImageManager::Barrier> cacheExternalTextureBufferForTesting(
93 const sp<GraphicBuffer>& buffer);
94 std::shared_ptr<ImageManager::Barrier> unbindExternalTextureBufferForTesting(uint64_t bufferId);
Alec Mourid43ccab2019-03-13 12:23:45 -070095
Mathias Agopian3f844832013-08-07 21:24:32 -070096protected:
John Reck992a2ca2020-09-03 17:20:56 -070097 Framebuffer* getFramebufferForDrawing();
Alec Mourief44c2d2019-07-15 15:27:22 -070098 void dump(std::string& result) override EXCLUDES(mRenderingMutex)
99 EXCLUDES(mFramebufferImageCacheMutex);
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700100 size_t getMaxTextureSize() const override;
101 size_t getMaxViewportDims() const override;
Alec Mouria90a5702021-04-16 16:36:21 +0000102 void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable)
103 EXCLUDES(mRenderingMutex);
104 void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
Derek Sollenbergerd3f60652021-06-11 15:34:36 -0400105 bool canSkipPostRenderCleanup() const override;
Patrick Williams2e9748f2022-08-09 22:48:18 +0000106 void drawLayersInternal(const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
Sally Qi4cabdd02021-08-05 16:45:57 -0700107 const DisplaySettings& display,
Sally Qi59a9f502021-10-12 18:53:23 +0000108 const std::vector<LayerSettings>& layers,
Sally Qi4cabdd02021-08-05 16:45:57 -0700109 const std::shared_ptr<ExternalTexture>& buffer,
110 const bool useFramebufferCache, base::unique_fd&& bufferFence) override;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700111
112private:
John Reck992a2ca2020-09-03 17:20:56 -0700113 friend class BindNativeBufferAsFramebuffer;
114
Peiyong Linf11f39b2018-09-05 14:37:41 -0700115 enum GlesVersion {
116 GLES_VERSION_1_0 = 0x10000,
117 GLES_VERSION_1_1 = 0x10001,
118 GLES_VERSION_2_0 = 0x20000,
119 GLES_VERSION_3_0 = 0x30000,
120 };
121
Alec Mouri8002fca2019-06-28 15:24:13 -0700122 static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
Peiyong Linf11f39b2018-09-05 14:37:41 -0700123 static GlesVersion parseGlesVersion(const char* str);
Peiyong Lina5e9f1b2018-11-27 22:49:37 -0800124 static EGLContext createEglContext(EGLDisplay display, EGLConfig config,
Alec Mourid6f09462020-12-07 11:18:17 -0800125 EGLContext shareContext,
126 std::optional<ContextPriority> contextPriority,
Peiyong Linfb530cf2018-12-15 05:07:38 +0000127 Protection protection);
Alec Mourid6f09462020-12-07 11:18:17 -0800128 static std::optional<RenderEngine::ContextPriority> createContextPriority(
129 const RenderEngineCreationArgs& args);
Peiyong Lind8460c82020-07-28 16:04:22 -0700130 static EGLSurface createStubEglPbufferSurface(EGLDisplay display, EGLConfig config,
131 int hwcFormat, Protection protection);
Alec Mouri8002fca2019-06-28 15:24:13 -0700132 std::unique_ptr<Framebuffer> createFramebuffer();
133 std::unique_ptr<Image> createImage();
134 void checkErrors() const;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800135 void checkErrors(const char* tag) const;
Peiyong Lin1c097612019-03-22 16:21:46 -0700136 void setScissor(const Rect& region);
137 void disableScissor();
Alec Mouri554d06e2018-12-20 00:15:33 -0800138 bool waitSync(EGLSyncKHR sync, EGLint flags);
Alec Mouri16a99402019-07-29 16:37:30 -0700139 status_t cacheExternalTextureBufferInternal(const sp<GraphicBuffer>& buffer)
140 EXCLUDES(mRenderingMutex);
141 void unbindExternalTextureBufferInternal(uint64_t bufferId) EXCLUDES(mRenderingMutex);
John Reck992a2ca2020-09-03 17:20:56 -0700142 status_t bindFrameBuffer(Framebuffer* framebuffer);
143 void unbindFrameBuffer(Framebuffer* framebuffer);
144 void bindExternalTextureImage(uint32_t texName, const Image& image);
Alec Mouri04eae7d2020-09-14 15:34:16 -0700145 void bindExternalTextureBuffer(uint32_t texName, const sp<GraphicBuffer>& buffer,
146 const sp<Fence>& fence) EXCLUDES(mRenderingMutex);
Marin Shalamanov23c31af2020-09-09 15:01:47 +0200147 void cleanFramebufferCache() EXCLUDES(mFramebufferImageCacheMutex) override;
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);
Alec Mouri8002fca2019-06-28 15:24:13 -0700168 base::unique_fd flush();
169 bool finish();
170 bool waitFence(base::unique_fd fenceFd);
171 void clearWithColor(float red, float green, float blue, float alpha);
172 void fillRegionWithColor(const Region& region, float red, float green, float blue, float alpha);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800173 void handleShadow(const FloatRect& casterRect, float casterCornerRadius,
174 const ShadowSettings& shadowSettings);
Alec Mouri8002fca2019-06-28 15:24:13 -0700175 void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
176 const half4& color, float cornerRadius);
177 void setupLayerTexturing(const Texture& texture);
178 void setupFillWithColor(float r, float g, float b, float a);
179 void setColorTransform(const mat4& colorTransform);
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800180 void setDisplayColorTransform(const mat4& colorTransform);
Alec Mouri8002fca2019-06-28 15:24:13 -0700181 void disableTexturing();
182 void disableBlending();
183 void setupCornerRadiusCropSize(float width, float height);
184
185 // HDR and color management related functions and state
186 void setSourceY410BT2020(bool enable);
187 void setSourceDataSpace(ui::Dataspace source);
188 void setOutputDataSpace(ui::Dataspace dataspace);
189 void setDisplayMaxLuminance(const float maxLuminance);
190
191 // drawing
192 void drawMesh(const Mesh& mesh);
Peiyong Lin1c097612019-03-22 16:21:46 -0700193
Peiyong Linf11f39b2018-09-05 14:37:41 -0700194 EGLDisplay mEGLDisplay;
195 EGLConfig mEGLConfig;
196 EGLContext mEGLContext;
Peiyong Lind8460c82020-07-28 16:04:22 -0700197 EGLSurface mStubSurface;
Peiyong Linfb530cf2018-12-15 05:07:38 +0000198 EGLContext mProtectedEGLContext;
Peiyong Lind8460c82020-07-28 16:04:22 -0700199 EGLSurface mProtectedStubSurface;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700200 GLint mMaxViewportDims[2];
201 GLint mMaxTextureSize;
202 GLuint mVpWidth;
203 GLuint mVpHeight;
204 Description mState;
Alec Mouri2725c092020-11-25 09:53:56 -0800205 std::unique_ptr<GLShadowTexture> mShadowTexture = nullptr;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700206
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700207 mat4 mSrgbToXyz;
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700208 mat4 mDisplayP3ToXyz;
Valerie Haueb8e0762018-11-06 10:10:42 -0800209 mat4 mBt2020ToXyz;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700210 mat4 mXyzToSrgb;
211 mat4 mXyzToDisplayP3;
212 mat4 mXyzToBt2020;
Valerie Haueb8e0762018-11-06 10:10:42 -0800213 mat4 mSrgbToDisplayP3;
214 mat4 mSrgbToBt2020;
215 mat4 mDisplayP3ToSrgb;
216 mat4 mDisplayP3ToBt2020;
217 mat4 mBt2020ToSrgb;
218 mat4 mBt2020ToDisplayP3;
Peiyong Line5a9a7f2018-08-30 15:32:13 -0700219
Peiyong Linfb530cf2018-12-15 05:07:38 +0000220 bool mInProtectedContext = false;
Alec Mouri554d06e2018-12-20 00:15:33 -0800221 // If set to true, then enables tracing flush() and finish() to systrace.
222 bool mTraceGpuCompletion = false;
Alec Mourida4cf3b2019-02-12 15:33:01 -0800223 // Maximum size of mFramebufferImageCache. If more images would be cached, then (approximately)
224 // the last recently used buffer should be kicked out.
225 uint32_t mFramebufferImageCacheSize = 0;
226
227 // Cache of output images, keyed by corresponding GraphicBuffer ID.
Alec Mourief44c2d2019-07-15 15:27:22 -0700228 std::deque<std::pair<uint64_t, EGLImageKHR>> mFramebufferImageCache
229 GUARDED_BY(mFramebufferImageCacheMutex);
230 // The only reason why we have this mutex is so that we don't segfault when
231 // dumping info.
232 std::mutex mFramebufferImageCacheMutex;
Peiyong Linfb069302018-04-25 14:34:31 -0700233
234 // Current dataspace of layer being rendered
235 ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN;
236
237 // Current output dataspace of the render engine
238 ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN;
239
Peiyong Lin13effd12018-07-24 17:01:47 -0700240 // Whether device supports color management, currently color management
241 // supports sRGB, DisplayP3 color spaces.
242 const bool mUseColorManagement = false;
Alec Mouri554d06e2018-12-20 00:15:33 -0800243
Alec Mouri081be4c2020-09-16 10:24:47 -0700244 // Whether only shaders performing tone mapping from HDR to SDR will be generated on
245 // primeCache().
246 const bool mPrecacheToneMapperShaderOnly = false;
247
Alec Mouri539319f2018-12-19 17:56:23 -0800248 // Cache of GL images that we'll store per GraphicBuffer ID
Alec Mourif0497272019-03-11 15:53:11 -0700249 std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache GUARDED_BY(mRenderingMutex);
Alec Mouri368e1582020-08-13 10:14:29 -0700250 std::unordered_map<uint32_t, std::optional<uint64_t>> mTextureView;
251
Alec Mourif0497272019-03-11 15:53:11 -0700252 // Mutex guarding rendering operations, so that:
253 // 1. GL operations aren't interleaved, and
254 // 2. Internal state related to rendering that is potentially modified by
255 // multiple threads is guaranteed thread-safe.
256 std::mutex mRenderingMutex;
257
Alec Mouri820c7402019-01-23 13:02:39 -0800258 std::unique_ptr<Framebuffer> mDrawingBuffer;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +0000259 // this is a 1x1 RGB buffer, but over-allocate in case a driver wants more
260 // memory or if it needs to satisfy alignment requirements. In this case:
261 // assume that each channel requires 4 bytes, and add 3 additional bytes to
262 // ensure that we align on a word. Allocating 16 bytes will provide a
263 // guarantee that we don't clobber memory.
264 uint32_t mPlaceholderDrawBuffer[4];
Alec Mouri368e1582020-08-13 10:14:29 -0700265 // Placeholder buffer and image, similar to mPlaceholderDrawBuffer, but
266 // instead these are intended for cleaning up texture memory with the
267 // GL_TEXTURE_EXTERNAL_OES target.
268 ANativeWindowBuffer* mPlaceholderBuffer = nullptr;
269 EGLImage mPlaceholderImage = EGL_NO_IMAGE_KHR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +0000270 sp<Fence> mLastDrawFence;
271 // Store a separate boolean checking if prior resources were cleaned up, as
272 // devices that don't support native sync fences can't rely on a last draw
273 // fence that doesn't exist.
274 bool mPriorResourcesCleaned = true;
Alec Mouri820c7402019-01-23 13:02:39 -0800275
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800276 // Blur effect processor, only instantiated when a layer requests it.
277 BlurFilter* mBlurFilter = nullptr;
278
Alec Mouri554d06e2018-12-20 00:15:33 -0800279 class FlushTracer {
280 public:
281 FlushTracer(GLESRenderEngine* engine);
282 ~FlushTracer();
283 void queueSync(EGLSyncKHR sync) EXCLUDES(mMutex);
284
285 struct QueueEntry {
286 EGLSyncKHR mSync = nullptr;
287 uint64_t mFrameNum = 0;
288 };
289
290 private:
291 void loop();
292 GLESRenderEngine* const mEngine;
293 std::thread mThread;
294 std::condition_variable_any mCondition;
295 std::mutex mMutex;
296 std::queue<QueueEntry> mQueue GUARDED_BY(mMutex);
297 uint64_t mFramesQueued GUARDED_BY(mMutex) = 0;
298 bool mRunning = true;
299 };
300 friend class FlushTracer;
Alec Mouri16a99402019-07-29 16:37:30 -0700301 friend class ImageManager;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800302 friend class GLFramebuffer;
303 friend class BlurFilter;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800304 friend class GenericProgram;
Alec Mouri554d06e2018-12-20 00:15:33 -0800305 std::unique_ptr<FlushTracer> mFlushTracer;
Alec Mouri2725c092020-11-25 09:53:56 -0800306 std::unique_ptr<ImageManager> mImageManager;
Mathias Agopian3f844832013-08-07 21:24:32 -0700307};
308
Peiyong Lin46080ef2018-10-26 18:43:14 -0700309} // namespace gl
310} // namespace renderengine
311} // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -0700312
Peiyong Lin7e219eb2018-12-03 05:40:42 -0800313#endif /* SF_GLESRENDERENGINE_H_ */