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#include <assert.h> 32bf215546Sopenharmony_ci#include <stdlib.h> 33bf215546Sopenharmony_ci#include <string.h> 34bf215546Sopenharmony_ci#include "eglconfig.h" 35bf215546Sopenharmony_ci#include "eglcontext.h" 36bf215546Sopenharmony_ci#include "egldisplay.h" 37bf215546Sopenharmony_ci#include "eglcurrent.h" 38bf215546Sopenharmony_ci#include "eglsurface.h" 39bf215546Sopenharmony_ci#include "egllog.h" 40bf215546Sopenharmony_ci#include "util/macros.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci/** 44bf215546Sopenharmony_ci * Return the API bit (one of EGL_xxx_BIT) of the context. 45bf215546Sopenharmony_ci */ 46bf215546Sopenharmony_cistatic EGLint 47bf215546Sopenharmony_ci_eglGetContextAPIBit(_EGLContext *ctx) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci EGLint bit = 0; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci switch (ctx->ClientAPI) { 52bf215546Sopenharmony_ci case EGL_OPENGL_ES_API: 53bf215546Sopenharmony_ci switch (ctx->ClientMajorVersion) { 54bf215546Sopenharmony_ci case 1: 55bf215546Sopenharmony_ci bit = EGL_OPENGL_ES_BIT; 56bf215546Sopenharmony_ci break; 57bf215546Sopenharmony_ci case 2: 58bf215546Sopenharmony_ci bit = EGL_OPENGL_ES2_BIT; 59bf215546Sopenharmony_ci break; 60bf215546Sopenharmony_ci case 3: 61bf215546Sopenharmony_ci bit = EGL_OPENGL_ES3_BIT_KHR; 62bf215546Sopenharmony_ci break; 63bf215546Sopenharmony_ci default: 64bf215546Sopenharmony_ci break; 65bf215546Sopenharmony_ci } 66bf215546Sopenharmony_ci break; 67bf215546Sopenharmony_ci case EGL_OPENVG_API: 68bf215546Sopenharmony_ci bit = EGL_OPENVG_BIT; 69bf215546Sopenharmony_ci break; 70bf215546Sopenharmony_ci case EGL_OPENGL_API: 71bf215546Sopenharmony_ci bit = EGL_OPENGL_BIT; 72bf215546Sopenharmony_ci break; 73bf215546Sopenharmony_ci default: 74bf215546Sopenharmony_ci break; 75bf215546Sopenharmony_ci } 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci return bit; 78bf215546Sopenharmony_ci} 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci/** 82bf215546Sopenharmony_ci * Parse the list of context attributes and return the proper error code. 83bf215546Sopenharmony_ci */ 84bf215546Sopenharmony_cistatic EGLint 85bf215546Sopenharmony_ci_eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *disp, 86bf215546Sopenharmony_ci const EGLint *attrib_list) 87bf215546Sopenharmony_ci{ 88bf215546Sopenharmony_ci EGLenum api = ctx->ClientAPI; 89bf215546Sopenharmony_ci EGLint i, err = EGL_SUCCESS; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci if (!attrib_list) 92bf215546Sopenharmony_ci return EGL_SUCCESS; 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) { 95bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]); 96bf215546Sopenharmony_ci return EGL_BAD_ATTRIBUTE; 97bf215546Sopenharmony_ci } 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci for (i = 0; attrib_list[i] != EGL_NONE; i++) { 100bf215546Sopenharmony_ci EGLint attr = attrib_list[i++]; 101bf215546Sopenharmony_ci EGLint val = attrib_list[i]; 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci switch (attr) { 104bf215546Sopenharmony_ci case EGL_CONTEXT_CLIENT_VERSION: 105bf215546Sopenharmony_ci /* The EGL 1.4 spec says: 106bf215546Sopenharmony_ci * 107bf215546Sopenharmony_ci * "attribute EGL_CONTEXT_CLIENT_VERSION is only valid when the 108bf215546Sopenharmony_ci * current rendering API is EGL_OPENGL_ES_API" 109bf215546Sopenharmony_ci * 110bf215546Sopenharmony_ci * The EGL_KHR_create_context spec says: 111bf215546Sopenharmony_ci * 112bf215546Sopenharmony_ci * "EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 113bf215546Sopenharmony_ci * (this token is an alias for EGL_CONTEXT_CLIENT_VERSION)" 114bf215546Sopenharmony_ci * 115bf215546Sopenharmony_ci * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and 116bf215546Sopenharmony_ci * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API 117bf215546Sopenharmony_ci * version. They are only meaningful for OpenGL and OpenGL ES 118bf215546Sopenharmony_ci * contexts, and specifying them for other types of contexts will 119bf215546Sopenharmony_ci * generate an error." 120bf215546Sopenharmony_ci */ 121bf215546Sopenharmony_ci if ((api != EGL_OPENGL_ES_API && 122bf215546Sopenharmony_ci (!disp->Extensions.KHR_create_context || api != EGL_OPENGL_API))) { 123bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 124bf215546Sopenharmony_ci break; 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci ctx->ClientMajorVersion = val; 128bf215546Sopenharmony_ci break; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci case EGL_CONTEXT_MINOR_VERSION_KHR: 131bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 132bf215546Sopenharmony_ci * 133bf215546Sopenharmony_ci * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and 134bf215546Sopenharmony_ci * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API 135bf215546Sopenharmony_ci * version. They are only meaningful for OpenGL and OpenGL ES 136bf215546Sopenharmony_ci * contexts, and specifying them for other types of contexts will 137bf215546Sopenharmony_ci * generate an error." 138bf215546Sopenharmony_ci */ 139bf215546Sopenharmony_ci if (!disp->Extensions.KHR_create_context || 140bf215546Sopenharmony_ci (api != EGL_OPENGL_ES_API && api != EGL_OPENGL_API)) { 141bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 142bf215546Sopenharmony_ci break; 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci ctx->ClientMinorVersion = val; 146bf215546Sopenharmony_ci break; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci case EGL_CONTEXT_FLAGS_KHR: 149bf215546Sopenharmony_ci if (!disp->Extensions.KHR_create_context) { 150bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 151bf215546Sopenharmony_ci break; 152bf215546Sopenharmony_ci } 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 155bf215546Sopenharmony_ci * 156bf215546Sopenharmony_ci * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in 157bf215546Sopenharmony_ci * EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created. 158bf215546Sopenharmony_ci * [...] 159bf215546Sopenharmony_ci * In some cases a debug context may be identical to a non-debug 160bf215546Sopenharmony_ci * context. This bit is supported for OpenGL and OpenGL ES 161bf215546Sopenharmony_ci * contexts." 162bf215546Sopenharmony_ci */ 163bf215546Sopenharmony_ci if ((val & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) && 164bf215546Sopenharmony_ci (api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API)) { 165bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 166bf215546Sopenharmony_ci break; 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 170bf215546Sopenharmony_ci * 171bf215546Sopenharmony_ci * "If the EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR flag bit 172bf215546Sopenharmony_ci * is set in EGL_CONTEXT_FLAGS_KHR, then a <forward-compatible> 173bf215546Sopenharmony_ci * context will be created. Forward-compatible contexts are 174bf215546Sopenharmony_ci * defined only for OpenGL versions 3.0 and later. They must not 175bf215546Sopenharmony_ci * support functionality marked as <deprecated> by that version of 176bf215546Sopenharmony_ci * the API, while a non-forward-compatible context must support 177bf215546Sopenharmony_ci * all functionality in that version, deprecated or not. This bit 178bf215546Sopenharmony_ci * is supported for OpenGL contexts, and requesting a 179bf215546Sopenharmony_ci * forward-compatible context for OpenGL versions less than 3.0 180bf215546Sopenharmony_ci * will generate an error." 181bf215546Sopenharmony_ci * 182bf215546Sopenharmony_ci * Note: since the forward-compatible flag can be set more than one way, 183bf215546Sopenharmony_ci * the OpenGL version check is performed once, below. 184bf215546Sopenharmony_ci */ 185bf215546Sopenharmony_ci if ((val & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) && 186bf215546Sopenharmony_ci api != EGL_OPENGL_API) { 187bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 188bf215546Sopenharmony_ci break; 189bf215546Sopenharmony_ci } 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci if ((val & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) && 192bf215546Sopenharmony_ci api != EGL_OPENGL_API) { 193bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 194bf215546Sopenharmony_ci * 195bf215546Sopenharmony_ci * 10) Which error should be generated if robust buffer access 196bf215546Sopenharmony_ci * or reset notifications are requested under OpenGL ES? 197bf215546Sopenharmony_ci * 198bf215546Sopenharmony_ci * As per Issue 6, this extension does not support creating 199bf215546Sopenharmony_ci * robust contexts for OpenGL ES. This is only supported via 200bf215546Sopenharmony_ci * the EGL_EXT_create_context_robustness extension. 201bf215546Sopenharmony_ci * 202bf215546Sopenharmony_ci * Attempting to use this extension to create robust OpenGL 203bf215546Sopenharmony_ci * ES context will generate an EGL_BAD_ATTRIBUTE error. This 204bf215546Sopenharmony_ci * specific error is generated because this extension does 205bf215546Sopenharmony_ci * not define the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 206bf215546Sopenharmony_ci * and EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 207bf215546Sopenharmony_ci * bits for OpenGL ES contexts. Thus, use of these bits fall 208bf215546Sopenharmony_ci * under condition described by: "If an attribute is 209bf215546Sopenharmony_ci * specified that is not meaningful for the client API 210bf215546Sopenharmony_ci * type.." in the above specification. 211bf215546Sopenharmony_ci * 212bf215546Sopenharmony_ci * The spec requires that we emit the error even if the display 213bf215546Sopenharmony_ci * supports EGL_EXT_create_context_robustness. To create a robust 214bf215546Sopenharmony_ci * GLES context, the *attribute* 215bf215546Sopenharmony_ci * EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT must be used, not the 216bf215546Sopenharmony_ci * *flag* EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR. 217bf215546Sopenharmony_ci */ 218bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 219bf215546Sopenharmony_ci break; 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci ctx->Flags |= val; 223bf215546Sopenharmony_ci break; 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: 226bf215546Sopenharmony_ci if (!disp->Extensions.KHR_create_context) { 227bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 228bf215546Sopenharmony_ci break; 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 232bf215546Sopenharmony_ci * 233bf215546Sopenharmony_ci * "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for 234bf215546Sopenharmony_ci * OpenGL contexts, and specifying it for other types of 235bf215546Sopenharmony_ci * contexts, including OpenGL ES contexts, will generate an 236bf215546Sopenharmony_ci * error." 237bf215546Sopenharmony_ci */ 238bf215546Sopenharmony_ci if (api != EGL_OPENGL_API) { 239bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 240bf215546Sopenharmony_ci break; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci ctx->Profile = val; 244bf215546Sopenharmony_ci break; 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR: 247bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 248bf215546Sopenharmony_ci * 249bf215546Sopenharmony_ci * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only 250bf215546Sopenharmony_ci * meaningful for OpenGL contexts, and specifying it for other 251bf215546Sopenharmony_ci * types of contexts, including OpenGL ES contexts, will generate 252bf215546Sopenharmony_ci * an error." 253bf215546Sopenharmony_ci * 254bf215546Sopenharmony_ci * EGL 1.5 defines EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 255bf215546Sopenharmony_ci * (without a suffix) which has the same value as the KHR token, 256bf215546Sopenharmony_ci * and specifies that it now works with both GL and ES contexts: 257bf215546Sopenharmony_ci * 258bf215546Sopenharmony_ci * "This attribute is supported only for OpenGL and OpenGL ES 259bf215546Sopenharmony_ci * contexts." 260bf215546Sopenharmony_ci */ 261bf215546Sopenharmony_ci if (!(disp->Extensions.KHR_create_context && api == EGL_OPENGL_API) 262bf215546Sopenharmony_ci && !(disp->Version >= 15 && (api == EGL_OPENGL_API || 263bf215546Sopenharmony_ci api == EGL_OPENGL_ES_API))) { 264bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 265bf215546Sopenharmony_ci break; 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci ctx->ResetNotificationStrategy = val; 269bf215546Sopenharmony_ci break; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: 272bf215546Sopenharmony_ci /* The EGL_EXT_create_context_robustness spec says: 273bf215546Sopenharmony_ci * 274bf215546Sopenharmony_ci * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only 275bf215546Sopenharmony_ci * meaningful for OpenGL ES contexts, and specifying it for other 276bf215546Sopenharmony_ci * types of contexts will generate an EGL_BAD_ATTRIBUTE error." 277bf215546Sopenharmony_ci */ 278bf215546Sopenharmony_ci if (!disp->Extensions.EXT_create_context_robustness 279bf215546Sopenharmony_ci || api != EGL_OPENGL_ES_API) { 280bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 281bf215546Sopenharmony_ci break; 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci ctx->ResetNotificationStrategy = val; 285bf215546Sopenharmony_ci break; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: 288bf215546Sopenharmony_ci if (!disp->Extensions.EXT_create_context_robustness) { 289bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 290bf215546Sopenharmony_ci break; 291bf215546Sopenharmony_ci } 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci if (val == EGL_TRUE) 294bf215546Sopenharmony_ci ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; 295bf215546Sopenharmony_ci break; 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_ROBUST_ACCESS: 298bf215546Sopenharmony_ci if (disp->Version < 15) { 299bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 300bf215546Sopenharmony_ci break; 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci if (val == EGL_TRUE) 304bf215546Sopenharmony_ci ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; 305bf215546Sopenharmony_ci break; 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_DEBUG: 308bf215546Sopenharmony_ci if (disp->Version < 15) { 309bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 310bf215546Sopenharmony_ci break; 311bf215546Sopenharmony_ci } 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci if (val == EGL_TRUE) 314bf215546Sopenharmony_ci ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; 315bf215546Sopenharmony_ci break; 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE: 318bf215546Sopenharmony_ci if (disp->Version < 15) { 319bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 320bf215546Sopenharmony_ci break; 321bf215546Sopenharmony_ci } 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci if (val == EGL_TRUE) 324bf215546Sopenharmony_ci ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; 325bf215546Sopenharmony_ci break; 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_NO_ERROR_KHR: 328bf215546Sopenharmony_ci if (disp->Version < 14 || 329bf215546Sopenharmony_ci !disp->Extensions.KHR_create_context_no_error) { 330bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 331bf215546Sopenharmony_ci break; 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci /* The KHR_no_error spec only applies against OpenGL 2.0+ and 335bf215546Sopenharmony_ci * OpenGL ES 2.0+ 336bf215546Sopenharmony_ci */ 337bf215546Sopenharmony_ci if (((api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API) || 338bf215546Sopenharmony_ci ctx->ClientMajorVersion < 2) && val == EGL_TRUE) { 339bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 340bf215546Sopenharmony_ci break; 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci /* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */ 344bf215546Sopenharmony_ci ctx->NoError = !!val; 345bf215546Sopenharmony_ci break; 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_LEVEL_IMG: 348bf215546Sopenharmony_ci /* The EGL_IMG_context_priority spec says: 349bf215546Sopenharmony_ci * 350bf215546Sopenharmony_ci * "EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of 351bf215546Sopenharmony_ci * the context to be created. This attribute is a hint, as an 352bf215546Sopenharmony_ci * implementation may not support multiple contexts at some 353bf215546Sopenharmony_ci * priority levels and system policy may limit access to high 354bf215546Sopenharmony_ci * priority contexts to appropriate system privilege level. The 355bf215546Sopenharmony_ci * default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is 356bf215546Sopenharmony_ci * EGL_CONTEXT_PRIORITY_MEDIUM_IMG." 357bf215546Sopenharmony_ci */ 358bf215546Sopenharmony_ci { 359bf215546Sopenharmony_ci int bit; 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci switch (val) { 362bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_HIGH_IMG: 363bf215546Sopenharmony_ci bit = __EGL_CONTEXT_PRIORITY_HIGH_BIT; 364bf215546Sopenharmony_ci break; 365bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: 366bf215546Sopenharmony_ci bit = __EGL_CONTEXT_PRIORITY_MEDIUM_BIT; 367bf215546Sopenharmony_ci break; 368bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_LOW_IMG: 369bf215546Sopenharmony_ci bit = __EGL_CONTEXT_PRIORITY_LOW_BIT; 370bf215546Sopenharmony_ci break; 371bf215546Sopenharmony_ci default: 372bf215546Sopenharmony_ci bit = -1; 373bf215546Sopenharmony_ci break; 374bf215546Sopenharmony_ci } 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci if (bit < 0) { 377bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 378bf215546Sopenharmony_ci break; 379bf215546Sopenharmony_ci } 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci /* "This extension allows an EGLContext to be created with a 382bf215546Sopenharmony_ci * priority hint. It is possible that an implementation will not 383bf215546Sopenharmony_ci * honour the hint, especially if there are constraints on the 384bf215546Sopenharmony_ci * number of high priority contexts available in the system, or 385bf215546Sopenharmony_ci * system policy limits access to high priority contexts to 386bf215546Sopenharmony_ci * appropriate system privilege level. A query is provided to find 387bf215546Sopenharmony_ci * the real priority level assigned to the context after creation." 388bf215546Sopenharmony_ci * 389bf215546Sopenharmony_ci * We currently assume that the driver applies the priority hint 390bf215546Sopenharmony_ci * and filters out any it cannot handle during the screen setup, 391bf215546Sopenharmony_ci * e.g. dri2_setup_screen(). As such we can mask any change that 392bf215546Sopenharmony_ci * the driver would fail, and ctx->ContextPriority matches the 393bf215546Sopenharmony_ci * hint applied to the driver/hardware backend. 394bf215546Sopenharmony_ci */ 395bf215546Sopenharmony_ci if (disp->Extensions.IMG_context_priority & (1 << bit)) 396bf215546Sopenharmony_ci ctx->ContextPriority = val; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci break; 399bf215546Sopenharmony_ci } 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci case EGL_CONTEXT_RELEASE_BEHAVIOR_KHR: 402bf215546Sopenharmony_ci if (val == EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR || 403bf215546Sopenharmony_ci val == EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR) { 404bf215546Sopenharmony_ci ctx->ReleaseBehavior = val; 405bf215546Sopenharmony_ci } else { 406bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci break; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci default: 411bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 412bf215546Sopenharmony_ci break; 413bf215546Sopenharmony_ci } 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci if (err != EGL_SUCCESS) { 416bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr); 417bf215546Sopenharmony_ci break; 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci } 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci if (api == EGL_OPENGL_API) { 422bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 423bf215546Sopenharmony_ci * 424bf215546Sopenharmony_ci * "If the requested OpenGL version is less than 3.2, 425bf215546Sopenharmony_ci * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the 426bf215546Sopenharmony_ci * functionality of the context is determined solely by the 427bf215546Sopenharmony_ci * requested version." 428bf215546Sopenharmony_ci * 429bf215546Sopenharmony_ci * Since the value is ignored, only validate the setting if the version 430bf215546Sopenharmony_ci * is >= 3.2. 431bf215546Sopenharmony_ci */ 432bf215546Sopenharmony_ci if (ctx->ClientMajorVersion >= 4 433bf215546Sopenharmony_ci || (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) { 434bf215546Sopenharmony_ci switch (ctx->Profile) { 435bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR: 436bf215546Sopenharmony_ci case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR: 437bf215546Sopenharmony_ci break; 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci default: 440bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 441bf215546Sopenharmony_ci * 442bf215546Sopenharmony_ci * "* If an OpenGL context is requested, the requested version 443bf215546Sopenharmony_ci * is greater than 3.2, and the value for attribute 444bf215546Sopenharmony_ci * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has 445bf215546Sopenharmony_ci * any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 446bf215546Sopenharmony_ci * and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has 447bf215546Sopenharmony_ci * more than one of these bits set; or if the implementation does 448bf215546Sopenharmony_ci * not support the requested profile, then an EGL_BAD_MATCH error 449bf215546Sopenharmony_ci * is generated." 450bf215546Sopenharmony_ci */ 451bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 452bf215546Sopenharmony_ci break; 453bf215546Sopenharmony_ci } 454bf215546Sopenharmony_ci } 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 457bf215546Sopenharmony_ci * 458bf215546Sopenharmony_ci * "* If an OpenGL context is requested and the values for 459bf215546Sopenharmony_ci * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and 460bf215546Sopenharmony_ci * EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with 461bf215546Sopenharmony_ci * the value for attribute 462bf215546Sopenharmony_ci * EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL 463bf215546Sopenharmony_ci * version and feature set that are not defined, than an 464bf215546Sopenharmony_ci * EGL_BAD_MATCH error is generated. 465bf215546Sopenharmony_ci * 466bf215546Sopenharmony_ci * ... Thus, examples of invalid combinations of attributes 467bf215546Sopenharmony_ci * include: 468bf215546Sopenharmony_ci * 469bf215546Sopenharmony_ci * - Major version < 1 or > 4 470bf215546Sopenharmony_ci * - Major version == 1 and minor version < 0 or > 5 471bf215546Sopenharmony_ci * - Major version == 2 and minor version < 0 or > 1 472bf215546Sopenharmony_ci * - Major version == 3 and minor version < 0 or > 2 473bf215546Sopenharmony_ci * - Major version == 4 and minor version < 0 or > 2 474bf215546Sopenharmony_ci * - Forward-compatible flag set and major version < 3" 475bf215546Sopenharmony_ci */ 476bf215546Sopenharmony_ci if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) 477bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci switch (ctx->ClientMajorVersion) { 480bf215546Sopenharmony_ci case 1: 481bf215546Sopenharmony_ci if (ctx->ClientMinorVersion > 5 482bf215546Sopenharmony_ci || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) 483bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 484bf215546Sopenharmony_ci break; 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci case 2: 487bf215546Sopenharmony_ci if (ctx->ClientMinorVersion > 1 488bf215546Sopenharmony_ci || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) 489bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 490bf215546Sopenharmony_ci break; 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci case 3: 493bf215546Sopenharmony_ci /* Note: The text above is incorrect. There *is* an OpenGL 3.3! 494bf215546Sopenharmony_ci */ 495bf215546Sopenharmony_ci if (ctx->ClientMinorVersion > 3) 496bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 497bf215546Sopenharmony_ci break; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci case 4: 500bf215546Sopenharmony_ci default: 501bf215546Sopenharmony_ci /* Don't put additional version checks here. We don't know that 502bf215546Sopenharmony_ci * there won't be versions > 4.2. 503bf215546Sopenharmony_ci */ 504bf215546Sopenharmony_ci break; 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci } else if (api == EGL_OPENGL_ES_API) { 507bf215546Sopenharmony_ci /* The EGL_KHR_create_context spec says: 508bf215546Sopenharmony_ci * 509bf215546Sopenharmony_ci * "* If an OpenGL ES context is requested and the values for 510bf215546Sopenharmony_ci * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and 511bf215546Sopenharmony_ci * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that 512bf215546Sopenharmony_ci * is not defined, than an EGL_BAD_MATCH error is generated. 513bf215546Sopenharmony_ci * 514bf215546Sopenharmony_ci * ... Examples of invalid combinations of attributes include: 515bf215546Sopenharmony_ci * 516bf215546Sopenharmony_ci * - Major version < 1 or > 2 517bf215546Sopenharmony_ci * - Major version == 1 and minor version < 0 or > 1 518bf215546Sopenharmony_ci * - Major version == 2 and minor version != 0 519bf215546Sopenharmony_ci */ 520bf215546Sopenharmony_ci if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) 521bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci switch (ctx->ClientMajorVersion) { 524bf215546Sopenharmony_ci case 1: 525bf215546Sopenharmony_ci if (ctx->ClientMinorVersion > 1) 526bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 527bf215546Sopenharmony_ci break; 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci case 2: 530bf215546Sopenharmony_ci if (ctx->ClientMinorVersion > 0) 531bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 532bf215546Sopenharmony_ci break; 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci case 3: 535bf215546Sopenharmony_ci /* Don't put additional version checks here. We don't know that 536bf215546Sopenharmony_ci * there won't be versions > 3.0. 537bf215546Sopenharmony_ci */ 538bf215546Sopenharmony_ci break; 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci default: 541bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 542bf215546Sopenharmony_ci break; 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci switch (ctx->ResetNotificationStrategy) { 547bf215546Sopenharmony_ci case EGL_NO_RESET_NOTIFICATION_KHR: 548bf215546Sopenharmony_ci case EGL_LOSE_CONTEXT_ON_RESET_KHR: 549bf215546Sopenharmony_ci break; 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci default: 552bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 553bf215546Sopenharmony_ci break; 554bf215546Sopenharmony_ci } 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci /* The EGL_KHR_create_context_no_error spec says: 557bf215546Sopenharmony_ci * 558bf215546Sopenharmony_ci * "BAD_MATCH is generated if the EGL_CONTEXT_OPENGL_NO_ERROR_KHR is TRUE at 559bf215546Sopenharmony_ci * the same time as a debug or robustness context is specified." 560bf215546Sopenharmony_ci */ 561bf215546Sopenharmony_ci if (ctx->NoError && (ctx->Flags & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR || 562bf215546Sopenharmony_ci ctx->Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) { 563bf215546Sopenharmony_ci err = EGL_BAD_MATCH; 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 567bf215546Sopenharmony_ci | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 568bf215546Sopenharmony_ci | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) { 569bf215546Sopenharmony_ci err = EGL_BAD_ATTRIBUTE; 570bf215546Sopenharmony_ci } 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci return err; 573bf215546Sopenharmony_ci} 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci/** 577bf215546Sopenharmony_ci * Initialize the given _EGLContext object to defaults and/or the values 578bf215546Sopenharmony_ci * in the attrib_list. 579bf215546Sopenharmony_ci * 580bf215546Sopenharmony_ci * According to EGL 1.5 Section 3.7: 581bf215546Sopenharmony_ci * 582bf215546Sopenharmony_ci * "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all 583bf215546Sopenharmony_ci * purposes except eglCreateContext." 584bf215546Sopenharmony_ci * 585bf215546Sopenharmony_ci * And since we only support GL and GLES, this is the only place where the 586bf215546Sopenharmony_ci * bound API matters at all. We look up the current API from the current 587bf215546Sopenharmony_ci * thread, and stash that in the context we're initializing. Our caller is 588bf215546Sopenharmony_ci * responsible for determining whether that's an API it supports. 589bf215546Sopenharmony_ci */ 590bf215546Sopenharmony_ciEGLBoolean 591bf215546Sopenharmony_ci_eglInitContext(_EGLContext *ctx, _EGLDisplay *disp, _EGLConfig *conf, 592bf215546Sopenharmony_ci const EGLint *attrib_list) 593bf215546Sopenharmony_ci{ 594bf215546Sopenharmony_ci const EGLenum api = eglQueryAPI(); 595bf215546Sopenharmony_ci EGLint err; 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci if (api == EGL_NONE) 598bf215546Sopenharmony_ci return _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)"); 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci _eglInitResource(&ctx->Resource, sizeof(*ctx), disp); 601bf215546Sopenharmony_ci ctx->ClientAPI = api; 602bf215546Sopenharmony_ci ctx->Config = conf; 603bf215546Sopenharmony_ci ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci ctx->ClientMajorVersion = 1; /* the default, per EGL spec */ 606bf215546Sopenharmony_ci ctx->ClientMinorVersion = 0; 607bf215546Sopenharmony_ci ctx->Flags = 0; 608bf215546Sopenharmony_ci ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR; 609bf215546Sopenharmony_ci ctx->ContextPriority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; 610bf215546Sopenharmony_ci ctx->ReleaseBehavior = EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR; 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci err = _eglParseContextAttribList(ctx, disp, attrib_list); 613bf215546Sopenharmony_ci if (err == EGL_SUCCESS && ctx->Config) { 614bf215546Sopenharmony_ci EGLint api_bit; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci api_bit = _eglGetContextAPIBit(ctx); 617bf215546Sopenharmony_ci if (!(ctx->Config->RenderableType & api_bit)) { 618bf215546Sopenharmony_ci _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x", 619bf215546Sopenharmony_ci api_bit, ctx->Config->RenderableType); 620bf215546Sopenharmony_ci err = EGL_BAD_CONFIG; 621bf215546Sopenharmony_ci } 622bf215546Sopenharmony_ci } 623bf215546Sopenharmony_ci if (err != EGL_SUCCESS) 624bf215546Sopenharmony_ci return _eglError(err, "eglCreateContext"); 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci return EGL_TRUE; 627bf215546Sopenharmony_ci} 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_cistatic EGLint 631bf215546Sopenharmony_ci_eglQueryContextRenderBuffer(_EGLContext *ctx) 632bf215546Sopenharmony_ci{ 633bf215546Sopenharmony_ci _EGLSurface *surf = ctx->DrawSurface; 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci /* From the EGL 1.5 spec: 636bf215546Sopenharmony_ci * 637bf215546Sopenharmony_ci * - If the context is not bound to a surface, then EGL_NONE will be 638bf215546Sopenharmony_ci * returned. 639bf215546Sopenharmony_ci */ 640bf215546Sopenharmony_ci if (!surf) 641bf215546Sopenharmony_ci return EGL_NONE; 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci switch (surf->Type) { 644bf215546Sopenharmony_ci default: 645bf215546Sopenharmony_ci unreachable("bad EGLSurface type"); 646bf215546Sopenharmony_ci case EGL_PIXMAP_BIT: 647bf215546Sopenharmony_ci /* - If the context is bound to a pixmap surface, then EGL_SINGLE_BUFFER 648bf215546Sopenharmony_ci * will be returned. 649bf215546Sopenharmony_ci */ 650bf215546Sopenharmony_ci return EGL_SINGLE_BUFFER; 651bf215546Sopenharmony_ci case EGL_PBUFFER_BIT: 652bf215546Sopenharmony_ci /* - If the context is bound to a pbuffer surface, then EGL_BACK_BUFFER 653bf215546Sopenharmony_ci * will be returned. 654bf215546Sopenharmony_ci */ 655bf215546Sopenharmony_ci return EGL_BACK_BUFFER; 656bf215546Sopenharmony_ci case EGL_WINDOW_BIT: 657bf215546Sopenharmony_ci /* - If the context is bound to a window surface, then either 658bf215546Sopenharmony_ci * EGL_BACK_BUFFER or EGL_SINGLE_BUFFER may be returned. The value 659bf215546Sopenharmony_ci * returned depends on both the buffer requested by the setting of the 660bf215546Sopenharmony_ci * EGL_RENDER_BUFFER property of the surface [...], and on the client 661bf215546Sopenharmony_ci * API (not all client APIs support single-buffer Rendering to window 662bf215546Sopenharmony_ci * surfaces). Some client APIs allow control of whether rendering goes 663bf215546Sopenharmony_ci * to the front or back buffer. This client API-specific choice is not 664bf215546Sopenharmony_ci * reflected in the returned value, which only describes the buffer 665bf215546Sopenharmony_ci * that will be rendered to by default if not overridden by the client 666bf215546Sopenharmony_ci * API. 667bf215546Sopenharmony_ci */ 668bf215546Sopenharmony_ci return surf->ActiveRenderBuffer; 669bf215546Sopenharmony_ci } 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ciEGLBoolean 674bf215546Sopenharmony_ci_eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value) 675bf215546Sopenharmony_ci{ 676bf215546Sopenharmony_ci if (!value) 677bf215546Sopenharmony_ci return _eglError(EGL_BAD_PARAMETER, "eglQueryContext"); 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci switch (attribute) { 680bf215546Sopenharmony_ci case EGL_CONFIG_ID: 681bf215546Sopenharmony_ci /* 682bf215546Sopenharmony_ci * From EGL_KHR_no_config_context: 683bf215546Sopenharmony_ci * 684bf215546Sopenharmony_ci * "Querying EGL_CONFIG_ID returns the ID of the EGLConfig with 685bf215546Sopenharmony_ci * respect to which the context was created, or zero if created 686bf215546Sopenharmony_ci * without respect to an EGLConfig." 687bf215546Sopenharmony_ci */ 688bf215546Sopenharmony_ci *value = c->Config ? c->Config->ConfigID : 0; 689bf215546Sopenharmony_ci break; 690bf215546Sopenharmony_ci case EGL_CONTEXT_CLIENT_VERSION: 691bf215546Sopenharmony_ci *value = c->ClientMajorVersion; 692bf215546Sopenharmony_ci break; 693bf215546Sopenharmony_ci case EGL_CONTEXT_CLIENT_TYPE: 694bf215546Sopenharmony_ci *value = c->ClientAPI; 695bf215546Sopenharmony_ci break; 696bf215546Sopenharmony_ci case EGL_RENDER_BUFFER: 697bf215546Sopenharmony_ci *value = _eglQueryContextRenderBuffer(c); 698bf215546Sopenharmony_ci break; 699bf215546Sopenharmony_ci case EGL_CONTEXT_PRIORITY_LEVEL_IMG: 700bf215546Sopenharmony_ci *value = c->ContextPriority; 701bf215546Sopenharmony_ci break; 702bf215546Sopenharmony_ci default: 703bf215546Sopenharmony_ci return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext"); 704bf215546Sopenharmony_ci } 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci return EGL_TRUE; 707bf215546Sopenharmony_ci} 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci/** 711bf215546Sopenharmony_ci * Bind the context to the thread and return the previous context. 712bf215546Sopenharmony_ci * 713bf215546Sopenharmony_ci * Note that the context may be NULL. 714bf215546Sopenharmony_ci */ 715bf215546Sopenharmony_ci_EGLContext * 716bf215546Sopenharmony_ci_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t) 717bf215546Sopenharmony_ci{ 718bf215546Sopenharmony_ci _EGLContext *oldCtx; 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci oldCtx = t->CurrentContext; 721bf215546Sopenharmony_ci if (ctx != oldCtx) { 722bf215546Sopenharmony_ci if (oldCtx) 723bf215546Sopenharmony_ci oldCtx->Binding = NULL; 724bf215546Sopenharmony_ci if (ctx) 725bf215546Sopenharmony_ci ctx->Binding = t; 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_ci t->CurrentContext = ctx; 728bf215546Sopenharmony_ci } 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci return oldCtx; 731bf215546Sopenharmony_ci} 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci/** 735bf215546Sopenharmony_ci * Return true if the given context and surfaces can be made current. 736bf215546Sopenharmony_ci */ 737bf215546Sopenharmony_cistatic EGLBoolean 738bf215546Sopenharmony_ci_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) 739bf215546Sopenharmony_ci{ 740bf215546Sopenharmony_ci _EGLThreadInfo *t = _eglGetCurrentThread(); 741bf215546Sopenharmony_ci _EGLDisplay *disp; 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci /* this is easy */ 744bf215546Sopenharmony_ci if (!ctx) { 745bf215546Sopenharmony_ci if (draw || read) 746bf215546Sopenharmony_ci return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); 747bf215546Sopenharmony_ci return EGL_TRUE; 748bf215546Sopenharmony_ci } 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci disp = ctx->Resource.Display; 751bf215546Sopenharmony_ci if (!disp->Extensions.KHR_surfaceless_context 752bf215546Sopenharmony_ci && (draw == NULL || read == NULL)) 753bf215546Sopenharmony_ci return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci /* 756bf215546Sopenharmony_ci * The spec says 757bf215546Sopenharmony_ci * 758bf215546Sopenharmony_ci * "If ctx is current to some other thread, or if either draw or read are 759bf215546Sopenharmony_ci * bound to contexts in another thread, an EGL_BAD_ACCESS error is 760bf215546Sopenharmony_ci * generated." 761bf215546Sopenharmony_ci * 762bf215546Sopenharmony_ci * and 763bf215546Sopenharmony_ci * 764bf215546Sopenharmony_ci * "at most one context may be bound to a particular surface at a given 765bf215546Sopenharmony_ci * time" 766bf215546Sopenharmony_ci */ 767bf215546Sopenharmony_ci if (ctx->Binding && ctx->Binding != t) 768bf215546Sopenharmony_ci return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); 769bf215546Sopenharmony_ci if (draw && draw->CurrentContext && draw->CurrentContext != ctx) { 770bf215546Sopenharmony_ci if (draw->CurrentContext->Binding != t) 771bf215546Sopenharmony_ci return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); 772bf215546Sopenharmony_ci } 773bf215546Sopenharmony_ci if (read && read->CurrentContext && read->CurrentContext != ctx) { 774bf215546Sopenharmony_ci if (read->CurrentContext->Binding != t) 775bf215546Sopenharmony_ci return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); 776bf215546Sopenharmony_ci } 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci /* If the context has a config then it must match that of the two 779bf215546Sopenharmony_ci * surfaces */ 780bf215546Sopenharmony_ci if (ctx->Config) { 781bf215546Sopenharmony_ci if ((draw && draw->Config != ctx->Config) || 782bf215546Sopenharmony_ci (read && read->Config != ctx->Config)) 783bf215546Sopenharmony_ci return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); 784bf215546Sopenharmony_ci } else { 785bf215546Sopenharmony_ci /* Otherwise we must be using the EGL_KHR_no_config_context 786bf215546Sopenharmony_ci * extension */ 787bf215546Sopenharmony_ci assert(disp->Extensions.KHR_no_config_context); 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci /* The extension doesn't permit binding draw and read buffers with 790bf215546Sopenharmony_ci * differing contexts */ 791bf215546Sopenharmony_ci if (draw && read && draw->Config != read->Config) 792bf215546Sopenharmony_ci return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); 793bf215546Sopenharmony_ci } 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_ci return EGL_TRUE; 796bf215546Sopenharmony_ci} 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci/** 800bf215546Sopenharmony_ci * Bind the context to the current thread and given surfaces. Return the 801bf215546Sopenharmony_ci * previous bound context and surfaces. The caller should unreference the 802bf215546Sopenharmony_ci * returned context and surfaces. 803bf215546Sopenharmony_ci * 804bf215546Sopenharmony_ci * Making a second call with the resources returned by the first call 805bf215546Sopenharmony_ci * unsurprisingly undoes the first call, except for the resouce reference 806bf215546Sopenharmony_ci * counts. 807bf215546Sopenharmony_ci */ 808bf215546Sopenharmony_ciEGLBoolean 809bf215546Sopenharmony_ci_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read, 810bf215546Sopenharmony_ci _EGLContext **old_ctx, 811bf215546Sopenharmony_ci _EGLSurface **old_draw, _EGLSurface **old_read) 812bf215546Sopenharmony_ci{ 813bf215546Sopenharmony_ci _EGLThreadInfo *t = _eglGetCurrentThread(); 814bf215546Sopenharmony_ci _EGLContext *prev_ctx; 815bf215546Sopenharmony_ci _EGLSurface *prev_draw, *prev_read; 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci if (!_eglCheckMakeCurrent(ctx, draw, read)) 818bf215546Sopenharmony_ci return EGL_FALSE; 819bf215546Sopenharmony_ci 820bf215546Sopenharmony_ci /* increment refcounts before binding */ 821bf215546Sopenharmony_ci _eglGetContext(ctx); 822bf215546Sopenharmony_ci _eglGetSurface(draw); 823bf215546Sopenharmony_ci _eglGetSurface(read); 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_ci /* bind the new context */ 826bf215546Sopenharmony_ci prev_ctx = _eglBindContextToThread(ctx, t); 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci /* break previous bindings */ 829bf215546Sopenharmony_ci if (prev_ctx) { 830bf215546Sopenharmony_ci prev_draw = prev_ctx->DrawSurface; 831bf215546Sopenharmony_ci prev_read = prev_ctx->ReadSurface; 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci if (prev_draw) 834bf215546Sopenharmony_ci prev_draw->CurrentContext = NULL; 835bf215546Sopenharmony_ci if (prev_read) 836bf215546Sopenharmony_ci prev_read->CurrentContext = NULL; 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci prev_ctx->DrawSurface = NULL; 839bf215546Sopenharmony_ci prev_ctx->ReadSurface = NULL; 840bf215546Sopenharmony_ci } 841bf215546Sopenharmony_ci else { 842bf215546Sopenharmony_ci prev_draw = prev_read = NULL; 843bf215546Sopenharmony_ci } 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci /* establish new bindings */ 846bf215546Sopenharmony_ci if (ctx) { 847bf215546Sopenharmony_ci if (draw) 848bf215546Sopenharmony_ci draw->CurrentContext = ctx; 849bf215546Sopenharmony_ci if (read) 850bf215546Sopenharmony_ci read->CurrentContext = ctx; 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci ctx->DrawSurface = draw; 853bf215546Sopenharmony_ci ctx->ReadSurface = read; 854bf215546Sopenharmony_ci } 855bf215546Sopenharmony_ci 856bf215546Sopenharmony_ci assert(old_ctx && old_draw && old_read); 857bf215546Sopenharmony_ci *old_ctx = prev_ctx; 858bf215546Sopenharmony_ci *old_draw = prev_draw; 859bf215546Sopenharmony_ci *old_read = prev_read; 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci return EGL_TRUE; 862bf215546Sopenharmony_ci} 863