1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc. 4bf215546Sopenharmony_ci * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 5bf215546Sopenharmony_ci * Copyright 2010-2011 LunarG, Inc. 6bf215546Sopenharmony_ci * All Rights Reserved. 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 10bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 11bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 12bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 13bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 14bf215546Sopenharmony_ci * the following conditions: 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 17bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 18bf215546Sopenharmony_ci * of the Software. 19bf215546Sopenharmony_ci * 20bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 27bf215546Sopenharmony_ci * 28bf215546Sopenharmony_ci **************************************************************************/ 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci/** 32bf215546Sopenharmony_ci * Public EGL API entrypoints 33bf215546Sopenharmony_ci * 34bf215546Sopenharmony_ci * Generally, we use the EGLDisplay parameter as a key to lookup the 35bf215546Sopenharmony_ci * appropriate device driver handle, then jump though the driver's 36bf215546Sopenharmony_ci * dispatch table to handle the function. 37bf215546Sopenharmony_ci * 38bf215546Sopenharmony_ci * That allows us the option of supporting multiple, simultaneous, 39bf215546Sopenharmony_ci * heterogeneous hardware devices in the future. 40bf215546Sopenharmony_ci * 41bf215546Sopenharmony_ci * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are 42bf215546Sopenharmony_ci * opaque handles. Internal objects are linked to a display to 43bf215546Sopenharmony_ci * create the handles. 44bf215546Sopenharmony_ci * 45bf215546Sopenharmony_ci * For each public API entry point, the opaque handles are looked up 46bf215546Sopenharmony_ci * before being dispatched to the drivers. When it fails to look up 47bf215546Sopenharmony_ci * a handle, one of 48bf215546Sopenharmony_ci * 49bf215546Sopenharmony_ci * EGL_BAD_DISPLAY 50bf215546Sopenharmony_ci * EGL_BAD_CONFIG 51bf215546Sopenharmony_ci * EGL_BAD_CONTEXT 52bf215546Sopenharmony_ci * EGL_BAD_SURFACE 53bf215546Sopenharmony_ci * EGL_BAD_SCREEN_MESA 54bf215546Sopenharmony_ci * EGL_BAD_MODE_MESA 55bf215546Sopenharmony_ci * 56bf215546Sopenharmony_ci * is generated and the driver function is not called. An 57bf215546Sopenharmony_ci * uninitialized EGLDisplay has no driver associated with it. When 58bf215546Sopenharmony_ci * such display is detected, 59bf215546Sopenharmony_ci * 60bf215546Sopenharmony_ci * EGL_NOT_INITIALIZED 61bf215546Sopenharmony_ci * 62bf215546Sopenharmony_ci * is generated. 63bf215546Sopenharmony_ci * 64bf215546Sopenharmony_ci * Some of the entry points use current display, context, or surface 65bf215546Sopenharmony_ci * implicitly. For such entry points, the implicit objects are also 66bf215546Sopenharmony_ci * checked before calling the driver function. Other than the 67bf215546Sopenharmony_ci * errors listed above, 68bf215546Sopenharmony_ci * 69bf215546Sopenharmony_ci * EGL_BAD_CURRENT_SURFACE 70bf215546Sopenharmony_ci * 71bf215546Sopenharmony_ci * may also be generated. 72bf215546Sopenharmony_ci * 73bf215546Sopenharmony_ci * Notes on naming conventions: 74bf215546Sopenharmony_ci * 75bf215546Sopenharmony_ci * eglFooBar - public EGL function 76bf215546Sopenharmony_ci * EGL_FOO_BAR - public EGL token 77bf215546Sopenharmony_ci * EGLDatatype - public EGL datatype 78bf215546Sopenharmony_ci * 79bf215546Sopenharmony_ci * _eglFooBar - private EGL function 80bf215546Sopenharmony_ci * _EGLDatatype - private EGL datatype, typedef'd struct 81bf215546Sopenharmony_ci * _egl_struct - private EGL struct, non-typedef'd 82bf215546Sopenharmony_ci * 83bf215546Sopenharmony_ci */ 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci#ifdef USE_LIBGLVND 87bf215546Sopenharmony_ci#define EGLAPI 88bf215546Sopenharmony_ci#undef PUBLIC 89bf215546Sopenharmony_ci#define PUBLIC 90bf215546Sopenharmony_ci#endif 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci#include <assert.h> 93bf215546Sopenharmony_ci#include <stdio.h> 94bf215546Sopenharmony_ci#include <stdlib.h> 95bf215546Sopenharmony_ci#include <string.h> 96bf215546Sopenharmony_ci#include "c11/threads.h" 97bf215546Sopenharmony_ci#include "util/debug.h" 98bf215546Sopenharmony_ci#include "util/macros.h" 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci#include "egldefines.h" 101bf215546Sopenharmony_ci#include "eglglobals.h" 102bf215546Sopenharmony_ci#include "eglcontext.h" 103bf215546Sopenharmony_ci#include "egldisplay.h" 104bf215546Sopenharmony_ci#include "egltypedefs.h" 105bf215546Sopenharmony_ci#include "eglcurrent.h" 106bf215546Sopenharmony_ci#include "egldevice.h" 107bf215546Sopenharmony_ci#include "egldriver.h" 108bf215546Sopenharmony_ci#include "eglsurface.h" 109bf215546Sopenharmony_ci#include "eglconfig.h" 110bf215546Sopenharmony_ci#include "eglimage.h" 111bf215546Sopenharmony_ci#include "eglsync.h" 112bf215546Sopenharmony_ci#include "egllog.h" 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci#include "GL/mesa_glinterop.h" 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci/** 117bf215546Sopenharmony_ci * Macros to help return an API entrypoint. 118bf215546Sopenharmony_ci * 119bf215546Sopenharmony_ci * These macros will unlock the display and record the error code. 120bf215546Sopenharmony_ci */ 121bf215546Sopenharmony_ci#define RETURN_EGL_ERROR(disp, err, ret) \ 122bf215546Sopenharmony_ci do { \ 123bf215546Sopenharmony_ci if (disp) \ 124bf215546Sopenharmony_ci _eglUnlockDisplay(disp); \ 125bf215546Sopenharmony_ci /* EGL error codes are non-zero */ \ 126bf215546Sopenharmony_ci if (err) \ 127bf215546Sopenharmony_ci _eglError(err, __func__); \ 128bf215546Sopenharmony_ci return ret; \ 129bf215546Sopenharmony_ci } while (0) 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci#define RETURN_EGL_SUCCESS(disp, ret) \ 132bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret) 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci/* record EGL_SUCCESS only when ret evaluates to true */ 135bf215546Sopenharmony_ci#define RETURN_EGL_EVAL(disp, ret) \ 136bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret) 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci/* 140bf215546Sopenharmony_ci * A bunch of macros and checks to simplify error checking. 141bf215546Sopenharmony_ci */ 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci#define _EGL_CHECK_DISPLAY(disp, ret) \ 144bf215546Sopenharmony_ci do { \ 145bf215546Sopenharmony_ci if (!_eglCheckDisplay(disp, __func__)) \ 146bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, 0, ret); \ 147bf215546Sopenharmony_ci } while (0) 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci#define _EGL_CHECK_OBJECT(disp, type, obj, ret) \ 150bf215546Sopenharmony_ci do { \ 151bf215546Sopenharmony_ci if (!_eglCheck ## type(disp, obj, __func__)) \ 152bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, 0, ret); \ 153bf215546Sopenharmony_ci } while (0) 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci#define _EGL_CHECK_SURFACE(disp, surf, ret) \ 156bf215546Sopenharmony_ci _EGL_CHECK_OBJECT(disp, Surface, surf, ret) 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci#define _EGL_CHECK_CONTEXT(disp, context, ret) \ 159bf215546Sopenharmony_ci _EGL_CHECK_OBJECT(disp, Context, context, ret) 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci#define _EGL_CHECK_CONFIG(disp, conf, ret) \ 162bf215546Sopenharmony_ci _EGL_CHECK_OBJECT(disp, Config, conf, ret) 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci#define _EGL_CHECK_SYNC(disp, s, ret) \ 165bf215546Sopenharmony_ci _EGL_CHECK_OBJECT(disp, Sync, s, ret) 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ciextern const _EGLDriver _eglDriver; 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_cistruct _egl_entrypoint { 172bf215546Sopenharmony_ci const char *name; 173bf215546Sopenharmony_ci _EGLProc function; 174bf215546Sopenharmony_ci}; 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_cistatic inline bool 178bf215546Sopenharmony_ci_eglCheckDisplay(_EGLDisplay *disp, const char *msg) 179bf215546Sopenharmony_ci{ 180bf215546Sopenharmony_ci if (!disp) { 181bf215546Sopenharmony_ci _eglError(EGL_BAD_DISPLAY, msg); 182bf215546Sopenharmony_ci return false; 183bf215546Sopenharmony_ci } 184bf215546Sopenharmony_ci if (!disp->Initialized) { 185bf215546Sopenharmony_ci _eglError(EGL_NOT_INITIALIZED, msg); 186bf215546Sopenharmony_ci return false; 187bf215546Sopenharmony_ci } 188bf215546Sopenharmony_ci return true; 189bf215546Sopenharmony_ci} 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_cistatic inline bool 193bf215546Sopenharmony_ci_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg) 194bf215546Sopenharmony_ci{ 195bf215546Sopenharmony_ci if (!_eglCheckDisplay(disp, msg)) 196bf215546Sopenharmony_ci return false; 197bf215546Sopenharmony_ci if (!surf) { 198bf215546Sopenharmony_ci _eglError(EGL_BAD_SURFACE, msg); 199bf215546Sopenharmony_ci return false; 200bf215546Sopenharmony_ci } 201bf215546Sopenharmony_ci return true; 202bf215546Sopenharmony_ci} 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_cistatic inline bool 206bf215546Sopenharmony_ci_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg) 207bf215546Sopenharmony_ci{ 208bf215546Sopenharmony_ci if (!_eglCheckDisplay(disp, msg)) 209bf215546Sopenharmony_ci return false; 210bf215546Sopenharmony_ci if (!context) { 211bf215546Sopenharmony_ci _eglError(EGL_BAD_CONTEXT, msg); 212bf215546Sopenharmony_ci return false; 213bf215546Sopenharmony_ci } 214bf215546Sopenharmony_ci return true; 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_cistatic inline bool 219bf215546Sopenharmony_ci_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) 220bf215546Sopenharmony_ci{ 221bf215546Sopenharmony_ci if (!_eglCheckDisplay(disp, msg)) 222bf215546Sopenharmony_ci return false; 223bf215546Sopenharmony_ci if (!conf) { 224bf215546Sopenharmony_ci _eglError(EGL_BAD_CONFIG, msg); 225bf215546Sopenharmony_ci return false; 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci return true; 228bf215546Sopenharmony_ci} 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_cistatic inline bool 232bf215546Sopenharmony_ci_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg) 233bf215546Sopenharmony_ci{ 234bf215546Sopenharmony_ci if (!_eglCheckDisplay(disp, msg)) 235bf215546Sopenharmony_ci return false; 236bf215546Sopenharmony_ci if (!s) { 237bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, msg); 238bf215546Sopenharmony_ci return false; 239bf215546Sopenharmony_ci } 240bf215546Sopenharmony_ci return true; 241bf215546Sopenharmony_ci} 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci/** 245bf215546Sopenharmony_ci * Lookup and lock a display. 246bf215546Sopenharmony_ci */ 247bf215546Sopenharmony_cistatic inline _EGLDisplay * 248bf215546Sopenharmony_ci_eglLockDisplay(EGLDisplay dpy) 249bf215546Sopenharmony_ci{ 250bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLookupDisplay(dpy); 251bf215546Sopenharmony_ci if (disp) 252bf215546Sopenharmony_ci mtx_lock(&disp->Mutex); 253bf215546Sopenharmony_ci return disp; 254bf215546Sopenharmony_ci} 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci/** 258bf215546Sopenharmony_ci * Unlock a display. 259bf215546Sopenharmony_ci */ 260bf215546Sopenharmony_cistatic inline void 261bf215546Sopenharmony_ci_eglUnlockDisplay(_EGLDisplay *disp) 262bf215546Sopenharmony_ci{ 263bf215546Sopenharmony_ci mtx_unlock(&disp->Mutex); 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_cistatic EGLBoolean 267bf215546Sopenharmony_ci_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object) 268bf215546Sopenharmony_ci{ 269bf215546Sopenharmony_ci _EGLThreadInfo *thr = _eglGetCurrentThread(); 270bf215546Sopenharmony_ci thr->CurrentFuncName = funcName; 271bf215546Sopenharmony_ci thr->CurrentObjectLabel = NULL; 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci if (objectType == EGL_OBJECT_THREAD_KHR) 274bf215546Sopenharmony_ci thr->CurrentObjectLabel = thr->Label; 275bf215546Sopenharmony_ci else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp) 276bf215546Sopenharmony_ci thr->CurrentObjectLabel = disp->Label; 277bf215546Sopenharmony_ci else if (object) 278bf215546Sopenharmony_ci thr->CurrentObjectLabel = object->Label; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci return EGL_TRUE; 281bf215546Sopenharmony_ci} 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci#define _EGL_FUNC_START(disp, objectType, object, ret) \ 284bf215546Sopenharmony_ci do { \ 285bf215546Sopenharmony_ci if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \ 286bf215546Sopenharmony_ci if (disp) \ 287bf215546Sopenharmony_ci _eglUnlockDisplay(disp); \ 288bf215546Sopenharmony_ci return ret; \ 289bf215546Sopenharmony_ci } \ 290bf215546Sopenharmony_ci } while(0) 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci/** 293bf215546Sopenharmony_ci * Convert an attribute list from EGLint[] to EGLAttrib[]. 294bf215546Sopenharmony_ci * 295bf215546Sopenharmony_ci * Return an EGL error code. The output parameter out_attrib_list is modified 296bf215546Sopenharmony_ci * only on success. 297bf215546Sopenharmony_ci */ 298bf215546Sopenharmony_cistatic EGLint 299bf215546Sopenharmony_ci_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list) 300bf215546Sopenharmony_ci{ 301bf215546Sopenharmony_ci size_t len = 0; 302bf215546Sopenharmony_ci EGLAttrib *attrib_list; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci if (int_list) { 305bf215546Sopenharmony_ci while (int_list[2*len] != EGL_NONE) 306bf215546Sopenharmony_ci ++len; 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci if (len == 0) { 310bf215546Sopenharmony_ci *out_attrib_list = NULL; 311bf215546Sopenharmony_ci return EGL_SUCCESS; 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib)) 315bf215546Sopenharmony_ci return EGL_BAD_ALLOC; 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib)); 318bf215546Sopenharmony_ci if (!attrib_list) 319bf215546Sopenharmony_ci return EGL_BAD_ALLOC; 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci for (size_t i = 0; i < len; ++i) { 322bf215546Sopenharmony_ci attrib_list[2*i + 0] = int_list[2*i + 0]; 323bf215546Sopenharmony_ci attrib_list[2*i + 1] = int_list[2*i + 1]; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci attrib_list[2*len] = EGL_NONE; 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci *out_attrib_list = attrib_list; 329bf215546Sopenharmony_ci return EGL_SUCCESS; 330bf215546Sopenharmony_ci} 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_cistatic EGLint * 334bf215546Sopenharmony_ci_eglConvertAttribsToInt(const EGLAttrib *attr_list) 335bf215546Sopenharmony_ci{ 336bf215546Sopenharmony_ci size_t size = _eglNumAttribs(attr_list); 337bf215546Sopenharmony_ci EGLint *int_attribs = NULL; 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci /* Convert attributes from EGLAttrib[] to EGLint[] */ 340bf215546Sopenharmony_ci if (size) { 341bf215546Sopenharmony_ci int_attribs = calloc(size, sizeof(int_attribs[0])); 342bf215546Sopenharmony_ci if (!int_attribs) 343bf215546Sopenharmony_ci return NULL; 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci for (size_t i = 0; i < size; i++) 346bf215546Sopenharmony_ci int_attribs[i] = attr_list[i]; 347bf215546Sopenharmony_ci } 348bf215546Sopenharmony_ci return int_attribs; 349bf215546Sopenharmony_ci} 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci/** 353bf215546Sopenharmony_ci * This is typically the first EGL function that an application calls. 354bf215546Sopenharmony_ci * It associates a private _EGLDisplay object to the native display. 355bf215546Sopenharmony_ci */ 356bf215546Sopenharmony_ciEGLDisplay EGLAPIENTRY 357bf215546Sopenharmony_cieglGetDisplay(EGLNativeDisplayType nativeDisplay) 358bf215546Sopenharmony_ci{ 359bf215546Sopenharmony_ci _EGLPlatformType plat; 360bf215546Sopenharmony_ci _EGLDisplay *disp; 361bf215546Sopenharmony_ci void *native_display_ptr; 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay)); 366bf215546Sopenharmony_ci native_display_ptr = (void*) nativeDisplay; 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci plat = _eglGetNativePlatform(native_display_ptr); 369bf215546Sopenharmony_ci disp = _eglFindDisplay(plat, native_display_ptr, NULL); 370bf215546Sopenharmony_ci return _eglGetDisplayHandle(disp); 371bf215546Sopenharmony_ci} 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_cistatic EGLDisplay 374bf215546Sopenharmony_ci_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display, 375bf215546Sopenharmony_ci const EGLAttrib *attrib_list) 376bf215546Sopenharmony_ci{ 377bf215546Sopenharmony_ci _EGLDisplay *disp; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci switch (platform) { 380bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM 381bf215546Sopenharmony_ci case EGL_PLATFORM_X11_EXT: 382bf215546Sopenharmony_ci disp = _eglGetX11Display((Display*) native_display, attrib_list); 383bf215546Sopenharmony_ci break; 384bf215546Sopenharmony_ci#endif 385bf215546Sopenharmony_ci#ifdef HAVE_XCB_PLATFORM 386bf215546Sopenharmony_ci case EGL_PLATFORM_XCB_EXT: 387bf215546Sopenharmony_ci disp = _eglGetXcbDisplay((xcb_connection_t*) native_display, attrib_list); 388bf215546Sopenharmony_ci break; 389bf215546Sopenharmony_ci#endif 390bf215546Sopenharmony_ci#ifdef HAVE_DRM_PLATFORM 391bf215546Sopenharmony_ci case EGL_PLATFORM_GBM_MESA: 392bf215546Sopenharmony_ci disp = _eglGetGbmDisplay((struct gbm_device*) native_display, 393bf215546Sopenharmony_ci attrib_list); 394bf215546Sopenharmony_ci break; 395bf215546Sopenharmony_ci#endif 396bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM 397bf215546Sopenharmony_ci case EGL_PLATFORM_WAYLAND_EXT: 398bf215546Sopenharmony_ci disp = _eglGetWaylandDisplay((struct wl_display*) native_display, 399bf215546Sopenharmony_ci attrib_list); 400bf215546Sopenharmony_ci break; 401bf215546Sopenharmony_ci#endif 402bf215546Sopenharmony_ci case EGL_PLATFORM_SURFACELESS_MESA: 403bf215546Sopenharmony_ci disp = _eglGetSurfacelessDisplay(native_display, attrib_list); 404bf215546Sopenharmony_ci break; 405bf215546Sopenharmony_ci#ifdef HAVE_ANDROID_PLATFORM 406bf215546Sopenharmony_ci case EGL_PLATFORM_ANDROID_KHR: 407bf215546Sopenharmony_ci disp = _eglGetAndroidDisplay(native_display, attrib_list); 408bf215546Sopenharmony_ci break; 409bf215546Sopenharmony_ci#endif 410bf215546Sopenharmony_ci#ifdef HAVE_OHOS_PLATFORM 411bf215546Sopenharmony_ci case EGL_PLATFORM_OHOS_KHR: 412bf215546Sopenharmony_ci disp = _eglGetOHOSDisplay(native_display, attrib_list); 413bf215546Sopenharmony_ci break; 414bf215546Sopenharmony_ci#endif 415bf215546Sopenharmony_ci case EGL_PLATFORM_DEVICE_EXT: 416bf215546Sopenharmony_ci disp = _eglGetDeviceDisplay(native_display, attrib_list); 417bf215546Sopenharmony_ci break; 418bf215546Sopenharmony_ci default: 419bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL); 420bf215546Sopenharmony_ci } 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci return _eglGetDisplayHandle(disp); 423bf215546Sopenharmony_ci} 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_cistatic EGLDisplay EGLAPIENTRY 426bf215546Sopenharmony_cieglGetPlatformDisplayEXT(EGLenum platform, void *native_display, 427bf215546Sopenharmony_ci const EGLint *int_attribs) 428bf215546Sopenharmony_ci{ 429bf215546Sopenharmony_ci EGLAttrib *attrib_list; 430bf215546Sopenharmony_ci EGLDisplay disp; 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci if (_eglConvertIntsToAttribs(int_attribs, &attrib_list) != EGL_SUCCESS) 435bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL); 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list); 438bf215546Sopenharmony_ci free(attrib_list); 439bf215546Sopenharmony_ci return disp; 440bf215546Sopenharmony_ci} 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ciEGLDisplay EGLAPIENTRY 443bf215546Sopenharmony_cieglGetPlatformDisplay(EGLenum platform, void *native_display, 444bf215546Sopenharmony_ci const EGLAttrib *attrib_list) 445bf215546Sopenharmony_ci{ 446bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY); 447bf215546Sopenharmony_ci return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list); 448bf215546Sopenharmony_ci} 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci/** 451bf215546Sopenharmony_ci * Copy the extension into the string and update the string pointer. 452bf215546Sopenharmony_ci */ 453bf215546Sopenharmony_cistatic EGLint 454bf215546Sopenharmony_ci_eglAppendExtension(char **str, const char *ext) 455bf215546Sopenharmony_ci{ 456bf215546Sopenharmony_ci char *s = *str; 457bf215546Sopenharmony_ci size_t len = strlen(ext); 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci if (s) { 460bf215546Sopenharmony_ci memcpy(s, ext, len); 461bf215546Sopenharmony_ci s[len++] = ' '; 462bf215546Sopenharmony_ci s[len] = '\0'; 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci *str += len; 465bf215546Sopenharmony_ci } 466bf215546Sopenharmony_ci else { 467bf215546Sopenharmony_ci len++; 468bf215546Sopenharmony_ci } 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci return (EGLint) len; 471bf215546Sopenharmony_ci} 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci/** 474bf215546Sopenharmony_ci * Examine the individual extension enable/disable flags and recompute 475bf215546Sopenharmony_ci * the driver's Extensions string. 476bf215546Sopenharmony_ci */ 477bf215546Sopenharmony_cistatic void 478bf215546Sopenharmony_ci_eglCreateExtensionsString(_EGLDisplay *disp) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci#define _EGL_CHECK_EXTENSION(ext) \ 481bf215546Sopenharmony_ci do { \ 482bf215546Sopenharmony_ci if (disp->Extensions.ext) { \ 483bf215546Sopenharmony_ci _eglAppendExtension(&exts, "EGL_" #ext); \ 484bf215546Sopenharmony_ci assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \ 485bf215546Sopenharmony_ci } \ 486bf215546Sopenharmony_ci } while (0) 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci char *exts = disp->ExtensionsString; 489bf215546Sopenharmony_ci 490bf215546Sopenharmony_ci /* Please keep these sorted alphabetically. */ 491bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(ANDROID_blob_cache); 492bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target); 493bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer); 494bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync); 495bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(ANDROID_recordable); 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(CHROMIUM_sync_control); 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_buffer_age); 500bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_create_context_robustness); 501bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import); 502bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers); 503bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_protected_surface); 504bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_present_opaque); 505bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata); 506bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata); 507bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage); 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(IMG_context_priority); 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_cl_event2); 512bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_config_attribs); 513bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_context_flush_control); 514bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_create_context); 515bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_create_context_no_error); 516bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_fence_sync); 517bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses); 518bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_gl_colorspace); 519bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image); 520bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image); 521bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image); 522bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image); 523bf215546Sopenharmony_ci if (disp->Extensions.KHR_image_base && disp->Extensions.KHR_image_pixmap) 524bf215546Sopenharmony_ci disp->Extensions.KHR_image = EGL_TRUE; 525bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_image); 526bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_image_base); 527bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_image_pixmap); 528bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer); 529bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_no_config_context); 530bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_partial_update); 531bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_reusable_sync); 532bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_surfaceless_context); 533bf215546Sopenharmony_ci if (disp->Extensions.EXT_swap_buffers_with_damage) 534bf215546Sopenharmony_ci _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage"); 535bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(EXT_pixel_format_float); 536bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(KHR_wait_sync); 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci if (disp->Extensions.KHR_no_config_context) 539bf215546Sopenharmony_ci _eglAppendExtension(&exts, "EGL_MESA_configless_context"); 540bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(MESA_drm_image); 541bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export); 542bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(MESA_query_driver); 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(NOK_swap_region); 545bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap); 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(NV_post_sub_buffer); 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(WL_bind_wayland_display); 550bf215546Sopenharmony_ci _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image); 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_ci#undef _EGL_CHECK_EXTENSION 553bf215546Sopenharmony_ci} 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_cistatic void 556bf215546Sopenharmony_ci_eglCreateAPIsString(_EGLDisplay *disp) 557bf215546Sopenharmony_ci{ 558bf215546Sopenharmony_ci#define addstr(str) \ 559bf215546Sopenharmony_ci { \ 560bf215546Sopenharmony_ci const size_t old_len = strlen(disp->ClientAPIsString); \ 561bf215546Sopenharmony_ci const size_t add_len = sizeof(str); \ 562bf215546Sopenharmony_ci const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \ 563bf215546Sopenharmony_ci if (old_len + add_len <= max_len) \ 564bf215546Sopenharmony_ci strcat(disp->ClientAPIsString, str " "); \ 565bf215546Sopenharmony_ci else \ 566bf215546Sopenharmony_ci assert(!"disp->ClientAPIsString is not large enough"); \ 567bf215546Sopenharmony_ci } 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci if (disp->ClientAPIs & EGL_OPENGL_BIT) 570bf215546Sopenharmony_ci addstr("OpenGL"); 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci if (disp->ClientAPIs & EGL_OPENGL_ES_BIT || 573bf215546Sopenharmony_ci disp->ClientAPIs & EGL_OPENGL_ES2_BIT || 574bf215546Sopenharmony_ci disp->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) { 575bf215546Sopenharmony_ci addstr("OpenGL_ES"); 576bf215546Sopenharmony_ci } 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci if (disp->ClientAPIs & EGL_OPENVG_BIT) 579bf215546Sopenharmony_ci addstr("OpenVG"); 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci#undef addstr 582bf215546Sopenharmony_ci} 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_cistatic void 585bf215546Sopenharmony_ci_eglComputeVersion(_EGLDisplay *disp) 586bf215546Sopenharmony_ci{ 587bf215546Sopenharmony_ci disp->Version = 14; 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci if (disp->Extensions.KHR_fence_sync && 590bf215546Sopenharmony_ci disp->Extensions.KHR_cl_event2 && 591bf215546Sopenharmony_ci disp->Extensions.KHR_wait_sync && 592bf215546Sopenharmony_ci disp->Extensions.KHR_image_base && 593bf215546Sopenharmony_ci disp->Extensions.KHR_gl_texture_2D_image && 594bf215546Sopenharmony_ci disp->Extensions.KHR_gl_texture_3D_image && 595bf215546Sopenharmony_ci disp->Extensions.KHR_gl_texture_cubemap_image && 596bf215546Sopenharmony_ci disp->Extensions.KHR_gl_renderbuffer_image && 597bf215546Sopenharmony_ci disp->Extensions.KHR_create_context && 598bf215546Sopenharmony_ci disp->Extensions.EXT_create_context_robustness && 599bf215546Sopenharmony_ci disp->Extensions.KHR_get_all_proc_addresses && 600bf215546Sopenharmony_ci disp->Extensions.KHR_gl_colorspace && 601bf215546Sopenharmony_ci disp->Extensions.KHR_surfaceless_context) 602bf215546Sopenharmony_ci disp->Version = 15; 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci /* For Android P and below limit the EGL version to 1.4 */ 605bf215546Sopenharmony_ci#if defined(ANDROID) && ANDROID_API_LEVEL <= 28 606bf215546Sopenharmony_ci disp->Version = 14; 607bf215546Sopenharmony_ci#endif 608bf215546Sopenharmony_ci} 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci/** 611bf215546Sopenharmony_ci * This is typically the second EGL function that an application calls. 612bf215546Sopenharmony_ci * Here we load/initialize the actual hardware driver. 613bf215546Sopenharmony_ci */ 614bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 615bf215546Sopenharmony_cieglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 616bf215546Sopenharmony_ci{ 617bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci if (!disp) 622bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci if (!disp->Initialized) { 625bf215546Sopenharmony_ci /* set options */ 626bf215546Sopenharmony_ci disp->Options.ForceSoftware = 627bf215546Sopenharmony_ci env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false); 628bf215546Sopenharmony_ci if (disp->Options.ForceSoftware) 629bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "Found 'LIBGL_ALWAYS_SOFTWARE' set, will use a CPU renderer"); 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE"); 632bf215546Sopenharmony_ci disp->Options.Zink = env && !strcmp(env, "zink"); 633bf215546Sopenharmony_ci disp->Options.ForceSoftware |= disp->Options.Zink; 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci /** 636bf215546Sopenharmony_ci * Initialize the display using the driver's function. 637bf215546Sopenharmony_ci * If the initialisation fails, try again using only software rendering. 638bf215546Sopenharmony_ci */ 639bf215546Sopenharmony_ci if (!_eglDriver.Initialize(disp)) { 640bf215546Sopenharmony_ci if (disp->Options.ForceSoftware) 641bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); 642bf215546Sopenharmony_ci else { 643bf215546Sopenharmony_ci disp->Options.ForceSoftware = EGL_TRUE; 644bf215546Sopenharmony_ci if (!_eglDriver.Initialize(disp)) 645bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); 646bf215546Sopenharmony_ci } 647bf215546Sopenharmony_ci } 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci disp->Initialized = EGL_TRUE; 650bf215546Sopenharmony_ci disp->Driver = &_eglDriver; 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci /* limit to APIs supported by core */ 653bf215546Sopenharmony_ci disp->ClientAPIs &= _EGL_API_ALL_BITS; 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ci /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec 656bf215546Sopenharmony_ci * classifies it as an EGL display extension, though conceptually it's an 657bf215546Sopenharmony_ci * EGL client extension. 658bf215546Sopenharmony_ci * 659bf215546Sopenharmony_ci * From the EGL_KHR_get_all_proc_addresses spec: 660bf215546Sopenharmony_ci * 661bf215546Sopenharmony_ci * The EGL implementation must expose the name 662bf215546Sopenharmony_ci * EGL_KHR_client_get_all_proc_addresses if and only if it exposes 663bf215546Sopenharmony_ci * EGL_KHR_get_all_proc_addresses and supports 664bf215546Sopenharmony_ci * EGL_EXT_client_extensions. 665bf215546Sopenharmony_ci * 666bf215546Sopenharmony_ci * Mesa unconditionally exposes both client extensions mentioned above, 667bf215546Sopenharmony_ci * so the spec requires that each EGLDisplay unconditionally expose 668bf215546Sopenharmony_ci * EGL_KHR_get_all_proc_addresses also. 669bf215546Sopenharmony_ci */ 670bf215546Sopenharmony_ci disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE; 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware 673bf215546Sopenharmony_ci * programs. It is driver agnostic and handled in the main EGL code. 674bf215546Sopenharmony_ci */ 675bf215546Sopenharmony_ci disp->Extensions.KHR_config_attribs = EGL_TRUE; 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci _eglComputeVersion(disp); 678bf215546Sopenharmony_ci _eglCreateExtensionsString(disp); 679bf215546Sopenharmony_ci _eglCreateAPIsString(disp); 680bf215546Sopenharmony_ci snprintf(disp->VersionString, sizeof(disp->VersionString), 681bf215546Sopenharmony_ci "%d.%d", disp->Version / 10, disp->Version % 10); 682bf215546Sopenharmony_ci } 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci /* Update applications version of major and minor if not NULL */ 685bf215546Sopenharmony_ci if ((major != NULL) && (minor != NULL)) { 686bf215546Sopenharmony_ci *major = disp->Version / 10; 687bf215546Sopenharmony_ci *minor = disp->Version % 10; 688bf215546Sopenharmony_ci } 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, EGL_TRUE); 691bf215546Sopenharmony_ci} 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 695bf215546Sopenharmony_cieglTerminate(EGLDisplay dpy) 696bf215546Sopenharmony_ci{ 697bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_ci if (!disp) 702bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci if (disp->Initialized) { 705bf215546Sopenharmony_ci disp->Driver->Terminate(disp); 706bf215546Sopenharmony_ci /* do not reset disp->Driver */ 707bf215546Sopenharmony_ci disp->ClientAPIsString[0] = 0; 708bf215546Sopenharmony_ci disp->Initialized = EGL_FALSE; 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci /* Reset blob cache funcs on terminate. */ 711bf215546Sopenharmony_ci disp->BlobCacheSet = NULL; 712bf215546Sopenharmony_ci disp->BlobCacheGet = NULL; 713bf215546Sopenharmony_ci } 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, EGL_TRUE); 716bf215546Sopenharmony_ci} 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ciconst char * EGLAPIENTRY 720bf215546Sopenharmony_cieglQueryString(EGLDisplay dpy, EGLint name) 721bf215546Sopenharmony_ci{ 722bf215546Sopenharmony_ci _EGLDisplay *disp; 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci#if !USE_LIBGLVND 725bf215546Sopenharmony_ci if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) { 726bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString); 727bf215546Sopenharmony_ci } 728bf215546Sopenharmony_ci#endif 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci disp = _eglLockDisplay(dpy); 731bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL); 732bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, NULL); 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci switch (name) { 735bf215546Sopenharmony_ci case EGL_VENDOR: 736bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING); 737bf215546Sopenharmony_ci case EGL_VERSION: 738bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, disp->VersionString); 739bf215546Sopenharmony_ci case EGL_EXTENSIONS: 740bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, disp->ExtensionsString); 741bf215546Sopenharmony_ci case EGL_CLIENT_APIS: 742bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString); 743bf215546Sopenharmony_ci default: 744bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL); 745bf215546Sopenharmony_ci } 746bf215546Sopenharmony_ci} 747bf215546Sopenharmony_ci 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 750bf215546Sopenharmony_cieglGetConfigs(EGLDisplay dpy, EGLConfig *configs, 751bf215546Sopenharmony_ci EGLint config_size, EGLint *num_config) 752bf215546Sopenharmony_ci{ 753bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 754bf215546Sopenharmony_ci EGLBoolean ret; 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_ci if (!num_config) 761bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci ret = _eglGetConfigs(disp, configs, config_size, num_config); 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 766bf215546Sopenharmony_ci} 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 770bf215546Sopenharmony_cieglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, 771bf215546Sopenharmony_ci EGLint config_size, EGLint *num_config) 772bf215546Sopenharmony_ci{ 773bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 774bf215546Sopenharmony_ci EGLBoolean ret; 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci if (!num_config) 781bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci ret = _eglChooseConfig(disp, attrib_list, configs, 784bf215546Sopenharmony_ci config_size, num_config); 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 787bf215546Sopenharmony_ci} 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 791bf215546Sopenharmony_cieglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, 792bf215546Sopenharmony_ci EGLint attribute, EGLint *value) 793bf215546Sopenharmony_ci{ 794bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 795bf215546Sopenharmony_ci _EGLConfig *conf = _eglLookupConfig(config, disp); 796bf215546Sopenharmony_ci EGLBoolean ret; 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_ci _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE); 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci ret = _eglGetConfigAttrib(disp, conf, attribute, value); 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 805bf215546Sopenharmony_ci} 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci 808bf215546Sopenharmony_ciEGLContext EGLAPIENTRY 809bf215546Sopenharmony_cieglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, 810bf215546Sopenharmony_ci const EGLint *attrib_list) 811bf215546Sopenharmony_ci{ 812bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 813bf215546Sopenharmony_ci _EGLConfig *conf = _eglLookupConfig(config, disp); 814bf215546Sopenharmony_ci _EGLContext *share = _eglLookupContext(share_list, disp); 815bf215546Sopenharmony_ci _EGLContext *context; 816bf215546Sopenharmony_ci EGLContext ret; 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT); 819bf215546Sopenharmony_ci 820bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT); 821bf215546Sopenharmony_ci 822bf215546Sopenharmony_ci if (config != EGL_NO_CONFIG_KHR) 823bf215546Sopenharmony_ci _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT); 824bf215546Sopenharmony_ci else if (!disp->Extensions.KHR_no_config_context) 825bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT); 826bf215546Sopenharmony_ci 827bf215546Sopenharmony_ci if (!share && share_list != EGL_NO_CONTEXT) 828bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT); 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_ci context = disp->Driver->CreateContext(disp, conf, share, attrib_list); 831bf215546Sopenharmony_ci ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT; 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 834bf215546Sopenharmony_ci} 835bf215546Sopenharmony_ci 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 838bf215546Sopenharmony_cieglDestroyContext(EGLDisplay dpy, EGLContext ctx) 839bf215546Sopenharmony_ci{ 840bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 841bf215546Sopenharmony_ci _EGLContext *context = _eglLookupContext(ctx, disp); 842bf215546Sopenharmony_ci EGLBoolean ret; 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE); 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE); 847bf215546Sopenharmony_ci _eglUnlinkContext(context); 848bf215546Sopenharmony_ci ret = disp->Driver->DestroyContext(disp, context); 849bf215546Sopenharmony_ci 850bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 851bf215546Sopenharmony_ci} 852bf215546Sopenharmony_ci 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 855bf215546Sopenharmony_cieglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, 856bf215546Sopenharmony_ci EGLContext ctx) 857bf215546Sopenharmony_ci{ 858bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 859bf215546Sopenharmony_ci _EGLContext *context = _eglLookupContext(ctx, disp); 860bf215546Sopenharmony_ci _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); 861bf215546Sopenharmony_ci _EGLSurface *read_surf = _eglLookupSurface(read, disp); 862bf215546Sopenharmony_ci EGLBoolean ret; 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE); 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci if (!disp) 867bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci /* display is allowed to be uninitialized under certain condition */ 870bf215546Sopenharmony_ci if (!disp->Initialized) { 871bf215546Sopenharmony_ci if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || 872bf215546Sopenharmony_ci ctx != EGL_NO_CONTEXT) 873bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); 874bf215546Sopenharmony_ci } 875bf215546Sopenharmony_ci if (!disp->Driver) 876bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, EGL_TRUE); 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci if (!context && ctx != EGL_NO_CONTEXT) 879bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 880bf215546Sopenharmony_ci if (!draw_surf || !read_surf) { 881bf215546Sopenharmony_ci /* From the EGL 1.4 (20130211) spec: 882bf215546Sopenharmony_ci * 883bf215546Sopenharmony_ci * To release the current context without assigning a new one, set ctx 884bf215546Sopenharmony_ci * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE. 885bf215546Sopenharmony_ci */ 886bf215546Sopenharmony_ci if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT) 887bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 888bf215546Sopenharmony_ci 889bf215546Sopenharmony_ci if ((!draw_surf && draw != EGL_NO_SURFACE) || 890bf215546Sopenharmony_ci (!read_surf && read != EGL_NO_SURFACE)) 891bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 892bf215546Sopenharmony_ci if (draw_surf || read_surf) 893bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); 894bf215546Sopenharmony_ci } 895bf215546Sopenharmony_ci 896bf215546Sopenharmony_ci /* If a native window underlying either draw or read is no longer valid, 897bf215546Sopenharmony_ci * an EGL_BAD_NATIVE_WINDOW error is generated. 898bf215546Sopenharmony_ci */ 899bf215546Sopenharmony_ci if (draw_surf && draw_surf->Lost) 900bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); 901bf215546Sopenharmony_ci if (read_surf && read_surf->Lost) 902bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); 903bf215546Sopenharmony_ci /* EGL_EXT_protected_surface spec says: 904bf215546Sopenharmony_ci * If EGL_PROTECTED_CONTENT_EXT attributes of read is EGL_TRUE and 905bf215546Sopenharmony_ci * EGL_PROTECTED_CONTENT_EXT attributes of draw is EGL_FALSE, an 906bf215546Sopenharmony_ci * EGL_BAD_ACCESS error is generated. 907bf215546Sopenharmony_ci */ 908bf215546Sopenharmony_ci if (read_surf && read_surf->ProtectedContent && 909bf215546Sopenharmony_ci draw_surf && !draw_surf->ProtectedContent) 910bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE); 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context); 913bf215546Sopenharmony_ci 914bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 915bf215546Sopenharmony_ci} 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 919bf215546Sopenharmony_cieglQueryContext(EGLDisplay dpy, EGLContext ctx, 920bf215546Sopenharmony_ci EGLint attribute, EGLint *value) 921bf215546Sopenharmony_ci{ 922bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 923bf215546Sopenharmony_ci _EGLContext *context = _eglLookupContext(ctx, disp); 924bf215546Sopenharmony_ci EGLBoolean ret; 925bf215546Sopenharmony_ci 926bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE); 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE); 929bf215546Sopenharmony_ci 930bf215546Sopenharmony_ci ret = _eglQueryContext(context, attribute, value); 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 933bf215546Sopenharmony_ci} 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci 936bf215546Sopenharmony_ci/* In EGL specs 1.4 and 1.5, at the end of sections 3.5.1 and 3.5.4, it says 937bf215546Sopenharmony_ci * that if native_surface was already used to create a window or pixmap, we 938bf215546Sopenharmony_ci * can't create a new one. This is what this function checks for. 939bf215546Sopenharmony_ci */ 940bf215546Sopenharmony_cistatic bool 941bf215546Sopenharmony_ci_eglNativeSurfaceAlreadyUsed(_EGLDisplay *disp, void *native_surface) 942bf215546Sopenharmony_ci{ 943bf215546Sopenharmony_ci _EGLResource *list; 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ci list = disp->ResourceLists[_EGL_RESOURCE_SURFACE]; 946bf215546Sopenharmony_ci while (list) { 947bf215546Sopenharmony_ci _EGLSurface *surf = (_EGLSurface *) list; 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci list = list->Next; 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci if (surf->Type == EGL_PBUFFER_BIT) 952bf215546Sopenharmony_ci continue; 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_ci if (surf->NativeSurface == native_surface) 955bf215546Sopenharmony_ci return true; 956bf215546Sopenharmony_ci } 957bf215546Sopenharmony_ci 958bf215546Sopenharmony_ci return false; 959bf215546Sopenharmony_ci} 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_cistatic EGLSurface 963bf215546Sopenharmony_ci_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config, 964bf215546Sopenharmony_ci void *native_window, const EGLint *attrib_list) 965bf215546Sopenharmony_ci{ 966bf215546Sopenharmony_ci _EGLConfig *conf = _eglLookupConfig(config, disp); 967bf215546Sopenharmony_ci _EGLSurface *surf; 968bf215546Sopenharmony_ci EGLSurface ret; 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci if (native_window == NULL) 972bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS || 975bf215546Sopenharmony_ci disp->Platform == _EGL_PLATFORM_DEVICE)) { 976bf215546Sopenharmony_ci /* From the EGL_MESA_platform_surfaceless spec (v1): 977bf215546Sopenharmony_ci * 978bf215546Sopenharmony_ci * eglCreatePlatformWindowSurface fails when called with a <display> 979bf215546Sopenharmony_ci * that belongs to the surfaceless platform. It returns 980bf215546Sopenharmony_ci * EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The 981bf215546Sopenharmony_ci * justification for this unconditional failure is that the 982bf215546Sopenharmony_ci * surfaceless platform has no native windows, and therefore the 983bf215546Sopenharmony_ci * <native_window> parameter is always invalid. 984bf215546Sopenharmony_ci * 985bf215546Sopenharmony_ci * This check must occur before checking the EGLConfig, which emits 986bf215546Sopenharmony_ci * EGL_BAD_CONFIG. 987bf215546Sopenharmony_ci */ 988bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 989bf215546Sopenharmony_ci } 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_ci _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); 992bf215546Sopenharmony_ci 993bf215546Sopenharmony_ci if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0) 994bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE); 995bf215546Sopenharmony_ci 996bf215546Sopenharmony_ci if (_eglNativeSurfaceAlreadyUsed(disp, native_window)) 997bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE); 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ci surf = disp->Driver->CreateWindowSurface(disp, conf, native_window, attrib_list); 1000bf215546Sopenharmony_ci ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1003bf215546Sopenharmony_ci} 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci 1006bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY 1007bf215546Sopenharmony_cieglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, 1008bf215546Sopenharmony_ci EGLNativeWindowType window, const EGLint *attrib_list) 1009bf215546Sopenharmony_ci{ 1010bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1011bf215546Sopenharmony_ci 1012bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1013bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(void*) == sizeof(window)); 1014bf215546Sopenharmony_ci return _eglCreateWindowSurfaceCommon(disp, config, (void*) window, 1015bf215546Sopenharmony_ci attrib_list); 1016bf215546Sopenharmony_ci} 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_cistatic void * 1019bf215546Sopenharmony_ci_fixupNativeWindow(_EGLDisplay *disp, void *native_window) 1020bf215546Sopenharmony_ci{ 1021bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM 1022bf215546Sopenharmony_ci if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) { 1023bf215546Sopenharmony_ci /* The `native_window` parameter for the X11 platform differs between 1024bf215546Sopenharmony_ci * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In 1025bf215546Sopenharmony_ci * eglCreateWindowSurface(), the type of `native_window` is an Xlib 1026bf215546Sopenharmony_ci * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is 1027bf215546Sopenharmony_ci * `Window*`. Convert `Window*` to `Window` because that's what 1028bf215546Sopenharmony_ci * dri2_x11_create_window_surface() expects. 1029bf215546Sopenharmony_ci */ 1030bf215546Sopenharmony_ci return (void *)(* (Window*) native_window); 1031bf215546Sopenharmony_ci } 1032bf215546Sopenharmony_ci#endif 1033bf215546Sopenharmony_ci#ifdef HAVE_XCB_PLATFORM 1034bf215546Sopenharmony_ci if (disp && disp->Platform == _EGL_PLATFORM_XCB && native_window != NULL) { 1035bf215546Sopenharmony_ci /* Similar to with X11, we need to convert (xcb_window_t *) 1036bf215546Sopenharmony_ci * (i.e., uint32_t *) to xcb_window_t. We have to do an intermediate cast 1037bf215546Sopenharmony_ci * to uintptr_t, since uint32_t may be smaller than a pointer. 1038bf215546Sopenharmony_ci */ 1039bf215546Sopenharmony_ci return (void *)(uintptr_t) (* (uint32_t*) native_window); 1040bf215546Sopenharmony_ci } 1041bf215546Sopenharmony_ci#endif 1042bf215546Sopenharmony_ci return native_window; 1043bf215546Sopenharmony_ci} 1044bf215546Sopenharmony_ci 1045bf215546Sopenharmony_cistatic EGLSurface EGLAPIENTRY 1046bf215546Sopenharmony_cieglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, 1047bf215546Sopenharmony_ci void *native_window, 1048bf215546Sopenharmony_ci const EGLint *attrib_list) 1049bf215546Sopenharmony_ci{ 1050bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1051bf215546Sopenharmony_ci 1052bf215546Sopenharmony_ci native_window = _fixupNativeWindow(disp, native_window); 1053bf215546Sopenharmony_ci 1054bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1055bf215546Sopenharmony_ci return _eglCreateWindowSurfaceCommon(disp, config, native_window, 1056bf215546Sopenharmony_ci attrib_list); 1057bf215546Sopenharmony_ci} 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY 1061bf215546Sopenharmony_cieglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, 1062bf215546Sopenharmony_ci void *native_window, 1063bf215546Sopenharmony_ci const EGLAttrib *attrib_list) 1064bf215546Sopenharmony_ci{ 1065bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1066bf215546Sopenharmony_ci EGLSurface surface; 1067bf215546Sopenharmony_ci EGLint *int_attribs; 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1070bf215546Sopenharmony_ci 1071bf215546Sopenharmony_ci int_attribs = _eglConvertAttribsToInt(attrib_list); 1072bf215546Sopenharmony_ci if (attrib_list && !int_attribs) 1073bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE); 1074bf215546Sopenharmony_ci 1075bf215546Sopenharmony_ci native_window = _fixupNativeWindow(disp, native_window); 1076bf215546Sopenharmony_ci surface = _eglCreateWindowSurfaceCommon(disp, config, native_window, 1077bf215546Sopenharmony_ci int_attribs); 1078bf215546Sopenharmony_ci free(int_attribs); 1079bf215546Sopenharmony_ci return surface; 1080bf215546Sopenharmony_ci} 1081bf215546Sopenharmony_ci 1082bf215546Sopenharmony_cistatic void * 1083bf215546Sopenharmony_ci_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap) 1084bf215546Sopenharmony_ci{ 1085bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM 1086bf215546Sopenharmony_ci /* The `native_pixmap` parameter for the X11 platform differs between 1087bf215546Sopenharmony_ci * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In 1088bf215546Sopenharmony_ci * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib 1089bf215546Sopenharmony_ci * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is 1090bf215546Sopenharmony_ci * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what 1091bf215546Sopenharmony_ci * dri2_x11_create_pixmap_surface() expects. 1092bf215546Sopenharmony_ci */ 1093bf215546Sopenharmony_ci if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) 1094bf215546Sopenharmony_ci return (void *)(* (Pixmap*) native_pixmap); 1095bf215546Sopenharmony_ci#endif 1096bf215546Sopenharmony_ci#ifdef HAVE_XCB_PLATFORM 1097bf215546Sopenharmony_ci if (disp && disp->Platform == _EGL_PLATFORM_XCB && native_pixmap != NULL) { 1098bf215546Sopenharmony_ci /* Similar to with X11, we need to convert (xcb_pixmap_t *) 1099bf215546Sopenharmony_ci * (i.e., uint32_t *) to xcb_pixmap_t. We have to do an intermediate cast 1100bf215546Sopenharmony_ci * to uintptr_t, since uint32_t may be smaller than a pointer. 1101bf215546Sopenharmony_ci */ 1102bf215546Sopenharmony_ci return (void *)(uintptr_t) (* (uint32_t*) native_pixmap); 1103bf215546Sopenharmony_ci } 1104bf215546Sopenharmony_ci#endif 1105bf215546Sopenharmony_ci return native_pixmap; 1106bf215546Sopenharmony_ci} 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_cistatic EGLSurface 1109bf215546Sopenharmony_ci_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, 1110bf215546Sopenharmony_ci void *native_pixmap, const EGLint *attrib_list) 1111bf215546Sopenharmony_ci{ 1112bf215546Sopenharmony_ci _EGLConfig *conf = _eglLookupConfig(config, disp); 1113bf215546Sopenharmony_ci _EGLSurface *surf; 1114bf215546Sopenharmony_ci EGLSurface ret; 1115bf215546Sopenharmony_ci 1116bf215546Sopenharmony_ci if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS || 1117bf215546Sopenharmony_ci disp->Platform == _EGL_PLATFORM_DEVICE)) { 1118bf215546Sopenharmony_ci /* From the EGL_MESA_platform_surfaceless spec (v1): 1119bf215546Sopenharmony_ci * 1120bf215546Sopenharmony_ci * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface 1121bf215546Sopenharmony_ci * also fails when called with a <display> that belongs to the 1122bf215546Sopenharmony_ci * surfaceless platform. It returns EGL_NO_SURFACE and generates 1123bf215546Sopenharmony_ci * EGL_BAD_NATIVE_PIXMAP. 1124bf215546Sopenharmony_ci * 1125bf215546Sopenharmony_ci * This check must occur before checking the EGLConfig, which emits 1126bf215546Sopenharmony_ci * EGL_BAD_CONFIG. 1127bf215546Sopenharmony_ci */ 1128bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); 1129bf215546Sopenharmony_ci } 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0) 1134bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE); 1135bf215546Sopenharmony_ci 1136bf215546Sopenharmony_ci if (native_pixmap == NULL) 1137bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_ci if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap)) 1140bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE); 1141bf215546Sopenharmony_ci 1142bf215546Sopenharmony_ci surf = disp->Driver->CreatePixmapSurface(disp, conf, native_pixmap, attrib_list); 1143bf215546Sopenharmony_ci ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1146bf215546Sopenharmony_ci} 1147bf215546Sopenharmony_ci 1148bf215546Sopenharmony_ci 1149bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY 1150bf215546Sopenharmony_cieglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, 1151bf215546Sopenharmony_ci EGLNativePixmapType pixmap, const EGLint *attrib_list) 1152bf215546Sopenharmony_ci{ 1153bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1154bf215546Sopenharmony_ci 1155bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1156bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(void*) == sizeof(pixmap)); 1157bf215546Sopenharmony_ci return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap, 1158bf215546Sopenharmony_ci attrib_list); 1159bf215546Sopenharmony_ci} 1160bf215546Sopenharmony_ci 1161bf215546Sopenharmony_cistatic EGLSurface EGLAPIENTRY 1162bf215546Sopenharmony_cieglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, 1163bf215546Sopenharmony_ci void *native_pixmap, 1164bf215546Sopenharmony_ci const EGLint *attrib_list) 1165bf215546Sopenharmony_ci{ 1166bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1167bf215546Sopenharmony_ci 1168bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1169bf215546Sopenharmony_ci native_pixmap = _fixupNativePixmap(disp, native_pixmap); 1170bf215546Sopenharmony_ci return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap, 1171bf215546Sopenharmony_ci attrib_list); 1172bf215546Sopenharmony_ci} 1173bf215546Sopenharmony_ci 1174bf215546Sopenharmony_ci 1175bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY 1176bf215546Sopenharmony_cieglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, 1177bf215546Sopenharmony_ci void *native_pixmap, 1178bf215546Sopenharmony_ci const EGLAttrib *attrib_list) 1179bf215546Sopenharmony_ci{ 1180bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1181bf215546Sopenharmony_ci EGLSurface surface; 1182bf215546Sopenharmony_ci EGLint *int_attribs; 1183bf215546Sopenharmony_ci 1184bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci int_attribs = _eglConvertAttribsToInt(attrib_list); 1187bf215546Sopenharmony_ci if (attrib_list && !int_attribs) 1188bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE); 1189bf215546Sopenharmony_ci 1190bf215546Sopenharmony_ci native_pixmap = _fixupNativePixmap(disp, native_pixmap); 1191bf215546Sopenharmony_ci surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap, 1192bf215546Sopenharmony_ci int_attribs); 1193bf215546Sopenharmony_ci free(int_attribs); 1194bf215546Sopenharmony_ci return surface; 1195bf215546Sopenharmony_ci} 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY 1199bf215546Sopenharmony_cieglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, 1200bf215546Sopenharmony_ci const EGLint *attrib_list) 1201bf215546Sopenharmony_ci{ 1202bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1203bf215546Sopenharmony_ci _EGLConfig *conf = _eglLookupConfig(config, disp); 1204bf215546Sopenharmony_ci _EGLSurface *surf; 1205bf215546Sopenharmony_ci EGLSurface ret; 1206bf215546Sopenharmony_ci 1207bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1208bf215546Sopenharmony_ci _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_ci if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0) 1211bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE); 1212bf215546Sopenharmony_ci 1213bf215546Sopenharmony_ci surf = disp->Driver->CreatePbufferSurface(disp, conf, attrib_list); 1214bf215546Sopenharmony_ci ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1217bf215546Sopenharmony_ci} 1218bf215546Sopenharmony_ci 1219bf215546Sopenharmony_ci 1220bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1221bf215546Sopenharmony_cieglDestroySurface(EGLDisplay dpy, EGLSurface surface) 1222bf215546Sopenharmony_ci{ 1223bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1224bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1225bf215546Sopenharmony_ci EGLBoolean ret; 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1228bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1229bf215546Sopenharmony_ci _eglUnlinkSurface(surf); 1230bf215546Sopenharmony_ci ret = disp->Driver->DestroySurface(disp, surf); 1231bf215546Sopenharmony_ci 1232bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1233bf215546Sopenharmony_ci} 1234bf215546Sopenharmony_ci 1235bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1236bf215546Sopenharmony_cieglQuerySurface(EGLDisplay dpy, EGLSurface surface, 1237bf215546Sopenharmony_ci EGLint attribute, EGLint *value) 1238bf215546Sopenharmony_ci{ 1239bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1240bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1241bf215546Sopenharmony_ci EGLBoolean ret; 1242bf215546Sopenharmony_ci 1243bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1244bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1245bf215546Sopenharmony_ci 1246bf215546Sopenharmony_ci if (disp->Driver->QuerySurface) 1247bf215546Sopenharmony_ci ret = disp->Driver->QuerySurface(disp, surf, attribute, value); 1248bf215546Sopenharmony_ci else 1249bf215546Sopenharmony_ci ret = _eglQuerySurface(disp, surf, attribute, value); 1250bf215546Sopenharmony_ci 1251bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1252bf215546Sopenharmony_ci} 1253bf215546Sopenharmony_ci 1254bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1255bf215546Sopenharmony_cieglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, 1256bf215546Sopenharmony_ci EGLint attribute, EGLint value) 1257bf215546Sopenharmony_ci{ 1258bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1259bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1260bf215546Sopenharmony_ci EGLBoolean ret; 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1263bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_ci ret = _eglSurfaceAttrib(disp, surf, attribute, value); 1266bf215546Sopenharmony_ci 1267bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1268bf215546Sopenharmony_ci} 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci 1271bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1272bf215546Sopenharmony_cieglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 1273bf215546Sopenharmony_ci{ 1274bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1275bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1276bf215546Sopenharmony_ci EGLBoolean ret; 1277bf215546Sopenharmony_ci 1278bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1279bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1280bf215546Sopenharmony_ci ret = disp->Driver->BindTexImage(disp, surf, buffer); 1281bf215546Sopenharmony_ci 1282bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1283bf215546Sopenharmony_ci} 1284bf215546Sopenharmony_ci 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1287bf215546Sopenharmony_cieglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 1288bf215546Sopenharmony_ci{ 1289bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1290bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1291bf215546Sopenharmony_ci EGLBoolean ret; 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1294bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1295bf215546Sopenharmony_ci ret = disp->Driver->ReleaseTexImage(disp, surf, buffer); 1296bf215546Sopenharmony_ci 1297bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1298bf215546Sopenharmony_ci} 1299bf215546Sopenharmony_ci 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1302bf215546Sopenharmony_cieglSwapInterval(EGLDisplay dpy, EGLint interval) 1303bf215546Sopenharmony_ci{ 1304bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1305bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1306bf215546Sopenharmony_ci _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL; 1307bf215546Sopenharmony_ci EGLBoolean ret; 1308bf215546Sopenharmony_ci 1309bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1310bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 1311bf215546Sopenharmony_ci 1312bf215546Sopenharmony_ci if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1313bf215546Sopenharmony_ci ctx->Resource.Display != disp) 1314bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); 1315bf215546Sopenharmony_ci 1316bf215546Sopenharmony_ci if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE) 1317bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1318bf215546Sopenharmony_ci 1319bf215546Sopenharmony_ci if (surf->Type != EGL_WINDOW_BIT) 1320bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_TRUE); 1321bf215546Sopenharmony_ci 1322bf215546Sopenharmony_ci interval = CLAMP(interval, 1323bf215546Sopenharmony_ci surf->Config->MinSwapInterval, 1324bf215546Sopenharmony_ci surf->Config->MaxSwapInterval); 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ci if (surf->SwapInterval != interval && disp->Driver->SwapInterval) 1327bf215546Sopenharmony_ci ret = disp->Driver->SwapInterval(disp, surf, interval); 1328bf215546Sopenharmony_ci else 1329bf215546Sopenharmony_ci ret = EGL_TRUE; 1330bf215546Sopenharmony_ci 1331bf215546Sopenharmony_ci if (ret) 1332bf215546Sopenharmony_ci surf->SwapInterval = interval; 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1335bf215546Sopenharmony_ci} 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci 1338bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1339bf215546Sopenharmony_cieglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 1340bf215546Sopenharmony_ci{ 1341bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1342bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1343bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1344bf215546Sopenharmony_ci EGLBoolean ret; 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1347bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1348bf215546Sopenharmony_ci 1349bf215546Sopenharmony_ci /* surface must be bound to current context in EGL 1.4 */ 1350bf215546Sopenharmony_ci #ifndef _EGL_BUILT_IN_DRIVER_HAIKU 1351bf215546Sopenharmony_ci if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1352bf215546Sopenharmony_ci surf != ctx->DrawSurface) 1353bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1354bf215546Sopenharmony_ci #endif 1355bf215546Sopenharmony_ci 1356bf215546Sopenharmony_ci if (surf->Type != EGL_WINDOW_BIT) 1357bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_TRUE); 1358bf215546Sopenharmony_ci 1359bf215546Sopenharmony_ci /* From the EGL 1.5 spec: 1360bf215546Sopenharmony_ci * 1361bf215546Sopenharmony_ci * If eglSwapBuffers is called and the native window associated with 1362bf215546Sopenharmony_ci * surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is 1363bf215546Sopenharmony_ci * generated. 1364bf215546Sopenharmony_ci */ 1365bf215546Sopenharmony_ci if (surf->Lost) 1366bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); 1367bf215546Sopenharmony_ci 1368bf215546Sopenharmony_ci ret = disp->Driver->SwapBuffers(disp, surf); 1369bf215546Sopenharmony_ci 1370bf215546Sopenharmony_ci /* EGL_KHR_partial_update 1371bf215546Sopenharmony_ci * Frame boundary successfully reached, 1372bf215546Sopenharmony_ci * reset damage region and reset BufferAgeRead 1373bf215546Sopenharmony_ci */ 1374bf215546Sopenharmony_ci if (ret) { 1375bf215546Sopenharmony_ci surf->SetDamageRegionCalled = EGL_FALSE; 1376bf215546Sopenharmony_ci surf->BufferAgeRead = EGL_FALSE; 1377bf215546Sopenharmony_ci } 1378bf215546Sopenharmony_ci 1379bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1380bf215546Sopenharmony_ci} 1381bf215546Sopenharmony_ci 1382bf215546Sopenharmony_ci 1383bf215546Sopenharmony_cistatic EGLBoolean 1384bf215546Sopenharmony_ci_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf, 1385bf215546Sopenharmony_ci const EGLint *rects, EGLint n_rects) 1386bf215546Sopenharmony_ci{ 1387bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1388bf215546Sopenharmony_ci EGLBoolean ret; 1389bf215546Sopenharmony_ci 1390bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1391bf215546Sopenharmony_ci 1392bf215546Sopenharmony_ci /* surface must be bound to current context in EGL 1.4 */ 1393bf215546Sopenharmony_ci if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1394bf215546Sopenharmony_ci surf != ctx->DrawSurface) 1395bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 1396bf215546Sopenharmony_ci 1397bf215546Sopenharmony_ci if (surf->Type != EGL_WINDOW_BIT) 1398bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_TRUE); 1399bf215546Sopenharmony_ci 1400bf215546Sopenharmony_ci if ((n_rects > 0 && rects == NULL) || n_rects < 0) 1401bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1402bf215546Sopenharmony_ci 1403bf215546Sopenharmony_ci ret = disp->Driver->SwapBuffersWithDamageEXT(disp, surf, rects, n_rects); 1404bf215546Sopenharmony_ci 1405bf215546Sopenharmony_ci /* EGL_KHR_partial_update 1406bf215546Sopenharmony_ci * Frame boundary successfully reached, 1407bf215546Sopenharmony_ci * reset damage region and reset BufferAgeRead 1408bf215546Sopenharmony_ci */ 1409bf215546Sopenharmony_ci if (ret) { 1410bf215546Sopenharmony_ci surf->SetDamageRegionCalled = EGL_FALSE; 1411bf215546Sopenharmony_ci surf->BufferAgeRead = EGL_FALSE; 1412bf215546Sopenharmony_ci } 1413bf215546Sopenharmony_ci 1414bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1415bf215546Sopenharmony_ci} 1416bf215546Sopenharmony_ci 1417bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 1418bf215546Sopenharmony_cieglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, 1419bf215546Sopenharmony_ci const EGLint *rects, EGLint n_rects) 1420bf215546Sopenharmony_ci{ 1421bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1422bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1423bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1424bf215546Sopenharmony_ci return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects); 1425bf215546Sopenharmony_ci} 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 1428bf215546Sopenharmony_cieglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, 1429bf215546Sopenharmony_ci const EGLint *rects, EGLint n_rects) 1430bf215546Sopenharmony_ci{ 1431bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1432bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1433bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1434bf215546Sopenharmony_ci return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects); 1435bf215546Sopenharmony_ci} 1436bf215546Sopenharmony_ci 1437bf215546Sopenharmony_ci/** 1438bf215546Sopenharmony_ci * Clamp the rectangles so that they lie within the surface. 1439bf215546Sopenharmony_ci */ 1440bf215546Sopenharmony_ci 1441bf215546Sopenharmony_cistatic void 1442bf215546Sopenharmony_ci_eglSetDamageRegionKHRClampRects(_EGLSurface* surf, 1443bf215546Sopenharmony_ci EGLint *rects, EGLint n_rects) 1444bf215546Sopenharmony_ci{ 1445bf215546Sopenharmony_ci EGLint i; 1446bf215546Sopenharmony_ci EGLint surf_height = surf->Height; 1447bf215546Sopenharmony_ci EGLint surf_width = surf->Width; 1448bf215546Sopenharmony_ci 1449bf215546Sopenharmony_ci for (i = 0; i < (4 * n_rects); i += 4) { 1450bf215546Sopenharmony_ci EGLint x1, y1, x2, y2; 1451bf215546Sopenharmony_ci x1 = rects[i]; 1452bf215546Sopenharmony_ci y1 = rects[i + 1]; 1453bf215546Sopenharmony_ci x2 = rects[i + 2] + x1; 1454bf215546Sopenharmony_ci y2 = rects[i + 3] + y1; 1455bf215546Sopenharmony_ci 1456bf215546Sopenharmony_ci rects[i] = CLAMP(x1, 0, surf_width); 1457bf215546Sopenharmony_ci rects[i + 1] = CLAMP(y1, 0, surf_height); 1458bf215546Sopenharmony_ci rects[i + 2] = CLAMP(x2, 0, surf_width) - rects[i]; 1459bf215546Sopenharmony_ci rects[i + 3] = CLAMP(y2, 0, surf_height) - rects[i + 1]; 1460bf215546Sopenharmony_ci } 1461bf215546Sopenharmony_ci} 1462bf215546Sopenharmony_ci 1463bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 1464bf215546Sopenharmony_cieglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface, 1465bf215546Sopenharmony_ci EGLint *rects, EGLint n_rects) 1466bf215546Sopenharmony_ci{ 1467bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1468bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1469bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1470bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1471bf215546Sopenharmony_ci EGLBoolean ret; 1472bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1473bf215546Sopenharmony_ci 1474bf215546Sopenharmony_ci if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1475bf215546Sopenharmony_ci surf->Type != EGL_WINDOW_BIT || 1476bf215546Sopenharmony_ci ctx->DrawSurface != surf || 1477bf215546Sopenharmony_ci surf->SwapBehavior != EGL_BUFFER_DESTROYED) 1478bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); 1479bf215546Sopenharmony_ci 1480bf215546Sopenharmony_ci /* If the damage region is already set or 1481bf215546Sopenharmony_ci * buffer age is not queried between 1482bf215546Sopenharmony_ci * frame boundaries, throw bad access error 1483bf215546Sopenharmony_ci */ 1484bf215546Sopenharmony_ci 1485bf215546Sopenharmony_ci if (surf->SetDamageRegionCalled || !surf->BufferAgeRead) 1486bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE); 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci _eglSetDamageRegionKHRClampRects(surf, rects, n_rects); 1489bf215546Sopenharmony_ci ret = disp->Driver->SetDamageRegion(disp, surf, rects, n_rects); 1490bf215546Sopenharmony_ci 1491bf215546Sopenharmony_ci if (ret) 1492bf215546Sopenharmony_ci surf->SetDamageRegionCalled = EGL_TRUE; 1493bf215546Sopenharmony_ci 1494bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1495bf215546Sopenharmony_ci} 1496bf215546Sopenharmony_ci 1497bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1498bf215546Sopenharmony_cieglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 1499bf215546Sopenharmony_ci{ 1500bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1501bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 1502bf215546Sopenharmony_ci EGLBoolean ret; 1503bf215546Sopenharmony_ci void *native_pixmap_ptr; 1504bf215546Sopenharmony_ci 1505bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 1506bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(void*) == sizeof(target)); 1507bf215546Sopenharmony_ci native_pixmap_ptr = (void*) target; 1508bf215546Sopenharmony_ci 1509bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 1510bf215546Sopenharmony_ci if (surf->ProtectedContent) 1511bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE); 1512bf215546Sopenharmony_ci ret = disp->Driver->CopyBuffers(disp, surf, native_pixmap_ptr); 1513bf215546Sopenharmony_ci 1514bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1515bf215546Sopenharmony_ci} 1516bf215546Sopenharmony_ci 1517bf215546Sopenharmony_ci 1518bf215546Sopenharmony_cistatic EGLBoolean 1519bf215546Sopenharmony_ci_eglWaitClientCommon(void) 1520bf215546Sopenharmony_ci{ 1521bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1522bf215546Sopenharmony_ci _EGLDisplay *disp; 1523bf215546Sopenharmony_ci EGLBoolean ret; 1524bf215546Sopenharmony_ci 1525bf215546Sopenharmony_ci if (!ctx) 1526bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1527bf215546Sopenharmony_ci 1528bf215546Sopenharmony_ci disp = ctx->Resource.Display; 1529bf215546Sopenharmony_ci mtx_lock(&disp->Mutex); 1530bf215546Sopenharmony_ci 1531bf215546Sopenharmony_ci /* let bad current context imply bad current surface */ 1532bf215546Sopenharmony_ci if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1533bf215546Sopenharmony_ci _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) 1534bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 1535bf215546Sopenharmony_ci 1536bf215546Sopenharmony_ci /* a valid current context implies an initialized current display */ 1537bf215546Sopenharmony_ci assert(disp->Initialized); 1538bf215546Sopenharmony_ci ret = disp->Driver->WaitClient(disp, ctx); 1539bf215546Sopenharmony_ci 1540bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1541bf215546Sopenharmony_ci} 1542bf215546Sopenharmony_ci 1543bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1544bf215546Sopenharmony_cieglWaitClient(void) 1545bf215546Sopenharmony_ci{ 1546bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE); 1547bf215546Sopenharmony_ci return _eglWaitClientCommon(); 1548bf215546Sopenharmony_ci} 1549bf215546Sopenharmony_ci 1550bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1551bf215546Sopenharmony_cieglWaitGL(void) 1552bf215546Sopenharmony_ci{ 1553bf215546Sopenharmony_ci /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */ 1554bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE); 1555bf215546Sopenharmony_ci return _eglWaitClientCommon(); 1556bf215546Sopenharmony_ci} 1557bf215546Sopenharmony_ci 1558bf215546Sopenharmony_ci 1559bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1560bf215546Sopenharmony_cieglWaitNative(EGLint engine) 1561bf215546Sopenharmony_ci{ 1562bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1563bf215546Sopenharmony_ci _EGLDisplay *disp; 1564bf215546Sopenharmony_ci EGLBoolean ret; 1565bf215546Sopenharmony_ci 1566bf215546Sopenharmony_ci if (!ctx) 1567bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1568bf215546Sopenharmony_ci 1569bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE); 1570bf215546Sopenharmony_ci 1571bf215546Sopenharmony_ci disp = ctx->Resource.Display; 1572bf215546Sopenharmony_ci mtx_lock(&disp->Mutex); 1573bf215546Sopenharmony_ci 1574bf215546Sopenharmony_ci /* let bad current context imply bad current surface */ 1575bf215546Sopenharmony_ci if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 1576bf215546Sopenharmony_ci _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) 1577bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); 1578bf215546Sopenharmony_ci 1579bf215546Sopenharmony_ci /* a valid current context implies an initialized current display */ 1580bf215546Sopenharmony_ci assert(disp->Initialized); 1581bf215546Sopenharmony_ci ret = disp->Driver->WaitNative(engine); 1582bf215546Sopenharmony_ci 1583bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1584bf215546Sopenharmony_ci} 1585bf215546Sopenharmony_ci 1586bf215546Sopenharmony_ci 1587bf215546Sopenharmony_ciEGLDisplay EGLAPIENTRY 1588bf215546Sopenharmony_cieglGetCurrentDisplay(void) 1589bf215546Sopenharmony_ci{ 1590bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1591bf215546Sopenharmony_ci EGLDisplay ret; 1592bf215546Sopenharmony_ci 1593bf215546Sopenharmony_ci ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; 1594bf215546Sopenharmony_ci 1595bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, ret); 1596bf215546Sopenharmony_ci} 1597bf215546Sopenharmony_ci 1598bf215546Sopenharmony_ci 1599bf215546Sopenharmony_ciEGLContext EGLAPIENTRY 1600bf215546Sopenharmony_cieglGetCurrentContext(void) 1601bf215546Sopenharmony_ci{ 1602bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1603bf215546Sopenharmony_ci EGLContext ret; 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_ci ret = _eglGetContextHandle(ctx); 1606bf215546Sopenharmony_ci 1607bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, ret); 1608bf215546Sopenharmony_ci} 1609bf215546Sopenharmony_ci 1610bf215546Sopenharmony_ci 1611bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY 1612bf215546Sopenharmony_cieglGetCurrentSurface(EGLint readdraw) 1613bf215546Sopenharmony_ci{ 1614bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1615bf215546Sopenharmony_ci EGLint err = EGL_SUCCESS; 1616bf215546Sopenharmony_ci _EGLSurface *surf; 1617bf215546Sopenharmony_ci EGLSurface ret; 1618bf215546Sopenharmony_ci 1619bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE); 1620bf215546Sopenharmony_ci 1621bf215546Sopenharmony_ci if (!ctx) 1622bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE); 1623bf215546Sopenharmony_ci 1624bf215546Sopenharmony_ci switch (readdraw) { 1625bf215546Sopenharmony_ci case EGL_DRAW: 1626bf215546Sopenharmony_ci surf = ctx->DrawSurface; 1627bf215546Sopenharmony_ci break; 1628bf215546Sopenharmony_ci case EGL_READ: 1629bf215546Sopenharmony_ci surf = ctx->ReadSurface; 1630bf215546Sopenharmony_ci break; 1631bf215546Sopenharmony_ci default: 1632bf215546Sopenharmony_ci surf = NULL; 1633bf215546Sopenharmony_ci err = EGL_BAD_PARAMETER; 1634bf215546Sopenharmony_ci break; 1635bf215546Sopenharmony_ci } 1636bf215546Sopenharmony_ci 1637bf215546Sopenharmony_ci ret = _eglGetSurfaceHandle(surf); 1638bf215546Sopenharmony_ci 1639bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, err, ret); 1640bf215546Sopenharmony_ci} 1641bf215546Sopenharmony_ci 1642bf215546Sopenharmony_ci 1643bf215546Sopenharmony_ciEGLint EGLAPIENTRY 1644bf215546Sopenharmony_cieglGetError(void) 1645bf215546Sopenharmony_ci{ 1646bf215546Sopenharmony_ci _EGLThreadInfo *t = _eglGetCurrentThread(); 1647bf215546Sopenharmony_ci EGLint e = t->LastError; 1648bf215546Sopenharmony_ci t->LastError = EGL_SUCCESS; 1649bf215546Sopenharmony_ci return e; 1650bf215546Sopenharmony_ci} 1651bf215546Sopenharmony_ci 1652bf215546Sopenharmony_ci 1653bf215546Sopenharmony_ci/** 1654bf215546Sopenharmony_ci ** EGL 1.2 1655bf215546Sopenharmony_ci **/ 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci/** 1658bf215546Sopenharmony_ci * Specify the client API to use for subsequent calls including: 1659bf215546Sopenharmony_ci * eglCreateContext() 1660bf215546Sopenharmony_ci * eglGetCurrentContext() 1661bf215546Sopenharmony_ci * eglGetCurrentDisplay() 1662bf215546Sopenharmony_ci * eglGetCurrentSurface() 1663bf215546Sopenharmony_ci * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT) 1664bf215546Sopenharmony_ci * eglWaitClient() 1665bf215546Sopenharmony_ci * eglWaitNative() 1666bf215546Sopenharmony_ci * See section 3.7 "Rendering Context" in the EGL specification for details. 1667bf215546Sopenharmony_ci */ 1668bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1669bf215546Sopenharmony_cieglBindAPI(EGLenum api) 1670bf215546Sopenharmony_ci{ 1671bf215546Sopenharmony_ci _EGLThreadInfo *t; 1672bf215546Sopenharmony_ci 1673bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE); 1674bf215546Sopenharmony_ci 1675bf215546Sopenharmony_ci t = _eglGetCurrentThread(); 1676bf215546Sopenharmony_ci 1677bf215546Sopenharmony_ci if (!_eglIsApiValid(api)) 1678bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); 1679bf215546Sopenharmony_ci 1680bf215546Sopenharmony_ci t->CurrentAPI = api; 1681bf215546Sopenharmony_ci 1682bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1683bf215546Sopenharmony_ci} 1684bf215546Sopenharmony_ci 1685bf215546Sopenharmony_ci 1686bf215546Sopenharmony_ci/** 1687bf215546Sopenharmony_ci * Return the last value set with eglBindAPI(). 1688bf215546Sopenharmony_ci */ 1689bf215546Sopenharmony_ciEGLenum EGLAPIENTRY 1690bf215546Sopenharmony_cieglQueryAPI(void) 1691bf215546Sopenharmony_ci{ 1692bf215546Sopenharmony_ci _EGLThreadInfo *t = _eglGetCurrentThread(); 1693bf215546Sopenharmony_ci EGLenum ret; 1694bf215546Sopenharmony_ci 1695bf215546Sopenharmony_ci /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ 1696bf215546Sopenharmony_ci ret = t->CurrentAPI; 1697bf215546Sopenharmony_ci 1698bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, ret); 1699bf215546Sopenharmony_ci} 1700bf215546Sopenharmony_ci 1701bf215546Sopenharmony_ci 1702bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY 1703bf215546Sopenharmony_cieglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, 1704bf215546Sopenharmony_ci EGLClientBuffer buffer, EGLConfig config, 1705bf215546Sopenharmony_ci const EGLint *attrib_list) 1706bf215546Sopenharmony_ci{ 1707bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1708bf215546Sopenharmony_ci _EGLConfig *conf = _eglLookupConfig(config, disp); 1709bf215546Sopenharmony_ci 1710bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE); 1711bf215546Sopenharmony_ci 1712bf215546Sopenharmony_ci _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); 1713bf215546Sopenharmony_ci 1714bf215546Sopenharmony_ci /* OpenVG is not supported */ 1715bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE); 1716bf215546Sopenharmony_ci} 1717bf215546Sopenharmony_ci 1718bf215546Sopenharmony_ci 1719bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1720bf215546Sopenharmony_cieglReleaseThread(void) 1721bf215546Sopenharmony_ci{ 1722bf215546Sopenharmony_ci /* unbind current contexts */ 1723bf215546Sopenharmony_ci _EGLThreadInfo *t = _eglGetCurrentThread(); 1724bf215546Sopenharmony_ci _EGLContext *ctx = t->CurrentContext; 1725bf215546Sopenharmony_ci 1726bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE); 1727bf215546Sopenharmony_ci 1728bf215546Sopenharmony_ci if (ctx) { 1729bf215546Sopenharmony_ci _EGLDisplay *disp = ctx->Resource.Display; 1730bf215546Sopenharmony_ci 1731bf215546Sopenharmony_ci mtx_lock(&disp->Mutex); 1732bf215546Sopenharmony_ci (void) disp->Driver->MakeCurrent(disp, NULL, NULL, NULL); 1733bf215546Sopenharmony_ci mtx_unlock(&disp->Mutex); 1734bf215546Sopenharmony_ci } 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci _eglDestroyCurrentThread(); 1737bf215546Sopenharmony_ci 1738bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, EGL_TRUE); 1739bf215546Sopenharmony_ci} 1740bf215546Sopenharmony_ci 1741bf215546Sopenharmony_ci 1742bf215546Sopenharmony_cistatic EGLImage 1743bf215546Sopenharmony_ci_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target, 1744bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 1745bf215546Sopenharmony_ci{ 1746bf215546Sopenharmony_ci _EGLContext *context = _eglLookupContext(ctx, disp); 1747bf215546Sopenharmony_ci _EGLImage *img; 1748bf215546Sopenharmony_ci EGLImage ret; 1749bf215546Sopenharmony_ci 1750bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR); 1751bf215546Sopenharmony_ci if (!disp->Extensions.KHR_image_base) 1752bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); 1753bf215546Sopenharmony_ci if (!context && ctx != EGL_NO_CONTEXT) 1754bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); 1755bf215546Sopenharmony_ci /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display, 1756bf215546Sopenharmony_ci * <ctx> must be EGL_NO_CONTEXT..." 1757bf215546Sopenharmony_ci */ 1758bf215546Sopenharmony_ci if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT) 1759bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); 1760bf215546Sopenharmony_ci 1761bf215546Sopenharmony_ci img = disp->Driver->CreateImageKHR(disp, context, target, buffer, attr_list); 1762bf215546Sopenharmony_ci ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; 1763bf215546Sopenharmony_ci 1764bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1765bf215546Sopenharmony_ci} 1766bf215546Sopenharmony_ci 1767bf215546Sopenharmony_cistatic EGLImage EGLAPIENTRY 1768bf215546Sopenharmony_cieglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, 1769bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLint *attr_list) 1770bf215546Sopenharmony_ci{ 1771bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1772bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR); 1773bf215546Sopenharmony_ci return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list); 1774bf215546Sopenharmony_ci} 1775bf215546Sopenharmony_ci 1776bf215546Sopenharmony_ci 1777bf215546Sopenharmony_ciEGLImage EGLAPIENTRY 1778bf215546Sopenharmony_cieglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, 1779bf215546Sopenharmony_ci EGLClientBuffer buffer, const EGLAttrib *attr_list) 1780bf215546Sopenharmony_ci{ 1781bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1782bf215546Sopenharmony_ci EGLImage image; 1783bf215546Sopenharmony_ci EGLint *int_attribs; 1784bf215546Sopenharmony_ci 1785bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR); 1786bf215546Sopenharmony_ci 1787bf215546Sopenharmony_ci int_attribs = _eglConvertAttribsToInt(attr_list); 1788bf215546Sopenharmony_ci if (attr_list && !int_attribs) 1789bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE); 1790bf215546Sopenharmony_ci 1791bf215546Sopenharmony_ci image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs); 1792bf215546Sopenharmony_ci free(int_attribs); 1793bf215546Sopenharmony_ci return image; 1794bf215546Sopenharmony_ci} 1795bf215546Sopenharmony_ci 1796bf215546Sopenharmony_ci 1797bf215546Sopenharmony_cistatic EGLBoolean 1798bf215546Sopenharmony_ci_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img) 1799bf215546Sopenharmony_ci{ 1800bf215546Sopenharmony_ci EGLBoolean ret; 1801bf215546Sopenharmony_ci 1802bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 1803bf215546Sopenharmony_ci if (!disp->Extensions.KHR_image_base) 1804bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_FALSE); 1805bf215546Sopenharmony_ci if (!img) 1806bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 1807bf215546Sopenharmony_ci 1808bf215546Sopenharmony_ci _eglUnlinkImage(img); 1809bf215546Sopenharmony_ci ret = disp->Driver->DestroyImageKHR(disp, img); 1810bf215546Sopenharmony_ci 1811bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1812bf215546Sopenharmony_ci} 1813bf215546Sopenharmony_ci 1814bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1815bf215546Sopenharmony_cieglDestroyImage(EGLDisplay dpy, EGLImage image) 1816bf215546Sopenharmony_ci{ 1817bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1818bf215546Sopenharmony_ci _EGLImage *img = _eglLookupImage(image, disp); 1819bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); 1820bf215546Sopenharmony_ci return _eglDestroyImageCommon(disp, img); 1821bf215546Sopenharmony_ci} 1822bf215546Sopenharmony_ci 1823bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 1824bf215546Sopenharmony_cieglDestroyImageKHR(EGLDisplay dpy, EGLImage image) 1825bf215546Sopenharmony_ci{ 1826bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1827bf215546Sopenharmony_ci _EGLImage *img = _eglLookupImage(image, disp); 1828bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); 1829bf215546Sopenharmony_ci return _eglDestroyImageCommon(disp, img); 1830bf215546Sopenharmony_ci} 1831bf215546Sopenharmony_ci 1832bf215546Sopenharmony_ci 1833bf215546Sopenharmony_cistatic EGLSync 1834bf215546Sopenharmony_ci_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list, 1835bf215546Sopenharmony_ci EGLBoolean orig_is_EGLAttrib, 1836bf215546Sopenharmony_ci EGLenum invalid_type_error) 1837bf215546Sopenharmony_ci{ 1838bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 1839bf215546Sopenharmony_ci _EGLSync *sync; 1840bf215546Sopenharmony_ci EGLSync ret; 1841bf215546Sopenharmony_ci 1842bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR); 1843bf215546Sopenharmony_ci 1844bf215546Sopenharmony_ci if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) { 1845bf215546Sopenharmony_ci /* There exist two EGLAttrib variants of eglCreateSync*: 1846bf215546Sopenharmony_ci * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync 1847bf215546Sopenharmony_ci * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2 1848bf215546Sopenharmony_ci * support as a proxy for EGL 1.5 support, even though that's not 1849bf215546Sopenharmony_ci * entirely correct (though _eglComputeVersion does the same). 1850bf215546Sopenharmony_ci * 1851bf215546Sopenharmony_ci * The EGL spec provides no guidance on how to handle unsupported 1852bf215546Sopenharmony_ci * functions. EGL_BAD_MATCH seems reasonable. 1853bf215546Sopenharmony_ci */ 1854bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR); 1855bf215546Sopenharmony_ci } 1856bf215546Sopenharmony_ci 1857bf215546Sopenharmony_ci /* If type is EGL_SYNC_FENCE and no context is current for the bound API 1858bf215546Sopenharmony_ci * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH 1859bf215546Sopenharmony_ci * error is generated. 1860bf215546Sopenharmony_ci */ 1861bf215546Sopenharmony_ci if (!ctx && 1862bf215546Sopenharmony_ci (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID)) 1863bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR); 1864bf215546Sopenharmony_ci 1865bf215546Sopenharmony_ci /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */ 1866bf215546Sopenharmony_ci if (ctx && (ctx->Resource.Display != disp || 1867bf215546Sopenharmony_ci (ctx->ClientAPI != EGL_OPENGL_ES_API && 1868bf215546Sopenharmony_ci ctx->ClientAPI != EGL_OPENGL_API))) 1869bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR); 1870bf215546Sopenharmony_ci 1871bf215546Sopenharmony_ci switch (type) { 1872bf215546Sopenharmony_ci case EGL_SYNC_FENCE_KHR: 1873bf215546Sopenharmony_ci if (!disp->Extensions.KHR_fence_sync) 1874bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); 1875bf215546Sopenharmony_ci break; 1876bf215546Sopenharmony_ci case EGL_SYNC_REUSABLE_KHR: 1877bf215546Sopenharmony_ci if (!disp->Extensions.KHR_reusable_sync) 1878bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); 1879bf215546Sopenharmony_ci break; 1880bf215546Sopenharmony_ci case EGL_SYNC_CL_EVENT_KHR: 1881bf215546Sopenharmony_ci if (!disp->Extensions.KHR_cl_event2) 1882bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); 1883bf215546Sopenharmony_ci break; 1884bf215546Sopenharmony_ci case EGL_SYNC_NATIVE_FENCE_ANDROID: 1885bf215546Sopenharmony_ci if (!disp->Extensions.ANDROID_native_fence_sync) 1886bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); 1887bf215546Sopenharmony_ci break; 1888bf215546Sopenharmony_ci default: 1889bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); 1890bf215546Sopenharmony_ci } 1891bf215546Sopenharmony_ci 1892bf215546Sopenharmony_ci sync = disp->Driver->CreateSyncKHR(disp, type, attrib_list); 1893bf215546Sopenharmony_ci ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR; 1894bf215546Sopenharmony_ci 1895bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1896bf215546Sopenharmony_ci} 1897bf215546Sopenharmony_ci 1898bf215546Sopenharmony_ci 1899bf215546Sopenharmony_cistatic EGLSync EGLAPIENTRY 1900bf215546Sopenharmony_cieglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list) 1901bf215546Sopenharmony_ci{ 1902bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1903bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL); 1904bf215546Sopenharmony_ci 1905bf215546Sopenharmony_ci EGLSync sync; 1906bf215546Sopenharmony_ci EGLAttrib *attrib_list; 1907bf215546Sopenharmony_ci EGLint err; 1908bf215546Sopenharmony_ci 1909bf215546Sopenharmony_ci if (sizeof(int_list[0]) == sizeof(attrib_list[0])) { 1910bf215546Sopenharmony_ci attrib_list = (EGLAttrib *) int_list; 1911bf215546Sopenharmony_ci } else { 1912bf215546Sopenharmony_ci err = _eglConvertIntsToAttribs(int_list, &attrib_list); 1913bf215546Sopenharmony_ci if (err != EGL_SUCCESS) 1914bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC); 1915bf215546Sopenharmony_ci } 1916bf215546Sopenharmony_ci 1917bf215546Sopenharmony_ci sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE, 1918bf215546Sopenharmony_ci EGL_BAD_ATTRIBUTE); 1919bf215546Sopenharmony_ci 1920bf215546Sopenharmony_ci if (sizeof(int_list[0]) != sizeof(attrib_list[0])) 1921bf215546Sopenharmony_ci free(attrib_list); 1922bf215546Sopenharmony_ci 1923bf215546Sopenharmony_ci /* Don't double-unlock the display. _eglCreateSync already unlocked it. */ 1924bf215546Sopenharmony_ci return sync; 1925bf215546Sopenharmony_ci} 1926bf215546Sopenharmony_ci 1927bf215546Sopenharmony_ci 1928bf215546Sopenharmony_cistatic EGLSync EGLAPIENTRY 1929bf215546Sopenharmony_cieglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) 1930bf215546Sopenharmony_ci{ 1931bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1932bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL); 1933bf215546Sopenharmony_ci return _eglCreateSync(disp, type, attrib_list, EGL_TRUE, 1934bf215546Sopenharmony_ci EGL_BAD_ATTRIBUTE); 1935bf215546Sopenharmony_ci} 1936bf215546Sopenharmony_ci 1937bf215546Sopenharmony_ci 1938bf215546Sopenharmony_ciEGLSync EGLAPIENTRY 1939bf215546Sopenharmony_cieglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) 1940bf215546Sopenharmony_ci{ 1941bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1942bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL); 1943bf215546Sopenharmony_ci return _eglCreateSync(disp, type, attrib_list, EGL_TRUE, 1944bf215546Sopenharmony_ci EGL_BAD_PARAMETER); 1945bf215546Sopenharmony_ci} 1946bf215546Sopenharmony_ci 1947bf215546Sopenharmony_ci 1948bf215546Sopenharmony_cistatic EGLBoolean 1949bf215546Sopenharmony_ci_eglDestroySync(_EGLDisplay *disp, _EGLSync *s) 1950bf215546Sopenharmony_ci{ 1951bf215546Sopenharmony_ci EGLBoolean ret; 1952bf215546Sopenharmony_ci 1953bf215546Sopenharmony_ci _EGL_CHECK_SYNC(disp, s, EGL_FALSE); 1954bf215546Sopenharmony_ci assert(disp->Extensions.KHR_reusable_sync || 1955bf215546Sopenharmony_ci disp->Extensions.KHR_fence_sync || 1956bf215546Sopenharmony_ci disp->Extensions.ANDROID_native_fence_sync); 1957bf215546Sopenharmony_ci 1958bf215546Sopenharmony_ci _eglUnlinkSync(s); 1959bf215546Sopenharmony_ci ret = disp->Driver->DestroySyncKHR(disp, s); 1960bf215546Sopenharmony_ci 1961bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 1962bf215546Sopenharmony_ci} 1963bf215546Sopenharmony_ci 1964bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 1965bf215546Sopenharmony_cieglDestroySync(EGLDisplay dpy, EGLSync sync) 1966bf215546Sopenharmony_ci{ 1967bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1968bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 1969bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 1970bf215546Sopenharmony_ci return _eglDestroySync(disp, s); 1971bf215546Sopenharmony_ci} 1972bf215546Sopenharmony_ci 1973bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 1974bf215546Sopenharmony_cieglDestroySyncKHR(EGLDisplay dpy, EGLSync sync) 1975bf215546Sopenharmony_ci{ 1976bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 1977bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 1978bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 1979bf215546Sopenharmony_ci return _eglDestroySync(disp, s); 1980bf215546Sopenharmony_ci} 1981bf215546Sopenharmony_ci 1982bf215546Sopenharmony_ci 1983bf215546Sopenharmony_cistatic EGLint 1984bf215546Sopenharmony_ci_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy, 1985bf215546Sopenharmony_ci _EGLSync *s, EGLint flags, EGLTime timeout) 1986bf215546Sopenharmony_ci{ 1987bf215546Sopenharmony_ci EGLint ret; 1988bf215546Sopenharmony_ci 1989bf215546Sopenharmony_ci _EGL_CHECK_SYNC(disp, s, EGL_FALSE); 1990bf215546Sopenharmony_ci assert(disp->Extensions.KHR_reusable_sync || 1991bf215546Sopenharmony_ci disp->Extensions.KHR_fence_sync || 1992bf215546Sopenharmony_ci disp->Extensions.ANDROID_native_fence_sync); 1993bf215546Sopenharmony_ci 1994bf215546Sopenharmony_ci if (s->SyncStatus == EGL_SIGNALED_KHR) 1995bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR); 1996bf215546Sopenharmony_ci 1997bf215546Sopenharmony_ci /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be 1998bf215546Sopenharmony_ci * unlocked here to allow other threads also to be able to 1999bf215546Sopenharmony_ci * go into waiting state. 2000bf215546Sopenharmony_ci */ 2001bf215546Sopenharmony_ci 2002bf215546Sopenharmony_ci if (s->Type == EGL_SYNC_REUSABLE_KHR) 2003bf215546Sopenharmony_ci _eglUnlockDisplay(dpy); 2004bf215546Sopenharmony_ci 2005bf215546Sopenharmony_ci ret = disp->Driver->ClientWaitSyncKHR(disp, s, flags, timeout); 2006bf215546Sopenharmony_ci 2007bf215546Sopenharmony_ci /* 2008bf215546Sopenharmony_ci * 'disp' is already unlocked for reusable sync type, 2009bf215546Sopenharmony_ci * so passing 'NULL' to bypass unlocking display. 2010bf215546Sopenharmony_ci */ 2011bf215546Sopenharmony_ci if (s->Type == EGL_SYNC_REUSABLE_KHR) 2012bf215546Sopenharmony_ci RETURN_EGL_EVAL(NULL, ret); 2013bf215546Sopenharmony_ci else 2014bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2015bf215546Sopenharmony_ci} 2016bf215546Sopenharmony_ci 2017bf215546Sopenharmony_ciEGLint EGLAPIENTRY 2018bf215546Sopenharmony_cieglClientWaitSync(EGLDisplay dpy, EGLSync sync, 2019bf215546Sopenharmony_ci EGLint flags, EGLTime timeout) 2020bf215546Sopenharmony_ci{ 2021bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2022bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2023bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2024bf215546Sopenharmony_ci return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout); 2025bf215546Sopenharmony_ci} 2026bf215546Sopenharmony_ci 2027bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY 2028bf215546Sopenharmony_cieglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync, 2029bf215546Sopenharmony_ci EGLint flags, EGLTime timeout) 2030bf215546Sopenharmony_ci{ 2031bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2032bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2033bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2034bf215546Sopenharmony_ci return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout); 2035bf215546Sopenharmony_ci} 2036bf215546Sopenharmony_ci 2037bf215546Sopenharmony_ci 2038bf215546Sopenharmony_cistatic EGLint 2039bf215546Sopenharmony_ci_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags) 2040bf215546Sopenharmony_ci{ 2041bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 2042bf215546Sopenharmony_ci EGLint ret; 2043bf215546Sopenharmony_ci 2044bf215546Sopenharmony_ci _EGL_CHECK_SYNC(disp, s, EGL_FALSE); 2045bf215546Sopenharmony_ci assert(disp->Extensions.KHR_wait_sync); 2046bf215546Sopenharmony_ci 2047bf215546Sopenharmony_ci /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */ 2048bf215546Sopenharmony_ci if (ctx == EGL_NO_CONTEXT || 2049bf215546Sopenharmony_ci (ctx->ClientAPI != EGL_OPENGL_ES_API && 2050bf215546Sopenharmony_ci ctx->ClientAPI != EGL_OPENGL_API)) 2051bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); 2052bf215546Sopenharmony_ci 2053bf215546Sopenharmony_ci /* the API doesn't allow any flags yet */ 2054bf215546Sopenharmony_ci if (flags != 0) 2055bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2056bf215546Sopenharmony_ci 2057bf215546Sopenharmony_ci ret = disp->Driver->WaitSyncKHR(disp, s); 2058bf215546Sopenharmony_ci 2059bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2060bf215546Sopenharmony_ci} 2061bf215546Sopenharmony_ci 2062bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY 2063bf215546Sopenharmony_cieglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags) 2064bf215546Sopenharmony_ci{ 2065bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2066bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2067bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2068bf215546Sopenharmony_ci return _eglWaitSyncCommon(disp, s, flags); 2069bf215546Sopenharmony_ci} 2070bf215546Sopenharmony_ci 2071bf215546Sopenharmony_ci 2072bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 2073bf215546Sopenharmony_cieglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) 2074bf215546Sopenharmony_ci{ 2075bf215546Sopenharmony_ci /* The KHR version returns EGLint, while the core version returns 2076bf215546Sopenharmony_ci * EGLBoolean. In both cases, the return values can only be EGL_FALSE and 2077bf215546Sopenharmony_ci * EGL_TRUE. 2078bf215546Sopenharmony_ci */ 2079bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2080bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2081bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2082bf215546Sopenharmony_ci return _eglWaitSyncCommon(disp, s, flags); 2083bf215546Sopenharmony_ci} 2084bf215546Sopenharmony_ci 2085bf215546Sopenharmony_ci 2086bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2087bf215546Sopenharmony_cieglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode) 2088bf215546Sopenharmony_ci{ 2089bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2090bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2091bf215546Sopenharmony_ci EGLBoolean ret; 2092bf215546Sopenharmony_ci 2093bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2094bf215546Sopenharmony_ci 2095bf215546Sopenharmony_ci _EGL_CHECK_SYNC(disp, s, EGL_FALSE); 2096bf215546Sopenharmony_ci assert(disp->Extensions.KHR_reusable_sync); 2097bf215546Sopenharmony_ci ret = disp->Driver->SignalSyncKHR(disp, s, mode); 2098bf215546Sopenharmony_ci 2099bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2100bf215546Sopenharmony_ci} 2101bf215546Sopenharmony_ci 2102bf215546Sopenharmony_ci 2103bf215546Sopenharmony_cistatic EGLBoolean 2104bf215546Sopenharmony_ci_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value) 2105bf215546Sopenharmony_ci{ 2106bf215546Sopenharmony_ci EGLBoolean ret; 2107bf215546Sopenharmony_ci 2108bf215546Sopenharmony_ci _EGL_CHECK_SYNC(disp, s, EGL_FALSE); 2109bf215546Sopenharmony_ci assert(disp->Extensions.KHR_reusable_sync || 2110bf215546Sopenharmony_ci disp->Extensions.KHR_fence_sync || 2111bf215546Sopenharmony_ci disp->Extensions.ANDROID_native_fence_sync); 2112bf215546Sopenharmony_ci 2113bf215546Sopenharmony_ci ret = _eglGetSyncAttrib(disp, s, attribute, value); 2114bf215546Sopenharmony_ci 2115bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2116bf215546Sopenharmony_ci} 2117bf215546Sopenharmony_ci 2118bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY 2119bf215546Sopenharmony_cieglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) 2120bf215546Sopenharmony_ci{ 2121bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2122bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2123bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2124bf215546Sopenharmony_ci 2125bf215546Sopenharmony_ci if (!value) 2126bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2127bf215546Sopenharmony_ci 2128bf215546Sopenharmony_ci return _eglGetSyncAttribCommon(disp, s, attribute, value); 2129bf215546Sopenharmony_ci} 2130bf215546Sopenharmony_ci 2131bf215546Sopenharmony_ci 2132bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2133bf215546Sopenharmony_cieglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value) 2134bf215546Sopenharmony_ci{ 2135bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2136bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2137bf215546Sopenharmony_ci EGLAttrib attrib; 2138bf215546Sopenharmony_ci EGLBoolean result; 2139bf215546Sopenharmony_ci 2140bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2141bf215546Sopenharmony_ci 2142bf215546Sopenharmony_ci if (!value) 2143bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2144bf215546Sopenharmony_ci 2145bf215546Sopenharmony_ci attrib = *value; 2146bf215546Sopenharmony_ci result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib); 2147bf215546Sopenharmony_ci 2148bf215546Sopenharmony_ci /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR: 2149bf215546Sopenharmony_ci * 2150bf215546Sopenharmony_ci * If any error occurs, <*value> is not modified. 2151bf215546Sopenharmony_ci */ 2152bf215546Sopenharmony_ci if (result == EGL_FALSE) 2153bf215546Sopenharmony_ci return result; 2154bf215546Sopenharmony_ci 2155bf215546Sopenharmony_ci *value = attrib; 2156bf215546Sopenharmony_ci return result; 2157bf215546Sopenharmony_ci} 2158bf215546Sopenharmony_ci 2159bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY 2160bf215546Sopenharmony_cieglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) 2161bf215546Sopenharmony_ci{ 2162bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2163bf215546Sopenharmony_ci _EGLSync *s = _eglLookupSync(sync, disp); 2164bf215546Sopenharmony_ci EGLint ret; 2165bf215546Sopenharmony_ci 2166bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); 2167bf215546Sopenharmony_ci 2168bf215546Sopenharmony_ci /* the spec doesn't seem to specify what happens if the fence 2169bf215546Sopenharmony_ci * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems 2170bf215546Sopenharmony_ci * sensible: 2171bf215546Sopenharmony_ci */ 2172bf215546Sopenharmony_ci if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID))) 2173bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID); 2174bf215546Sopenharmony_ci 2175bf215546Sopenharmony_ci _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID); 2176bf215546Sopenharmony_ci assert(disp->Extensions.ANDROID_native_fence_sync); 2177bf215546Sopenharmony_ci ret = disp->Driver->DupNativeFenceFDANDROID(disp, s); 2178bf215546Sopenharmony_ci 2179bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, ret); 2180bf215546Sopenharmony_ci} 2181bf215546Sopenharmony_ci 2182bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2183bf215546Sopenharmony_cieglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, 2184bf215546Sopenharmony_ci EGLint numRects, const EGLint *rects) 2185bf215546Sopenharmony_ci{ 2186bf215546Sopenharmony_ci _EGLContext *ctx = _eglGetCurrentContext(); 2187bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2188bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 2189bf215546Sopenharmony_ci EGLBoolean ret; 2190bf215546Sopenharmony_ci 2191bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 2192bf215546Sopenharmony_ci 2193bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 2194bf215546Sopenharmony_ci 2195bf215546Sopenharmony_ci if (!disp->Extensions.NOK_swap_region) 2196bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_FALSE); 2197bf215546Sopenharmony_ci 2198bf215546Sopenharmony_ci /* surface must be bound to current context in EGL 1.4 */ 2199bf215546Sopenharmony_ci if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || 2200bf215546Sopenharmony_ci surf != ctx->DrawSurface) 2201bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); 2202bf215546Sopenharmony_ci 2203bf215546Sopenharmony_ci ret = disp->Driver->SwapBuffersRegionNOK(disp, surf, numRects, rects); 2204bf215546Sopenharmony_ci 2205bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2206bf215546Sopenharmony_ci} 2207bf215546Sopenharmony_ci 2208bf215546Sopenharmony_ci 2209bf215546Sopenharmony_cistatic EGLImage EGLAPIENTRY 2210bf215546Sopenharmony_cieglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) 2211bf215546Sopenharmony_ci{ 2212bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2213bf215546Sopenharmony_ci _EGLImage *img; 2214bf215546Sopenharmony_ci EGLImage ret; 2215bf215546Sopenharmony_ci 2216bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL); 2217bf215546Sopenharmony_ci 2218bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR); 2219bf215546Sopenharmony_ci if (!disp->Extensions.MESA_drm_image) 2220bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); 2221bf215546Sopenharmony_ci 2222bf215546Sopenharmony_ci img = disp->Driver->CreateDRMImageMESA(disp, attr_list); 2223bf215546Sopenharmony_ci ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; 2224bf215546Sopenharmony_ci 2225bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2226bf215546Sopenharmony_ci} 2227bf215546Sopenharmony_ci 2228bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2229bf215546Sopenharmony_cieglExportDRMImageMESA(EGLDisplay dpy, EGLImage image, 2230bf215546Sopenharmony_ci EGLint *name, EGLint *handle, EGLint *stride) 2231bf215546Sopenharmony_ci{ 2232bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2233bf215546Sopenharmony_ci _EGLImage *img = _eglLookupImage(image, disp); 2234bf215546Sopenharmony_ci EGLBoolean ret; 2235bf215546Sopenharmony_ci 2236bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); 2237bf215546Sopenharmony_ci 2238bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2239bf215546Sopenharmony_ci assert(disp->Extensions.MESA_drm_image); 2240bf215546Sopenharmony_ci 2241bf215546Sopenharmony_ci if (!img) 2242bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2243bf215546Sopenharmony_ci 2244bf215546Sopenharmony_ci ret = disp->Driver->ExportDRMImageMESA(disp, img, name, handle, stride); 2245bf215546Sopenharmony_ci 2246bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2247bf215546Sopenharmony_ci} 2248bf215546Sopenharmony_ci 2249bf215546Sopenharmony_ci 2250bf215546Sopenharmony_cistruct wl_display; 2251bf215546Sopenharmony_ci 2252bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2253bf215546Sopenharmony_cieglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 2254bf215546Sopenharmony_ci{ 2255bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2256bf215546Sopenharmony_ci EGLBoolean ret; 2257bf215546Sopenharmony_ci 2258bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 2259bf215546Sopenharmony_ci 2260bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2261bf215546Sopenharmony_ci assert(disp->Extensions.WL_bind_wayland_display); 2262bf215546Sopenharmony_ci 2263bf215546Sopenharmony_ci if (!display) 2264bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2265bf215546Sopenharmony_ci 2266bf215546Sopenharmony_ci ret = disp->Driver->BindWaylandDisplayWL(disp, display); 2267bf215546Sopenharmony_ci 2268bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2269bf215546Sopenharmony_ci} 2270bf215546Sopenharmony_ci 2271bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2272bf215546Sopenharmony_cieglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) 2273bf215546Sopenharmony_ci{ 2274bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2275bf215546Sopenharmony_ci EGLBoolean ret; 2276bf215546Sopenharmony_ci 2277bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 2278bf215546Sopenharmony_ci 2279bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2280bf215546Sopenharmony_ci assert(disp->Extensions.WL_bind_wayland_display); 2281bf215546Sopenharmony_ci 2282bf215546Sopenharmony_ci if (!display) 2283bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2284bf215546Sopenharmony_ci 2285bf215546Sopenharmony_ci ret = disp->Driver->UnbindWaylandDisplayWL(disp, display); 2286bf215546Sopenharmony_ci 2287bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2288bf215546Sopenharmony_ci} 2289bf215546Sopenharmony_ci 2290bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2291bf215546Sopenharmony_cieglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, 2292bf215546Sopenharmony_ci EGLint attribute, EGLint *value) 2293bf215546Sopenharmony_ci{ 2294bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2295bf215546Sopenharmony_ci EGLBoolean ret; 2296bf215546Sopenharmony_ci 2297bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE); 2298bf215546Sopenharmony_ci 2299bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2300bf215546Sopenharmony_ci assert(disp->Extensions.WL_bind_wayland_display); 2301bf215546Sopenharmony_ci 2302bf215546Sopenharmony_ci if (!buffer) 2303bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2304bf215546Sopenharmony_ci 2305bf215546Sopenharmony_ci ret = disp->Driver->QueryWaylandBufferWL(disp, buffer, attribute, value); 2306bf215546Sopenharmony_ci 2307bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2308bf215546Sopenharmony_ci} 2309bf215546Sopenharmony_ci 2310bf215546Sopenharmony_ci 2311bf215546Sopenharmony_cistatic struct wl_buffer * EGLAPIENTRY 2312bf215546Sopenharmony_cieglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image) 2313bf215546Sopenharmony_ci{ 2314bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2315bf215546Sopenharmony_ci _EGLImage *img; 2316bf215546Sopenharmony_ci struct wl_buffer *ret; 2317bf215546Sopenharmony_ci 2318bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL); 2319bf215546Sopenharmony_ci 2320bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, NULL); 2321bf215546Sopenharmony_ci if (!disp->Extensions.WL_create_wayland_buffer_from_image) 2322bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, NULL); 2323bf215546Sopenharmony_ci 2324bf215546Sopenharmony_ci img = _eglLookupImage(image, disp); 2325bf215546Sopenharmony_ci 2326bf215546Sopenharmony_ci if (!img) 2327bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL); 2328bf215546Sopenharmony_ci 2329bf215546Sopenharmony_ci ret = disp->Driver->CreateWaylandBufferFromImageWL(disp, img); 2330bf215546Sopenharmony_ci 2331bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2332bf215546Sopenharmony_ci} 2333bf215546Sopenharmony_ci 2334bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2335bf215546Sopenharmony_cieglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, 2336bf215546Sopenharmony_ci EGLint x, EGLint y, EGLint width, EGLint height) 2337bf215546Sopenharmony_ci{ 2338bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2339bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 2340bf215546Sopenharmony_ci EGLBoolean ret; 2341bf215546Sopenharmony_ci 2342bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 2343bf215546Sopenharmony_ci 2344bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 2345bf215546Sopenharmony_ci 2346bf215546Sopenharmony_ci if (!disp->Extensions.NV_post_sub_buffer) 2347bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_FALSE); 2348bf215546Sopenharmony_ci 2349bf215546Sopenharmony_ci ret = disp->Driver->PostSubBufferNV(disp, surf, x, y, width, height); 2350bf215546Sopenharmony_ci 2351bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2352bf215546Sopenharmony_ci} 2353bf215546Sopenharmony_ci 2354bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2355bf215546Sopenharmony_cieglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface, 2356bf215546Sopenharmony_ci EGLuint64KHR *ust, EGLuint64KHR *msc, 2357bf215546Sopenharmony_ci EGLuint64KHR *sbc) 2358bf215546Sopenharmony_ci{ 2359bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2360bf215546Sopenharmony_ci _EGLSurface *surf = _eglLookupSurface(surface, disp); 2361bf215546Sopenharmony_ci EGLBoolean ret; 2362bf215546Sopenharmony_ci 2363bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE); 2364bf215546Sopenharmony_ci 2365bf215546Sopenharmony_ci _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); 2366bf215546Sopenharmony_ci if (!disp->Extensions.CHROMIUM_sync_control) 2367bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_FALSE); 2368bf215546Sopenharmony_ci 2369bf215546Sopenharmony_ci if (!ust || !msc || !sbc) 2370bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2371bf215546Sopenharmony_ci 2372bf215546Sopenharmony_ci ret = disp->Driver->GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc); 2373bf215546Sopenharmony_ci 2374bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2375bf215546Sopenharmony_ci} 2376bf215546Sopenharmony_ci 2377bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2378bf215546Sopenharmony_cieglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image, 2379bf215546Sopenharmony_ci EGLint *fourcc, EGLint *nplanes, 2380bf215546Sopenharmony_ci EGLuint64KHR *modifiers) 2381bf215546Sopenharmony_ci{ 2382bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2383bf215546Sopenharmony_ci _EGLImage *img = _eglLookupImage(image, disp); 2384bf215546Sopenharmony_ci EGLBoolean ret; 2385bf215546Sopenharmony_ci 2386bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); 2387bf215546Sopenharmony_ci 2388bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2389bf215546Sopenharmony_ci assert(disp->Extensions.MESA_image_dma_buf_export); 2390bf215546Sopenharmony_ci 2391bf215546Sopenharmony_ci if (!img) 2392bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2393bf215546Sopenharmony_ci 2394bf215546Sopenharmony_ci ret = disp->Driver->ExportDMABUFImageQueryMESA(disp, img, fourcc, nplanes, modifiers); 2395bf215546Sopenharmony_ci 2396bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2397bf215546Sopenharmony_ci} 2398bf215546Sopenharmony_ci 2399bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2400bf215546Sopenharmony_cieglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image, 2401bf215546Sopenharmony_ci int *fds, EGLint *strides, EGLint *offsets) 2402bf215546Sopenharmony_ci{ 2403bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2404bf215546Sopenharmony_ci _EGLImage *img = _eglLookupImage(image, disp); 2405bf215546Sopenharmony_ci EGLBoolean ret; 2406bf215546Sopenharmony_ci 2407bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE); 2408bf215546Sopenharmony_ci 2409bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2410bf215546Sopenharmony_ci assert(disp->Extensions.MESA_image_dma_buf_export); 2411bf215546Sopenharmony_ci 2412bf215546Sopenharmony_ci if (!img) 2413bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); 2414bf215546Sopenharmony_ci 2415bf215546Sopenharmony_ci ret = disp->Driver->ExportDMABUFImageMESA(disp, img, fds, strides, offsets); 2416bf215546Sopenharmony_ci 2417bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2418bf215546Sopenharmony_ci} 2419bf215546Sopenharmony_ci 2420bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY 2421bf215546Sopenharmony_cieglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object, 2422bf215546Sopenharmony_ci EGLLabelKHR label) 2423bf215546Sopenharmony_ci{ 2424bf215546Sopenharmony_ci _EGLDisplay *disp = NULL; 2425bf215546Sopenharmony_ci _EGLResourceType type; 2426bf215546Sopenharmony_ci 2427bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC); 2428bf215546Sopenharmony_ci 2429bf215546Sopenharmony_ci if (objectType == EGL_OBJECT_THREAD_KHR) { 2430bf215546Sopenharmony_ci _EGLThreadInfo *t = _eglGetCurrentThread(); 2431bf215546Sopenharmony_ci 2432bf215546Sopenharmony_ci t->Label = label; 2433bf215546Sopenharmony_ci return EGL_SUCCESS; 2434bf215546Sopenharmony_ci } 2435bf215546Sopenharmony_ci 2436bf215546Sopenharmony_ci disp = _eglLockDisplay(dpy); 2437bf215546Sopenharmony_ci if (disp == NULL) 2438bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY); 2439bf215546Sopenharmony_ci 2440bf215546Sopenharmony_ci if (objectType == EGL_OBJECT_DISPLAY_KHR) { 2441bf215546Sopenharmony_ci if (dpy != (EGLDisplay) object) 2442bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER); 2443bf215546Sopenharmony_ci 2444bf215546Sopenharmony_ci disp->Label = label; 2445bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_SUCCESS); 2446bf215546Sopenharmony_ci } 2447bf215546Sopenharmony_ci 2448bf215546Sopenharmony_ci switch (objectType) { 2449bf215546Sopenharmony_ci case EGL_OBJECT_CONTEXT_KHR: 2450bf215546Sopenharmony_ci type = _EGL_RESOURCE_CONTEXT; 2451bf215546Sopenharmony_ci break; 2452bf215546Sopenharmony_ci case EGL_OBJECT_SURFACE_KHR: 2453bf215546Sopenharmony_ci type = _EGL_RESOURCE_SURFACE; 2454bf215546Sopenharmony_ci break; 2455bf215546Sopenharmony_ci case EGL_OBJECT_IMAGE_KHR: 2456bf215546Sopenharmony_ci type = _EGL_RESOURCE_IMAGE; 2457bf215546Sopenharmony_ci break; 2458bf215546Sopenharmony_ci case EGL_OBJECT_SYNC_KHR: 2459bf215546Sopenharmony_ci type = _EGL_RESOURCE_SYNC; 2460bf215546Sopenharmony_ci break; 2461bf215546Sopenharmony_ci case EGL_OBJECT_STREAM_KHR: 2462bf215546Sopenharmony_ci default: 2463bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER); 2464bf215546Sopenharmony_ci } 2465bf215546Sopenharmony_ci 2466bf215546Sopenharmony_ci if (_eglCheckResource(object, type, disp)) { 2467bf215546Sopenharmony_ci _EGLResource *res = (_EGLResource *) object; 2468bf215546Sopenharmony_ci 2469bf215546Sopenharmony_ci res->Label = label; 2470bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, EGL_SUCCESS); 2471bf215546Sopenharmony_ci } 2472bf215546Sopenharmony_ci 2473bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER); 2474bf215546Sopenharmony_ci} 2475bf215546Sopenharmony_ci 2476bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY 2477bf215546Sopenharmony_cieglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, 2478bf215546Sopenharmony_ci const EGLAttrib *attrib_list) 2479bf215546Sopenharmony_ci{ 2480bf215546Sopenharmony_ci unsigned int newEnabled; 2481bf215546Sopenharmony_ci 2482bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC); 2483bf215546Sopenharmony_ci 2484bf215546Sopenharmony_ci mtx_lock(_eglGlobal.Mutex); 2485bf215546Sopenharmony_ci 2486bf215546Sopenharmony_ci newEnabled = _eglGlobal.debugTypesEnabled; 2487bf215546Sopenharmony_ci if (attrib_list != NULL) { 2488bf215546Sopenharmony_ci int i; 2489bf215546Sopenharmony_ci 2490bf215546Sopenharmony_ci for (i = 0; attrib_list[i] != EGL_NONE; i += 2) { 2491bf215546Sopenharmony_ci switch (attrib_list[i]) { 2492bf215546Sopenharmony_ci case EGL_DEBUG_MSG_CRITICAL_KHR: 2493bf215546Sopenharmony_ci case EGL_DEBUG_MSG_ERROR_KHR: 2494bf215546Sopenharmony_ci case EGL_DEBUG_MSG_WARN_KHR: 2495bf215546Sopenharmony_ci case EGL_DEBUG_MSG_INFO_KHR: 2496bf215546Sopenharmony_ci if (attrib_list[i + 1]) 2497bf215546Sopenharmony_ci newEnabled |= DebugBitFromType(attrib_list[i]); 2498bf215546Sopenharmony_ci else 2499bf215546Sopenharmony_ci newEnabled &= ~DebugBitFromType(attrib_list[i]); 2500bf215546Sopenharmony_ci break; 2501bf215546Sopenharmony_ci default: 2502bf215546Sopenharmony_ci // On error, set the last error code, call the current 2503bf215546Sopenharmony_ci // debug callback, and return the error code. 2504bf215546Sopenharmony_ci mtx_unlock(_eglGlobal.Mutex); 2505bf215546Sopenharmony_ci _eglReportError(EGL_BAD_ATTRIBUTE, NULL, 2506bf215546Sopenharmony_ci "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]); 2507bf215546Sopenharmony_ci return EGL_BAD_ATTRIBUTE; 2508bf215546Sopenharmony_ci } 2509bf215546Sopenharmony_ci } 2510bf215546Sopenharmony_ci } 2511bf215546Sopenharmony_ci 2512bf215546Sopenharmony_ci if (callback != NULL) { 2513bf215546Sopenharmony_ci _eglGlobal.debugCallback = callback; 2514bf215546Sopenharmony_ci _eglGlobal.debugTypesEnabled = newEnabled; 2515bf215546Sopenharmony_ci } else { 2516bf215546Sopenharmony_ci _eglGlobal.debugCallback = NULL; 2517bf215546Sopenharmony_ci _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR; 2518bf215546Sopenharmony_ci } 2519bf215546Sopenharmony_ci 2520bf215546Sopenharmony_ci mtx_unlock(_eglGlobal.Mutex); 2521bf215546Sopenharmony_ci return EGL_SUCCESS; 2522bf215546Sopenharmony_ci} 2523bf215546Sopenharmony_ci 2524bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2525bf215546Sopenharmony_cieglQueryDebugKHR(EGLint attribute, EGLAttrib *value) 2526bf215546Sopenharmony_ci{ 2527bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC); 2528bf215546Sopenharmony_ci 2529bf215546Sopenharmony_ci mtx_lock(_eglGlobal.Mutex); 2530bf215546Sopenharmony_ci 2531bf215546Sopenharmony_ci switch (attribute) { 2532bf215546Sopenharmony_ci case EGL_DEBUG_MSG_CRITICAL_KHR: 2533bf215546Sopenharmony_ci case EGL_DEBUG_MSG_ERROR_KHR: 2534bf215546Sopenharmony_ci case EGL_DEBUG_MSG_WARN_KHR: 2535bf215546Sopenharmony_ci case EGL_DEBUG_MSG_INFO_KHR: 2536bf215546Sopenharmony_ci if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute)) 2537bf215546Sopenharmony_ci *value = EGL_TRUE; 2538bf215546Sopenharmony_ci else 2539bf215546Sopenharmony_ci *value = EGL_FALSE; 2540bf215546Sopenharmony_ci break; 2541bf215546Sopenharmony_ci case EGL_DEBUG_CALLBACK_KHR: 2542bf215546Sopenharmony_ci *value = (EGLAttrib) _eglGlobal.debugCallback; 2543bf215546Sopenharmony_ci break; 2544bf215546Sopenharmony_ci default: 2545bf215546Sopenharmony_ci mtx_unlock(_eglGlobal.Mutex); 2546bf215546Sopenharmony_ci _eglReportError(EGL_BAD_ATTRIBUTE, NULL, 2547bf215546Sopenharmony_ci "Invalid attribute 0x%04lx", (unsigned long) attribute); 2548bf215546Sopenharmony_ci return EGL_FALSE; 2549bf215546Sopenharmony_ci } 2550bf215546Sopenharmony_ci 2551bf215546Sopenharmony_ci mtx_unlock(_eglGlobal.Mutex); 2552bf215546Sopenharmony_ci return EGL_TRUE; 2553bf215546Sopenharmony_ci} 2554bf215546Sopenharmony_ci 2555bf215546Sopenharmony_cistatic int 2556bf215546Sopenharmony_ci_eglFunctionCompare(const void *key, const void *elem) 2557bf215546Sopenharmony_ci{ 2558bf215546Sopenharmony_ci const char *procname = key; 2559bf215546Sopenharmony_ci const struct _egl_entrypoint *entrypoint = elem; 2560bf215546Sopenharmony_ci return strcmp(procname, entrypoint->name); 2561bf215546Sopenharmony_ci} 2562bf215546Sopenharmony_ci 2563bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2564bf215546Sopenharmony_cieglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats, 2565bf215546Sopenharmony_ci EGLint *formats, EGLint *num_formats) 2566bf215546Sopenharmony_ci{ 2567bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2568bf215546Sopenharmony_ci EGLBoolean ret; 2569bf215546Sopenharmony_ci 2570bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE); 2571bf215546Sopenharmony_ci 2572bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2573bf215546Sopenharmony_ci 2574bf215546Sopenharmony_ci ret = disp->Driver->QueryDmaBufFormatsEXT(disp, max_formats, formats, num_formats); 2575bf215546Sopenharmony_ci 2576bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2577bf215546Sopenharmony_ci} 2578bf215546Sopenharmony_ci 2579bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2580bf215546Sopenharmony_cieglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers, 2581bf215546Sopenharmony_ci EGLuint64KHR *modifiers, EGLBoolean *external_only, 2582bf215546Sopenharmony_ci EGLint *num_modifiers) 2583bf215546Sopenharmony_ci{ 2584bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2585bf215546Sopenharmony_ci EGLBoolean ret; 2586bf215546Sopenharmony_ci 2587bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE); 2588bf215546Sopenharmony_ci 2589bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2590bf215546Sopenharmony_ci 2591bf215546Sopenharmony_ci ret = disp->Driver->QueryDmaBufModifiersEXT(disp, format, max_modifiers, modifiers, 2592bf215546Sopenharmony_ci external_only, num_modifiers); 2593bf215546Sopenharmony_ci 2594bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2595bf215546Sopenharmony_ci} 2596bf215546Sopenharmony_ci 2597bf215546Sopenharmony_cistatic void EGLAPIENTRY 2598bf215546Sopenharmony_cieglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set, 2599bf215546Sopenharmony_ci EGLGetBlobFuncANDROID get) 2600bf215546Sopenharmony_ci{ 2601bf215546Sopenharmony_ci /* This function does not return anything so we cannot 2602bf215546Sopenharmony_ci * utilize the helper macros _EGL_FUNC_START or _EGL_CHECK_DISPLAY. 2603bf215546Sopenharmony_ci */ 2604bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2605bf215546Sopenharmony_ci if (!_eglSetFuncName(__func__, disp, EGL_OBJECT_DISPLAY_KHR, NULL)) { 2606bf215546Sopenharmony_ci if (disp) 2607bf215546Sopenharmony_ci _eglUnlockDisplay(disp); 2608bf215546Sopenharmony_ci return; 2609bf215546Sopenharmony_ci } 2610bf215546Sopenharmony_ci 2611bf215546Sopenharmony_ci if (!_eglCheckDisplay(disp, __func__)) { 2612bf215546Sopenharmony_ci if (disp) 2613bf215546Sopenharmony_ci _eglUnlockDisplay(disp); 2614bf215546Sopenharmony_ci return; 2615bf215546Sopenharmony_ci } 2616bf215546Sopenharmony_ci 2617bf215546Sopenharmony_ci if (!set || !get) { 2618bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, 2619bf215546Sopenharmony_ci "eglSetBlobCacheFuncsANDROID: NULL handler given"); 2620bf215546Sopenharmony_ci _eglUnlockDisplay(disp); 2621bf215546Sopenharmony_ci return; 2622bf215546Sopenharmony_ci } 2623bf215546Sopenharmony_ci 2624bf215546Sopenharmony_ci if (disp->BlobCacheSet) { 2625bf215546Sopenharmony_ci _eglError(EGL_BAD_PARAMETER, 2626bf215546Sopenharmony_ci "eglSetBlobCacheFuncsANDROID: functions already set"); 2627bf215546Sopenharmony_ci _eglUnlockDisplay(disp); 2628bf215546Sopenharmony_ci return; 2629bf215546Sopenharmony_ci } 2630bf215546Sopenharmony_ci 2631bf215546Sopenharmony_ci disp->BlobCacheSet = set; 2632bf215546Sopenharmony_ci disp->BlobCacheGet = get; 2633bf215546Sopenharmony_ci 2634bf215546Sopenharmony_ci disp->Driver->SetBlobCacheFuncsANDROID(disp, set, get); 2635bf215546Sopenharmony_ci 2636bf215546Sopenharmony_ci _eglUnlockDisplay(disp); 2637bf215546Sopenharmony_ci} 2638bf215546Sopenharmony_ci 2639bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2640bf215546Sopenharmony_cieglQueryDeviceAttribEXT(EGLDeviceEXT device, 2641bf215546Sopenharmony_ci EGLint attribute, 2642bf215546Sopenharmony_ci EGLAttrib *value) 2643bf215546Sopenharmony_ci{ 2644bf215546Sopenharmony_ci _EGLDevice *dev = _eglLookupDevice(device); 2645bf215546Sopenharmony_ci EGLBoolean ret; 2646bf215546Sopenharmony_ci 2647bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE); 2648bf215546Sopenharmony_ci if (!dev) 2649bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, EGL_FALSE); 2650bf215546Sopenharmony_ci 2651bf215546Sopenharmony_ci ret = _eglQueryDeviceAttribEXT(dev, attribute, value); 2652bf215546Sopenharmony_ci RETURN_EGL_EVAL(NULL, ret); 2653bf215546Sopenharmony_ci} 2654bf215546Sopenharmony_ci 2655bf215546Sopenharmony_cistatic const char * EGLAPIENTRY 2656bf215546Sopenharmony_cieglQueryDeviceStringEXT(EGLDeviceEXT device, 2657bf215546Sopenharmony_ci EGLint name) 2658bf215546Sopenharmony_ci{ 2659bf215546Sopenharmony_ci _EGLDevice *dev = _eglLookupDevice(device); 2660bf215546Sopenharmony_ci 2661bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL); 2662bf215546Sopenharmony_ci if (!dev) 2663bf215546Sopenharmony_ci RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, NULL); 2664bf215546Sopenharmony_ci 2665bf215546Sopenharmony_ci RETURN_EGL_EVAL(NULL, _eglQueryDeviceStringEXT(dev, name)); 2666bf215546Sopenharmony_ci} 2667bf215546Sopenharmony_ci 2668bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2669bf215546Sopenharmony_cieglQueryDevicesEXT(EGLint max_devices, 2670bf215546Sopenharmony_ci EGLDeviceEXT *devices, 2671bf215546Sopenharmony_ci EGLint *num_devices) 2672bf215546Sopenharmony_ci{ 2673bf215546Sopenharmony_ci EGLBoolean ret; 2674bf215546Sopenharmony_ci 2675bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE); 2676bf215546Sopenharmony_ci ret = _eglQueryDevicesEXT(max_devices, (_EGLDevice **) devices, 2677bf215546Sopenharmony_ci num_devices); 2678bf215546Sopenharmony_ci RETURN_EGL_EVAL(NULL, ret); 2679bf215546Sopenharmony_ci} 2680bf215546Sopenharmony_ci 2681bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY 2682bf215546Sopenharmony_cieglQueryDisplayAttribEXT(EGLDisplay dpy, 2683bf215546Sopenharmony_ci EGLint attribute, 2684bf215546Sopenharmony_ci EGLAttrib *value) 2685bf215546Sopenharmony_ci{ 2686bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2687bf215546Sopenharmony_ci 2688bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE); 2689bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, EGL_FALSE); 2690bf215546Sopenharmony_ci 2691bf215546Sopenharmony_ci switch (attribute) { 2692bf215546Sopenharmony_ci case EGL_DEVICE_EXT: 2693bf215546Sopenharmony_ci *value = (EGLAttrib) disp->Device; 2694bf215546Sopenharmony_ci break; 2695bf215546Sopenharmony_ci default: 2696bf215546Sopenharmony_ci RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_FALSE); 2697bf215546Sopenharmony_ci } 2698bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(disp, EGL_TRUE); 2699bf215546Sopenharmony_ci} 2700bf215546Sopenharmony_ci 2701bf215546Sopenharmony_cistatic char * EGLAPIENTRY 2702bf215546Sopenharmony_cieglGetDisplayDriverConfig(EGLDisplay dpy) 2703bf215546Sopenharmony_ci{ 2704bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2705bf215546Sopenharmony_ci char *ret; 2706bf215546Sopenharmony_ci 2707bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL); 2708bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, NULL); 2709bf215546Sopenharmony_ci 2710bf215546Sopenharmony_ci assert(disp->Extensions.MESA_query_driver); 2711bf215546Sopenharmony_ci 2712bf215546Sopenharmony_ci ret = disp->Driver->QueryDriverConfig(disp); 2713bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2714bf215546Sopenharmony_ci} 2715bf215546Sopenharmony_ci 2716bf215546Sopenharmony_cistatic const char * EGLAPIENTRY 2717bf215546Sopenharmony_cieglGetDisplayDriverName(EGLDisplay dpy) 2718bf215546Sopenharmony_ci{ 2719bf215546Sopenharmony_ci _EGLDisplay *disp = _eglLockDisplay(dpy); 2720bf215546Sopenharmony_ci const char *ret; 2721bf215546Sopenharmony_ci 2722bf215546Sopenharmony_ci _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL); 2723bf215546Sopenharmony_ci _EGL_CHECK_DISPLAY(disp, NULL); 2724bf215546Sopenharmony_ci 2725bf215546Sopenharmony_ci assert(disp->Extensions.MESA_query_driver); 2726bf215546Sopenharmony_ci 2727bf215546Sopenharmony_ci ret = disp->Driver->QueryDriverName(disp); 2728bf215546Sopenharmony_ci RETURN_EGL_EVAL(disp, ret); 2729bf215546Sopenharmony_ci} 2730bf215546Sopenharmony_ci 2731bf215546Sopenharmony_ci__eglMustCastToProperFunctionPointerType EGLAPIENTRY 2732bf215546Sopenharmony_cieglGetProcAddress(const char *procname) 2733bf215546Sopenharmony_ci{ 2734bf215546Sopenharmony_ci static const struct _egl_entrypoint egl_functions[] = { 2735bf215546Sopenharmony_ci#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f }, 2736bf215546Sopenharmony_ci#include "eglentrypoint.h" 2737bf215546Sopenharmony_ci#undef EGL_ENTRYPOINT 2738bf215546Sopenharmony_ci }; 2739bf215546Sopenharmony_ci _EGLProc ret = NULL; 2740bf215546Sopenharmony_ci 2741bf215546Sopenharmony_ci if (!procname) 2742bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, NULL); 2743bf215546Sopenharmony_ci 2744bf215546Sopenharmony_ci _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL); 2745bf215546Sopenharmony_ci 2746bf215546Sopenharmony_ci if (strncmp(procname, "egl", 3) == 0) { 2747bf215546Sopenharmony_ci const struct _egl_entrypoint *entrypoint = 2748bf215546Sopenharmony_ci bsearch(procname, 2749bf215546Sopenharmony_ci egl_functions, ARRAY_SIZE(egl_functions), 2750bf215546Sopenharmony_ci sizeof(egl_functions[0]), 2751bf215546Sopenharmony_ci _eglFunctionCompare); 2752bf215546Sopenharmony_ci if (entrypoint) 2753bf215546Sopenharmony_ci ret = entrypoint->function; 2754bf215546Sopenharmony_ci } 2755bf215546Sopenharmony_ci 2756bf215546Sopenharmony_ci if (!ret && _eglDriver.GetProcAddress) 2757bf215546Sopenharmony_ci ret = _eglDriver.GetProcAddress(procname); 2758bf215546Sopenharmony_ci 2759bf215546Sopenharmony_ci RETURN_EGL_SUCCESS(NULL, ret); 2760bf215546Sopenharmony_ci} 2761bf215546Sopenharmony_ci 2762bf215546Sopenharmony_cistatic int 2763bf215546Sopenharmony_ci_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context, 2764bf215546Sopenharmony_ci _EGLDisplay **disp, _EGLContext **ctx) 2765bf215546Sopenharmony_ci{ 2766bf215546Sopenharmony_ci 2767bf215546Sopenharmony_ci *disp = _eglLockDisplay(dpy); 2768bf215546Sopenharmony_ci if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) { 2769bf215546Sopenharmony_ci if (*disp) 2770bf215546Sopenharmony_ci _eglUnlockDisplay(*disp); 2771bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_DISPLAY; 2772bf215546Sopenharmony_ci } 2773bf215546Sopenharmony_ci 2774bf215546Sopenharmony_ci *ctx = _eglLookupContext(context, *disp); 2775bf215546Sopenharmony_ci if (!*ctx || 2776bf215546Sopenharmony_ci ((*ctx)->ClientAPI != EGL_OPENGL_API && 2777bf215546Sopenharmony_ci (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) { 2778bf215546Sopenharmony_ci _eglUnlockDisplay(*disp); 2779bf215546Sopenharmony_ci return MESA_GLINTEROP_INVALID_CONTEXT; 2780bf215546Sopenharmony_ci } 2781bf215546Sopenharmony_ci 2782bf215546Sopenharmony_ci return MESA_GLINTEROP_SUCCESS; 2783bf215546Sopenharmony_ci} 2784bf215546Sopenharmony_ci 2785bf215546Sopenharmony_ciPUBLIC int 2786bf215546Sopenharmony_ciMesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context, 2787bf215546Sopenharmony_ci struct mesa_glinterop_device_info *out) 2788bf215546Sopenharmony_ci{ 2789bf215546Sopenharmony_ci _EGLDisplay *disp; 2790bf215546Sopenharmony_ci _EGLContext *ctx; 2791bf215546Sopenharmony_ci int ret; 2792bf215546Sopenharmony_ci 2793bf215546Sopenharmony_ci ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx); 2794bf215546Sopenharmony_ci if (ret != MESA_GLINTEROP_SUCCESS) 2795bf215546Sopenharmony_ci return ret; 2796bf215546Sopenharmony_ci 2797bf215546Sopenharmony_ci if (disp->Driver->GLInteropQueryDeviceInfo) 2798bf215546Sopenharmony_ci ret = disp->Driver->GLInteropQueryDeviceInfo(disp, ctx, out); 2799bf215546Sopenharmony_ci else 2800bf215546Sopenharmony_ci ret = MESA_GLINTEROP_UNSUPPORTED; 2801bf215546Sopenharmony_ci 2802bf215546Sopenharmony_ci _eglUnlockDisplay(disp); 2803bf215546Sopenharmony_ci return ret; 2804bf215546Sopenharmony_ci} 2805bf215546Sopenharmony_ci 2806bf215546Sopenharmony_ciPUBLIC int 2807bf215546Sopenharmony_ciMesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context, 2808bf215546Sopenharmony_ci struct mesa_glinterop_export_in *in, 2809bf215546Sopenharmony_ci struct mesa_glinterop_export_out *out) 2810bf215546Sopenharmony_ci{ 2811bf215546Sopenharmony_ci _EGLDisplay *disp; 2812bf215546Sopenharmony_ci _EGLContext *ctx; 2813bf215546Sopenharmony_ci int ret; 2814bf215546Sopenharmony_ci 2815bf215546Sopenharmony_ci ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx); 2816bf215546Sopenharmony_ci if (ret != MESA_GLINTEROP_SUCCESS) 2817bf215546Sopenharmony_ci return ret; 2818bf215546Sopenharmony_ci 2819bf215546Sopenharmony_ci if (disp->Driver->GLInteropExportObject) 2820bf215546Sopenharmony_ci ret = disp->Driver->GLInteropExportObject(disp, ctx, in, out); 2821bf215546Sopenharmony_ci else 2822bf215546Sopenharmony_ci ret = MESA_GLINTEROP_UNSUPPORTED; 2823bf215546Sopenharmony_ci 2824bf215546Sopenharmony_ci _eglUnlockDisplay(disp); 2825bf215546Sopenharmony_ci return ret; 2826bf215546Sopenharmony_ci} 2827