xref: /aosp_15_r20/external/libva/va/glx/va_glx_impl.c (revision 54e60f844a168e9a219354de272cd517ee8cd4b7)
1*54e60f84SAndroid Build Coastguard Worker /*
2*54e60f84SAndroid Build Coastguard Worker  * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
3*54e60f84SAndroid Build Coastguard Worker  *
4*54e60f84SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*54e60f84SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
6*54e60f84SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
7*54e60f84SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
8*54e60f84SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
9*54e60f84SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
10*54e60f84SAndroid Build Coastguard Worker  * the following conditions:
11*54e60f84SAndroid Build Coastguard Worker  *
12*54e60f84SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
13*54e60f84SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
14*54e60f84SAndroid Build Coastguard Worker  * of the Software.
15*54e60f84SAndroid Build Coastguard Worker  *
16*54e60f84SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*54e60f84SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*54e60f84SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19*54e60f84SAndroid Build Coastguard Worker  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20*54e60f84SAndroid Build Coastguard Worker  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21*54e60f84SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22*54e60f84SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*54e60f84SAndroid Build Coastguard Worker  */
24*54e60f84SAndroid Build Coastguard Worker 
25*54e60f84SAndroid Build Coastguard Worker #define _GNU_SOURCE 1
26*54e60f84SAndroid Build Coastguard Worker #include "sysdeps.h"
27*54e60f84SAndroid Build Coastguard Worker #include "va_glx_private.h"
28*54e60f84SAndroid Build Coastguard Worker #include "va_glx_impl.h"
29*54e60f84SAndroid Build Coastguard Worker #include <stdio.h>
30*54e60f84SAndroid Build Coastguard Worker #include <stdlib.h>
31*54e60f84SAndroid Build Coastguard Worker #include <stdarg.h>
32*54e60f84SAndroid Build Coastguard Worker #include <string.h>
33*54e60f84SAndroid Build Coastguard Worker #include <assert.h>
34*54e60f84SAndroid Build Coastguard Worker #include <dlfcn.h>
35*54e60f84SAndroid Build Coastguard Worker 
va_glx_error_message(const char * format,...)36*54e60f84SAndroid Build Coastguard Worker static void va_glx_error_message(const char *format, ...)
37*54e60f84SAndroid Build Coastguard Worker {
38*54e60f84SAndroid Build Coastguard Worker     va_list args;
39*54e60f84SAndroid Build Coastguard Worker     va_start(args, format);
40*54e60f84SAndroid Build Coastguard Worker     fprintf(stderr, "libva-glx error: ");
41*54e60f84SAndroid Build Coastguard Worker     vfprintf(stderr, format, args);
42*54e60f84SAndroid Build Coastguard Worker     va_end(args);
43*54e60f84SAndroid Build Coastguard Worker }
44*54e60f84SAndroid Build Coastguard Worker 
45*54e60f84SAndroid Build Coastguard Worker // X error trap
46*54e60f84SAndroid Build Coastguard Worker static int x11_error_code = 0;
47*54e60f84SAndroid Build Coastguard Worker static int (*old_error_handler)(Display *, XErrorEvent *);
48*54e60f84SAndroid Build Coastguard Worker 
error_handler(Display * dpy,XErrorEvent * error)49*54e60f84SAndroid Build Coastguard Worker static int error_handler(Display *dpy, XErrorEvent *error)
50*54e60f84SAndroid Build Coastguard Worker {
51*54e60f84SAndroid Build Coastguard Worker     x11_error_code = error->error_code;
52*54e60f84SAndroid Build Coastguard Worker     return 0;
53*54e60f84SAndroid Build Coastguard Worker }
54*54e60f84SAndroid Build Coastguard Worker 
x11_trap_errors(void)55*54e60f84SAndroid Build Coastguard Worker static void x11_trap_errors(void)
56*54e60f84SAndroid Build Coastguard Worker {
57*54e60f84SAndroid Build Coastguard Worker     x11_error_code    = 0;
58*54e60f84SAndroid Build Coastguard Worker     old_error_handler = XSetErrorHandler(error_handler);
59*54e60f84SAndroid Build Coastguard Worker }
60*54e60f84SAndroid Build Coastguard Worker 
x11_untrap_errors(void)61*54e60f84SAndroid Build Coastguard Worker static int x11_untrap_errors(void)
62*54e60f84SAndroid Build Coastguard Worker {
63*54e60f84SAndroid Build Coastguard Worker     XSetErrorHandler(old_error_handler);
64*54e60f84SAndroid Build Coastguard Worker     return x11_error_code;
65*54e60f84SAndroid Build Coastguard Worker }
66*54e60f84SAndroid Build Coastguard Worker 
67*54e60f84SAndroid Build Coastguard Worker // Returns a string representation of an OpenGL error
gl_get_error_string(GLenum error)68*54e60f84SAndroid Build Coastguard Worker static const char *gl_get_error_string(GLenum error)
69*54e60f84SAndroid Build Coastguard Worker {
70*54e60f84SAndroid Build Coastguard Worker     static const struct {
71*54e60f84SAndroid Build Coastguard Worker         GLenum val;
72*54e60f84SAndroid Build Coastguard Worker         const char *str;
73*54e60f84SAndroid Build Coastguard Worker     }
74*54e60f84SAndroid Build Coastguard Worker     gl_errors[] = {
75*54e60f84SAndroid Build Coastguard Worker         { GL_NO_ERROR,          "no error" },
76*54e60f84SAndroid Build Coastguard Worker         { GL_INVALID_ENUM,      "invalid enumerant" },
77*54e60f84SAndroid Build Coastguard Worker         { GL_INVALID_VALUE,     "invalid value" },
78*54e60f84SAndroid Build Coastguard Worker         { GL_INVALID_OPERATION, "invalid operation" },
79*54e60f84SAndroid Build Coastguard Worker         { GL_STACK_OVERFLOW,    "stack overflow" },
80*54e60f84SAndroid Build Coastguard Worker         { GL_STACK_UNDERFLOW,   "stack underflow" },
81*54e60f84SAndroid Build Coastguard Worker         { GL_OUT_OF_MEMORY,     "out of memory" },
82*54e60f84SAndroid Build Coastguard Worker #ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
83*54e60f84SAndroid Build Coastguard Worker         { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" },
84*54e60f84SAndroid Build Coastguard Worker #endif
85*54e60f84SAndroid Build Coastguard Worker         { ~0, NULL }
86*54e60f84SAndroid Build Coastguard Worker     };
87*54e60f84SAndroid Build Coastguard Worker 
88*54e60f84SAndroid Build Coastguard Worker     int i;
89*54e60f84SAndroid Build Coastguard Worker     for (i = 0; gl_errors[i].str; i++) {
90*54e60f84SAndroid Build Coastguard Worker         if (gl_errors[i].val == error)
91*54e60f84SAndroid Build Coastguard Worker             return gl_errors[i].str;
92*54e60f84SAndroid Build Coastguard Worker     }
93*54e60f84SAndroid Build Coastguard Worker     return "unknown";
94*54e60f84SAndroid Build Coastguard Worker }
95*54e60f84SAndroid Build Coastguard Worker 
gl_do_check_error(int report)96*54e60f84SAndroid Build Coastguard Worker static inline int gl_do_check_error(int report)
97*54e60f84SAndroid Build Coastguard Worker {
98*54e60f84SAndroid Build Coastguard Worker     GLenum error;
99*54e60f84SAndroid Build Coastguard Worker     int is_error = 0;
100*54e60f84SAndroid Build Coastguard Worker     while ((error = glGetError()) != GL_NO_ERROR) {
101*54e60f84SAndroid Build Coastguard Worker         if (report)
102*54e60f84SAndroid Build Coastguard Worker             va_glx_error_message("glError: %s caught\n",
103*54e60f84SAndroid Build Coastguard Worker                                  gl_get_error_string(error));
104*54e60f84SAndroid Build Coastguard Worker         is_error = 1;
105*54e60f84SAndroid Build Coastguard Worker     }
106*54e60f84SAndroid Build Coastguard Worker     return is_error;
107*54e60f84SAndroid Build Coastguard Worker }
108*54e60f84SAndroid Build Coastguard Worker 
gl_purge_errors(void)109*54e60f84SAndroid Build Coastguard Worker static inline void gl_purge_errors(void)
110*54e60f84SAndroid Build Coastguard Worker {
111*54e60f84SAndroid Build Coastguard Worker     gl_do_check_error(0);
112*54e60f84SAndroid Build Coastguard Worker }
113*54e60f84SAndroid Build Coastguard Worker 
gl_check_error(void)114*54e60f84SAndroid Build Coastguard Worker static inline int gl_check_error(void)
115*54e60f84SAndroid Build Coastguard Worker {
116*54e60f84SAndroid Build Coastguard Worker     return gl_do_check_error(1);
117*54e60f84SAndroid Build Coastguard Worker }
118*54e60f84SAndroid Build Coastguard Worker 
119*54e60f84SAndroid Build Coastguard Worker // glGetTexLevelParameteriv() wrapper
gl_get_texture_param(GLenum param,unsigned int * pval)120*54e60f84SAndroid Build Coastguard Worker static int gl_get_texture_param(GLenum param, unsigned int *pval)
121*54e60f84SAndroid Build Coastguard Worker {
122*54e60f84SAndroid Build Coastguard Worker     GLint val;
123*54e60f84SAndroid Build Coastguard Worker 
124*54e60f84SAndroid Build Coastguard Worker     gl_purge_errors();
125*54e60f84SAndroid Build Coastguard Worker     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, param, &val);
126*54e60f84SAndroid Build Coastguard Worker     if (gl_check_error())
127*54e60f84SAndroid Build Coastguard Worker         return 0;
128*54e60f84SAndroid Build Coastguard Worker     if (pval)
129*54e60f84SAndroid Build Coastguard Worker         *pval = val;
130*54e60f84SAndroid Build Coastguard Worker     return 1;
131*54e60f84SAndroid Build Coastguard Worker }
132*54e60f84SAndroid Build Coastguard Worker 
133*54e60f84SAndroid Build Coastguard Worker // Returns the OpenGL VTable
gl_get_vtable(VADriverContextP ctx)134*54e60f84SAndroid Build Coastguard Worker static inline VAOpenGLVTableP gl_get_vtable(VADriverContextP ctx)
135*54e60f84SAndroid Build Coastguard Worker {
136*54e60f84SAndroid Build Coastguard Worker     return &VA_DRIVER_CONTEXT_GLX(ctx)->gl_vtable;
137*54e60f84SAndroid Build Coastguard Worker }
138*54e60f84SAndroid Build Coastguard Worker 
139*54e60f84SAndroid Build Coastguard Worker // Lookup for a GLX function
140*54e60f84SAndroid Build Coastguard Worker typedef void (*GLFuncPtr)(void);
141*54e60f84SAndroid Build Coastguard Worker typedef GLFuncPtr(*GLXGetProcAddressProc)(const char *);
142*54e60f84SAndroid Build Coastguard Worker 
get_proc_address_default(const char * name)143*54e60f84SAndroid Build Coastguard Worker static GLFuncPtr get_proc_address_default(const char *name)
144*54e60f84SAndroid Build Coastguard Worker {
145*54e60f84SAndroid Build Coastguard Worker     return NULL;
146*54e60f84SAndroid Build Coastguard Worker }
147*54e60f84SAndroid Build Coastguard Worker 
get_proc_address_func(void)148*54e60f84SAndroid Build Coastguard Worker static GLXGetProcAddressProc get_proc_address_func(void)
149*54e60f84SAndroid Build Coastguard Worker {
150*54e60f84SAndroid Build Coastguard Worker     GLXGetProcAddressProc get_proc_func;
151*54e60f84SAndroid Build Coastguard Worker 
152*54e60f84SAndroid Build Coastguard Worker     dlerror();
153*54e60f84SAndroid Build Coastguard Worker     get_proc_func = (GLXGetProcAddressProc)
154*54e60f84SAndroid Build Coastguard Worker                     dlsym(RTLD_DEFAULT, "glXGetProcAddress");
155*54e60f84SAndroid Build Coastguard Worker     if (!dlerror())
156*54e60f84SAndroid Build Coastguard Worker         return get_proc_func;
157*54e60f84SAndroid Build Coastguard Worker 
158*54e60f84SAndroid Build Coastguard Worker     get_proc_func = (GLXGetProcAddressProc)
159*54e60f84SAndroid Build Coastguard Worker                     dlsym(RTLD_DEFAULT, "glXGetProcAddressARB");
160*54e60f84SAndroid Build Coastguard Worker     if (!dlerror())
161*54e60f84SAndroid Build Coastguard Worker         return get_proc_func;
162*54e60f84SAndroid Build Coastguard Worker 
163*54e60f84SAndroid Build Coastguard Worker     return get_proc_address_default;
164*54e60f84SAndroid Build Coastguard Worker }
165*54e60f84SAndroid Build Coastguard Worker 
get_proc_address(const char * name)166*54e60f84SAndroid Build Coastguard Worker static inline GLFuncPtr get_proc_address(const char *name)
167*54e60f84SAndroid Build Coastguard Worker {
168*54e60f84SAndroid Build Coastguard Worker     static GLXGetProcAddressProc get_proc_func = NULL;
169*54e60f84SAndroid Build Coastguard Worker     if (!get_proc_func)
170*54e60f84SAndroid Build Coastguard Worker         get_proc_func = get_proc_address_func();
171*54e60f84SAndroid Build Coastguard Worker     return get_proc_func(name);
172*54e60f84SAndroid Build Coastguard Worker }
173*54e60f84SAndroid Build Coastguard Worker 
174*54e60f84SAndroid Build Coastguard Worker // Check for GLX extensions (TFP, FBO)
check_extension(const char * name,const char * ext)175*54e60f84SAndroid Build Coastguard Worker static int check_extension(const char *name, const char *ext)
176*54e60f84SAndroid Build Coastguard Worker {
177*54e60f84SAndroid Build Coastguard Worker     const char *end;
178*54e60f84SAndroid Build Coastguard Worker     int name_len, n;
179*54e60f84SAndroid Build Coastguard Worker 
180*54e60f84SAndroid Build Coastguard Worker     if (!name || !ext)
181*54e60f84SAndroid Build Coastguard Worker         return 0;
182*54e60f84SAndroid Build Coastguard Worker 
183*54e60f84SAndroid Build Coastguard Worker     end = ext + strlen(ext);
184*54e60f84SAndroid Build Coastguard Worker     name_len = strlen(name);
185*54e60f84SAndroid Build Coastguard Worker     while (ext < end) {
186*54e60f84SAndroid Build Coastguard Worker         n = strcspn(ext, " ");
187*54e60f84SAndroid Build Coastguard Worker         if (n == name_len && strncmp(name, ext, n) == 0)
188*54e60f84SAndroid Build Coastguard Worker             return 1;
189*54e60f84SAndroid Build Coastguard Worker         ext += (n + 1);
190*54e60f84SAndroid Build Coastguard Worker     }
191*54e60f84SAndroid Build Coastguard Worker     return 0;
192*54e60f84SAndroid Build Coastguard Worker }
193*54e60f84SAndroid Build Coastguard Worker 
check_extension3(const char * name)194*54e60f84SAndroid Build Coastguard Worker static int check_extension3(const char *name)
195*54e60f84SAndroid Build Coastguard Worker {
196*54e60f84SAndroid Build Coastguard Worker     int nbExtensions, i;
197*54e60f84SAndroid Build Coastguard Worker     PFNGLGETSTRINGIPROC glGetStringi = 0;
198*54e60f84SAndroid Build Coastguard Worker 
199*54e60f84SAndroid Build Coastguard Worker     glGetStringi = (PFNGLGETSTRINGIPROC) get_proc_address("glGetStringi");
200*54e60f84SAndroid Build Coastguard Worker     if (!glGetStringi)
201*54e60f84SAndroid Build Coastguard Worker         return 0;
202*54e60f84SAndroid Build Coastguard Worker 
203*54e60f84SAndroid Build Coastguard Worker 
204*54e60f84SAndroid Build Coastguard Worker     glGetIntegerv(GL_NUM_EXTENSIONS, &nbExtensions);
205*54e60f84SAndroid Build Coastguard Worker     for (i = 0; i < nbExtensions; i++) {
206*54e60f84SAndroid Build Coastguard Worker         const GLubyte *strExtension = glGetStringi(GL_EXTENSIONS, i);
207*54e60f84SAndroid Build Coastguard Worker         if (strcmp((const char *) strExtension, name) == 0)
208*54e60f84SAndroid Build Coastguard Worker             return 1;
209*54e60f84SAndroid Build Coastguard Worker     }
210*54e60f84SAndroid Build Coastguard Worker 
211*54e60f84SAndroid Build Coastguard Worker     return 0;
212*54e60f84SAndroid Build Coastguard Worker }
213*54e60f84SAndroid Build Coastguard Worker 
check_tfp_extensions(VADriverContextP ctx)214*54e60f84SAndroid Build Coastguard Worker static int check_tfp_extensions(VADriverContextP ctx)
215*54e60f84SAndroid Build Coastguard Worker {
216*54e60f84SAndroid Build Coastguard Worker     const char *gl_extensions;
217*54e60f84SAndroid Build Coastguard Worker     const char *glx_extensions;
218*54e60f84SAndroid Build Coastguard Worker 
219*54e60f84SAndroid Build Coastguard Worker     gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
220*54e60f84SAndroid Build Coastguard Worker     if (!check_extension("GL_ARB_texture_non_power_of_two", gl_extensions) && !check_extension3("GL_ARB_texture_non_power_of_two"))
221*54e60f84SAndroid Build Coastguard Worker         return 0;
222*54e60f84SAndroid Build Coastguard Worker 
223*54e60f84SAndroid Build Coastguard Worker     glx_extensions = glXQueryExtensionsString(ctx->native_dpy, ctx->x11_screen);
224*54e60f84SAndroid Build Coastguard Worker     if (!check_extension("GLX_EXT_texture_from_pixmap", glx_extensions))
225*54e60f84SAndroid Build Coastguard Worker         return 0;
226*54e60f84SAndroid Build Coastguard Worker 
227*54e60f84SAndroid Build Coastguard Worker     return 1;
228*54e60f84SAndroid Build Coastguard Worker }
229*54e60f84SAndroid Build Coastguard Worker 
check_fbo_extensions(VADriverContextP ctx)230*54e60f84SAndroid Build Coastguard Worker static int check_fbo_extensions(VADriverContextP ctx)
231*54e60f84SAndroid Build Coastguard Worker {
232*54e60f84SAndroid Build Coastguard Worker     const char *gl_extensions;
233*54e60f84SAndroid Build Coastguard Worker 
234*54e60f84SAndroid Build Coastguard Worker     gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
235*54e60f84SAndroid Build Coastguard Worker     if (check_extension("GL_ARB_framebuffer_object", gl_extensions) || check_extension3("GL_ARB_framebuffer_object"))
236*54e60f84SAndroid Build Coastguard Worker         return 1;
237*54e60f84SAndroid Build Coastguard Worker     if (check_extension("GL_EXT_framebuffer_object", gl_extensions) || check_extension3("GL_EXT_framebuffer_object"))
238*54e60f84SAndroid Build Coastguard Worker         return 1;
239*54e60f84SAndroid Build Coastguard Worker 
240*54e60f84SAndroid Build Coastguard Worker     return 0;
241*54e60f84SAndroid Build Coastguard Worker }
242*54e60f84SAndroid Build Coastguard Worker 
243*54e60f84SAndroid Build Coastguard Worker // Load GLX extensions
load_tfp_extensions(VADriverContextP ctx)244*54e60f84SAndroid Build Coastguard Worker static int load_tfp_extensions(VADriverContextP ctx)
245*54e60f84SAndroid Build Coastguard Worker {
246*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
247*54e60f84SAndroid Build Coastguard Worker 
248*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->glx_create_pixmap = (PFNGLXCREATEPIXMAPPROC)
249*54e60f84SAndroid Build Coastguard Worker                                        get_proc_address("glXCreatePixmap");
250*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->glx_create_pixmap)
251*54e60f84SAndroid Build Coastguard Worker         return 0;
252*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->glx_destroy_pixmap = (PFNGLXDESTROYPIXMAPPROC)
253*54e60f84SAndroid Build Coastguard Worker                                         get_proc_address("glXDestroyPixmap");
254*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->glx_destroy_pixmap)
255*54e60f84SAndroid Build Coastguard Worker         return 0;
256*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC)
257*54e60f84SAndroid Build Coastguard Worker                                         get_proc_address("glXBindTexImageEXT");
258*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->glx_bind_tex_image)
259*54e60f84SAndroid Build Coastguard Worker         return 0;
260*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->glx_release_tex_image = (PFNGLXRELEASETEXIMAGEEXTPROC)
261*54e60f84SAndroid Build Coastguard Worker                                            get_proc_address("glXReleaseTexImageEXT");
262*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->glx_release_tex_image)
263*54e60f84SAndroid Build Coastguard Worker         return 0;
264*54e60f84SAndroid Build Coastguard Worker     return 1;
265*54e60f84SAndroid Build Coastguard Worker }
266*54e60f84SAndroid Build Coastguard Worker 
load_fbo_extensions(VADriverContextP ctx)267*54e60f84SAndroid Build Coastguard Worker static int load_fbo_extensions(VADriverContextP ctx)
268*54e60f84SAndroid Build Coastguard Worker {
269*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
270*54e60f84SAndroid Build Coastguard Worker 
271*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_gen_framebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
272*54e60f84SAndroid Build Coastguard Worker                                          get_proc_address("glGenFramebuffersEXT");
273*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_gen_framebuffers)
274*54e60f84SAndroid Build Coastguard Worker         return 0;
275*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_delete_framebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
276*54e60f84SAndroid Build Coastguard Worker                                             get_proc_address("glDeleteFramebuffersEXT");
277*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_delete_framebuffers)
278*54e60f84SAndroid Build Coastguard Worker         return 0;
279*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_bind_framebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
280*54e60f84SAndroid Build Coastguard Worker                                          get_proc_address("glBindFramebufferEXT");
281*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_bind_framebuffer)
282*54e60f84SAndroid Build Coastguard Worker         return 0;
283*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_gen_renderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
284*54e60f84SAndroid Build Coastguard Worker                                           get_proc_address("glGenRenderbuffersEXT");
285*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_gen_renderbuffers)
286*54e60f84SAndroid Build Coastguard Worker         return 0;
287*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_delete_renderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
288*54e60f84SAndroid Build Coastguard Worker             get_proc_address("glDeleteRenderbuffersEXT");
289*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_delete_renderbuffers)
290*54e60f84SAndroid Build Coastguard Worker         return 0;
291*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_bind_renderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
292*54e60f84SAndroid Build Coastguard Worker                                           get_proc_address("glBindRenderbufferEXT");
293*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_bind_renderbuffer)
294*54e60f84SAndroid Build Coastguard Worker         return 0;
295*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_renderbuffer_storage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
296*54e60f84SAndroid Build Coastguard Worker             get_proc_address("glRenderbufferStorageEXT");
297*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_renderbuffer_storage)
298*54e60f84SAndroid Build Coastguard Worker         return 0;
299*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_framebuffer_renderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
300*54e60f84SAndroid Build Coastguard Worker             get_proc_address("glFramebufferRenderbufferEXT");
301*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_framebuffer_renderbuffer)
302*54e60f84SAndroid Build Coastguard Worker         return 0;
303*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_framebuffer_texture_2d = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
304*54e60f84SAndroid Build Coastguard Worker             get_proc_address("glFramebufferTexture2DEXT");
305*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_framebuffer_texture_2d)
306*54e60f84SAndroid Build Coastguard Worker         return 0;
307*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_check_framebuffer_status = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
308*54e60f84SAndroid Build Coastguard Worker             get_proc_address("glCheckFramebufferStatusEXT");
309*54e60f84SAndroid Build Coastguard Worker     if (!pOpenGLVTable->gl_check_framebuffer_status)
310*54e60f84SAndroid Build Coastguard Worker         return 0;
311*54e60f84SAndroid Build Coastguard Worker     return 1;
312*54e60f84SAndroid Build Coastguard Worker }
313*54e60f84SAndroid Build Coastguard Worker 
314*54e60f84SAndroid Build Coastguard Worker 
315*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
316*54e60f84SAndroid Build Coastguard Worker /* === VA/GLX helpers                                                    === */
317*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
318*54e60f84SAndroid Build Coastguard Worker 
319*54e60f84SAndroid Build Coastguard Worker // OpenGL context state
320*54e60f84SAndroid Build Coastguard Worker typedef struct OpenGLContextState *OpenGLContextStateP;
321*54e60f84SAndroid Build Coastguard Worker 
322*54e60f84SAndroid Build Coastguard Worker struct OpenGLContextState {
323*54e60f84SAndroid Build Coastguard Worker     Display     *display;
324*54e60f84SAndroid Build Coastguard Worker     Window       window;
325*54e60f84SAndroid Build Coastguard Worker     GLXContext   context;
326*54e60f84SAndroid Build Coastguard Worker };
327*54e60f84SAndroid Build Coastguard Worker 
328*54e60f84SAndroid Build Coastguard Worker static void
gl_destroy_context(OpenGLContextStateP cs)329*54e60f84SAndroid Build Coastguard Worker gl_destroy_context(OpenGLContextStateP cs)
330*54e60f84SAndroid Build Coastguard Worker {
331*54e60f84SAndroid Build Coastguard Worker     if (!cs)
332*54e60f84SAndroid Build Coastguard Worker         return;
333*54e60f84SAndroid Build Coastguard Worker 
334*54e60f84SAndroid Build Coastguard Worker     if (cs->display && cs->context) {
335*54e60f84SAndroid Build Coastguard Worker         if (glXGetCurrentContext() == cs->context)
336*54e60f84SAndroid Build Coastguard Worker             glXMakeCurrent(cs->display, None, NULL);
337*54e60f84SAndroid Build Coastguard Worker         glXDestroyContext(cs->display, cs->context);
338*54e60f84SAndroid Build Coastguard Worker         cs->display = NULL;
339*54e60f84SAndroid Build Coastguard Worker         cs->context = NULL;
340*54e60f84SAndroid Build Coastguard Worker     }
341*54e60f84SAndroid Build Coastguard Worker     free(cs);
342*54e60f84SAndroid Build Coastguard Worker }
343*54e60f84SAndroid Build Coastguard Worker 
344*54e60f84SAndroid Build Coastguard Worker static OpenGLContextStateP
gl_create_context(VADriverContextP ctx,OpenGLContextStateP parent)345*54e60f84SAndroid Build Coastguard Worker gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
346*54e60f84SAndroid Build Coastguard Worker {
347*54e60f84SAndroid Build Coastguard Worker     OpenGLContextStateP cs;
348*54e60f84SAndroid Build Coastguard Worker     GLXFBConfig *fbconfigs = NULL;
349*54e60f84SAndroid Build Coastguard Worker     int fbconfig_id, val, n, n_fbconfigs;
350*54e60f84SAndroid Build Coastguard Worker     Status status;
351*54e60f84SAndroid Build Coastguard Worker 
352*54e60f84SAndroid Build Coastguard Worker     static GLint fbconfig_attrs[] = {
353*54e60f84SAndroid Build Coastguard Worker         GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
354*54e60f84SAndroid Build Coastguard Worker         GLX_RENDER_TYPE,   GLX_RGBA_BIT,
355*54e60f84SAndroid Build Coastguard Worker         GLX_DOUBLEBUFFER,  True,
356*54e60f84SAndroid Build Coastguard Worker         GLX_RED_SIZE,      8,
357*54e60f84SAndroid Build Coastguard Worker         GLX_GREEN_SIZE,    8,
358*54e60f84SAndroid Build Coastguard Worker         GLX_BLUE_SIZE,     8,
359*54e60f84SAndroid Build Coastguard Worker         None
360*54e60f84SAndroid Build Coastguard Worker     };
361*54e60f84SAndroid Build Coastguard Worker 
362*54e60f84SAndroid Build Coastguard Worker     cs = malloc(sizeof(*cs));
363*54e60f84SAndroid Build Coastguard Worker     if (!cs)
364*54e60f84SAndroid Build Coastguard Worker         goto error;
365*54e60f84SAndroid Build Coastguard Worker 
366*54e60f84SAndroid Build Coastguard Worker     if (parent) {
367*54e60f84SAndroid Build Coastguard Worker         cs->display = parent->display;
368*54e60f84SAndroid Build Coastguard Worker         cs->window  = parent->window;
369*54e60f84SAndroid Build Coastguard Worker     } else {
370*54e60f84SAndroid Build Coastguard Worker         cs->display = ctx->native_dpy;
371*54e60f84SAndroid Build Coastguard Worker         cs->window  = None;
372*54e60f84SAndroid Build Coastguard Worker     }
373*54e60f84SAndroid Build Coastguard Worker     cs->context = NULL;
374*54e60f84SAndroid Build Coastguard Worker 
375*54e60f84SAndroid Build Coastguard Worker     if (parent && parent->context) {
376*54e60f84SAndroid Build Coastguard Worker         status = glXQueryContext(
377*54e60f84SAndroid Build Coastguard Worker                      parent->display,
378*54e60f84SAndroid Build Coastguard Worker                      parent->context,
379*54e60f84SAndroid Build Coastguard Worker                      GLX_FBCONFIG_ID, &fbconfig_id
380*54e60f84SAndroid Build Coastguard Worker                  );
381*54e60f84SAndroid Build Coastguard Worker         if (status != Success)
382*54e60f84SAndroid Build Coastguard Worker             goto error;
383*54e60f84SAndroid Build Coastguard Worker 
384*54e60f84SAndroid Build Coastguard Worker         if (fbconfig_id == GLX_DONT_CARE)
385*54e60f84SAndroid Build Coastguard Worker             goto choose_fbconfig;
386*54e60f84SAndroid Build Coastguard Worker 
387*54e60f84SAndroid Build Coastguard Worker         fbconfigs = glXGetFBConfigs(
388*54e60f84SAndroid Build Coastguard Worker                         parent->display,
389*54e60f84SAndroid Build Coastguard Worker                         DefaultScreen(parent->display),
390*54e60f84SAndroid Build Coastguard Worker                         &n_fbconfigs
391*54e60f84SAndroid Build Coastguard Worker                     );
392*54e60f84SAndroid Build Coastguard Worker         if (!fbconfigs)
393*54e60f84SAndroid Build Coastguard Worker             goto error;
394*54e60f84SAndroid Build Coastguard Worker 
395*54e60f84SAndroid Build Coastguard Worker         /* Find out a GLXFBConfig compatible with the parent context */
396*54e60f84SAndroid Build Coastguard Worker         for (n = 0; n < n_fbconfigs; n++) {
397*54e60f84SAndroid Build Coastguard Worker             status = glXGetFBConfigAttrib(
398*54e60f84SAndroid Build Coastguard Worker                          cs->display,
399*54e60f84SAndroid Build Coastguard Worker                          fbconfigs[n],
400*54e60f84SAndroid Build Coastguard Worker                          GLX_FBCONFIG_ID, &val
401*54e60f84SAndroid Build Coastguard Worker                      );
402*54e60f84SAndroid Build Coastguard Worker             if (status == Success && val == fbconfig_id)
403*54e60f84SAndroid Build Coastguard Worker                 break;
404*54e60f84SAndroid Build Coastguard Worker         }
405*54e60f84SAndroid Build Coastguard Worker         if (n == n_fbconfigs)
406*54e60f84SAndroid Build Coastguard Worker             goto error;
407*54e60f84SAndroid Build Coastguard Worker     } else {
408*54e60f84SAndroid Build Coastguard Worker choose_fbconfig:
409*54e60f84SAndroid Build Coastguard Worker         fbconfigs = glXChooseFBConfig(
410*54e60f84SAndroid Build Coastguard Worker                         ctx->native_dpy,
411*54e60f84SAndroid Build Coastguard Worker                         ctx->x11_screen,
412*54e60f84SAndroid Build Coastguard Worker                         fbconfig_attrs, &n_fbconfigs
413*54e60f84SAndroid Build Coastguard Worker                     );
414*54e60f84SAndroid Build Coastguard Worker         if (!fbconfigs)
415*54e60f84SAndroid Build Coastguard Worker             goto error;
416*54e60f84SAndroid Build Coastguard Worker 
417*54e60f84SAndroid Build Coastguard Worker         /* Select the first one */
418*54e60f84SAndroid Build Coastguard Worker         n = 0;
419*54e60f84SAndroid Build Coastguard Worker     }
420*54e60f84SAndroid Build Coastguard Worker 
421*54e60f84SAndroid Build Coastguard Worker     cs->context = glXCreateNewContext(
422*54e60f84SAndroid Build Coastguard Worker                       cs->display,
423*54e60f84SAndroid Build Coastguard Worker                       fbconfigs[n],
424*54e60f84SAndroid Build Coastguard Worker                       GLX_RGBA_TYPE,
425*54e60f84SAndroid Build Coastguard Worker                       parent ? parent->context : NULL,
426*54e60f84SAndroid Build Coastguard Worker                       True
427*54e60f84SAndroid Build Coastguard Worker                   );
428*54e60f84SAndroid Build Coastguard Worker     if (cs->context)
429*54e60f84SAndroid Build Coastguard Worker         goto end;
430*54e60f84SAndroid Build Coastguard Worker 
431*54e60f84SAndroid Build Coastguard Worker error:
432*54e60f84SAndroid Build Coastguard Worker     gl_destroy_context(cs);
433*54e60f84SAndroid Build Coastguard Worker     cs = NULL;
434*54e60f84SAndroid Build Coastguard Worker end:
435*54e60f84SAndroid Build Coastguard Worker     if (fbconfigs)
436*54e60f84SAndroid Build Coastguard Worker         XFree(fbconfigs);
437*54e60f84SAndroid Build Coastguard Worker     return cs;
438*54e60f84SAndroid Build Coastguard Worker }
439*54e60f84SAndroid Build Coastguard Worker 
gl_get_current_context(OpenGLContextStateP cs)440*54e60f84SAndroid Build Coastguard Worker static void gl_get_current_context(OpenGLContextStateP cs)
441*54e60f84SAndroid Build Coastguard Worker {
442*54e60f84SAndroid Build Coastguard Worker     cs->display = glXGetCurrentDisplay();
443*54e60f84SAndroid Build Coastguard Worker     cs->window  = glXGetCurrentDrawable();
444*54e60f84SAndroid Build Coastguard Worker     cs->context = glXGetCurrentContext();
445*54e60f84SAndroid Build Coastguard Worker }
446*54e60f84SAndroid Build Coastguard Worker 
447*54e60f84SAndroid Build Coastguard Worker static int
gl_set_current_context(OpenGLContextStateP new_cs,OpenGLContextStateP old_cs)448*54e60f84SAndroid Build Coastguard Worker gl_set_current_context(OpenGLContextStateP new_cs, OpenGLContextStateP old_cs)
449*54e60f84SAndroid Build Coastguard Worker {
450*54e60f84SAndroid Build Coastguard Worker     /* If display is NULL, this could be that new_cs was retrieved from
451*54e60f84SAndroid Build Coastguard Worker        gl_get_current_context() with none set previously. If that case,
452*54e60f84SAndroid Build Coastguard Worker        the other fields are also NULL and we don't return an error */
453*54e60f84SAndroid Build Coastguard Worker     if (!new_cs->display)
454*54e60f84SAndroid Build Coastguard Worker         return !new_cs->window && !new_cs->context;
455*54e60f84SAndroid Build Coastguard Worker 
456*54e60f84SAndroid Build Coastguard Worker     if (old_cs) {
457*54e60f84SAndroid Build Coastguard Worker         if (old_cs == new_cs)
458*54e60f84SAndroid Build Coastguard Worker             return 1;
459*54e60f84SAndroid Build Coastguard Worker         gl_get_current_context(old_cs);
460*54e60f84SAndroid Build Coastguard Worker         if (old_cs->display == new_cs->display &&
461*54e60f84SAndroid Build Coastguard Worker             old_cs->window  == new_cs->window  &&
462*54e60f84SAndroid Build Coastguard Worker             old_cs->context == new_cs->context)
463*54e60f84SAndroid Build Coastguard Worker             return 1;
464*54e60f84SAndroid Build Coastguard Worker     }
465*54e60f84SAndroid Build Coastguard Worker     return glXMakeCurrent(new_cs->display, new_cs->window, new_cs->context);
466*54e60f84SAndroid Build Coastguard Worker }
467*54e60f84SAndroid Build Coastguard Worker 
468*54e60f84SAndroid Build Coastguard Worker /** Unique VASurfaceGLX identifier */
469*54e60f84SAndroid Build Coastguard Worker #define VA_SURFACE_GLX_MAGIC VA_FOURCC('V','A','G','L')
470*54e60f84SAndroid Build Coastguard Worker 
471*54e60f84SAndroid Build Coastguard Worker struct VASurfaceGLX {
472*54e60f84SAndroid Build Coastguard Worker     uint32_t            magic;      ///< Magic number identifying a VASurfaceGLX
473*54e60f84SAndroid Build Coastguard Worker     GLenum              target;     ///< GL target to which the texture is bound
474*54e60f84SAndroid Build Coastguard Worker     GLuint              texture;    ///< GL texture
475*54e60f84SAndroid Build Coastguard Worker     VASurfaceID         surface;    ///< Associated VA surface
476*54e60f84SAndroid Build Coastguard Worker     unsigned int        width;
477*54e60f84SAndroid Build Coastguard Worker     unsigned int        height;
478*54e60f84SAndroid Build Coastguard Worker     OpenGLContextStateP gl_context;
479*54e60f84SAndroid Build Coastguard Worker     int                 is_bound;
480*54e60f84SAndroid Build Coastguard Worker     Pixmap              pixmap;
481*54e60f84SAndroid Build Coastguard Worker     GLuint              pix_texture;
482*54e60f84SAndroid Build Coastguard Worker     GLXPixmap           glx_pixmap;
483*54e60f84SAndroid Build Coastguard Worker     GLuint              fbo;
484*54e60f84SAndroid Build Coastguard Worker };
485*54e60f84SAndroid Build Coastguard Worker 
486*54e60f84SAndroid Build Coastguard Worker // Create Pixmaps for GLX texture-from-pixmap extension
create_tfp_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)487*54e60f84SAndroid Build Coastguard Worker static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
488*54e60f84SAndroid Build Coastguard Worker {
489*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx);
490*54e60f84SAndroid Build Coastguard Worker     const unsigned int    width         = pSurfaceGLX->width;
491*54e60f84SAndroid Build Coastguard Worker     const unsigned int    height        = pSurfaceGLX->height;
492*54e60f84SAndroid Build Coastguard Worker     Pixmap                pixmap        = None;
493*54e60f84SAndroid Build Coastguard Worker     GLXFBConfig          *fbconfig      = NULL;
494*54e60f84SAndroid Build Coastguard Worker     GLXPixmap             glx_pixmap    = None;
495*54e60f84SAndroid Build Coastguard Worker     Window                root_window;
496*54e60f84SAndroid Build Coastguard Worker     XWindowAttributes     wattr;
497*54e60f84SAndroid Build Coastguard Worker     int                  *attrib;
498*54e60f84SAndroid Build Coastguard Worker     int                   n_fbconfig_attrs;
499*54e60f84SAndroid Build Coastguard Worker 
500*54e60f84SAndroid Build Coastguard Worker     root_window = RootWindow(ctx->native_dpy, ctx->x11_screen);
501*54e60f84SAndroid Build Coastguard Worker     XGetWindowAttributes(ctx->native_dpy, root_window, &wattr);
502*54e60f84SAndroid Build Coastguard Worker     if (wattr.depth != 24 && wattr.depth != 32)
503*54e60f84SAndroid Build Coastguard Worker         return 0;
504*54e60f84SAndroid Build Coastguard Worker     pixmap = XCreatePixmap(
505*54e60f84SAndroid Build Coastguard Worker                  ctx->native_dpy,
506*54e60f84SAndroid Build Coastguard Worker                  root_window,
507*54e60f84SAndroid Build Coastguard Worker                  width,
508*54e60f84SAndroid Build Coastguard Worker                  height,
509*54e60f84SAndroid Build Coastguard Worker                  wattr.depth
510*54e60f84SAndroid Build Coastguard Worker              );
511*54e60f84SAndroid Build Coastguard Worker     if (!pixmap)
512*54e60f84SAndroid Build Coastguard Worker         return 0;
513*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->pixmap = pixmap;
514*54e60f84SAndroid Build Coastguard Worker 
515*54e60f84SAndroid Build Coastguard Worker     int fbconfig_attrs[32] = {
516*54e60f84SAndroid Build Coastguard Worker         GLX_DRAWABLE_TYPE,      GLX_PIXMAP_BIT,
517*54e60f84SAndroid Build Coastguard Worker         GLX_DOUBLEBUFFER,       GL_TRUE,
518*54e60f84SAndroid Build Coastguard Worker         GLX_RENDER_TYPE,        GLX_RGBA_BIT,
519*54e60f84SAndroid Build Coastguard Worker         GLX_X_RENDERABLE,       GL_TRUE,
520*54e60f84SAndroid Build Coastguard Worker         GLX_Y_INVERTED_EXT,     GL_TRUE,
521*54e60f84SAndroid Build Coastguard Worker         GLX_RED_SIZE,           8,
522*54e60f84SAndroid Build Coastguard Worker         GLX_GREEN_SIZE,         8,
523*54e60f84SAndroid Build Coastguard Worker         GLX_BLUE_SIZE,          8,
524*54e60f84SAndroid Build Coastguard Worker         /*
525*54e60f84SAndroid Build Coastguard Worker          * depth test isn't enabled in the implementaion of VA GLX,
526*54e60f84SAndroid Build Coastguard Worker          * so depth buffer is unnecessary. However to workaround a
527*54e60f84SAndroid Build Coastguard Worker          * bug in older verson of xorg-server, always require a depth
528*54e60f84SAndroid Build Coastguard Worker          * buffer.
529*54e60f84SAndroid Build Coastguard Worker          *
530*54e60f84SAndroid Build Coastguard Worker          * See https://bugs.freedesktop.org/show_bug.cgi?id=76755
531*54e60f84SAndroid Build Coastguard Worker          */
532*54e60f84SAndroid Build Coastguard Worker         GLX_DEPTH_SIZE,         1,
533*54e60f84SAndroid Build Coastguard Worker         GL_NONE,
534*54e60f84SAndroid Build Coastguard Worker     };
535*54e60f84SAndroid Build Coastguard Worker     for (attrib = fbconfig_attrs; *attrib != GL_NONE; attrib += 2)
536*54e60f84SAndroid Build Coastguard Worker         ;
537*54e60f84SAndroid Build Coastguard Worker     if (wattr.depth == 32) {
538*54e60f84SAndroid Build Coastguard Worker         *attrib++ = GLX_ALPHA_SIZE;
539*54e60f84SAndroid Build Coastguard Worker         *attrib++ = 8;
540*54e60f84SAndroid Build Coastguard Worker         *attrib++ = GLX_BIND_TO_TEXTURE_RGBA_EXT;
541*54e60f84SAndroid Build Coastguard Worker         *attrib++ = GL_TRUE;
542*54e60f84SAndroid Build Coastguard Worker     } else {
543*54e60f84SAndroid Build Coastguard Worker         *attrib++ = GLX_BIND_TO_TEXTURE_RGB_EXT;
544*54e60f84SAndroid Build Coastguard Worker         *attrib++ = GL_TRUE;
545*54e60f84SAndroid Build Coastguard Worker     }
546*54e60f84SAndroid Build Coastguard Worker     *attrib++ = GL_NONE;
547*54e60f84SAndroid Build Coastguard Worker 
548*54e60f84SAndroid Build Coastguard Worker     fbconfig = glXChooseFBConfig(
549*54e60f84SAndroid Build Coastguard Worker                    ctx->native_dpy,
550*54e60f84SAndroid Build Coastguard Worker                    ctx->x11_screen,
551*54e60f84SAndroid Build Coastguard Worker                    fbconfig_attrs,
552*54e60f84SAndroid Build Coastguard Worker                    &n_fbconfig_attrs
553*54e60f84SAndroid Build Coastguard Worker                );
554*54e60f84SAndroid Build Coastguard Worker     if (!fbconfig)
555*54e60f84SAndroid Build Coastguard Worker         return 0;
556*54e60f84SAndroid Build Coastguard Worker 
557*54e60f84SAndroid Build Coastguard Worker     int pixmap_attrs[10] = {
558*54e60f84SAndroid Build Coastguard Worker         GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
559*54e60f84SAndroid Build Coastguard Worker         GLX_MIPMAP_TEXTURE_EXT, GL_FALSE,
560*54e60f84SAndroid Build Coastguard Worker         GL_NONE,
561*54e60f84SAndroid Build Coastguard Worker     };
562*54e60f84SAndroid Build Coastguard Worker     for (attrib = pixmap_attrs; *attrib != GL_NONE; attrib += 2)
563*54e60f84SAndroid Build Coastguard Worker         ;
564*54e60f84SAndroid Build Coastguard Worker     *attrib++ = GLX_TEXTURE_FORMAT_EXT;
565*54e60f84SAndroid Build Coastguard Worker     if (wattr.depth == 32)
566*54e60f84SAndroid Build Coastguard Worker         *attrib++ = GLX_TEXTURE_FORMAT_RGBA_EXT;
567*54e60f84SAndroid Build Coastguard Worker     else
568*54e60f84SAndroid Build Coastguard Worker         *attrib++ = GLX_TEXTURE_FORMAT_RGB_EXT;
569*54e60f84SAndroid Build Coastguard Worker     *attrib++ = GL_NONE;
570*54e60f84SAndroid Build Coastguard Worker 
571*54e60f84SAndroid Build Coastguard Worker     x11_trap_errors();
572*54e60f84SAndroid Build Coastguard Worker     glx_pixmap = pOpenGLVTable->glx_create_pixmap(
573*54e60f84SAndroid Build Coastguard Worker                      ctx->native_dpy,
574*54e60f84SAndroid Build Coastguard Worker                      fbconfig[0],
575*54e60f84SAndroid Build Coastguard Worker                      pixmap,
576*54e60f84SAndroid Build Coastguard Worker                      pixmap_attrs
577*54e60f84SAndroid Build Coastguard Worker                  );
578*54e60f84SAndroid Build Coastguard Worker     free(fbconfig);
579*54e60f84SAndroid Build Coastguard Worker     if (x11_untrap_errors() != 0)
580*54e60f84SAndroid Build Coastguard Worker         return 0;
581*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->glx_pixmap = glx_pixmap;
582*54e60f84SAndroid Build Coastguard Worker 
583*54e60f84SAndroid Build Coastguard Worker     glGenTextures(1, &pSurfaceGLX->pix_texture);
584*54e60f84SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, pSurfaceGLX->pix_texture);
585*54e60f84SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
586*54e60f84SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
587*54e60f84SAndroid Build Coastguard Worker     return 1;
588*54e60f84SAndroid Build Coastguard Worker }
589*54e60f84SAndroid Build Coastguard Worker 
590*54e60f84SAndroid Build Coastguard Worker // Destroy Pixmaps used for TFP
destroy_tfp_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)591*54e60f84SAndroid Build Coastguard Worker static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
592*54e60f84SAndroid Build Coastguard Worker {
593*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx);
594*54e60f84SAndroid Build Coastguard Worker 
595*54e60f84SAndroid Build Coastguard Worker     if (pSurfaceGLX->pix_texture) {
596*54e60f84SAndroid Build Coastguard Worker         glDeleteTextures(1, &pSurfaceGLX->pix_texture);
597*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX->pix_texture = 0;
598*54e60f84SAndroid Build Coastguard Worker     }
599*54e60f84SAndroid Build Coastguard Worker 
600*54e60f84SAndroid Build Coastguard Worker     if (pSurfaceGLX->glx_pixmap) {
601*54e60f84SAndroid Build Coastguard Worker         pOpenGLVTable->glx_destroy_pixmap(ctx->native_dpy, pSurfaceGLX->glx_pixmap);
602*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX->glx_pixmap = None;
603*54e60f84SAndroid Build Coastguard Worker     }
604*54e60f84SAndroid Build Coastguard Worker 
605*54e60f84SAndroid Build Coastguard Worker     if (pSurfaceGLX->pixmap) {
606*54e60f84SAndroid Build Coastguard Worker         XFreePixmap(ctx->native_dpy, pSurfaceGLX->pixmap);
607*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX->pixmap = None;
608*54e60f84SAndroid Build Coastguard Worker     }
609*54e60f84SAndroid Build Coastguard Worker }
610*54e60f84SAndroid Build Coastguard Worker 
611*54e60f84SAndroid Build Coastguard Worker // Bind GLX Pixmap to texture
bind_pixmap(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)612*54e60f84SAndroid Build Coastguard Worker static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
613*54e60f84SAndroid Build Coastguard Worker {
614*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
615*54e60f84SAndroid Build Coastguard Worker 
616*54e60f84SAndroid Build Coastguard Worker     if (pSurfaceGLX->is_bound)
617*54e60f84SAndroid Build Coastguard Worker         return 1;
618*54e60f84SAndroid Build Coastguard Worker 
619*54e60f84SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, pSurfaceGLX->pix_texture);
620*54e60f84SAndroid Build Coastguard Worker 
621*54e60f84SAndroid Build Coastguard Worker     x11_trap_errors();
622*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->glx_bind_tex_image(
623*54e60f84SAndroid Build Coastguard Worker         ctx->native_dpy,
624*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX->glx_pixmap,
625*54e60f84SAndroid Build Coastguard Worker         GLX_FRONT_LEFT_EXT,
626*54e60f84SAndroid Build Coastguard Worker         NULL
627*54e60f84SAndroid Build Coastguard Worker     );
628*54e60f84SAndroid Build Coastguard Worker     XSync(ctx->native_dpy, False);
629*54e60f84SAndroid Build Coastguard Worker     if (x11_untrap_errors() != 0) {
630*54e60f84SAndroid Build Coastguard Worker         va_glx_error_message("failed to bind pixmap\n");
631*54e60f84SAndroid Build Coastguard Worker         return 0;
632*54e60f84SAndroid Build Coastguard Worker     }
633*54e60f84SAndroid Build Coastguard Worker 
634*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->is_bound = 1;
635*54e60f84SAndroid Build Coastguard Worker     return 1;
636*54e60f84SAndroid Build Coastguard Worker }
637*54e60f84SAndroid Build Coastguard Worker 
638*54e60f84SAndroid Build Coastguard Worker // Release GLX Pixmap from texture
unbind_pixmap(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)639*54e60f84SAndroid Build Coastguard Worker static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
640*54e60f84SAndroid Build Coastguard Worker {
641*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
642*54e60f84SAndroid Build Coastguard Worker 
643*54e60f84SAndroid Build Coastguard Worker     if (!pSurfaceGLX->is_bound)
644*54e60f84SAndroid Build Coastguard Worker         return 1;
645*54e60f84SAndroid Build Coastguard Worker 
646*54e60f84SAndroid Build Coastguard Worker     x11_trap_errors();
647*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->glx_release_tex_image(
648*54e60f84SAndroid Build Coastguard Worker         ctx->native_dpy,
649*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX->glx_pixmap,
650*54e60f84SAndroid Build Coastguard Worker         GLX_FRONT_LEFT_EXT
651*54e60f84SAndroid Build Coastguard Worker     );
652*54e60f84SAndroid Build Coastguard Worker     XSync(ctx->native_dpy, False);
653*54e60f84SAndroid Build Coastguard Worker     if (x11_untrap_errors() != 0) {
654*54e60f84SAndroid Build Coastguard Worker         va_glx_error_message("failed to release pixmap\n");
655*54e60f84SAndroid Build Coastguard Worker         return 0;
656*54e60f84SAndroid Build Coastguard Worker     }
657*54e60f84SAndroid Build Coastguard Worker 
658*54e60f84SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, 0);
659*54e60f84SAndroid Build Coastguard Worker 
660*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->is_bound = 0;
661*54e60f84SAndroid Build Coastguard Worker     return 1;
662*54e60f84SAndroid Build Coastguard Worker }
663*54e60f84SAndroid Build Coastguard Worker 
664*54e60f84SAndroid Build Coastguard Worker // Render GLX Pixmap to texture
render_pixmap(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)665*54e60f84SAndroid Build Coastguard Worker static void render_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
666*54e60f84SAndroid Build Coastguard Worker {
667*54e60f84SAndroid Build Coastguard Worker     const unsigned int w = pSurfaceGLX->width;
668*54e60f84SAndroid Build Coastguard Worker     const unsigned int h = pSurfaceGLX->height;
669*54e60f84SAndroid Build Coastguard Worker 
670*54e60f84SAndroid Build Coastguard Worker     glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
671*54e60f84SAndroid Build Coastguard Worker     glBegin(GL_QUADS);
672*54e60f84SAndroid Build Coastguard Worker     {
673*54e60f84SAndroid Build Coastguard Worker         glTexCoord2f(0.0f, 0.0f);
674*54e60f84SAndroid Build Coastguard Worker         glVertex2i(0, 0);
675*54e60f84SAndroid Build Coastguard Worker         glTexCoord2f(0.0f, 1.0f);
676*54e60f84SAndroid Build Coastguard Worker         glVertex2i(0, h);
677*54e60f84SAndroid Build Coastguard Worker         glTexCoord2f(1.0f, 1.0f);
678*54e60f84SAndroid Build Coastguard Worker         glVertex2i(w, h);
679*54e60f84SAndroid Build Coastguard Worker         glTexCoord2f(1.0f, 0.0f);
680*54e60f84SAndroid Build Coastguard Worker         glVertex2i(w, 0);
681*54e60f84SAndroid Build Coastguard Worker     }
682*54e60f84SAndroid Build Coastguard Worker     glEnd();
683*54e60f84SAndroid Build Coastguard Worker }
684*54e60f84SAndroid Build Coastguard Worker 
685*54e60f84SAndroid Build Coastguard Worker // Create offscreen surface
create_fbo_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)686*54e60f84SAndroid Build Coastguard Worker static int create_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
687*54e60f84SAndroid Build Coastguard Worker {
688*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
689*54e60f84SAndroid Build Coastguard Worker     GLuint fbo;
690*54e60f84SAndroid Build Coastguard Worker     GLenum status;
691*54e60f84SAndroid Build Coastguard Worker 
692*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_gen_framebuffers(1, &fbo);
693*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo);
694*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_framebuffer_texture_2d(
695*54e60f84SAndroid Build Coastguard Worker         GL_FRAMEBUFFER_EXT,
696*54e60f84SAndroid Build Coastguard Worker         GL_COLOR_ATTACHMENT0_EXT,
697*54e60f84SAndroid Build Coastguard Worker         GL_TEXTURE_2D,
698*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX->texture,
699*54e60f84SAndroid Build Coastguard Worker         0
700*54e60f84SAndroid Build Coastguard Worker     );
701*54e60f84SAndroid Build Coastguard Worker 
702*54e60f84SAndroid Build Coastguard Worker     status = pOpenGLVTable->gl_check_framebuffer_status(GL_DRAW_FRAMEBUFFER_EXT);
703*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0);
704*54e60f84SAndroid Build Coastguard Worker     if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
705*54e60f84SAndroid Build Coastguard Worker         return 0;
706*54e60f84SAndroid Build Coastguard Worker 
707*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->fbo = fbo;
708*54e60f84SAndroid Build Coastguard Worker     return 1;
709*54e60f84SAndroid Build Coastguard Worker }
710*54e60f84SAndroid Build Coastguard Worker 
711*54e60f84SAndroid Build Coastguard Worker // Destroy offscreen surface
destroy_fbo_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)712*54e60f84SAndroid Build Coastguard Worker static void destroy_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
713*54e60f84SAndroid Build Coastguard Worker {
714*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
715*54e60f84SAndroid Build Coastguard Worker 
716*54e60f84SAndroid Build Coastguard Worker     if (pSurfaceGLX->fbo) {
717*54e60f84SAndroid Build Coastguard Worker         pOpenGLVTable->gl_delete_framebuffers(1, &pSurfaceGLX->fbo);
718*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX->fbo = 0;
719*54e60f84SAndroid Build Coastguard Worker     }
720*54e60f84SAndroid Build Coastguard Worker }
721*54e60f84SAndroid Build Coastguard Worker 
722*54e60f84SAndroid Build Coastguard Worker // Setup matrices to match the FBO texture dimensions
fbo_enter(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)723*54e60f84SAndroid Build Coastguard Worker static void fbo_enter(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
724*54e60f84SAndroid Build Coastguard Worker {
725*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
726*54e60f84SAndroid Build Coastguard Worker     const unsigned int width  = pSurfaceGLX->width;
727*54e60f84SAndroid Build Coastguard Worker     const unsigned int height = pSurfaceGLX->height;
728*54e60f84SAndroid Build Coastguard Worker 
729*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, pSurfaceGLX->fbo);
730*54e60f84SAndroid Build Coastguard Worker     glPushAttrib(GL_VIEWPORT_BIT);
731*54e60f84SAndroid Build Coastguard Worker     glMatrixMode(GL_PROJECTION);
732*54e60f84SAndroid Build Coastguard Worker     glPushMatrix();
733*54e60f84SAndroid Build Coastguard Worker     glLoadIdentity();
734*54e60f84SAndroid Build Coastguard Worker     glMatrixMode(GL_MODELVIEW);
735*54e60f84SAndroid Build Coastguard Worker     glPushMatrix();
736*54e60f84SAndroid Build Coastguard Worker     glLoadIdentity();
737*54e60f84SAndroid Build Coastguard Worker     glViewport(0, 0, width, height);
738*54e60f84SAndroid Build Coastguard Worker     glTranslatef(-1.0f, -1.0f, 0.0f);
739*54e60f84SAndroid Build Coastguard Worker     glScalef(2.0f / width, 2.0f / height, 1.0f);
740*54e60f84SAndroid Build Coastguard Worker }
741*54e60f84SAndroid Build Coastguard Worker 
742*54e60f84SAndroid Build Coastguard Worker // Restore original OpenGL matrices
fbo_leave(VADriverContextP ctx)743*54e60f84SAndroid Build Coastguard Worker static void fbo_leave(VADriverContextP ctx)
744*54e60f84SAndroid Build Coastguard Worker {
745*54e60f84SAndroid Build Coastguard Worker     VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
746*54e60f84SAndroid Build Coastguard Worker 
747*54e60f84SAndroid Build Coastguard Worker     glPopAttrib();
748*54e60f84SAndroid Build Coastguard Worker     glMatrixMode(GL_PROJECTION);
749*54e60f84SAndroid Build Coastguard Worker     glPopMatrix();
750*54e60f84SAndroid Build Coastguard Worker     glMatrixMode(GL_MODELVIEW);
751*54e60f84SAndroid Build Coastguard Worker     glPopMatrix();
752*54e60f84SAndroid Build Coastguard Worker     pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0);
753*54e60f84SAndroid Build Coastguard Worker }
754*54e60f84SAndroid Build Coastguard Worker 
755*54e60f84SAndroid Build Coastguard Worker // Check internal texture format is supported
is_supported_internal_format(GLenum format)756*54e60f84SAndroid Build Coastguard Worker static int is_supported_internal_format(GLenum format)
757*54e60f84SAndroid Build Coastguard Worker {
758*54e60f84SAndroid Build Coastguard Worker     /* XXX: we don't support other textures than RGBA */
759*54e60f84SAndroid Build Coastguard Worker     switch (format) {
760*54e60f84SAndroid Build Coastguard Worker     case 4:
761*54e60f84SAndroid Build Coastguard Worker     case GL_RGBA:
762*54e60f84SAndroid Build Coastguard Worker     case GL_RGBA8:
763*54e60f84SAndroid Build Coastguard Worker         return 1;
764*54e60f84SAndroid Build Coastguard Worker     }
765*54e60f84SAndroid Build Coastguard Worker     return 0;
766*54e60f84SAndroid Build Coastguard Worker }
767*54e60f84SAndroid Build Coastguard Worker 
768*54e60f84SAndroid Build Coastguard Worker // Destroy VA/GLX surface
769*54e60f84SAndroid Build Coastguard Worker static void
destroy_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)770*54e60f84SAndroid Build Coastguard Worker destroy_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
771*54e60f84SAndroid Build Coastguard Worker {
772*54e60f84SAndroid Build Coastguard Worker     unbind_pixmap(ctx, pSurfaceGLX);
773*54e60f84SAndroid Build Coastguard Worker     destroy_fbo_surface(ctx, pSurfaceGLX);
774*54e60f84SAndroid Build Coastguard Worker     destroy_tfp_surface(ctx, pSurfaceGLX);
775*54e60f84SAndroid Build Coastguard Worker     free(pSurfaceGLX);
776*54e60f84SAndroid Build Coastguard Worker }
777*54e60f84SAndroid Build Coastguard Worker 
778*54e60f84SAndroid Build Coastguard Worker // Create VA/GLX surface
779*54e60f84SAndroid Build Coastguard Worker static VASurfaceGLXP
create_surface(VADriverContextP ctx,GLenum target,GLuint texture)780*54e60f84SAndroid Build Coastguard Worker create_surface(VADriverContextP ctx, GLenum target, GLuint texture)
781*54e60f84SAndroid Build Coastguard Worker {
782*54e60f84SAndroid Build Coastguard Worker     VASurfaceGLXP pSurfaceGLX = NULL;
783*54e60f84SAndroid Build Coastguard Worker     unsigned int internal_format, border_width, width, height;
784*54e60f84SAndroid Build Coastguard Worker     int is_error = 1;
785*54e60f84SAndroid Build Coastguard Worker 
786*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX = malloc(sizeof(*pSurfaceGLX));
787*54e60f84SAndroid Build Coastguard Worker     if (!pSurfaceGLX)
788*54e60f84SAndroid Build Coastguard Worker         goto end;
789*54e60f84SAndroid Build Coastguard Worker 
790*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->magic          = VA_SURFACE_GLX_MAGIC;
791*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->target         = target;
792*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->texture        = texture;
793*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->surface        = VA_INVALID_SURFACE;
794*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->gl_context     = NULL;
795*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->is_bound       = 0;
796*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->pixmap         = None;
797*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->pix_texture    = 0;
798*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->glx_pixmap     = None;
799*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->fbo            = 0;
800*54e60f84SAndroid Build Coastguard Worker 
801*54e60f84SAndroid Build Coastguard Worker     glEnable(target);
802*54e60f84SAndroid Build Coastguard Worker     glBindTexture(target, texture);
803*54e60f84SAndroid Build Coastguard Worker     if (!gl_get_texture_param(GL_TEXTURE_INTERNAL_FORMAT, &internal_format))
804*54e60f84SAndroid Build Coastguard Worker         goto end;
805*54e60f84SAndroid Build Coastguard Worker     if (!is_supported_internal_format(internal_format))
806*54e60f84SAndroid Build Coastguard Worker         goto end;
807*54e60f84SAndroid Build Coastguard Worker 
808*54e60f84SAndroid Build Coastguard Worker     /* Check texture dimensions */
809*54e60f84SAndroid Build Coastguard Worker     if (!gl_get_texture_param(GL_TEXTURE_BORDER, &border_width))
810*54e60f84SAndroid Build Coastguard Worker         goto end;
811*54e60f84SAndroid Build Coastguard Worker     if (!gl_get_texture_param(GL_TEXTURE_WIDTH, &width))
812*54e60f84SAndroid Build Coastguard Worker         goto end;
813*54e60f84SAndroid Build Coastguard Worker     if (!gl_get_texture_param(GL_TEXTURE_HEIGHT, &height))
814*54e60f84SAndroid Build Coastguard Worker         goto end;
815*54e60f84SAndroid Build Coastguard Worker 
816*54e60f84SAndroid Build Coastguard Worker     width  -= 2 * border_width;
817*54e60f84SAndroid Build Coastguard Worker     height -= 2 * border_width;
818*54e60f84SAndroid Build Coastguard Worker     if (width == 0 || height == 0)
819*54e60f84SAndroid Build Coastguard Worker         goto end;
820*54e60f84SAndroid Build Coastguard Worker 
821*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->width  = width;
822*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->height = height;
823*54e60f84SAndroid Build Coastguard Worker 
824*54e60f84SAndroid Build Coastguard Worker     /* Create TFP objects */
825*54e60f84SAndroid Build Coastguard Worker     if (!create_tfp_surface(ctx, pSurfaceGLX))
826*54e60f84SAndroid Build Coastguard Worker         goto end;
827*54e60f84SAndroid Build Coastguard Worker 
828*54e60f84SAndroid Build Coastguard Worker     /* Create FBO objects */
829*54e60f84SAndroid Build Coastguard Worker     if (!create_fbo_surface(ctx, pSurfaceGLX))
830*54e60f84SAndroid Build Coastguard Worker         goto end;
831*54e60f84SAndroid Build Coastguard Worker 
832*54e60f84SAndroid Build Coastguard Worker     is_error = 0;
833*54e60f84SAndroid Build Coastguard Worker end:
834*54e60f84SAndroid Build Coastguard Worker     if (is_error && pSurfaceGLX) {
835*54e60f84SAndroid Build Coastguard Worker         destroy_surface(ctx, pSurfaceGLX);
836*54e60f84SAndroid Build Coastguard Worker         pSurfaceGLX = NULL;
837*54e60f84SAndroid Build Coastguard Worker     }
838*54e60f84SAndroid Build Coastguard Worker     return pSurfaceGLX;
839*54e60f84SAndroid Build Coastguard Worker }
840*54e60f84SAndroid Build Coastguard Worker 
841*54e60f84SAndroid Build Coastguard Worker 
842*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
843*54e60f84SAndroid Build Coastguard Worker /* === VA/GLX implementation from the driver (fordward calls)            === */
844*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
845*54e60f84SAndroid Build Coastguard Worker 
846*54e60f84SAndroid Build Coastguard Worker #define INVOKE(ctx, func, args) do {                    \
847*54e60f84SAndroid Build Coastguard Worker         VADriverVTableGLXP vtable = (ctx)->vtable_glx;  \
848*54e60f84SAndroid Build Coastguard Worker         if (!vtable->va##func##GLX)                     \
849*54e60f84SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_UNIMPLEMENTED;       \
850*54e60f84SAndroid Build Coastguard Worker                                                         \
851*54e60f84SAndroid Build Coastguard Worker         VAStatus status = vtable->va##func##GLX args;   \
852*54e60f84SAndroid Build Coastguard Worker         if (status != VA_STATUS_SUCCESS)                \
853*54e60f84SAndroid Build Coastguard Worker             return status;                              \
854*54e60f84SAndroid Build Coastguard Worker     } while (0)
855*54e60f84SAndroid Build Coastguard Worker 
856*54e60f84SAndroid Build Coastguard Worker static VAStatus
vaCreateSurfaceGLX_impl_driver(VADriverContextP ctx,GLenum target,GLuint texture,void ** gl_surface)857*54e60f84SAndroid Build Coastguard Worker vaCreateSurfaceGLX_impl_driver(
858*54e60f84SAndroid Build Coastguard Worker     VADriverContextP    ctx,
859*54e60f84SAndroid Build Coastguard Worker     GLenum              target,
860*54e60f84SAndroid Build Coastguard Worker     GLuint              texture,
861*54e60f84SAndroid Build Coastguard Worker     void              **gl_surface
862*54e60f84SAndroid Build Coastguard Worker )
863*54e60f84SAndroid Build Coastguard Worker {
864*54e60f84SAndroid Build Coastguard Worker     INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface));
865*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
866*54e60f84SAndroid Build Coastguard Worker }
867*54e60f84SAndroid Build Coastguard Worker 
868*54e60f84SAndroid Build Coastguard Worker static VAStatus
vaDestroySurfaceGLX_impl_driver(VADriverContextP ctx,void * gl_surface)869*54e60f84SAndroid Build Coastguard Worker vaDestroySurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface)
870*54e60f84SAndroid Build Coastguard Worker {
871*54e60f84SAndroid Build Coastguard Worker     INVOKE(ctx, DestroySurface, (ctx, gl_surface));
872*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
873*54e60f84SAndroid Build Coastguard Worker }
874*54e60f84SAndroid Build Coastguard Worker 
875*54e60f84SAndroid Build Coastguard Worker static VAStatus
vaCopySurfaceGLX_impl_driver(VADriverContextP ctx,void * gl_surface,VASurfaceID surface,unsigned int flags)876*54e60f84SAndroid Build Coastguard Worker vaCopySurfaceGLX_impl_driver(
877*54e60f84SAndroid Build Coastguard Worker     VADriverContextP    ctx,
878*54e60f84SAndroid Build Coastguard Worker     void               *gl_surface,
879*54e60f84SAndroid Build Coastguard Worker     VASurfaceID         surface,
880*54e60f84SAndroid Build Coastguard Worker     unsigned int        flags
881*54e60f84SAndroid Build Coastguard Worker )
882*54e60f84SAndroid Build Coastguard Worker {
883*54e60f84SAndroid Build Coastguard Worker     INVOKE(ctx, CopySurface, (ctx, gl_surface, surface, flags));
884*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
885*54e60f84SAndroid Build Coastguard Worker }
886*54e60f84SAndroid Build Coastguard Worker 
887*54e60f84SAndroid Build Coastguard Worker #undef INVOKE
888*54e60f84SAndroid Build Coastguard Worker 
889*54e60f84SAndroid Build Coastguard Worker 
890*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
891*54e60f84SAndroid Build Coastguard Worker /* === VA/GLX implementation from libVA (generic and suboptimal path)    === */
892*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
893*54e60f84SAndroid Build Coastguard Worker 
894*54e60f84SAndroid Build Coastguard Worker #define INIT_SURFACE(surface, surface_arg) do {         \
895*54e60f84SAndroid Build Coastguard Worker         surface = (VASurfaceGLXP)(surface_arg);         \
896*54e60f84SAndroid Build Coastguard Worker         if (!check_surface(surface))                    \
897*54e60f84SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_SURFACE;     \
898*54e60f84SAndroid Build Coastguard Worker     } while (0)
899*54e60f84SAndroid Build Coastguard Worker 
900*54e60f84SAndroid Build Coastguard Worker // Check VASurfaceGLX is valid
check_surface(VASurfaceGLXP pSurfaceGLX)901*54e60f84SAndroid Build Coastguard Worker static inline int check_surface(VASurfaceGLXP pSurfaceGLX)
902*54e60f84SAndroid Build Coastguard Worker {
903*54e60f84SAndroid Build Coastguard Worker     return pSurfaceGLX && pSurfaceGLX->magic == VA_SURFACE_GLX_MAGIC;
904*54e60f84SAndroid Build Coastguard Worker }
905*54e60f84SAndroid Build Coastguard Worker 
906*54e60f84SAndroid Build Coastguard Worker static VAStatus
vaCreateSurfaceGLX_impl_libva(VADriverContextP ctx,GLenum target,GLuint texture,void ** gl_surface)907*54e60f84SAndroid Build Coastguard Worker vaCreateSurfaceGLX_impl_libva(
908*54e60f84SAndroid Build Coastguard Worker     VADriverContextP    ctx,
909*54e60f84SAndroid Build Coastguard Worker     GLenum              target,
910*54e60f84SAndroid Build Coastguard Worker     GLuint              texture,
911*54e60f84SAndroid Build Coastguard Worker     void              **gl_surface
912*54e60f84SAndroid Build Coastguard Worker )
913*54e60f84SAndroid Build Coastguard Worker {
914*54e60f84SAndroid Build Coastguard Worker     VASurfaceGLXP pSurfaceGLX;
915*54e60f84SAndroid Build Coastguard Worker     struct OpenGLContextState old_cs, *new_cs;
916*54e60f84SAndroid Build Coastguard Worker 
917*54e60f84SAndroid Build Coastguard Worker     gl_get_current_context(&old_cs);
918*54e60f84SAndroid Build Coastguard Worker     new_cs = gl_create_context(ctx, &old_cs);
919*54e60f84SAndroid Build Coastguard Worker     if (!new_cs)
920*54e60f84SAndroid Build Coastguard Worker         goto error;
921*54e60f84SAndroid Build Coastguard Worker     if (!gl_set_current_context(new_cs, NULL))
922*54e60f84SAndroid Build Coastguard Worker         goto error;
923*54e60f84SAndroid Build Coastguard Worker 
924*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX = create_surface(ctx, target, texture);
925*54e60f84SAndroid Build Coastguard Worker     if (!pSurfaceGLX)
926*54e60f84SAndroid Build Coastguard Worker         goto error;
927*54e60f84SAndroid Build Coastguard Worker 
928*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->gl_context = new_cs;
929*54e60f84SAndroid Build Coastguard Worker     *gl_surface = pSurfaceGLX;
930*54e60f84SAndroid Build Coastguard Worker 
931*54e60f84SAndroid Build Coastguard Worker     gl_set_current_context(&old_cs, NULL);
932*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
933*54e60f84SAndroid Build Coastguard Worker 
934*54e60f84SAndroid Build Coastguard Worker error:
935*54e60f84SAndroid Build Coastguard Worker     if (new_cs)
936*54e60f84SAndroid Build Coastguard Worker         gl_destroy_context(new_cs);
937*54e60f84SAndroid Build Coastguard Worker 
938*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_ERROR_ALLOCATION_FAILED;
939*54e60f84SAndroid Build Coastguard Worker }
940*54e60f84SAndroid Build Coastguard Worker 
941*54e60f84SAndroid Build Coastguard Worker static VAStatus
vaDestroySurfaceGLX_impl_libva(VADriverContextP ctx,void * gl_surface)942*54e60f84SAndroid Build Coastguard Worker vaDestroySurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface)
943*54e60f84SAndroid Build Coastguard Worker {
944*54e60f84SAndroid Build Coastguard Worker     VASurfaceGLXP pSurfaceGLX;
945*54e60f84SAndroid Build Coastguard Worker     struct OpenGLContextState old_cs = {0}, *new_cs;
946*54e60f84SAndroid Build Coastguard Worker 
947*54e60f84SAndroid Build Coastguard Worker     INIT_SURFACE(pSurfaceGLX, gl_surface);
948*54e60f84SAndroid Build Coastguard Worker 
949*54e60f84SAndroid Build Coastguard Worker     new_cs = pSurfaceGLX->gl_context;
950*54e60f84SAndroid Build Coastguard Worker     if (!gl_set_current_context(new_cs, &old_cs))
951*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_OPERATION_FAILED;
952*54e60f84SAndroid Build Coastguard Worker 
953*54e60f84SAndroid Build Coastguard Worker     destroy_surface(ctx, pSurfaceGLX);
954*54e60f84SAndroid Build Coastguard Worker 
955*54e60f84SAndroid Build Coastguard Worker     gl_destroy_context(new_cs);
956*54e60f84SAndroid Build Coastguard Worker     gl_set_current_context(&old_cs, NULL);
957*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
958*54e60f84SAndroid Build Coastguard Worker }
959*54e60f84SAndroid Build Coastguard Worker 
960*54e60f84SAndroid Build Coastguard Worker static inline VAStatus
deassociate_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)961*54e60f84SAndroid Build Coastguard Worker deassociate_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
962*54e60f84SAndroid Build Coastguard Worker {
963*54e60f84SAndroid Build Coastguard Worker     if (!unbind_pixmap(ctx, pSurfaceGLX))
964*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_OPERATION_FAILED;
965*54e60f84SAndroid Build Coastguard Worker 
966*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->surface = VA_INVALID_SURFACE;
967*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
968*54e60f84SAndroid Build Coastguard Worker }
969*54e60f84SAndroid Build Coastguard Worker 
970*54e60f84SAndroid Build Coastguard Worker static VAStatus
associate_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX,VASurfaceID surface,unsigned int flags)971*54e60f84SAndroid Build Coastguard Worker associate_surface(
972*54e60f84SAndroid Build Coastguard Worker     VADriverContextP    ctx,
973*54e60f84SAndroid Build Coastguard Worker     VASurfaceGLXP       pSurfaceGLX,
974*54e60f84SAndroid Build Coastguard Worker     VASurfaceID         surface,
975*54e60f84SAndroid Build Coastguard Worker     unsigned int        flags
976*54e60f84SAndroid Build Coastguard Worker )
977*54e60f84SAndroid Build Coastguard Worker {
978*54e60f84SAndroid Build Coastguard Worker     VAStatus status;
979*54e60f84SAndroid Build Coastguard Worker 
980*54e60f84SAndroid Build Coastguard Worker     /* XXX: optimise case where we are associating the same VA surface
981*54e60f84SAndroid Build Coastguard Worker        as before an no changed occurred to it */
982*54e60f84SAndroid Build Coastguard Worker     status = deassociate_surface(ctx, pSurfaceGLX);
983*54e60f84SAndroid Build Coastguard Worker     if (status != VA_STATUS_SUCCESS)
984*54e60f84SAndroid Build Coastguard Worker         return status;
985*54e60f84SAndroid Build Coastguard Worker 
986*54e60f84SAndroid Build Coastguard Worker     x11_trap_errors();
987*54e60f84SAndroid Build Coastguard Worker     status = ctx->vtable->vaPutSurface(
988*54e60f84SAndroid Build Coastguard Worker                  ctx,
989*54e60f84SAndroid Build Coastguard Worker                  surface,
990*54e60f84SAndroid Build Coastguard Worker                  (void *)pSurfaceGLX->pixmap,
991*54e60f84SAndroid Build Coastguard Worker                  0, 0, pSurfaceGLX->width, pSurfaceGLX->height,
992*54e60f84SAndroid Build Coastguard Worker                  0, 0, pSurfaceGLX->width, pSurfaceGLX->height,
993*54e60f84SAndroid Build Coastguard Worker                  NULL, 0,
994*54e60f84SAndroid Build Coastguard Worker                  flags
995*54e60f84SAndroid Build Coastguard Worker              );
996*54e60f84SAndroid Build Coastguard Worker     XSync(ctx->native_dpy, False);
997*54e60f84SAndroid Build Coastguard Worker     if (x11_untrap_errors() != 0)
998*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_OPERATION_FAILED;
999*54e60f84SAndroid Build Coastguard Worker     if (status != VA_STATUS_SUCCESS)
1000*54e60f84SAndroid Build Coastguard Worker         return status;
1001*54e60f84SAndroid Build Coastguard Worker 
1002*54e60f84SAndroid Build Coastguard Worker     pSurfaceGLX->surface = surface;
1003*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
1004*54e60f84SAndroid Build Coastguard Worker }
1005*54e60f84SAndroid Build Coastguard Worker 
1006*54e60f84SAndroid Build Coastguard Worker static inline VAStatus
sync_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)1007*54e60f84SAndroid Build Coastguard Worker sync_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1008*54e60f84SAndroid Build Coastguard Worker {
1009*54e60f84SAndroid Build Coastguard Worker     if (pSurfaceGLX->surface == VA_INVALID_SURFACE)
1010*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_INVALID_SURFACE;
1011*54e60f84SAndroid Build Coastguard Worker 
1012*54e60f84SAndroid Build Coastguard Worker     return ctx->vtable->vaSyncSurface(ctx, pSurfaceGLX->surface);
1013*54e60f84SAndroid Build Coastguard Worker }
1014*54e60f84SAndroid Build Coastguard Worker 
1015*54e60f84SAndroid Build Coastguard Worker static inline VAStatus
begin_render_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)1016*54e60f84SAndroid Build Coastguard Worker begin_render_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1017*54e60f84SAndroid Build Coastguard Worker {
1018*54e60f84SAndroid Build Coastguard Worker     VAStatus status;
1019*54e60f84SAndroid Build Coastguard Worker 
1020*54e60f84SAndroid Build Coastguard Worker     status = sync_surface(ctx, pSurfaceGLX);
1021*54e60f84SAndroid Build Coastguard Worker     if (status != VA_STATUS_SUCCESS)
1022*54e60f84SAndroid Build Coastguard Worker         return status;
1023*54e60f84SAndroid Build Coastguard Worker 
1024*54e60f84SAndroid Build Coastguard Worker     if (!bind_pixmap(ctx, pSurfaceGLX))
1025*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_OPERATION_FAILED;
1026*54e60f84SAndroid Build Coastguard Worker 
1027*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
1028*54e60f84SAndroid Build Coastguard Worker }
1029*54e60f84SAndroid Build Coastguard Worker 
1030*54e60f84SAndroid Build Coastguard Worker static inline VAStatus
end_render_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX)1031*54e60f84SAndroid Build Coastguard Worker end_render_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1032*54e60f84SAndroid Build Coastguard Worker {
1033*54e60f84SAndroid Build Coastguard Worker     if (!unbind_pixmap(ctx, pSurfaceGLX))
1034*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_OPERATION_FAILED;
1035*54e60f84SAndroid Build Coastguard Worker 
1036*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
1037*54e60f84SAndroid Build Coastguard Worker }
1038*54e60f84SAndroid Build Coastguard Worker 
1039*54e60f84SAndroid Build Coastguard Worker static VAStatus
copy_surface(VADriverContextP ctx,VASurfaceGLXP pSurfaceGLX,VASurfaceID surface,unsigned int flags)1040*54e60f84SAndroid Build Coastguard Worker copy_surface(
1041*54e60f84SAndroid Build Coastguard Worker     VADriverContextP    ctx,
1042*54e60f84SAndroid Build Coastguard Worker     VASurfaceGLXP       pSurfaceGLX,
1043*54e60f84SAndroid Build Coastguard Worker     VASurfaceID         surface,
1044*54e60f84SAndroid Build Coastguard Worker     unsigned int        flags
1045*54e60f84SAndroid Build Coastguard Worker )
1046*54e60f84SAndroid Build Coastguard Worker {
1047*54e60f84SAndroid Build Coastguard Worker     VAStatus status;
1048*54e60f84SAndroid Build Coastguard Worker 
1049*54e60f84SAndroid Build Coastguard Worker     /* Associate VA surface */
1050*54e60f84SAndroid Build Coastguard Worker     status = associate_surface(ctx, pSurfaceGLX, surface, flags);
1051*54e60f84SAndroid Build Coastguard Worker     if (status != VA_STATUS_SUCCESS)
1052*54e60f84SAndroid Build Coastguard Worker         return status;
1053*54e60f84SAndroid Build Coastguard Worker 
1054*54e60f84SAndroid Build Coastguard Worker     /* Render to FBO */
1055*54e60f84SAndroid Build Coastguard Worker     fbo_enter(ctx, pSurfaceGLX);
1056*54e60f84SAndroid Build Coastguard Worker     status = begin_render_surface(ctx, pSurfaceGLX);
1057*54e60f84SAndroid Build Coastguard Worker     if (status == VA_STATUS_SUCCESS) {
1058*54e60f84SAndroid Build Coastguard Worker         render_pixmap(ctx, pSurfaceGLX);
1059*54e60f84SAndroid Build Coastguard Worker         status = end_render_surface(ctx, pSurfaceGLX);
1060*54e60f84SAndroid Build Coastguard Worker     }
1061*54e60f84SAndroid Build Coastguard Worker     fbo_leave(ctx);
1062*54e60f84SAndroid Build Coastguard Worker     if (status != VA_STATUS_SUCCESS)
1063*54e60f84SAndroid Build Coastguard Worker         return status;
1064*54e60f84SAndroid Build Coastguard Worker 
1065*54e60f84SAndroid Build Coastguard Worker     return deassociate_surface(ctx, pSurfaceGLX);
1066*54e60f84SAndroid Build Coastguard Worker }
1067*54e60f84SAndroid Build Coastguard Worker 
1068*54e60f84SAndroid Build Coastguard Worker static VAStatus
vaCopySurfaceGLX_impl_libva(VADriverContextP ctx,void * gl_surface,VASurfaceID surface,unsigned int flags)1069*54e60f84SAndroid Build Coastguard Worker vaCopySurfaceGLX_impl_libva(
1070*54e60f84SAndroid Build Coastguard Worker     VADriverContextP    ctx,
1071*54e60f84SAndroid Build Coastguard Worker     void               *gl_surface,
1072*54e60f84SAndroid Build Coastguard Worker     VASurfaceID         surface,
1073*54e60f84SAndroid Build Coastguard Worker     unsigned int        flags
1074*54e60f84SAndroid Build Coastguard Worker )
1075*54e60f84SAndroid Build Coastguard Worker {
1076*54e60f84SAndroid Build Coastguard Worker     VASurfaceGLXP pSurfaceGLX;
1077*54e60f84SAndroid Build Coastguard Worker     VAStatus status;
1078*54e60f84SAndroid Build Coastguard Worker     struct OpenGLContextState old_cs = {0};
1079*54e60f84SAndroid Build Coastguard Worker 
1080*54e60f84SAndroid Build Coastguard Worker     INIT_SURFACE(pSurfaceGLX, gl_surface);
1081*54e60f84SAndroid Build Coastguard Worker 
1082*54e60f84SAndroid Build Coastguard Worker     if (!gl_set_current_context(pSurfaceGLX->gl_context, &old_cs))
1083*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_OPERATION_FAILED;
1084*54e60f84SAndroid Build Coastguard Worker 
1085*54e60f84SAndroid Build Coastguard Worker     status = copy_surface(ctx, pSurfaceGLX, surface, flags);
1086*54e60f84SAndroid Build Coastguard Worker 
1087*54e60f84SAndroid Build Coastguard Worker     gl_set_current_context(&old_cs, NULL);
1088*54e60f84SAndroid Build Coastguard Worker     return status;
1089*54e60f84SAndroid Build Coastguard Worker }
1090*54e60f84SAndroid Build Coastguard Worker 
1091*54e60f84SAndroid Build Coastguard Worker #undef INIT_SURFACE
1092*54e60f84SAndroid Build Coastguard Worker 
1093*54e60f84SAndroid Build Coastguard Worker 
1094*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
1095*54e60f84SAndroid Build Coastguard Worker /* === Private VA/GLX vtable initialization                              === */
1096*54e60f84SAndroid Build Coastguard Worker /* ========================================================================= */
1097*54e60f84SAndroid Build Coastguard Worker 
1098*54e60f84SAndroid Build Coastguard Worker // Initialize GLX driver context
va_glx_init_context(VADriverContextP ctx)1099*54e60f84SAndroid Build Coastguard Worker VAStatus va_glx_init_context(VADriverContextP ctx)
1100*54e60f84SAndroid Build Coastguard Worker {
1101*54e60f84SAndroid Build Coastguard Worker     VADriverContextGLXP glx_ctx = VA_DRIVER_CONTEXT_GLX(ctx);
1102*54e60f84SAndroid Build Coastguard Worker     VADriverVTableGLXP  vtable  = &glx_ctx->vtable;
1103*54e60f84SAndroid Build Coastguard Worker     int glx_major, glx_minor;
1104*54e60f84SAndroid Build Coastguard Worker 
1105*54e60f84SAndroid Build Coastguard Worker     if (glx_ctx->is_initialized)
1106*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_SUCCESS;
1107*54e60f84SAndroid Build Coastguard Worker 
1108*54e60f84SAndroid Build Coastguard Worker     if (ctx->vtable_glx && ctx->vtable_glx->vaCopySurfaceGLX) {
1109*54e60f84SAndroid Build Coastguard Worker         vtable->vaCreateSurfaceGLX      = vaCreateSurfaceGLX_impl_driver;
1110*54e60f84SAndroid Build Coastguard Worker         vtable->vaDestroySurfaceGLX     = vaDestroySurfaceGLX_impl_driver;
1111*54e60f84SAndroid Build Coastguard Worker         vtable->vaCopySurfaceGLX        = vaCopySurfaceGLX_impl_driver;
1112*54e60f84SAndroid Build Coastguard Worker     } else {
1113*54e60f84SAndroid Build Coastguard Worker         vtable->vaCreateSurfaceGLX      = vaCreateSurfaceGLX_impl_libva;
1114*54e60f84SAndroid Build Coastguard Worker         vtable->vaDestroySurfaceGLX     = vaDestroySurfaceGLX_impl_libva;
1115*54e60f84SAndroid Build Coastguard Worker         vtable->vaCopySurfaceGLX        = vaCopySurfaceGLX_impl_libva;
1116*54e60f84SAndroid Build Coastguard Worker 
1117*54e60f84SAndroid Build Coastguard Worker         if (!glXQueryVersion(ctx->native_dpy, &glx_major, &glx_minor))
1118*54e60f84SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_UNIMPLEMENTED;
1119*54e60f84SAndroid Build Coastguard Worker 
1120*54e60f84SAndroid Build Coastguard Worker         if (!check_tfp_extensions(ctx) || !load_tfp_extensions(ctx))
1121*54e60f84SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_UNIMPLEMENTED;
1122*54e60f84SAndroid Build Coastguard Worker 
1123*54e60f84SAndroid Build Coastguard Worker         if (!check_fbo_extensions(ctx) || !load_fbo_extensions(ctx))
1124*54e60f84SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_UNIMPLEMENTED;
1125*54e60f84SAndroid Build Coastguard Worker     }
1126*54e60f84SAndroid Build Coastguard Worker 
1127*54e60f84SAndroid Build Coastguard Worker     glx_ctx->is_initialized = 1;
1128*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
1129*54e60f84SAndroid Build Coastguard Worker }
1130