Branch data Line data Source code
1 : : /* 2 : : * This file is part of libplacebo. 3 : : * 4 : : * libplacebo is free software; you can redistribute it and/or 5 : : * modify it under the terms of the GNU Lesser General Public 6 : : * License as published by the Free Software Foundation; either 7 : : * version 2.1 of the License, or (at your option) any later version. 8 : : * 9 : : * libplacebo is distributed in the hope that it will be useful, 10 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : : * GNU Lesser General Public License for more details. 13 : : * 14 : : * You should have received a copy of the GNU Lesser General Public 15 : : * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>. 16 : : */ 17 : : 18 : : #include "common.h" 19 : : #include "gpu.h" 20 : : #include "utils.h" 21 : : 22 : 0 : const char *gl_err_str(GLenum err) 23 : : { 24 [ # # # # : 0 : switch (err) { # # # # # ] 25 : : #define CASE(name) case name: return #name 26 : : CASE(GL_NO_ERROR); 27 : 0 : CASE(GL_INVALID_ENUM); 28 : 0 : CASE(GL_INVALID_VALUE); 29 : 0 : CASE(GL_INVALID_OPERATION); 30 : 0 : CASE(GL_INVALID_FRAMEBUFFER_OPERATION); 31 : 0 : CASE(GL_OUT_OF_MEMORY); 32 : 0 : CASE(GL_STACK_UNDERFLOW); 33 : 0 : CASE(GL_STACK_OVERFLOW); 34 : : #undef CASE 35 : : 36 : 0 : default: return "unknown error"; 37 : : } 38 : : } 39 : : 40 : 16849 : void gl_poll_callbacks(pl_gpu gpu) 41 : : { 42 : : const gl_funcs *gl = gl_funcs_get(gpu); 43 : : struct pl_gl *p = PL_PRIV(gpu); 44 [ + + ]: 17374 : while (p->callbacks.num) { 45 : 1346 : struct gl_cb cb = p->callbacks.elem[0]; 46 : 1346 : GLenum res = gl->ClientWaitSync(cb.sync, 0, 0); 47 [ + - - + ]: 1871 : switch (res) { 48 : : case GL_ALREADY_SIGNALED: 49 : : case GL_CONDITION_SATISFIED: 50 [ - + ]: 525 : PL_ARRAY_REMOVE_AT(p->callbacks, 0); 51 : 525 : cb.callback(cb.priv); 52 : : continue; 53 : : 54 : : case GL_WAIT_FAILED: 55 [ # # ]: 0 : PL_ARRAY_REMOVE_AT(p->callbacks, 0); 56 : 0 : gl->DeleteSync(cb.sync); 57 : 0 : p->failed = true; 58 : 0 : gl_check_err(gpu, "gl_poll_callbacks"); // NOTE: will recurse! 59 : 0 : return; 60 : : 61 : : case GL_TIMEOUT_EXPIRED: 62 : : return; 63 : : 64 : : default: 65 : 0 : pl_unreachable(); 66 : : } 67 : : } 68 : : } 69 : : 70 : 16846 : bool gl_check_err(pl_gpu gpu, const char *fun) 71 : : { 72 : : const gl_funcs *gl = gl_funcs_get(gpu); 73 : : struct pl_gl *p = PL_PRIV(gpu); 74 : : bool ret = true; 75 : : 76 : 0 : while (true) { 77 : 16846 : GLenum error = gl->GetError(); 78 [ - + ]: 16846 : if (error == GL_NO_ERROR) 79 : : break; 80 : 0 : PL_ERR(gpu, "%s: OpenGL error: %s", fun, gl_err_str(error)); 81 : : ret = false; 82 : 0 : p->failed = true; 83 : : } 84 : : 85 : 16846 : gl_poll_callbacks(gpu); 86 : 16846 : return ret; 87 : : } 88 : : 89 : 4 : bool gl_is_software(pl_opengl pl_gl) 90 : : { 91 : 4 : struct gl_ctx *glctx = PL_PRIV(pl_gl); 92 : : const gl_funcs *gl = &glctx->func; 93 : 4 : const char *renderer = (char *) gl->GetString(GL_RENDERER); 94 : 4 : return !renderer || 95 [ - + ]: 4 : strcmp(renderer, "Software Rasterizer") == 0 || 96 [ - + ]: 4 : strstr(renderer, "llvmpipe") || 97 [ - + ]: 4 : strstr(renderer, "softpipe") || 98 [ + - - + ]: 8 : strcmp(renderer, "Mesa X11") == 0 || 99 [ - + ]: 4 : strcmp(renderer, "Apple Software Renderer") == 0; 100 : : } 101 : : 102 : 8 : bool gl_is_gles(pl_opengl pl_gl) 103 : : { 104 : 8 : struct gl_ctx *glctx = PL_PRIV(pl_gl); 105 : : const gl_funcs *gl = &glctx->func; 106 : 8 : const char *version = (char *) gl->GetString(GL_VERSION); 107 : 8 : return pl_str_startswith0(pl_str0(version), "OpenGL ES"); 108 : : } 109 : : 110 : 568 : bool gl_test_ext(pl_gpu gpu, const char *ext, int gl_ver, int gles_ver) 111 : : { 112 : 568 : struct pl_gl *p = PL_PRIV(gpu); 113 [ + - + + ]: 568 : if (gl_ver && p->gl_ver >= gl_ver) 114 : : return true; 115 [ + + - + ]: 16 : if (gles_ver && p->gles_ver >= gles_ver) 116 : : return true; 117 : : 118 [ + - ]: 4 : return ext ? pl_opengl_has_ext(p->gl, ext) : false; 119 : : } 120 : : 121 : 0 : const char *egl_err_str(EGLenum err) 122 : : { 123 [ # # # # : 0 : switch (err) { # # # # # # # # # # # ] 124 : : #define CASE(name) case name: return #name 125 : : CASE(EGL_SUCCESS); 126 : 0 : CASE(EGL_NOT_INITIALIZED); 127 : 0 : CASE(EGL_BAD_ACCESS); 128 : 0 : CASE(EGL_BAD_ALLOC); 129 : 0 : CASE(EGL_BAD_ATTRIBUTE); 130 : 0 : CASE(EGL_BAD_CONFIG); 131 : 0 : CASE(EGL_BAD_CONTEXT); 132 : 0 : CASE(EGL_BAD_CURRENT_SURFACE); 133 : 0 : CASE(EGL_BAD_DISPLAY); 134 : 0 : CASE(EGL_BAD_MATCH); 135 : 0 : CASE(EGL_BAD_NATIVE_PIXMAP); 136 : 0 : CASE(EGL_BAD_NATIVE_WINDOW); 137 : 0 : CASE(EGL_BAD_PARAMETER); 138 : 0 : CASE(EGL_BAD_SURFACE); 139 : : #undef CASE 140 : : 141 : 0 : default: return "unknown error"; 142 : : } 143 : : } 144 : : 145 : 20 : bool egl_check_err(pl_gpu gpu, const char *fun) 146 : : { 147 : 20 : struct pl_gl *p = PL_PRIV(gpu); 148 : : bool ret = true; 149 : : 150 : 0 : while (true) { 151 : 20 : GLenum error = eglGetError(); 152 [ + - ]: 20 : if (error == EGL_SUCCESS) 153 : 20 : return ret; 154 : 0 : PL_ERR(gpu, "%s: EGL error: %s", fun, egl_err_str(error)); 155 : : ret = false; 156 : 0 : p->failed = true; 157 : : } 158 : : }