blob: 33173470660d3c5cd554ef35f8dbd373bdc70d52 [file] [log] [blame]
Jesse Hall21558da2013-08-06 15:31:22 -07001/*
Mathias Agopian518ec112011-05-13 16:21:08 -07002 ** Copyright 2007, The Android Open Source Project
3 **
Jesse Hall21558da2013-08-06 15:31:22 -07004 ** 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
Mathias Agopian518ec112011-05-13 16:21:08 -07007 **
Jesse Hall21558da2013-08-06 15:31:22 -07008 ** http://www.apache.org/licenses/LICENSE-2.0
Mathias Agopian518ec112011-05-13 16:21:08 -07009 **
Jesse Hall21558da2013-08-06 15:31:22 -070010 ** 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
Mathias Agopian518ec112011-05-13 16:21:08 -070014 ** limitations under the License.
15 */
16
Jesse Hall1508ae62017-01-19 17:43:26 -080017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
Jesse Hallb29e5e82012-04-04 16:53:42 -070018
Mathias Agopian311b4792017-02-28 15:00:49 -080019#include "egl_display.h"
Mathias Agopian4b9511c2011-11-13 23:52:47 -080020
Yiwei Zhang8af003e2020-06-04 14:11:30 -070021#include <SurfaceFlingerProperties.h>
22#include <android-base/properties.h>
23#include <android/dlext.h>
24#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
25#include <configstore/Utils.h>
26#include <dlfcn.h>
27#include <graphicsenv/GraphicsEnv.h>
28
Mathias Agopian39c24a22013-04-04 23:17:56 -070029#include "../egl_impl.h"
Yiwei Zhang8af003e2020-06-04 14:11:30 -070030#include "EGL/eglext_angle.h"
Tobin Ehlis96a184d2018-07-18 16:14:07 -060031#include "Loader.h"
32#include "egl_angle_platform.h"
Jamie Gennisaca51c02011-11-03 17:42:43 -070033#include "egl_cache.h"
Mathias Agopian518ec112011-05-13 16:21:08 -070034#include "egl_object.h"
35#include "egl_tls.h"
Yiwei Zhang8af003e2020-06-04 14:11:30 -070036#include "private/EGL/display.h"
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -060037
38using namespace android::hardware::configstore;
39using namespace android::hardware::configstore::V1_0;
40
Mathias Agopian518ec112011-05-13 16:21:08 -070041namespace android {
Mathias Agopian518ec112011-05-13 16:21:08 -070042
Yiwei Zhang8af03062020-08-12 21:28:15 -070043static const char* const sVendorString = "Android";
44static const char* const sVersionString14 = "1.4 Android META-EGL";
45static const char* const sVersionString15 = "1.5 Android META-EGL";
46static const char* const sClientApiString = "OpenGL_ES";
Mathias Agopian4b9511c2011-11-13 23:52:47 -080047
Yiwei Zhang8af03062020-08-12 21:28:15 -070048extern const char* const gBuiltinExtensionString;
49extern const char* const gExtensionString;
Mathias Agopian4b9511c2011-11-13 23:52:47 -080050
Yiwei Zhang8af03062020-08-12 21:28:15 -070051extern void setGLHooksThreadSpecific(gl_hooks_t const* value);
Mathias Agopian518ec112011-05-13 16:21:08 -070052
Courtney Goeltzenleuchtera1e59f12018-03-05 08:19:25 -070053bool findExtension(const char* exts, const char* name, size_t nameLen) {
Jesse Hallc2e41222013-08-08 13:40:22 -070054 if (exts) {
Courtney Goeltzenleuchtera1e59f12018-03-05 08:19:25 -070055 if (!nameLen) {
56 nameLen = strlen(name);
57 }
Kalle Raita7804aa22016-04-18 16:03:37 -070058 for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
59 if (match[nameLen] == '\0' || match[nameLen] == ' ') {
60 return true;
61 }
Jesse Hallc2e41222013-08-08 13:40:22 -070062 }
63 }
64 return false;
65}
66
Krzysztof Kosińskidbccd222019-05-16 14:10:25 -070067bool needsAndroidPEglMitigation() {
Michael Hoisie4e0f56b2020-04-30 18:40:55 -040068 static const int32_t vndk_version = base::GetIntProperty("ro.vndk.version", -1);
Krzysztof Kosińskidbccd222019-05-16 14:10:25 -070069 return vndk_version <= 28;
70}
71
Mathias Agopianb7f9a242017-03-08 22:29:31 -080072int egl_get_init_count(EGLDisplay dpy) {
73 egl_display_t* eglDisplay = egl_display_t::get(dpy);
74 return eglDisplay ? eglDisplay->getRefsCount() : 0;
75}
76
Woody Chowa9550f32020-08-31 14:34:12 +090077std::map<EGLDisplay, std::unique_ptr<egl_display_t>> egl_display_t::displayMap;
78std::mutex egl_display_t::displayMapLock;
Mathias Agopian518ec112011-05-13 16:21:08 -070079
Yiwei Zhang8af03062020-08-12 21:28:15 -070080egl_display_t::egl_display_t()
81 : magic('_dpy'),
82 finishOnSwap(false),
83 traceGpuCompletion(false),
84 refs(0),
85 eglIsInitialized(false) {}
Mathias Agopian518ec112011-05-13 16:21:08 -070086
87egl_display_t::~egl_display_t() {
88 magic = 0;
Jamie Gennis76601082011-11-06 14:14:33 -080089 egl_cache_t::get()->terminate();
Mathias Agopian518ec112011-05-13 16:21:08 -070090}
91
92egl_display_t* egl_display_t::get(EGLDisplay dpy) {
Ivan Lozano7025b542017-12-06 14:19:44 -080093 if (uintptr_t(dpy) == 0) {
94 return nullptr;
95 }
96
Woody Chowa9550f32020-08-31 14:34:12 +090097 const std::lock_guard<std::mutex> lock(displayMapLock);
98 auto search = displayMap.find(dpy);
99 if (search == displayMap.end() || !search->second->isValid()) {
Jesse Halld6e99462016-09-28 11:26:57 -0700100 return nullptr;
101 }
Woody Chowa9550f32020-08-31 14:34:12 +0900102 return search->second.get();
Mathias Agopian518ec112011-05-13 16:21:08 -0700103}
104
105void egl_display_t::addObject(egl_object_t* object) {
Mathias Agopian65421432017-03-08 11:49:05 -0800106 std::lock_guard<std::mutex> _l(lock);
107 objects.insert(object);
Mathias Agopian518ec112011-05-13 16:21:08 -0700108}
109
Mathias Agopian5b287a62011-05-16 18:58:55 -0700110void egl_display_t::removeObject(egl_object_t* object) {
Mathias Agopian65421432017-03-08 11:49:05 -0800111 std::lock_guard<std::mutex> _l(lock);
112 objects.erase(object);
Mathias Agopian5b287a62011-05-16 18:58:55 -0700113}
114
Mathias Agopianf0480de2011-11-13 20:50:07 -0800115bool egl_display_t::getObject(egl_object_t* object) const {
Mathias Agopian65421432017-03-08 11:49:05 -0800116 std::lock_guard<std::mutex> _l(lock);
117 if (objects.find(object) != objects.end()) {
Mathias Agopianf0480de2011-11-13 20:50:07 -0800118 if (object->getDisplay() == this) {
119 object->incRef();
120 return true;
121 }
Mathias Agopian518ec112011-05-13 16:21:08 -0700122 }
123 return false;
124}
125
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600126EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp,
127 const EGLAttrib* attrib_list) {
Yiwei Zhang8af03062020-08-12 21:28:15 -0700128 if (uintptr_t(disp) >= NUM_DISPLAYS) return nullptr;
Mathias Agopian518ec112011-05-13 16:21:08 -0700129
Woody Chowa9550f32020-08-31 14:34:12 +0900130 return getPlatformDisplay(disp, attrib_list);
Mathias Agopian518ec112011-05-13 16:21:08 -0700131}
132
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600133static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx,
134 const EGLAttrib* attrib_list, EGLint* error) {
Cody Northrop1f00e172018-04-02 11:23:31 -0600135 EGLDisplay dpy = EGL_NO_DISPLAY;
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600136 *error = EGL_NONE;
Cody Northrop1f00e172018-04-02 11:23:31 -0600137
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600138 if (cnx->egl.eglGetPlatformDisplay) {
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600139 std::vector<EGLAttrib> attrs;
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600140 if (attrib_list) {
141 for (const EGLAttrib* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
142 attrs.push_back(attr[0]);
143 attrs.push_back(attr[1]);
144 }
145 }
Peiyong Lin2f707e62020-09-26 13:52:10 -0700146 const auto& eglFeatures = GraphicsEnv::getInstance().getAngleEglFeatures();
147 std::vector<const char*> features;
148 if (eglFeatures.size() > 0) {
149 for (const std::string& eglFeature : eglFeatures) {
150 features.push_back(eglFeature.c_str());
151 }
152 features.push_back(0);
153 attrs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
154 attrs.push_back(reinterpret_cast<EGLAttrib>(features.data()));
155 }
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600156
Courtney Goeltzenleuchterc1a1a862020-04-23 08:19:11 -0600157 attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
158 attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
159
Courtney Goeltzenleuchterc1a1a862020-04-23 08:19:11 -0600160 attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
Michael Hoisie4e0f56b2020-04-30 18:40:55 -0400161 attrs.push_back(base::GetBoolProperty("debug.angle.validation", false));
Courtney Goeltzenleuchterc1a1a862020-04-23 08:19:11 -0600162
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600163 attrs.push_back(EGL_NONE);
Cody Northrop1f00e172018-04-02 11:23:31 -0600164
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600165 dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
166 reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY),
167 attrs.data());
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600168 if (dpy == EGL_NO_DISPLAY) {
169 ALOGE("eglGetPlatformDisplay failed!");
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600170 } else {
Tobin Ehlis75ce4772018-11-20 09:48:47 -0700171 if (!angle::initializeAnglePlatform(dpy)) {
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600172 ALOGE("initializeAnglePlatform failed!");
173 }
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600174 }
Cody Northrop1f00e172018-04-02 11:23:31 -0600175 } else {
176 ALOGE("eglGetDisplay(%p) failed: Unable to look up eglGetPlatformDisplay from ANGLE",
177 display);
178 }
179
180 return dpy;
181}
182
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600183EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display,
184 const EGLAttrib* attrib_list) {
Jesse Hall1508ae62017-01-19 17:43:26 -0800185 ATRACE_CALL();
Mathias Agopian518ec112011-05-13 16:21:08 -0700186
187 // get our driver loader
188 Loader& loader(Loader::getInstance());
189
Mathias Agopianada798b2012-02-13 17:09:30 -0800190 egl_connection_t* const cnx = &gEGLImpl;
Yiwei Zhang5e21eb32019-06-05 00:26:03 -0700191 if (cnx->dso) {
Cody Northrop1f00e172018-04-02 11:23:31 -0600192 EGLDisplay dpy = EGL_NO_DISPLAY;
193
Peiyong Lin2f51e752023-06-15 22:35:14 +0000194 if (cnx->angleLoaded) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600195 EGLint error;
196 dpy = getPlatformDisplayAngle(display, cnx, attrib_list, &error);
197 if (error != EGL_NONE) {
198 return setError(error, dpy);
199 }
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600200 }
201 if (dpy == EGL_NO_DISPLAY) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600202 // NOTE: eglGetPlatformDisplay with a empty attribute list
203 // behaves the same as eglGetDisplay
204 if (cnx->egl.eglGetPlatformDisplay) {
205 dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANDROID_KHR, display,
206 attrib_list);
Ben Line17f69b2018-11-05 16:49:28 -0800207 }
208
209 // It is possible that eglGetPlatformDisplay does not have a
210 // working implementation for Android platform; in that case,
211 // one last fallback to eglGetDisplay
Yiwei Zhang8af03062020-08-12 21:28:15 -0700212 if (dpy == EGL_NO_DISPLAY) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600213 if (attrib_list) {
214 ALOGW("getPlatformDisplay: unexpected attribute list, attributes ignored");
215 }
216 dpy = cnx->egl.eglGetDisplay(display);
217 }
Cody Northrop1f00e172018-04-02 11:23:31 -0600218 }
219
Mathias Agopianada798b2012-02-13 17:09:30 -0800220 if (dpy == EGL_NO_DISPLAY) {
Courtney Goeltzenleuchteree768c22018-10-25 11:43:52 -0600221 loader.close(cnx);
Woody Chowa9550f32020-08-31 14:34:12 +0900222 } else {
223 const std::lock_guard<std::mutex> lock(displayMapLock);
224 if (displayMap.find(dpy) == displayMap.end()) {
225 auto d = std::make_unique<egl_display_t>();
226 d->disp.dpy = dpy;
227 displayMap[dpy] = std::move(d);
228 }
229 return dpy;
Mathias Agopian518ec112011-05-13 16:21:08 -0700230 }
231 }
232
Woody Chowa9550f32020-08-31 14:34:12 +0900233 return nullptr;
Mathias Agopian518ec112011-05-13 16:21:08 -0700234}
235
Yiwei Zhang8af03062020-08-12 21:28:15 -0700236EGLBoolean egl_display_t::initialize(EGLint* major, EGLint* minor) {
Mathias Agopian65421432017-03-08 11:49:05 -0800237 { // scope for refLock
238 std::unique_lock<std::mutex> _l(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800239 refs++;
240 if (refs > 1) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600241 // We don't know what to report until we know what the
242 // driver supports. Make sure we are initialized before
243 // returning the version info.
Yiwei Zhang8af03062020-08-12 21:28:15 -0700244 while (!eglIsInitialized) {
Mathias Agopian65421432017-03-08 11:49:05 -0800245 refCond.wait(_l);
246 }
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600247 egl_connection_t* const cnx = &gEGLImpl;
248
249 // TODO: If device doesn't provide 1.4 or 1.5 then we'll be
250 // changing the behavior from the past where we always advertise
251 // version 1.4. May need to check that revision is valid
252 // before using cnx->major & cnx->minor
253 if (major != nullptr) *major = cnx->major;
254 if (minor != nullptr) *minor = cnx->minor;
Michael Lentine54466bc2015-01-27 09:01:03 -0800255 return EGL_TRUE;
256 }
Yiwei Zhang8af03062020-08-12 21:28:15 -0700257 while (eglIsInitialized) {
Mathias Agopian65421432017-03-08 11:49:05 -0800258 refCond.wait(_l);
259 }
Michael Lentine54466bc2015-01-27 09:01:03 -0800260 }
261
Mathias Agopian65421432017-03-08 11:49:05 -0800262 { // scope for lock
263 std::lock_guard<std::mutex> _l(lock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800264
Michael Lentine54466bc2015-01-27 09:01:03 -0800265 setGLHooksThreadSpecific(&gHooksNoContext);
266
267 // initialize each EGL and
268 // build our own extension string first, based on the extension we know
269 // and the extension supported by our client implementation
270
271 egl_connection_t* const cnx = &gEGLImpl;
272 cnx->major = -1;
273 cnx->minor = -1;
274 if (cnx->dso) {
275 EGLDisplay idpy = disp.dpy;
276 if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
Yiwei Zhang8af03062020-08-12 21:28:15 -0700277 // ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
Michael Lentine54466bc2015-01-27 09:01:03 -0800278 // idpy, cnx->major, cnx->minor, cnx);
279
280 // display is now initialized
281 disp.state = egl_display_t::INITIALIZED;
282
283 // get the query-strings for this display for each implementation
Yiwei Zhang8af03062020-08-12 21:28:15 -0700284 disp.queryString.vendor = cnx->egl.eglQueryString(idpy, EGL_VENDOR);
285 disp.queryString.version = cnx->egl.eglQueryString(idpy, EGL_VERSION);
286 disp.queryString.extensions = cnx->egl.eglQueryString(idpy, EGL_EXTENSIONS);
287 disp.queryString.clientApi = cnx->egl.eglQueryString(idpy, EGL_CLIENT_APIS);
Michael Lentine54466bc2015-01-27 09:01:03 -0800288
289 } else {
290 ALOGW("eglInitialize(%p) failed (%s)", idpy,
Yiwei Zhang8af03062020-08-12 21:28:15 -0700291 egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
Michael Lentine54466bc2015-01-27 09:01:03 -0800292 }
293 }
294
Sean Callananad9061c2019-03-12 14:07:23 -0700295 if (cnx->minor == 5) {
296 // full list in egl_entries.in
Yiwei Zhang8af03062020-08-12 21:28:15 -0700297 if (!cnx->egl.eglCreateImage || !cnx->egl.eglDestroyImage ||
298 !cnx->egl.eglGetPlatformDisplay || !cnx->egl.eglCreatePlatformWindowSurface ||
299 !cnx->egl.eglCreatePlatformPixmapSurface || !cnx->egl.eglCreateSync ||
300 !cnx->egl.eglDestroySync || !cnx->egl.eglClientWaitSync ||
301 !cnx->egl.eglGetSyncAttrib || !cnx->egl.eglWaitSync) {
Sean Callananad9061c2019-03-12 14:07:23 -0700302 ALOGE("Driver indicates EGL 1.5 support, but does not have "
303 "a critical API");
304 cnx->minor = 4;
305 }
306 }
307
Michael Lentine54466bc2015-01-27 09:01:03 -0800308 // the query strings are per-display
Mathias Agopian65421432017-03-08 11:49:05 -0800309 mVendorString = sVendorString;
Courtney Goeltzenleuchter015ed672018-07-27 13:43:23 -0600310 mVersionString.clear();
311 cnx->driverVersion = EGL_MAKE_VERSION(1, 4, 0);
Courtney Goeltzenleuchterf5b5c412019-04-10 17:36:19 -0600312 mVersionString = sVersionString14;
Courtney Goeltzenleuchter015ed672018-07-27 13:43:23 -0600313 if ((cnx->major == 1) && (cnx->minor == 5)) {
314 mVersionString = sVersionString15;
315 cnx->driverVersion = EGL_MAKE_VERSION(1, 5, 0);
Courtney Goeltzenleuchter015ed672018-07-27 13:43:23 -0600316 }
317 if (mVersionString.empty()) {
318 ALOGW("Unexpected driver version: %d.%d, want 1.4 or 1.5", cnx->major, cnx->minor);
319 mVersionString = sVersionString14;
320 }
Mathias Agopian65421432017-03-08 11:49:05 -0800321 mClientApiString = sClientApiString;
Michael Lentine54466bc2015-01-27 09:01:03 -0800322
Mathias Agopian65421432017-03-08 11:49:05 -0800323 mExtensionString = gBuiltinExtensionString;
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600324
Yuxin Hu7fee4412023-03-14 01:43:05 +0000325 // b/269060366 Conditionally enabled EGL_ANDROID_get_frame_timestamps extension if the
326 // device's present timestamps are reliable (which may not be the case on emulators).
Peiyong Lin2f51e752023-06-15 22:35:14 +0000327 if (cnx->angleLoaded) {
Yuxin Hu7fee4412023-03-14 01:43:05 +0000328 if (android::base::GetBoolProperty("service.sf.present_timestamp", false)) {
Yuxin Hu0bc64a82023-05-08 23:48:42 +0000329 mExtensionString.append("EGL_ANDROID_get_frame_timestamps ");
Yuxin Hu7fee4412023-03-14 01:43:05 +0000330 }
331 } else {
Yuxin Hu0bc64a82023-05-08 23:48:42 +0000332 mExtensionString.append("EGL_ANDROID_get_frame_timestamps ");
Yuxin Hu7fee4412023-03-14 01:43:05 +0000333 }
334
Krzysztof Kosińskif2fc4e92018-04-18 16:29:49 -0700335 hasColorSpaceSupport = findExtension(disp.queryString.extensions, "EGL_KHR_gl_colorspace");
336
337 // Note: CDD requires that devices supporting wide color and/or HDR color also support
338 // the EGL_KHR_gl_colorspace extension.
Sundong Ahn204fb1f2020-04-23 21:56:36 +0900339 bool wideColorBoardConfig = android::sysprop::has_wide_color_display(false);
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600340
341 // Add wide-color extensions if device can support wide-color
Krzysztof Kosińskif2fc4e92018-04-18 16:29:49 -0700342 if (wideColorBoardConfig && hasColorSpaceSupport) {
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600343 mExtensionString.append(
344 "EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear "
Peiyong Line0ff3772018-12-08 22:23:20 -0800345 "EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3 "
346 "EGL_EXT_gl_colorspace_display_p3_passthrough ");
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600347 }
348
Sundong Ahn204fb1f2020-04-23 21:56:36 +0900349 bool hasHdrBoardConfig = android::sysprop::has_HDR_display(false);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700350
Krzysztof Kosińskif2fc4e92018-04-18 16:29:49 -0700351 if (hasHdrBoardConfig && hasColorSpaceSupport) {
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700352 // hasHDRBoardConfig indicates the system is capable of supporting HDR content.
353 // Typically that means there is an HDR capable display attached, but could be
354 // support for attaching an HDR display. In either case, advertise support for
355 // HDR color spaces.
Chris Glover9f746f62023-04-20 10:23:22 +0100356 mExtensionString.append("EGL_EXT_gl_colorspace_bt2020_hlg "
357 "EGL_EXT_gl_colorspace_bt2020_linear "
358 "EGL_EXT_gl_colorspace_bt2020_pq ");
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700359 }
360
Michael Lentine54466bc2015-01-27 09:01:03 -0800361 char const* start = gExtensionString;
Michael Lentine54466bc2015-01-27 09:01:03 -0800362 do {
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400363 // length of the extension name
364 size_t len = strcspn(start, " ");
365 if (len) {
366 // NOTE: we could avoid the copy if we had strnstr.
Mathias Agopian65421432017-03-08 11:49:05 -0800367 const std::string ext(start, len);
Krzysztof Kosińskidbccd222019-05-16 14:10:25 -0700368 // Mitigation for Android P vendor partitions: Adreno 530 driver shipped on
369 // some Android P vendor partitions this extension under the draft KHR name,
370 // but during Khronos review it was decided to demote it to EXT.
371 if (needsAndroidPEglMitigation() && ext == "EGL_EXT_image_gl_colorspace" &&
372 findExtension(disp.queryString.extensions, "EGL_KHR_image_gl_colorspace")) {
373 mExtensionString.append("EGL_EXT_image_gl_colorspace ");
374 }
Yuxin Hu7fee4412023-03-14 01:43:05 +0000375
Mathias Agopian65421432017-03-08 11:49:05 -0800376 if (findExtension(disp.queryString.extensions, ext.c_str(), len)) {
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400377 mExtensionString.append(ext + " ");
Michael Lentine54466bc2015-01-27 09:01:03 -0800378 }
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400379 // advance to the next extension name, skipping the space.
380 start += len;
381 start += (*start == ' ') ? 1 : 0;
Michael Lentine54466bc2015-01-27 09:01:03 -0800382 }
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400383 } while (*start != '\0');
Michael Lentine54466bc2015-01-27 09:01:03 -0800384
385 egl_cache_t::get()->initialize(this);
386
Michael Hoisie4e0f56b2020-04-30 18:40:55 -0400387 finishOnSwap = base::GetBoolProperty("debug.egl.finish", false);
388 traceGpuCompletion = base::GetBoolProperty("debug.egl.traceGpuCompletion", false);
Michael Lentine54466bc2015-01-27 09:01:03 -0800389
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600390 // TODO: If device doesn't provide 1.4 or 1.5 then we'll be
391 // changing the behavior from the past where we always advertise
392 // version 1.4. May need to check that revision is valid
393 // before using cnx->major & cnx->minor
394 if (major != nullptr) *major = cnx->major;
395 if (minor != nullptr) *minor = cnx->minor;
Mathias Agopian518ec112011-05-13 16:21:08 -0700396 }
397
Mathias Agopian65421432017-03-08 11:49:05 -0800398 { // scope for refLock
399 std::unique_lock<std::mutex> _l(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800400 eglIsInitialized = true;
Mathias Agopian65421432017-03-08 11:49:05 -0800401 refCond.notify_all();
Mathias Agopian518ec112011-05-13 16:21:08 -0700402 }
403
Mathias Agopian7773c432012-02-13 20:06:08 -0800404 return EGL_TRUE;
Mathias Agopian518ec112011-05-13 16:21:08 -0700405}
406
407EGLBoolean egl_display_t::terminate() {
Mathias Agopian65421432017-03-08 11:49:05 -0800408 { // scope for refLock
409 std::unique_lock<std::mutex> _rl(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800410 if (refs == 0) {
411 /*
412 * From the EGL spec (3.2):
413 * "Termination of a display that has already been terminated,
414 * (...), is allowed, but the only effect of such a call is
415 * to return EGL_TRUE (...)
416 */
417 return EGL_TRUE;
418 }
Mathias Agopian518ec112011-05-13 16:21:08 -0700419
Michael Lentine54466bc2015-01-27 09:01:03 -0800420 // this is specific to Android, display termination is ref-counted.
Mathias Agopian518ec112011-05-13 16:21:08 -0700421 refs--;
Michael Lentine54466bc2015-01-27 09:01:03 -0800422 if (refs > 0) {
423 return EGL_TRUE;
424 }
Mathias Agopian518ec112011-05-13 16:21:08 -0700425 }
426
427 EGLBoolean res = EGL_FALSE;
Michael Lentine54466bc2015-01-27 09:01:03 -0800428
Mathias Agopian65421432017-03-08 11:49:05 -0800429 { // scope for lock
430 std::lock_guard<std::mutex> _l(lock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800431
432 egl_connection_t* const cnx = &gEGLImpl;
433 if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600434 // If we're using ANGLE reset any custom DisplayPlatform
Peiyong Lin2f51e752023-06-15 22:35:14 +0000435 if (cnx->angleLoaded) {
Tobin Ehlis75ce4772018-11-20 09:48:47 -0700436 angle::resetAnglePlatform(disp.dpy);
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600437 }
Michael Lentine54466bc2015-01-27 09:01:03 -0800438 if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
439 ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
Yiwei Zhang8af03062020-08-12 21:28:15 -0700440 egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
Michael Lentine54466bc2015-01-27 09:01:03 -0800441 }
442 // REVISIT: it's unclear what to do if eglTerminate() fails
443 disp.state = egl_display_t::TERMINATED;
444 res = EGL_TRUE;
Mathias Agopian518ec112011-05-13 16:21:08 -0700445 }
Michael Lentine54466bc2015-01-27 09:01:03 -0800446
Michael Lentine54466bc2015-01-27 09:01:03 -0800447 // Reset the extension string since it will be regenerated if we get
448 // reinitialized.
Mathias Agopian65421432017-03-08 11:49:05 -0800449 mExtensionString.clear();
Michael Lentine54466bc2015-01-27 09:01:03 -0800450
451 // Mark all objects remaining in the list as terminated, unless
452 // there are no reference to them, it which case, we're free to
453 // delete them.
454 size_t count = objects.size();
Dan Alberteacd31f2016-02-02 15:08:34 -0800455 ALOGW_IF(count, "eglTerminate() called w/ %zu objects remaining", count);
Mathias Agopian65421432017-03-08 11:49:05 -0800456 for (auto o : objects) {
Michael Lentine54466bc2015-01-27 09:01:03 -0800457 o->destroy();
458 }
459
460 // this marks all object handles are "terminated"
461 objects.clear();
Mathias Agopian518ec112011-05-13 16:21:08 -0700462 }
463
Mathias Agopian65421432017-03-08 11:49:05 -0800464 { // scope for refLock
465 std::unique_lock<std::mutex> _rl(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800466 eglIsInitialized = false;
Mathias Agopian65421432017-03-08 11:49:05 -0800467 refCond.notify_all();
Mathias Agopian5b287a62011-05-16 18:58:55 -0700468 }
469
Mathias Agopian518ec112011-05-13 16:21:08 -0700470 return res;
471}
472
Yiwei Zhang8af03062020-08-12 21:28:15 -0700473void egl_display_t::loseCurrent(egl_context_t* cur_c) {
Mathias Agopianfb87e542012-01-30 18:20:52 -0800474 if (cur_c) {
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800475 egl_display_t* display = cur_c->getDisplay();
476 if (display) {
477 display->loseCurrentImpl(cur_c);
478 }
479 }
480}
Mathias Agopianfb87e542012-01-30 18:20:52 -0800481
Yiwei Zhang8af03062020-08-12 21:28:15 -0700482void egl_display_t::loseCurrentImpl(egl_context_t* cur_c) {
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800483 // by construction, these are either 0 or valid (possibly terminated)
484 // it should be impossible for these to be invalid
485 ContextRef _cur_c(cur_c);
Yi Kong48a6cd22018-07-18 10:07:09 -0700486 SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : nullptr);
487 SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : nullptr);
Mathias Agopianfb87e542012-01-30 18:20:52 -0800488
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800489 { // scope for the lock
Mathias Agopian65421432017-03-08 11:49:05 -0800490 std::lock_guard<std::mutex> _l(lock);
Mathias Agopianfb87e542012-01-30 18:20:52 -0800491 cur_c->onLooseCurrent();
Mathias Agopianfb87e542012-01-30 18:20:52 -0800492 }
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800493
494 // This cannot be called with the lock held because it might end-up
495 // calling back into EGL (in particular when a surface is destroyed
496 // it calls ANativeWindow::disconnect
497 _cur_c.release();
498 _cur_r.release();
499 _cur_d.release();
Mathias Agopianfb87e542012-01-30 18:20:52 -0800500}
501
Yiwei Zhang8af03062020-08-12 21:28:15 -0700502EGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c, EGLSurface draw,
503 EGLSurface read, EGLContext /*ctx*/, EGLSurface impl_draw,
504 EGLSurface impl_read, EGLContext impl_ctx) {
Mathias Agopianfb87e542012-01-30 18:20:52 -0800505 EGLBoolean result;
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800506
507 // by construction, these are either 0 or valid (possibly terminated)
508 // it should be impossible for these to be invalid
509 ContextRef _cur_c(cur_c);
Yi Kong48a6cd22018-07-18 10:07:09 -0700510 SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : nullptr);
511 SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : nullptr);
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800512
513 { // scope for the lock
Mathias Agopian65421432017-03-08 11:49:05 -0800514 std::lock_guard<std::mutex> _l(lock);
Mathias Agopianfb87e542012-01-30 18:20:52 -0800515 if (c) {
Yiwei Zhang8af03062020-08-12 21:28:15 -0700516 result = c->cnx->egl.eglMakeCurrent(disp.dpy, impl_draw, impl_read, impl_ctx);
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800517 if (result == EGL_TRUE) {
518 c->onMakeCurrent(draw, read);
519 }
520 } else {
Yiwei Zhang8af03062020-08-12 21:28:15 -0700521 result = cur_c->cnx->egl.eglMakeCurrent(disp.dpy, impl_draw, impl_read, impl_ctx);
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800522 if (result == EGL_TRUE) {
523 cur_c->onLooseCurrent();
524 }
Mathias Agopianfb87e542012-01-30 18:20:52 -0800525 }
526 }
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800527
528 if (result == EGL_TRUE) {
529 // This cannot be called with the lock held because it might end-up
530 // calling back into EGL (in particular when a surface is destroyed
531 // it calls ANativeWindow::disconnect
532 _cur_c.release();
533 _cur_r.release();
534 _cur_d.release();
535 }
536
Mathias Agopianfb87e542012-01-30 18:20:52 -0800537 return result;
538}
Mathias Agopian518ec112011-05-13 16:21:08 -0700539
Jesse Hallc2e41222013-08-08 13:40:22 -0700540bool egl_display_t::haveExtension(const char* name, size_t nameLen) const {
541 if (!nameLen) {
542 nameLen = strlen(name);
543 }
Mathias Agopian65421432017-03-08 11:49:05 -0800544 return findExtension(mExtensionString.c_str(), name, nameLen);
Jesse Hallc2e41222013-08-08 13:40:22 -0700545}
546
Yiwei Zhang8af03062020-08-12 21:28:15 -0700547egl_display_t* validate_display(EGLDisplay dpy) {
548 egl_display_t* const dp = get_display(dpy);
549 if (!dp) return setError(EGL_BAD_DISPLAY, (egl_display_t*)nullptr);
550 if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (egl_display_t*)nullptr);
551
552 return dp;
553}
554
555egl_display_t* validate_display_connection(EGLDisplay dpy, egl_connection_t** outCnx) {
556 *outCnx = nullptr;
557 egl_display_t* dp = validate_display(dpy);
558 if (!dp) return dp;
559 *outCnx = &gEGLImpl;
560 if ((*outCnx)->dso == nullptr) {
561 return setError(EGL_BAD_CONFIG, (egl_display_t*)nullptr);
562 }
563 return dp;
564}
565
Mathias Agopian518ec112011-05-13 16:21:08 -0700566}; // namespace android