The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

c/client: Split EGL creation functions into smaller helper functions

+164 -110
+164 -110
src/xrt/compositor/client/comp_egl_client.c
··· 65 65 typedef EGLBoolean 66 66 EGLAPIENTRY (*PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); 67 67 68 + static xrt_result_t 69 + client_egl_insert_fence(struct xrt_compositor *xc, xrt_graphics_sync_handle_t *out_handle); 70 + 68 71 69 72 /* 70 73 * ··· 100 103 101 104 return eglMakeCurrent(dpy, ctx->draw, ctx->read, ctx->ctx); 102 105 } 106 + 103 107 104 108 /* 105 109 * ··· 154 158 } 155 159 } 156 160 161 + 162 + /* 163 + * 164 + * Creation helper functions. 165 + * 166 + */ 167 + 157 168 static void 158 169 ensure_native_fence_is_loaded(EGLDisplay dpy, PFNEGLGETPROCADDRESSPROC get_gl_procaddr) 159 170 { ··· 178 189 #endif 179 190 } 180 191 192 + static xrt_result_t 193 + load_gl_functions(EGLint egl_client_type, PFNEGLGETPROCADDRESSPROC get_gl_procaddr) 194 + { 195 + switch (egl_client_type) { 196 + case EGL_OPENGL_API: 197 + #if defined(XRT_HAVE_OPENGL) 198 + EGL_DEBUG("Loading GL functions"); 199 + gladLoadGL(get_gl_procaddr); 200 + break; 201 + #else 202 + EGL_ERROR("OpenGL support not including in this runtime build"); 203 + return XRT_ERROR_OPENGL; 204 + #endif 205 + 206 + case EGL_OPENGL_ES_API: 207 + #if defined(XRT_HAVE_OPENGLES) 208 + EGL_DEBUG("Loading GLES2 functions"); 209 + gladLoadGLES2(get_gl_procaddr); 210 + break; 211 + #else 212 + EGL_ERROR("OpenGL|ES support not including in this runtime build"); 213 + return XRT_ERROR_OPENGL; 214 + #endif 215 + default: EGL_ERROR("Unsupported EGL client type: 0x%x", egl_client_type); return XRT_ERROR_OPENGL; 216 + } 217 + 218 + if (glGetString == NULL) { 219 + EGL_ERROR("glGetString not loaded!"); 220 + return XRT_ERROR_OPENGL; 221 + } 222 + 223 + return XRT_SUCCESS; 224 + } 225 + 226 + static xrt_result_t 227 + check_context_and_debug_print(EGLint egl_client_type) 228 + { 229 + EGL_DEBUG( // 230 + "OpenGL context:" // 231 + "\n\tGL_VERSION: %s" // 232 + "\n\tGL_RENDERER: %s" // 233 + "\n\tGL_VENDOR: %s", // 234 + glGetString(GL_VERSION), // 235 + glGetString(GL_RENDERER), // 236 + glGetString(GL_VENDOR)); // 237 + 238 + 239 + /* 240 + * If a renderer is old enough to not support OpenGL(ES) 3 or above 241 + * it won't support Monado at all, it's not a hard requirement and 242 + * lets us detect weird errors early on some platforms. 243 + */ 244 + if (!GLAD_GL_VERSION_3_0 && !GLAD_GL_ES_VERSION_3_0) { 245 + switch (egl_client_type) { 246 + default: EGL_ERROR("Unknown OpenGL version!"); break; 247 + case EGL_OPENGL_API: EGL_ERROR("Must have OpenGL 3.0 or above!"); break; 248 + case EGL_OPENGL_ES_API: EGL_ERROR("Must have OpenGL ES 3.0 or above!"); break; 249 + } 250 + 251 + return XRT_ERROR_OPENGL; 252 + } 253 + 254 + 255 + EGL_DEBUG("Extension availability:"); 256 + #define DUMP_EXTENSION_STATUS(EXT) EGL_DEBUG(" - " #EXT ": %s", GLAD_##EXT ? "true" : "false") 257 + 258 + DUMP_EXTENSION_STATUS(GL_EXT_memory_object); 259 + DUMP_EXTENSION_STATUS(GL_EXT_memory_object_fd); 260 + DUMP_EXTENSION_STATUS(GL_EXT_memory_object_win32); 261 + DUMP_EXTENSION_STATUS(GL_OES_EGL_image_external); 262 + 263 + DUMP_EXTENSION_STATUS(EGL_ANDROID_get_native_client_buffer); 264 + DUMP_EXTENSION_STATUS(EGL_ANDROID_native_fence_sync); 265 + DUMP_EXTENSION_STATUS(EGL_EXT_image_dma_buf_import_modifiers); 266 + DUMP_EXTENSION_STATUS(EGL_KHR_fence_sync); 267 + DUMP_EXTENSION_STATUS(EGL_KHR_image); 268 + DUMP_EXTENSION_STATUS(EGL_KHR_image_base); 269 + DUMP_EXTENSION_STATUS(EGL_KHR_reusable_sync); 270 + DUMP_EXTENSION_STATUS(EGL_KHR_wait_sync); 271 + 272 + #undef DUMP_EXTENSION_STATUS 273 + 274 + 275 + return XRT_SUCCESS; 276 + } 277 + 278 + static xrt_result_t 279 + get_client_gl_functions(client_gl_swapchain_create_func_t *out_sc_create_func, 280 + client_gl_insert_fence_func_t *out_insert_fence) 281 + { 282 + client_gl_swapchain_create_func_t sc_create_func = NULL; 283 + client_gl_insert_fence_func_t insert_fence_func = NULL; 284 + 285 + 286 + #if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD) 287 + 288 + if (GLAD_GL_EXT_memory_object && GLAD_GL_EXT_memory_object_fd) { 289 + EGL_DEBUG("Using GL memory object swapchain implementation"); 290 + sc_create_func = client_gl_memobj_swapchain_create; 291 + } 292 + 293 + if (sc_create_func == NULL && GLAD_EGL_EXT_image_dma_buf_import) { 294 + EGL_DEBUG("Using EGL_Image swapchain implementation"); 295 + sc_create_func = client_gl_eglimage_swapchain_create; 296 + } 297 + 298 + if (sc_create_func == NULL) { 299 + EGL_ERROR( 300 + "Could not find a required extension: need either EGL_EXT_image_dma_buf_import or " 301 + "GL_EXT_memory_object_fd"); 302 + return XRT_ERROR_OPENGL; 303 + } 304 + 305 + #elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER) 306 + 307 + EGL_DEBUG("Using EGL_Image swapchain implementation with AHardwareBuffer"); 308 + sc_create_func = client_gl_eglimage_swapchain_create; 309 + 310 + #endif 311 + 312 + /* 313 + * For now, only use the insert_fence callback only if 314 + * EGL_ANDROID_native_fence_sync is available, revisit this when a more 315 + * generic synchronization mechanism is implemented. 316 + */ 317 + if (GLAD_EGL_ANDROID_native_fence_sync) { 318 + insert_fence_func = client_egl_insert_fence; 319 + } 320 + 321 + *out_sc_create_func = sc_create_func; 322 + *out_insert_fence = insert_fence_func; 323 + 324 + return XRT_SUCCESS; 325 + } 326 + 181 327 182 328 /* 183 329 * 184 - * Functions. 330 + * GL callback functions. 185 331 * 186 332 */ 187 333 ··· 268 414 struct xrt_compositor_gl **out_xcgl) 269 415 { 270 416 log_level = debug_get_log_option_egl_log(); 417 + xrt_result_t xret; 271 418 272 419 273 420 /* ··· 319 466 320 467 321 468 /* 322 - * Load GL functions. 469 + * Use helpers to do all setup. 323 470 */ 324 471 325 - switch (egl_client_type) { 326 - case EGL_OPENGL_API: 327 - #if defined(XRT_HAVE_OPENGL) 328 - EGL_DEBUG("Loading GL functions"); 329 - gladLoadGL(get_gl_procaddr); 330 - break; 331 - #else 332 - EGL_ERROR("OpenGL support not including in this runtime build"); 472 + // Load GL functions, only EGL functions where loaded above. 473 + xret = load_gl_functions(egl_client_type, get_gl_procaddr); 474 + if (xret != XRT_SUCCESS) { 333 475 restore_context(&old); 334 - return XRT_ERROR_OPENGL; 335 - #endif 336 - 337 - case EGL_OPENGL_ES_API: 338 - #if defined(XRT_HAVE_OPENGLES) 339 - EGL_DEBUG("Loading GLES2 functions"); 340 - gladLoadGLES2(get_gl_procaddr); 341 - break; 342 - #else 343 - EGL_ERROR("OpenGL|ES support not including in this runtime build"); 344 - restore_context(&old); 345 - return XRT_ERROR_OPENGL; 346 - #endif 347 - default: 348 - EGL_ERROR("Unsupported EGL client type: 0x%x", egl_client_type); 349 - restore_context(&old); 350 - return XRT_ERROR_OPENGL; 476 + return xret; 351 477 } 352 478 353 - 354 - /* 355 - * Some sanity checking. 356 - */ 357 - 358 - if (glGetString == NULL) { 359 - EGL_ERROR("glGetString not loaded!"); 479 + // Some consistency/extension availability checking. 480 + xret = check_context_and_debug_print(egl_client_type); 481 + if (xret != XRT_SUCCESS) { 360 482 restore_context(&old); 361 - return XRT_ERROR_OPENGL; 483 + return xret; 362 484 } 363 485 364 - EGL_DEBUG("EGL made context:\n\tGL_VERSION: %s\n\tGL_RENDERER: %s\n\tGL_VENDOR: %s", // 365 - glGetString(GL_VERSION), glGetString(GL_RENDERER), glGetString(GL_VENDOR)); 486 + // Get functions. 487 + client_gl_swapchain_create_func_t sc_create_func = NULL; 488 + client_gl_insert_fence_func_t insert_fence_func = NULL; 366 489 367 - /* 368 - * If a renderer is old enough to not support OpenGL(ES) 3 or above 369 - * it won't support Monado at all, it's not a hard requirement and 370 - * lets us detect weird errors early on some platforms. 371 - */ 372 - if (!GLAD_GL_VERSION_3_0 && !GLAD_GL_ES_VERSION_3_0) { 373 - switch (egl_client_type) { 374 - default: EGL_ERROR("Unknown OpenGL version!"); break; 375 - case EGL_OPENGL_API: EGL_ERROR("OpenGL 3.0 or above!"); break; 376 - case EGL_OPENGL_ES_API: EGL_ERROR("OpenGL ES 3.0 or above!"); break; 377 - } 378 - 490 + xret = get_client_gl_functions(&sc_create_func, &insert_fence_func); 491 + if (xret != XRT_SUCCESS) { 379 492 restore_context(&old); 380 - return XRT_ERROR_OPENGL; 493 + return xret; 381 494 } 382 495 383 496 ··· 389 502 ceglc->current.dpy = display; 390 503 ceglc->current.ctx = context; 391 504 392 - client_gl_swapchain_create_func_t sc_create = NULL; 393 - 394 - EGL_DEBUG("Extension availability:"); 395 - #define DUMP_EXTENSION_STATUS(EXT) EGL_DEBUG(" - " #EXT ": %s", GLAD_##EXT ? "true" : "false") 396 - 397 - DUMP_EXTENSION_STATUS(GL_EXT_memory_object); 398 - DUMP_EXTENSION_STATUS(GL_EXT_memory_object_fd); 399 - DUMP_EXTENSION_STATUS(GL_EXT_memory_object_win32); 400 - DUMP_EXTENSION_STATUS(GL_OES_EGL_image_external); 401 - 402 - DUMP_EXTENSION_STATUS(EGL_ANDROID_get_native_client_buffer); 403 - DUMP_EXTENSION_STATUS(EGL_ANDROID_native_fence_sync); 404 - DUMP_EXTENSION_STATUS(EGL_EXT_image_dma_buf_import_modifiers); 405 - DUMP_EXTENSION_STATUS(EGL_KHR_fence_sync); 406 - DUMP_EXTENSION_STATUS(EGL_KHR_image); 407 - DUMP_EXTENSION_STATUS(EGL_KHR_image_base); 408 - DUMP_EXTENSION_STATUS(EGL_KHR_reusable_sync); 409 - DUMP_EXTENSION_STATUS(EGL_KHR_wait_sync); 410 - 411 - #undef DUMP_EXTENSION_STATUS 412 - 413 - #if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD) 414 - 415 - if (GLAD_GL_EXT_memory_object && GLAD_GL_EXT_memory_object_fd) { 416 - EGL_DEBUG("Using GL memory object swapchain implementation"); 417 - sc_create = client_gl_memobj_swapchain_create; 418 - } 419 - 420 - if (sc_create == NULL && GLAD_EGL_EXT_image_dma_buf_import) { 421 - EGL_DEBUG("Using EGL_Image swapchain implementation"); 422 - sc_create = client_gl_eglimage_swapchain_create; 423 - } 424 - 425 - if (sc_create == NULL) { 426 - free(ceglc); 427 - EGL_ERROR( 428 - "Could not find a required extension: need either EGL_EXT_image_dma_buf_import or " 429 - "GL_EXT_memory_object_fd"); 430 - restore_context(&old); 431 - return XRT_ERROR_OPENGL; 432 - } 433 - 434 - #elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER) 435 - 436 - EGL_DEBUG("Using EGL_Image swapchain implementation with AHardwareBuffer"); 437 - sc_create = client_gl_eglimage_swapchain_create; 438 - 439 - #endif 440 - 441 - /* 442 - * For now, only use the insert_fence callback only if 443 - * EGL_ANDROID_native_fence_sync is available, revisit this when a more 444 - * generic synchronization mechanism is implemented. 445 - */ 446 - client_gl_insert_fence_func_t insert_fence_func = NULL; 447 - if (GLAD_EGL_ANDROID_native_fence_sync) { 448 - insert_fence_func = client_egl_insert; 449 - } 450 - 451 505 bool bret = client_gl_compositor_init( // 452 506 &ceglc->base, // c 453 507 xcn, // xcn 454 508 client_egl_context_begin, // context_begin 455 509 client_egl_context_end, // context_end 456 - sc_create, // create_swapchain 510 + sc_create_func, // create_swapchain 457 511 insert_fence_func); // insert_fence 458 512 if (!bret) { 459 513 free(ceglc);