2 * Mesa 3-D graphics library
5 * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 #include "egldriver.h"
27 #include "eglcurrent.h"
30 #include "pipe/p_screen.h"
31 #include "util/u_memory.h"
32 #include "util/u_inlines.h"
35 #include "egl_g3d_api.h"
36 #include "egl_g3d_image.h"
37 #include "egl_g3d_st.h"
41 * Return the state tracker for the given context.
43 static struct st_api
*
44 egl_g3d_choose_st(_EGLDriver
*drv
, _EGLContext
*ctx
)
46 struct egl_g3d_driver
*gdrv
= egl_g3d_driver(drv
);
50 switch (ctx
->ClientAPI
) {
51 case EGL_OPENGL_ES_API
:
52 switch (ctx
->ClientVersion
) {
54 idx
= ST_API_OPENGL_ES1
;
57 idx
= ST_API_OPENGL_ES2
;
60 _eglLog(_EGL_WARNING
, "unknown client version %d",
72 _eglLog(_EGL_WARNING
, "unknown client API 0x%04x", ctx
->ClientAPI
);
76 stapi
= (idx
>= 0) ? gdrv
->stapis
[idx
] : NULL
;
81 egl_g3d_create_context(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
82 _EGLContext
*share
, const EGLint
*attribs
)
84 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
85 struct egl_g3d_context
*gshare
= egl_g3d_context(share
);
86 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
87 struct egl_g3d_context
*gctx
;
89 gctx
= CALLOC_STRUCT(egl_g3d_context
);
91 _eglError(EGL_BAD_ALLOC
, "eglCreateContext");
95 if (!_eglInitContext(&gctx
->base
, dpy
, conf
, attribs
)) {
100 gctx
->stapi
= egl_g3d_choose_st(drv
, &gctx
->base
);
106 gctx
->stctxi
= gctx
->stapi
->create_context(gctx
->stapi
, gdpy
->smapi
,
107 &gconf
->stvis
, (gshare
) ? gshare
->stctxi
: NULL
);
113 gctx
->stctxi
->st_manager_private
= (void *) &gctx
->base
;
122 destroy_context(_EGLDisplay
*dpy
, _EGLContext
*ctx
)
124 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
126 /* FIXME a context might live longer than its display */
127 if (!dpy
->Initialized
)
128 _eglLog(_EGL_FATAL
, "destroy a context with an unitialized display");
130 gctx
->stctxi
->destroy(gctx
->stctxi
);
136 egl_g3d_destroy_context(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*ctx
)
138 if (!_eglIsContextBound(ctx
))
139 destroy_context(dpy
, ctx
);
143 struct egl_g3d_create_surface_arg
{
146 EGLNativeWindowType win
;
147 EGLNativePixmapType pix
;
152 egl_g3d_create_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
153 struct egl_g3d_create_surface_arg
*arg
,
154 const EGLint
*attribs
)
156 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
157 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
158 struct egl_g3d_surface
*gsurf
;
159 struct native_surface
*nsurf
;
164 err
= "eglCreateWindowSurface";
167 err
= "eglCreatePixmapSurface";
169 #ifdef EGL_MESA_screen_surface
170 case EGL_SCREEN_BIT_MESA
:
171 err
= "eglCreateScreenSurface";
175 err
= "eglCreateUnknownSurface";
179 gsurf
= CALLOC_STRUCT(egl_g3d_surface
);
181 _eglError(EGL_BAD_ALLOC
, err
);
185 if (!_eglInitSurface(&gsurf
->base
, dpy
, arg
->type
, conf
, attribs
)) {
190 /* create the native surface */
193 nsurf
= gdpy
->native
->create_window_surface(gdpy
->native
,
194 arg
->u
.win
, gconf
->native
);
197 nsurf
= gdpy
->native
->create_pixmap_surface(gdpy
->native
,
198 arg
->u
.pix
, gconf
->native
);
200 #ifdef EGL_MESA_screen_surface
201 case EGL_SCREEN_BIT_MESA
:
202 /* prefer back buffer (move to _eglInitSurface?) */
203 gsurf
->base
.RenderBuffer
= EGL_BACK_BUFFER
;
204 nsurf
= gdpy
->native
->modeset
->create_scanout_surface(gdpy
->native
,
205 gconf
->native
, gsurf
->base
.Width
, gsurf
->base
.Height
);
217 /* initialize the geometry */
218 if (!nsurf
->validate(nsurf
, 0x0, &gsurf
->sequence_number
, NULL
,
219 &gsurf
->base
.Width
, &gsurf
->base
.Height
)) {
220 nsurf
->destroy(nsurf
);
225 gsurf
->stvis
= gconf
->stvis
;
226 if (gsurf
->base
.RenderBuffer
== EGL_SINGLE_BUFFER
)
227 gsurf
->stvis
.render_buffer
= ST_ATTACHMENT_FRONT_LEFT
;
229 gsurf
->stfbi
= egl_g3d_create_st_framebuffer(&gsurf
->base
);
231 nsurf
->destroy(nsurf
);
236 nsurf
->user_data
= &gsurf
->base
;
237 gsurf
->native
= nsurf
;
243 egl_g3d_create_window_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
244 _EGLConfig
*conf
, EGLNativeWindowType win
,
245 const EGLint
*attribs
)
247 struct egl_g3d_create_surface_arg arg
;
249 memset(&arg
, 0, sizeof(arg
));
250 arg
.type
= EGL_WINDOW_BIT
;
253 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
257 egl_g3d_create_pixmap_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
258 _EGLConfig
*conf
, EGLNativePixmapType pix
,
259 const EGLint
*attribs
)
261 struct egl_g3d_create_surface_arg arg
;
263 memset(&arg
, 0, sizeof(arg
));
264 arg
.type
= EGL_PIXMAP_BIT
;
267 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
271 egl_g3d_create_pbuffer_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
272 _EGLConfig
*conf
, const EGLint
*attribs
)
274 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
275 struct egl_g3d_surface
*gsurf
;
277 gsurf
= CALLOC_STRUCT(egl_g3d_surface
);
279 _eglError(EGL_BAD_ALLOC
, "eglCreatePbufferSurface");
283 if (!_eglInitSurface(&gsurf
->base
, dpy
, EGL_PBUFFER_BIT
, conf
, attribs
)) {
288 gsurf
->stvis
= gconf
->stvis
;
290 gsurf
->stfbi
= egl_g3d_create_st_framebuffer(&gsurf
->base
);
303 destroy_surface(_EGLDisplay
*dpy
, _EGLSurface
*surf
)
305 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
307 /* FIXME a surface might live longer than its display */
308 if (!dpy
->Initialized
)
309 _eglLog(_EGL_FATAL
, "destroy a surface with an unitialized display");
311 pipe_resource_reference(&gsurf
->render_texture
, NULL
);
312 egl_g3d_destroy_st_framebuffer(gsurf
->stfbi
);
314 gsurf
->native
->destroy(gsurf
->native
);
319 egl_g3d_destroy_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
321 if (!_eglIsSurfaceBound(surf
))
322 destroy_surface(dpy
, surf
);
327 egl_g3d_make_current(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
328 _EGLSurface
*draw
, _EGLSurface
*read
, _EGLContext
*ctx
)
330 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
331 struct egl_g3d_surface
*gdraw
= egl_g3d_surface(draw
);
332 struct egl_g3d_surface
*gread
= egl_g3d_surface(read
);
333 struct egl_g3d_context
*old_gctx
;
334 EGLBoolean ok
= EGL_TRUE
;
336 /* bind the new context and return the "orphaned" one */
337 if (!_eglBindContext(&ctx
, &draw
, &read
))
339 old_gctx
= egl_g3d_context(ctx
);
342 /* flush old context */
343 old_gctx
->stctxi
->flush(old_gctx
->stctxi
,
344 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
348 ok
= gctx
->stapi
->make_current(gctx
->stapi
, gctx
->stctxi
,
349 (gdraw
) ? gdraw
->stfbi
: NULL
, (gread
) ? gread
->stfbi
: NULL
);
351 gctx
->stctxi
->notify_invalid_framebuffer(gctx
->stctxi
, gdraw
->stfbi
);
352 if (gread
!= gdraw
) {
353 gctx
->stctxi
->notify_invalid_framebuffer(gctx
->stctxi
,
357 if (gdraw
->base
.Type
== EGL_WINDOW_BIT
) {
358 gctx
->base
.WindowRenderBuffer
=
359 (gdraw
->stvis
.render_buffer
== ST_ATTACHMENT_FRONT_LEFT
) ?
360 EGL_SINGLE_BUFFER
: EGL_BACK_BUFFER
;
365 ok
= old_gctx
->stapi
->make_current(old_gctx
->stapi
, NULL
, NULL
, NULL
);
366 old_gctx
->base
.WindowRenderBuffer
= EGL_NONE
;
369 if (ctx
&& !_eglIsContextLinked(ctx
))
370 destroy_context(dpy
, ctx
);
371 if (draw
&& !_eglIsSurfaceLinked(draw
))
372 destroy_surface(dpy
, draw
);
373 if (read
&& read
!= draw
&& !_eglIsSurfaceLinked(read
))
374 destroy_surface(dpy
, read
);
380 egl_g3d_swap_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
382 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
383 _EGLContext
*ctx
= _eglGetCurrentContext();
384 struct egl_g3d_context
*gctx
= NULL
;
386 /* no-op for pixmap or pbuffer surface */
387 if (gsurf
->base
.Type
== EGL_PIXMAP_BIT
||
388 gsurf
->base
.Type
== EGL_PBUFFER_BIT
)
391 /* or when the surface is single-buffered */
392 if (gsurf
->stvis
.render_buffer
== ST_ATTACHMENT_FRONT_LEFT
)
395 if (ctx
&& ctx
->DrawSurface
== surf
)
396 gctx
= egl_g3d_context(ctx
);
398 /* flush if the surface is current */
400 gctx
->stctxi
->flush(gctx
->stctxi
,
401 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
404 return gsurf
->native
->swap_buffers(gsurf
->native
);
408 * Get the pipe surface of the given attachment of the native surface.
410 static struct pipe_surface
*
411 get_pipe_surface(struct native_display
*ndpy
, struct native_surface
*nsurf
,
412 enum native_attachment natt
,
415 struct pipe_resource
*textures
[NUM_NATIVE_ATTACHMENTS
];
416 struct pipe_surface
*psurf
;
418 textures
[natt
] = NULL
;
419 nsurf
->validate(nsurf
, 1 << natt
, NULL
, textures
, NULL
, NULL
);
423 psurf
= ndpy
->screen
->get_tex_surface(ndpy
->screen
, textures
[natt
],
425 pipe_resource_reference(&textures
[natt
], NULL
);
431 egl_g3d_copy_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
,
432 EGLNativePixmapType target
)
434 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
435 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
436 _EGLContext
*ctx
= _eglGetCurrentContext();
437 struct egl_g3d_config
*gconf
;
438 struct native_surface
*nsurf
;
439 struct pipe_screen
*screen
= gdpy
->native
->screen
;
440 struct pipe_surface
*psurf
;
442 if (!gsurf
->render_texture
)
445 gconf
= egl_g3d_config(egl_g3d_find_pixmap_config(dpy
, target
));
447 return _eglError(EGL_BAD_NATIVE_PIXMAP
, "eglCopyBuffers");
449 nsurf
= gdpy
->native
->create_pixmap_surface(gdpy
->native
,
450 target
, gconf
->native
);
452 return _eglError(EGL_BAD_NATIVE_PIXMAP
, "eglCopyBuffers");
454 /* flush if the surface is current */
455 if (ctx
&& ctx
->DrawSurface
== &gsurf
->base
) {
456 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
457 gctx
->stctxi
->flush(gctx
->stctxi
,
458 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
461 /* create a pipe context to copy surfaces */
464 gdpy
->native
->screen
->context_create(gdpy
->native
->screen
, NULL
);
469 psurf
= get_pipe_surface(gdpy
->native
, nsurf
, NATIVE_ATTACHMENT_FRONT_LEFT
,
470 PIPE_BIND_BLIT_DESTINATION
);
472 struct pipe_surface
*psrc
;
474 psrc
= screen
->get_tex_surface(screen
, gsurf
->render_texture
,
475 0, 0, 0, PIPE_BIND_BLIT_SOURCE
);
477 gdpy
->pipe
->surface_copy(gdpy
->pipe
, psurf
, 0, 0,
478 psrc
, 0, 0, psurf
->width
, psurf
->height
);
479 pipe_surface_reference(&psrc
, NULL
);
481 nsurf
->flush_frontbuffer(nsurf
);
484 pipe_surface_reference(&psurf
, NULL
);
487 nsurf
->destroy(nsurf
);
493 egl_g3d_wait_client(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*ctx
)
495 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
496 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
497 struct pipe_screen
*screen
= gdpy
->native
->screen
;
498 struct pipe_fence_handle
*fence
= NULL
;
500 gctx
->stctxi
->flush(gctx
->stctxi
,
501 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, &fence
);
502 screen
->fence_finish(screen
, fence
, 0);
503 screen
->fence_reference(screen
, &fence
, NULL
);
509 egl_g3d_wait_native(_EGLDriver
*drv
, _EGLDisplay
*dpy
, EGLint engine
)
511 _EGLContext
*ctx
= _eglGetCurrentContext();
513 if (engine
!= EGL_CORE_NATIVE_ENGINE
)
514 return _eglError(EGL_BAD_PARAMETER
, "eglWaitNative");
516 if (ctx
&& ctx
->DrawSurface
) {
517 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(ctx
->DrawSurface
);
520 gsurf
->native
->wait(gsurf
->native
);
527 egl_g3d_bind_tex_image(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
528 _EGLSurface
*surf
, EGLint buffer
)
530 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
531 _EGLContext
*es1
= _eglGetAPIContext(EGL_OPENGL_ES_API
);
532 struct egl_g3d_context
*gctx
;
533 enum pipe_format internal_format
;
534 enum st_texture_type target
;
536 if (!gsurf
|| gsurf
->base
.Type
!= EGL_PBUFFER_BIT
)
537 return _eglError(EGL_BAD_SURFACE
, "eglBindTexImage");
538 if (buffer
!= EGL_BACK_BUFFER
)
539 return _eglError(EGL_BAD_PARAMETER
, "eglBindTexImage");
540 if (gsurf
->base
.BoundToTexture
)
541 return _eglError(EGL_BAD_ACCESS
, "eglBindTexImage");
543 switch (gsurf
->base
.TextureFormat
) {
544 case EGL_TEXTURE_RGB
:
545 internal_format
= PIPE_FORMAT_R8G8B8_UNORM
;
547 case EGL_TEXTURE_RGBA
:
548 internal_format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
551 return _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
554 switch (gsurf
->base
.TextureTarget
) {
556 target
= ST_TEXTURE_2D
;
559 return _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
564 if (!gsurf
->render_texture
)
567 /* flush properly if the surface is bound */
568 if (gsurf
->base
.CurrentContext
) {
569 gctx
= egl_g3d_context(gsurf
->base
.CurrentContext
);
570 gctx
->stctxi
->flush(gctx
->stctxi
,
571 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
574 gctx
= egl_g3d_context(es1
);
575 if (gctx
->stctxi
->teximage
) {
576 if (!gctx
->stctxi
->teximage(gctx
->stctxi
, target
,
577 gsurf
->base
.MipmapLevel
, internal_format
,
578 gsurf
->render_texture
, gsurf
->base
.MipmapTexture
))
580 gsurf
->base
.BoundToTexture
= EGL_TRUE
;
587 egl_g3d_release_tex_image(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
588 _EGLSurface
*surf
, EGLint buffer
)
590 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
592 if (!gsurf
|| gsurf
->base
.Type
!= EGL_PBUFFER_BIT
||
593 !gsurf
->base
.BoundToTexture
)
594 return _eglError(EGL_BAD_SURFACE
, "eglReleaseTexImage");
595 if (buffer
!= EGL_BACK_BUFFER
)
596 return _eglError(EGL_BAD_PARAMETER
, "eglReleaseTexImage");
598 if (gsurf
->render_texture
) {
599 _EGLContext
*ctx
= _eglGetAPIContext(EGL_OPENGL_ES_API
);
600 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
602 /* what if the context the surface binds to is no longer current? */
604 gctx
->stctxi
->teximage(gctx
->stctxi
, ST_TEXTURE_2D
,
605 gsurf
->base
.MipmapLevel
, PIPE_FORMAT_NONE
, NULL
, FALSE
);
609 gsurf
->base
.BoundToTexture
= EGL_FALSE
;
614 #ifdef EGL_MESA_screen_surface
617 egl_g3d_create_screen_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
618 _EGLConfig
*conf
, const EGLint
*attribs
)
620 struct egl_g3d_create_surface_arg arg
;
622 memset(&arg
, 0, sizeof(arg
));
623 arg
.type
= EGL_SCREEN_BIT_MESA
;
625 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
629 egl_g3d_show_screen_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
630 _EGLScreen
*scr
, _EGLSurface
*surf
,
633 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
634 struct egl_g3d_screen
*gscr
= egl_g3d_screen(scr
);
635 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
636 struct native_surface
*nsurf
;
637 const struct native_mode
*nmode
;
644 return _eglError(EGL_BAD_MATCH
, "eglShowSurfaceMESA");
645 if (gsurf
->base
.Type
!= EGL_SCREEN_BIT_MESA
)
646 return _eglError(EGL_BAD_SURFACE
, "eglShowScreenSurfaceMESA");
647 if (gsurf
->base
.Width
< mode
->Width
|| gsurf
->base
.Height
< mode
->Height
)
648 return _eglError(EGL_BAD_MATCH
,
649 "eglShowSurfaceMESA(surface smaller than mode size)");
651 /* find the index of the mode */
652 for (idx
= 0; idx
< gscr
->base
.NumModes
; idx
++)
653 if (mode
== &gscr
->base
.Modes
[idx
])
655 if (idx
>= gscr
->base
.NumModes
) {
656 return _eglError(EGL_BAD_MODE_MESA
,
657 "eglShowSurfaceMESA(unknown mode)");
660 nsurf
= gsurf
->native
;
661 nmode
= gscr
->native_modes
[idx
];
665 return _eglError(EGL_BAD_MATCH
, "eglShowSurfaceMESA");
667 /* disable the screen */
672 /* TODO surface panning by CRTC choosing */
673 changed
= gdpy
->native
->modeset
->program(gdpy
->native
, 0, nsurf
,
674 gscr
->base
.OriginX
, gscr
->base
.OriginY
, &gscr
->native
, 1, nmode
);
676 gscr
->base
.CurrentSurface
= &gsurf
->base
;
677 gscr
->base
.CurrentMode
= mode
;
683 #endif /* EGL_MESA_screen_surface */
686 * Find a config that supports the pixmap.
689 egl_g3d_find_pixmap_config(_EGLDisplay
*dpy
, EGLNativePixmapType pix
)
691 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
692 struct egl_g3d_config
*gconf
;
695 for (i
= 0; i
< dpy
->NumConfigs
; i
++) {
696 gconf
= egl_g3d_config(dpy
->Configs
[i
]);
697 if (gdpy
->native
->is_pixmap_supported(gdpy
->native
, pix
, gconf
->native
))
701 return (i
< dpy
->NumConfigs
) ? &gconf
->base
: NULL
;
705 egl_g3d_init_driver_api(_EGLDriver
*drv
)
707 _eglInitDriverFallbacks(drv
);
709 drv
->API
.CreateContext
= egl_g3d_create_context
;
710 drv
->API
.DestroyContext
= egl_g3d_destroy_context
;
711 drv
->API
.CreateWindowSurface
= egl_g3d_create_window_surface
;
712 drv
->API
.CreatePixmapSurface
= egl_g3d_create_pixmap_surface
;
713 drv
->API
.CreatePbufferSurface
= egl_g3d_create_pbuffer_surface
;
714 drv
->API
.DestroySurface
= egl_g3d_destroy_surface
;
715 drv
->API
.MakeCurrent
= egl_g3d_make_current
;
716 drv
->API
.SwapBuffers
= egl_g3d_swap_buffers
;
717 drv
->API
.CopyBuffers
= egl_g3d_copy_buffers
;
718 drv
->API
.WaitClient
= egl_g3d_wait_client
;
719 drv
->API
.WaitNative
= egl_g3d_wait_native
;
721 drv
->API
.BindTexImage
= egl_g3d_bind_tex_image
;
722 drv
->API
.ReleaseTexImage
= egl_g3d_release_tex_image
;
724 drv
->API
.CreateImageKHR
= egl_g3d_create_image
;
725 drv
->API
.DestroyImageKHR
= egl_g3d_destroy_image
;
727 #ifdef EGL_MESA_screen_surface
728 drv
->API
.CreateScreenSurfaceMESA
= egl_g3d_create_screen_surface
;
729 drv
->API
.ShowScreenSurfaceMESA
= egl_g3d_show_screen_surface
;