blob: a6e4a5ce5e70d8c71c566258ce776dac362b65b2 [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 -070041// ----------------------------------------------------------------------------
42namespace android {
43// ----------------------------------------------------------------------------
44
Mathias Agopian4b9511c2011-11-13 23:52:47 -080045static char const * const sVendorString = "Android";
Courtney Goeltzenleuchter015ed672018-07-27 13:43:23 -060046static char const* const sVersionString14 = "1.4 Android META-EGL";
47static char const* const sVersionString15 = "1.5 Android META-EGL";
Mathias Agopiancc2b1562012-05-21 14:01:37 -070048static char const * const sClientApiString = "OpenGL_ES";
Mathias Agopian4b9511c2011-11-13 23:52:47 -080049
Jesse Hall21558da2013-08-06 15:31:22 -070050extern char const * const gBuiltinExtensionString;
Mathias Agopiane9b3dfb2013-03-27 14:30:19 -070051extern char const * const gExtensionString;
Mathias Agopian4b9511c2011-11-13 23:52:47 -080052
Mathias Agopian518ec112011-05-13 16:21:08 -070053extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
54
Mathias Agopian518ec112011-05-13 16:21:08 -070055// ----------------------------------------------------------------------------
56
Courtney Goeltzenleuchtera1e59f12018-03-05 08:19:25 -070057bool findExtension(const char* exts, const char* name, size_t nameLen) {
Jesse Hallc2e41222013-08-08 13:40:22 -070058 if (exts) {
Courtney Goeltzenleuchtera1e59f12018-03-05 08:19:25 -070059 if (!nameLen) {
60 nameLen = strlen(name);
61 }
Kalle Raita7804aa22016-04-18 16:03:37 -070062 for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
63 if (match[nameLen] == '\0' || match[nameLen] == ' ') {
64 return true;
65 }
Jesse Hallc2e41222013-08-08 13:40:22 -070066 }
67 }
68 return false;
69}
70
Krzysztof Kosińskidbccd222019-05-16 14:10:25 -070071bool needsAndroidPEglMitigation() {
Michael Hoisie4e0f56b2020-04-30 18:40:55 -040072 static const int32_t vndk_version = base::GetIntProperty("ro.vndk.version", -1);
Krzysztof Kosińskidbccd222019-05-16 14:10:25 -070073 return vndk_version <= 28;
74}
75
Mathias Agopianb7f9a242017-03-08 22:29:31 -080076int egl_get_init_count(EGLDisplay dpy) {
77 egl_display_t* eglDisplay = egl_display_t::get(dpy);
78 return eglDisplay ? eglDisplay->getRefsCount() : 0;
79}
80
Mathias Agopian518ec112011-05-13 16:21:08 -070081egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
82
83egl_display_t::egl_display_t() :
Michael Lentine54466bc2015-01-27 09:01:03 -080084 magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0), eglIsInitialized(false) {
Mathias Agopian518ec112011-05-13 16:21:08 -070085}
86
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
Mathias Agopian518ec112011-05-13 16:21:08 -070097 uintptr_t index = uintptr_t(dpy)-1U;
Jesse Halld6e99462016-09-28 11:26:57 -070098 if (index >= NUM_DISPLAYS || !sDisplay[index].isValid()) {
99 return nullptr;
100 }
101 return &sDisplay[index];
Mathias Agopian518ec112011-05-13 16:21:08 -0700102}
103
104void egl_display_t::addObject(egl_object_t* object) {
Mathias Agopian65421432017-03-08 11:49:05 -0800105 std::lock_guard<std::mutex> _l(lock);
106 objects.insert(object);
Mathias Agopian518ec112011-05-13 16:21:08 -0700107}
108
Mathias Agopian5b287a62011-05-16 18:58:55 -0700109void egl_display_t::removeObject(egl_object_t* object) {
Mathias Agopian65421432017-03-08 11:49:05 -0800110 std::lock_guard<std::mutex> _l(lock);
111 objects.erase(object);
Mathias Agopian5b287a62011-05-16 18:58:55 -0700112}
113
Mathias Agopianf0480de2011-11-13 20:50:07 -0800114bool egl_display_t::getObject(egl_object_t* object) const {
Mathias Agopian65421432017-03-08 11:49:05 -0800115 std::lock_guard<std::mutex> _l(lock);
116 if (objects.find(object) != objects.end()) {
Mathias Agopianf0480de2011-11-13 20:50:07 -0800117 if (object->getDisplay() == this) {
118 object->incRef();
119 return true;
120 }
Mathias Agopian518ec112011-05-13 16:21:08 -0700121 }
122 return false;
123}
124
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600125EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp,
126 const EGLAttrib* attrib_list) {
Mathias Agopian518ec112011-05-13 16:21:08 -0700127 if (uintptr_t(disp) >= NUM_DISPLAYS)
Yi Kong48a6cd22018-07-18 10:07:09 -0700128 return nullptr;
Mathias Agopian518ec112011-05-13 16:21:08 -0700129
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600130 return sDisplay[uintptr_t(disp)].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 }
146
Courtney Goeltzenleuchterc1a1a862020-04-23 08:19:11 -0600147 attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
148 attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
149
Courtney Goeltzenleuchterc1a1a862020-04-23 08:19:11 -0600150 attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
Michael Hoisie4e0f56b2020-04-30 18:40:55 -0400151 attrs.push_back(base::GetBoolProperty("debug.angle.validation", false));
Courtney Goeltzenleuchterc1a1a862020-04-23 08:19:11 -0600152
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600153 attrs.push_back(EGL_NONE);
Cody Northrop1f00e172018-04-02 11:23:31 -0600154
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600155 dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
156 reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY),
157 attrs.data());
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600158 if (dpy == EGL_NO_DISPLAY) {
159 ALOGE("eglGetPlatformDisplay failed!");
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600160 } else {
Tobin Ehlis75ce4772018-11-20 09:48:47 -0700161 if (!angle::initializeAnglePlatform(dpy)) {
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600162 ALOGE("initializeAnglePlatform failed!");
163 }
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600164 }
Cody Northrop1f00e172018-04-02 11:23:31 -0600165 } else {
166 ALOGE("eglGetDisplay(%p) failed: Unable to look up eglGetPlatformDisplay from ANGLE",
167 display);
168 }
169
170 return dpy;
171}
172
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600173EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display,
174 const EGLAttrib* attrib_list) {
Mathias Agopian65421432017-03-08 11:49:05 -0800175 std::lock_guard<std::mutex> _l(lock);
Jesse Hall1508ae62017-01-19 17:43:26 -0800176 ATRACE_CALL();
Mathias Agopian518ec112011-05-13 16:21:08 -0700177
178 // get our driver loader
179 Loader& loader(Loader::getInstance());
180
Mathias Agopianada798b2012-02-13 17:09:30 -0800181 egl_connection_t* const cnx = &gEGLImpl;
Yiwei Zhang5e21eb32019-06-05 00:26:03 -0700182 if (cnx->dso) {
Cody Northrop1f00e172018-04-02 11:23:31 -0600183 EGLDisplay dpy = EGL_NO_DISPLAY;
184
Charlie Lao840bd532020-01-16 17:34:37 -0800185 if (cnx->useAngle) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600186 EGLint error;
187 dpy = getPlatformDisplayAngle(display, cnx, attrib_list, &error);
188 if (error != EGL_NONE) {
189 return setError(error, dpy);
190 }
Courtney Goeltzenleuchter555f1df2018-09-25 14:34:29 -0600191 }
192 if (dpy == EGL_NO_DISPLAY) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600193 // NOTE: eglGetPlatformDisplay with a empty attribute list
194 // behaves the same as eglGetDisplay
195 if (cnx->egl.eglGetPlatformDisplay) {
196 dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANDROID_KHR, display,
197 attrib_list);
Ben Line17f69b2018-11-05 16:49:28 -0800198 }
199
200 // It is possible that eglGetPlatformDisplay does not have a
201 // working implementation for Android platform; in that case,
202 // one last fallback to eglGetDisplay
203 if(dpy == EGL_NO_DISPLAY) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600204 if (attrib_list) {
205 ALOGW("getPlatformDisplay: unexpected attribute list, attributes ignored");
206 }
207 dpy = cnx->egl.eglGetDisplay(display);
208 }
Cody Northrop1f00e172018-04-02 11:23:31 -0600209 }
210
Mathias Agopianada798b2012-02-13 17:09:30 -0800211 disp.dpy = dpy;
212 if (dpy == EGL_NO_DISPLAY) {
Courtney Goeltzenleuchteree768c22018-10-25 11:43:52 -0600213 loader.close(cnx);
Mathias Agopian518ec112011-05-13 16:21:08 -0700214 }
215 }
216
217 return EGLDisplay(uintptr_t(display) + 1U);
218}
219
220EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
221
Mathias Agopian65421432017-03-08 11:49:05 -0800222 { // scope for refLock
223 std::unique_lock<std::mutex> _l(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800224 refs++;
225 if (refs > 1) {
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600226 // We don't know what to report until we know what the
227 // driver supports. Make sure we are initialized before
228 // returning the version info.
Mathias Agopian65421432017-03-08 11:49:05 -0800229 while(!eglIsInitialized) {
230 refCond.wait(_l);
231 }
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600232 egl_connection_t* const cnx = &gEGLImpl;
233
234 // TODO: If device doesn't provide 1.4 or 1.5 then we'll be
235 // changing the behavior from the past where we always advertise
236 // version 1.4. May need to check that revision is valid
237 // before using cnx->major & cnx->minor
238 if (major != nullptr) *major = cnx->major;
239 if (minor != nullptr) *minor = cnx->minor;
Michael Lentine54466bc2015-01-27 09:01:03 -0800240 return EGL_TRUE;
241 }
Mathias Agopian65421432017-03-08 11:49:05 -0800242 while(eglIsInitialized) {
243 refCond.wait(_l);
244 }
Michael Lentine54466bc2015-01-27 09:01:03 -0800245 }
246
Mathias Agopian65421432017-03-08 11:49:05 -0800247 { // scope for lock
248 std::lock_guard<std::mutex> _l(lock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800249
Michael Lentine54466bc2015-01-27 09:01:03 -0800250 setGLHooksThreadSpecific(&gHooksNoContext);
251
252 // initialize each EGL and
253 // build our own extension string first, based on the extension we know
254 // and the extension supported by our client implementation
255
256 egl_connection_t* const cnx = &gEGLImpl;
257 cnx->major = -1;
258 cnx->minor = -1;
259 if (cnx->dso) {
260 EGLDisplay idpy = disp.dpy;
261 if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
262 //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
263 // idpy, cnx->major, cnx->minor, cnx);
264
265 // display is now initialized
266 disp.state = egl_display_t::INITIALIZED;
267
268 // get the query-strings for this display for each implementation
269 disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
270 EGL_VENDOR);
271 disp.queryString.version = cnx->egl.eglQueryString(idpy,
272 EGL_VERSION);
273 disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
274 EGL_EXTENSIONS);
275 disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
276 EGL_CLIENT_APIS);
277
278 } else {
279 ALOGW("eglInitialize(%p) failed (%s)", idpy,
280 egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
281 }
282 }
283
Sean Callananad9061c2019-03-12 14:07:23 -0700284 if (cnx->minor == 5) {
285 // full list in egl_entries.in
286 if (!cnx->egl.eglCreateImage ||
287 !cnx->egl.eglDestroyImage ||
288 !cnx->egl.eglGetPlatformDisplay ||
289 !cnx->egl.eglCreatePlatformWindowSurface ||
290 !cnx->egl.eglCreatePlatformPixmapSurface ||
291 !cnx->egl.eglCreateSync ||
292 !cnx->egl.eglDestroySync ||
293 !cnx->egl.eglClientWaitSync ||
294 !cnx->egl.eglGetSyncAttrib ||
295 !cnx->egl.eglWaitSync) {
296 ALOGE("Driver indicates EGL 1.5 support, but does not have "
297 "a critical API");
298 cnx->minor = 4;
299 }
300 }
301
Michael Lentine54466bc2015-01-27 09:01:03 -0800302 // the query strings are per-display
Mathias Agopian65421432017-03-08 11:49:05 -0800303 mVendorString = sVendorString;
Courtney Goeltzenleuchter015ed672018-07-27 13:43:23 -0600304 mVersionString.clear();
305 cnx->driverVersion = EGL_MAKE_VERSION(1, 4, 0);
Courtney Goeltzenleuchterf5b5c412019-04-10 17:36:19 -0600306 mVersionString = sVersionString14;
Courtney Goeltzenleuchter015ed672018-07-27 13:43:23 -0600307 if ((cnx->major == 1) && (cnx->minor == 5)) {
308 mVersionString = sVersionString15;
309 cnx->driverVersion = EGL_MAKE_VERSION(1, 5, 0);
Courtney Goeltzenleuchter015ed672018-07-27 13:43:23 -0600310 }
311 if (mVersionString.empty()) {
312 ALOGW("Unexpected driver version: %d.%d, want 1.4 or 1.5", cnx->major, cnx->minor);
313 mVersionString = sVersionString14;
314 }
Mathias Agopian65421432017-03-08 11:49:05 -0800315 mClientApiString = sClientApiString;
Michael Lentine54466bc2015-01-27 09:01:03 -0800316
Mathias Agopian65421432017-03-08 11:49:05 -0800317 mExtensionString = gBuiltinExtensionString;
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600318
Krzysztof Kosińskif2fc4e92018-04-18 16:29:49 -0700319 hasColorSpaceSupport = findExtension(disp.queryString.extensions, "EGL_KHR_gl_colorspace");
320
321 // Note: CDD requires that devices supporting wide color and/or HDR color also support
322 // the EGL_KHR_gl_colorspace extension.
Sundong Ahn204fb1f2020-04-23 21:56:36 +0900323 bool wideColorBoardConfig = android::sysprop::has_wide_color_display(false);
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600324
325 // Add wide-color extensions if device can support wide-color
Krzysztof Kosińskif2fc4e92018-04-18 16:29:49 -0700326 if (wideColorBoardConfig && hasColorSpaceSupport) {
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600327 mExtensionString.append(
328 "EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear "
Peiyong Line0ff3772018-12-08 22:23:20 -0800329 "EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3 "
330 "EGL_EXT_gl_colorspace_display_p3_passthrough ");
Courtney Goeltzenleuchtere5d6f992017-07-07 14:55:40 -0600331 }
332
Sundong Ahn204fb1f2020-04-23 21:56:36 +0900333 bool hasHdrBoardConfig = android::sysprop::has_HDR_display(false);
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700334
Krzysztof Kosińskif2fc4e92018-04-18 16:29:49 -0700335 if (hasHdrBoardConfig && hasColorSpaceSupport) {
Courtney Goeltzenleuchter12ffe092017-11-16 14:27:48 -0700336 // hasHDRBoardConfig indicates the system is capable of supporting HDR content.
337 // Typically that means there is an HDR capable display attached, but could be
338 // support for attaching an HDR display. In either case, advertise support for
339 // HDR color spaces.
340 mExtensionString.append(
341 "EGL_EXT_gl_colorspace_bt2020_linear EGL_EXT_gl_colorspace_bt2020_pq ");
342 }
343
Michael Lentine54466bc2015-01-27 09:01:03 -0800344 char const* start = gExtensionString;
Michael Lentine54466bc2015-01-27 09:01:03 -0800345 do {
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400346 // length of the extension name
347 size_t len = strcspn(start, " ");
348 if (len) {
349 // NOTE: we could avoid the copy if we had strnstr.
Mathias Agopian65421432017-03-08 11:49:05 -0800350 const std::string ext(start, len);
Krzysztof Kosińskidbccd222019-05-16 14:10:25 -0700351 // Mitigation for Android P vendor partitions: Adreno 530 driver shipped on
352 // some Android P vendor partitions this extension under the draft KHR name,
353 // but during Khronos review it was decided to demote it to EXT.
354 if (needsAndroidPEglMitigation() && ext == "EGL_EXT_image_gl_colorspace" &&
355 findExtension(disp.queryString.extensions, "EGL_KHR_image_gl_colorspace")) {
356 mExtensionString.append("EGL_EXT_image_gl_colorspace ");
357 }
Mathias Agopian65421432017-03-08 11:49:05 -0800358 if (findExtension(disp.queryString.extensions, ext.c_str(), len)) {
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400359 mExtensionString.append(ext + " ");
Michael Lentine54466bc2015-01-27 09:01:03 -0800360 }
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400361 // advance to the next extension name, skipping the space.
362 start += len;
363 start += (*start == ' ') ? 1 : 0;
Michael Lentine54466bc2015-01-27 09:01:03 -0800364 }
Nicolas Capensecc0c9a2015-10-30 12:55:21 -0400365 } while (*start != '\0');
Michael Lentine54466bc2015-01-27 09:01:03 -0800366
367 egl_cache_t::get()->initialize(this);
368
Michael Hoisie4e0f56b2020-04-30 18:40:55 -0400369 finishOnSwap = base::GetBoolProperty("debug.egl.finish", false);
370 traceGpuCompletion = base::GetBoolProperty("debug.egl.traceGpuCompletion", false);
Michael Lentine54466bc2015-01-27 09:01:03 -0800371
Courtney Goeltzenleuchter4adf75b2018-10-11 13:09:40 -0600372 // TODO: If device doesn't provide 1.4 or 1.5 then we'll be
373 // changing the behavior from the past where we always advertise
374 // version 1.4. May need to check that revision is valid
375 // before using cnx->major & cnx->minor
376 if (major != nullptr) *major = cnx->major;
377 if (minor != nullptr) *minor = cnx->minor;
Mathias Agopian518ec112011-05-13 16:21:08 -0700378 }
379
Mathias Agopian65421432017-03-08 11:49:05 -0800380 { // scope for refLock
381 std::unique_lock<std::mutex> _l(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800382 eglIsInitialized = true;
Mathias Agopian65421432017-03-08 11:49:05 -0800383 refCond.notify_all();
Mathias Agopian518ec112011-05-13 16:21:08 -0700384 }
385
Mathias Agopian7773c432012-02-13 20:06:08 -0800386 return EGL_TRUE;
Mathias Agopian518ec112011-05-13 16:21:08 -0700387}
388
389EGLBoolean egl_display_t::terminate() {
390
Mathias Agopian65421432017-03-08 11:49:05 -0800391 { // scope for refLock
392 std::unique_lock<std::mutex> _rl(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800393 if (refs == 0) {
394 /*
395 * From the EGL spec (3.2):
396 * "Termination of a display that has already been terminated,
397 * (...), is allowed, but the only effect of such a call is
398 * to return EGL_TRUE (...)
399 */
400 return EGL_TRUE;
401 }
Mathias Agopian518ec112011-05-13 16:21:08 -0700402
Michael Lentine54466bc2015-01-27 09:01:03 -0800403 // this is specific to Android, display termination is ref-counted.
Mathias Agopian518ec112011-05-13 16:21:08 -0700404 refs--;
Michael Lentine54466bc2015-01-27 09:01:03 -0800405 if (refs > 0) {
406 return EGL_TRUE;
407 }
Mathias Agopian518ec112011-05-13 16:21:08 -0700408 }
409
410 EGLBoolean res = EGL_FALSE;
Michael Lentine54466bc2015-01-27 09:01:03 -0800411
Mathias Agopian65421432017-03-08 11:49:05 -0800412 { // scope for lock
413 std::lock_guard<std::mutex> _l(lock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800414
415 egl_connection_t* const cnx = &gEGLImpl;
416 if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600417 // If we're using ANGLE reset any custom DisplayPlatform
Charlie Lao840bd532020-01-16 17:34:37 -0800418 if (cnx->useAngle) {
Tobin Ehlis75ce4772018-11-20 09:48:47 -0700419 angle::resetAnglePlatform(disp.dpy);
Tobin Ehlis96a184d2018-07-18 16:14:07 -0600420 }
Michael Lentine54466bc2015-01-27 09:01:03 -0800421 if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
422 ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
423 egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
424 }
425 // REVISIT: it's unclear what to do if eglTerminate() fails
426 disp.state = egl_display_t::TERMINATED;
427 res = EGL_TRUE;
Mathias Agopian518ec112011-05-13 16:21:08 -0700428 }
Michael Lentine54466bc2015-01-27 09:01:03 -0800429
Michael Lentine54466bc2015-01-27 09:01:03 -0800430 // Reset the extension string since it will be regenerated if we get
431 // reinitialized.
Mathias Agopian65421432017-03-08 11:49:05 -0800432 mExtensionString.clear();
Michael Lentine54466bc2015-01-27 09:01:03 -0800433
434 // Mark all objects remaining in the list as terminated, unless
435 // there are no reference to them, it which case, we're free to
436 // delete them.
437 size_t count = objects.size();
Dan Alberteacd31f2016-02-02 15:08:34 -0800438 ALOGW_IF(count, "eglTerminate() called w/ %zu objects remaining", count);
Mathias Agopian65421432017-03-08 11:49:05 -0800439 for (auto o : objects) {
Michael Lentine54466bc2015-01-27 09:01:03 -0800440 o->destroy();
441 }
442
443 // this marks all object handles are "terminated"
444 objects.clear();
Mathias Agopian518ec112011-05-13 16:21:08 -0700445 }
446
Mathias Agopian65421432017-03-08 11:49:05 -0800447 { // scope for refLock
448 std::unique_lock<std::mutex> _rl(refLock);
Michael Lentine54466bc2015-01-27 09:01:03 -0800449 eglIsInitialized = false;
Mathias Agopian65421432017-03-08 11:49:05 -0800450 refCond.notify_all();
Mathias Agopian5b287a62011-05-16 18:58:55 -0700451 }
452
Mathias Agopian518ec112011-05-13 16:21:08 -0700453 return res;
454}
455
Mathias Agopianfb87e542012-01-30 18:20:52 -0800456void egl_display_t::loseCurrent(egl_context_t * cur_c)
457{
458 if (cur_c) {
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800459 egl_display_t* display = cur_c->getDisplay();
460 if (display) {
461 display->loseCurrentImpl(cur_c);
462 }
463 }
464}
Mathias Agopianfb87e542012-01-30 18:20:52 -0800465
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800466void egl_display_t::loseCurrentImpl(egl_context_t * cur_c)
467{
468 // by construction, these are either 0 or valid (possibly terminated)
469 // it should be impossible for these to be invalid
470 ContextRef _cur_c(cur_c);
Yi Kong48a6cd22018-07-18 10:07:09 -0700471 SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : nullptr);
472 SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : nullptr);
Mathias Agopianfb87e542012-01-30 18:20:52 -0800473
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800474 { // scope for the lock
Mathias Agopian65421432017-03-08 11:49:05 -0800475 std::lock_guard<std::mutex> _l(lock);
Mathias Agopianfb87e542012-01-30 18:20:52 -0800476 cur_c->onLooseCurrent();
477
Mathias Agopianfb87e542012-01-30 18:20:52 -0800478 }
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800479
480 // This cannot be called with the lock held because it might end-up
481 // calling back into EGL (in particular when a surface is destroyed
482 // it calls ANativeWindow::disconnect
483 _cur_c.release();
484 _cur_r.release();
485 _cur_d.release();
Mathias Agopianfb87e542012-01-30 18:20:52 -0800486}
487
488EGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -0700489 EGLSurface draw, EGLSurface read, EGLContext /*ctx*/,
Mathias Agopianfb87e542012-01-30 18:20:52 -0800490 EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
491{
Mathias Agopianfb87e542012-01-30 18:20:52 -0800492 EGLBoolean result;
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800493
494 // by construction, these are either 0 or valid (possibly terminated)
495 // it should be impossible for these to be invalid
496 ContextRef _cur_c(cur_c);
Yi Kong48a6cd22018-07-18 10:07:09 -0700497 SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : nullptr);
498 SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : nullptr);
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800499
500 { // scope for the lock
Mathias Agopian65421432017-03-08 11:49:05 -0800501 std::lock_guard<std::mutex> _l(lock);
Mathias Agopianfb87e542012-01-30 18:20:52 -0800502 if (c) {
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800503 result = c->cnx->egl.eglMakeCurrent(
Mathias Agopianada798b2012-02-13 17:09:30 -0800504 disp.dpy, impl_draw, impl_read, impl_ctx);
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800505 if (result == EGL_TRUE) {
506 c->onMakeCurrent(draw, read);
507 }
508 } else {
509 result = cur_c->cnx->egl.eglMakeCurrent(
Mathias Agopianada798b2012-02-13 17:09:30 -0800510 disp.dpy, impl_draw, impl_read, impl_ctx);
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800511 if (result == EGL_TRUE) {
512 cur_c->onLooseCurrent();
513 }
Mathias Agopianfb87e542012-01-30 18:20:52 -0800514 }
515 }
Mathias Agopiana4b2c042012-02-03 15:24:51 -0800516
517 if (result == EGL_TRUE) {
518 // This cannot be called with the lock held because it might end-up
519 // calling back into EGL (in particular when a surface is destroyed
520 // it calls ANativeWindow::disconnect
521 _cur_c.release();
522 _cur_r.release();
523 _cur_d.release();
524 }
525
Mathias Agopianfb87e542012-01-30 18:20:52 -0800526 return result;
527}
Mathias Agopian518ec112011-05-13 16:21:08 -0700528
Jesse Hallc2e41222013-08-08 13:40:22 -0700529bool egl_display_t::haveExtension(const char* name, size_t nameLen) const {
530 if (!nameLen) {
531 nameLen = strlen(name);
532 }
Mathias Agopian65421432017-03-08 11:49:05 -0800533 return findExtension(mExtensionString.c_str(), name, nameLen);
Jesse Hallc2e41222013-08-08 13:40:22 -0700534}
535
Jesse Halla0fef1c2012-04-17 12:02:26 -0700536// ----------------------------------------------------------------------------
Mathias Agopian518ec112011-05-13 16:21:08 -0700537}; // namespace android
538// ----------------------------------------------------------------------------