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_sync.h"
38 #include "egl_g3d_st.h"
39 #include "egl_g3d_loader.h"
43 * Return the state tracker for the given context.
45 static struct st_api
*
46 egl_g3d_choose_st(_EGLDriver
*drv
, _EGLContext
*ctx
,
47 enum st_profile_type
*profile
)
49 struct egl_g3d_driver
*gdrv
= egl_g3d_driver(drv
);
52 switch (ctx
->ClientAPI
) {
53 case EGL_OPENGL_ES_API
:
54 switch (ctx
->ClientVersion
) {
56 idx
= ST_API_OPENGL_ES1
;
59 idx
= ST_API_OPENGL_ES2
;
62 _eglLog(_EGL_WARNING
, "unknown client version %d",
74 _eglLog(_EGL_WARNING
, "unknown client API 0x%04x", ctx
->ClientAPI
);
79 case ST_API_OPENGL_ES1
:
80 *profile
= ST_PROFILE_OPENGL_ES1
;
82 case ST_API_OPENGL_ES2
:
83 *profile
= ST_PROFILE_OPENGL_ES2
;
86 *profile
= ST_PROFILE_DEFAULT
;
90 return (idx
>= 0) ? gdrv
->loader
->get_st_api(idx
) : NULL
;
94 egl_g3d_create_context(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
95 _EGLContext
*share
, const EGLint
*attribs
)
97 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
98 struct egl_g3d_context
*gshare
= egl_g3d_context(share
);
99 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
100 struct egl_g3d_context
*gctx
;
101 struct st_context_attribs stattribs
;
103 gctx
= CALLOC_STRUCT(egl_g3d_context
);
105 _eglError(EGL_BAD_ALLOC
, "eglCreateContext");
109 if (!_eglInitContext(&gctx
->base
, dpy
, conf
, attribs
)) {
114 memset(&stattribs
, 0, sizeof(stattribs
));
116 stattribs
.visual
= gconf
->stvis
;
118 gctx
->stapi
= egl_g3d_choose_st(drv
, &gctx
->base
, &stattribs
.profile
);
124 gctx
->stctxi
= gctx
->stapi
->create_context(gctx
->stapi
, gdpy
->smapi
,
125 &stattribs
, (gshare
) ? gshare
->stctxi
: NULL
);
131 gctx
->stctxi
->st_manager_private
= (void *) &gctx
->base
;
140 destroy_context(_EGLDisplay
*dpy
, _EGLContext
*ctx
)
142 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
144 /* FIXME a context might live longer than its display */
145 if (!dpy
->Initialized
)
146 _eglLog(_EGL_FATAL
, "destroy a context with an unitialized display");
148 gctx
->stctxi
->destroy(gctx
->stctxi
);
154 egl_g3d_destroy_context(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*ctx
)
156 if (!_eglIsContextBound(ctx
))
157 destroy_context(dpy
, ctx
);
161 struct egl_g3d_create_surface_arg
{
164 EGLNativeWindowType win
;
165 EGLNativePixmapType pix
;
170 egl_g3d_create_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
171 struct egl_g3d_create_surface_arg
*arg
,
172 const EGLint
*attribs
)
174 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
175 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
176 struct egl_g3d_surface
*gsurf
;
177 struct native_surface
*nsurf
;
182 err
= "eglCreateWindowSurface";
185 err
= "eglCreatePixmapSurface";
187 #ifdef EGL_MESA_screen_surface
188 case EGL_SCREEN_BIT_MESA
:
189 err
= "eglCreateScreenSurface";
193 err
= "eglCreateUnknownSurface";
197 gsurf
= CALLOC_STRUCT(egl_g3d_surface
);
199 _eglError(EGL_BAD_ALLOC
, err
);
203 if (!_eglInitSurface(&gsurf
->base
, dpy
, arg
->type
, conf
, attribs
)) {
208 /* create the native surface */
211 nsurf
= gdpy
->native
->create_window_surface(gdpy
->native
,
212 arg
->u
.win
, gconf
->native
);
215 nsurf
= gdpy
->native
->create_pixmap_surface(gdpy
->native
,
216 arg
->u
.pix
, gconf
->native
);
218 #ifdef EGL_MESA_screen_surface
219 case EGL_SCREEN_BIT_MESA
:
220 /* prefer back buffer (move to _eglInitSurface?) */
221 gsurf
->base
.RenderBuffer
= EGL_BACK_BUFFER
;
222 nsurf
= gdpy
->native
->modeset
->create_scanout_surface(gdpy
->native
,
223 gconf
->native
, gsurf
->base
.Width
, gsurf
->base
.Height
);
235 /* initialize the geometry */
236 if (!nsurf
->validate(nsurf
, 0x0, &gsurf
->sequence_number
, NULL
,
237 &gsurf
->base
.Width
, &gsurf
->base
.Height
)) {
238 nsurf
->destroy(nsurf
);
243 gsurf
->stvis
= gconf
->stvis
;
244 if (gsurf
->base
.RenderBuffer
== EGL_SINGLE_BUFFER
)
245 gsurf
->stvis
.render_buffer
= ST_ATTACHMENT_FRONT_LEFT
;
247 gsurf
->stfbi
= egl_g3d_create_st_framebuffer(&gsurf
->base
);
249 nsurf
->destroy(nsurf
);
254 nsurf
->user_data
= &gsurf
->base
;
255 gsurf
->native
= nsurf
;
261 egl_g3d_create_window_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
262 _EGLConfig
*conf
, EGLNativeWindowType win
,
263 const EGLint
*attribs
)
265 struct egl_g3d_create_surface_arg arg
;
267 memset(&arg
, 0, sizeof(arg
));
268 arg
.type
= EGL_WINDOW_BIT
;
271 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
275 egl_g3d_create_pixmap_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
276 _EGLConfig
*conf
, EGLNativePixmapType pix
,
277 const EGLint
*attribs
)
279 struct egl_g3d_create_surface_arg arg
;
281 memset(&arg
, 0, sizeof(arg
));
282 arg
.type
= EGL_PIXMAP_BIT
;
285 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
288 static struct egl_g3d_surface
*
289 create_pbuffer_surface(_EGLDisplay
*dpy
, _EGLConfig
*conf
,
290 const EGLint
*attribs
, const char *func
)
292 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
293 struct egl_g3d_surface
*gsurf
;
295 gsurf
= CALLOC_STRUCT(egl_g3d_surface
);
297 _eglError(EGL_BAD_ALLOC
, func
);
301 if (!_eglInitSurface(&gsurf
->base
, dpy
, EGL_PBUFFER_BIT
, conf
, attribs
)) {
306 gsurf
->stvis
= gconf
->stvis
;
308 gsurf
->stfbi
= egl_g3d_create_st_framebuffer(&gsurf
->base
);
318 egl_g3d_create_pbuffer_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
319 _EGLConfig
*conf
, const EGLint
*attribs
)
321 struct egl_g3d_surface
*gsurf
;
322 struct pipe_resource
*ptex
= NULL
;
324 gsurf
= create_pbuffer_surface(dpy
, conf
, attribs
,
325 "eglCreatePbufferSurface");
329 gsurf
->client_buffer_type
= EGL_NONE
;
331 if (!gsurf
->stfbi
->validate(gsurf
->stfbi
,
332 &gsurf
->stvis
.render_buffer
, 1, &ptex
)) {
333 egl_g3d_destroy_st_framebuffer(gsurf
->stfbi
);
342 egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
344 EGLClientBuffer buffer
,
346 const EGLint
*attribs
)
348 struct egl_g3d_surface
*gsurf
;
349 struct pipe_resource
*ptex
= NULL
;
350 EGLint pbuffer_attribs
[32];
354 case EGL_OPENVG_IMAGE
:
357 _eglError(EGL_BAD_PARAMETER
, "eglCreatePbufferFromClientBuffer");
362 /* parse the attributes first */
364 for (i
= 0; attribs
&& attribs
[i
] != EGL_NONE
; i
++) {
365 EGLint attr
= attribs
[i
++];
366 EGLint val
= attribs
[i
];
367 EGLint err
= EGL_SUCCESS
;
370 case EGL_TEXTURE_FORMAT
:
371 case EGL_TEXTURE_TARGET
:
372 case EGL_MIPMAP_TEXTURE
:
373 pbuffer_attribs
[count
++] = attr
;
374 pbuffer_attribs
[count
++] = val
;
377 err
= EGL_BAD_ATTRIBUTE
;
381 if (err
!= EGL_SUCCESS
) {
382 _eglError(err
, "eglCreatePbufferFromClientBuffer");
387 pbuffer_attribs
[count
++] = EGL_NONE
;
389 gsurf
= create_pbuffer_surface(dpy
, conf
, pbuffer_attribs
,
390 "eglCreatePbufferFromClientBuffer");
394 gsurf
->client_buffer_type
= buftype
;
395 gsurf
->client_buffer
= buffer
;
397 if (!gsurf
->stfbi
->validate(gsurf
->stfbi
,
398 &gsurf
->stvis
.render_buffer
, 1, &ptex
)) {
399 egl_g3d_destroy_st_framebuffer(gsurf
->stfbi
);
411 destroy_surface(_EGLDisplay
*dpy
, _EGLSurface
*surf
)
413 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
415 /* FIXME a surface might live longer than its display */
416 if (!dpy
->Initialized
)
417 _eglLog(_EGL_FATAL
, "destroy a surface with an unitialized display");
419 pipe_resource_reference(&gsurf
->render_texture
, NULL
);
420 egl_g3d_destroy_st_framebuffer(gsurf
->stfbi
);
422 gsurf
->native
->destroy(gsurf
->native
);
427 egl_g3d_destroy_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
429 if (!_eglIsSurfaceBound(surf
))
430 destroy_surface(dpy
, surf
);
435 egl_g3d_make_current(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
436 _EGLSurface
*draw
, _EGLSurface
*read
, _EGLContext
*ctx
)
438 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
439 struct egl_g3d_surface
*gdraw
= egl_g3d_surface(draw
);
440 struct egl_g3d_surface
*gread
= egl_g3d_surface(read
);
441 struct egl_g3d_context
*old_gctx
;
442 EGLBoolean ok
= EGL_TRUE
;
444 /* bind the new context and return the "orphaned" one */
445 if (!_eglBindContext(&ctx
, &draw
, &read
))
447 old_gctx
= egl_g3d_context(ctx
);
450 /* flush old context */
451 old_gctx
->stctxi
->flush(old_gctx
->stctxi
,
452 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
456 ok
= gctx
->stapi
->make_current(gctx
->stapi
, gctx
->stctxi
,
457 (gdraw
) ? gdraw
->stfbi
: NULL
, (gread
) ? gread
->stfbi
: NULL
);
460 gctx
->stctxi
->notify_invalid_framebuffer(gctx
->stctxi
,
463 if (gdraw
->base
.Type
== EGL_WINDOW_BIT
) {
464 gctx
->base
.WindowRenderBuffer
=
465 (gdraw
->stvis
.render_buffer
== ST_ATTACHMENT_FRONT_LEFT
) ?
466 EGL_SINGLE_BUFFER
: EGL_BACK_BUFFER
;
469 if (gread
&& gread
!= gdraw
) {
470 gctx
->stctxi
->notify_invalid_framebuffer(gctx
->stctxi
,
476 ok
= old_gctx
->stapi
->make_current(old_gctx
->stapi
, NULL
, NULL
, NULL
);
477 old_gctx
->base
.WindowRenderBuffer
= EGL_NONE
;
480 if (ctx
&& !_eglIsContextLinked(ctx
))
481 destroy_context(dpy
, ctx
);
482 if (draw
&& !_eglIsSurfaceLinked(draw
))
483 destroy_surface(dpy
, draw
);
484 if (read
&& read
!= draw
&& !_eglIsSurfaceLinked(read
))
485 destroy_surface(dpy
, read
);
491 egl_g3d_swap_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
493 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
494 _EGLContext
*ctx
= _eglGetCurrentContext();
495 struct egl_g3d_context
*gctx
= NULL
;
497 /* no-op for pixmap or pbuffer surface */
498 if (gsurf
->base
.Type
== EGL_PIXMAP_BIT
||
499 gsurf
->base
.Type
== EGL_PBUFFER_BIT
)
502 /* or when the surface is single-buffered */
503 if (gsurf
->stvis
.render_buffer
== ST_ATTACHMENT_FRONT_LEFT
)
506 if (ctx
&& ctx
->DrawSurface
== surf
)
507 gctx
= egl_g3d_context(ctx
);
509 /* flush if the surface is current */
511 gctx
->stctxi
->flush(gctx
->stctxi
,
512 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
515 return gsurf
->native
->swap_buffers(gsurf
->native
);
519 * Get the pipe surface of the given attachment of the native surface.
521 static struct pipe_resource
*
522 get_pipe_resource(struct native_display
*ndpy
, struct native_surface
*nsurf
,
523 enum native_attachment natt
)
525 struct pipe_resource
*textures
[NUM_NATIVE_ATTACHMENTS
];
527 textures
[natt
] = NULL
;
528 nsurf
->validate(nsurf
, 1 << natt
, NULL
, textures
, NULL
, NULL
);
530 return textures
[natt
];
534 egl_g3d_copy_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
,
535 EGLNativePixmapType target
)
537 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
538 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
539 _EGLContext
*ctx
= _eglGetCurrentContext();
540 struct egl_g3d_config
*gconf
;
541 struct native_surface
*nsurf
;
542 struct pipe_resource
*ptex
;
544 if (!gsurf
->render_texture
)
547 gconf
= egl_g3d_config(egl_g3d_find_pixmap_config(dpy
, target
));
549 return _eglError(EGL_BAD_NATIVE_PIXMAP
, "eglCopyBuffers");
551 nsurf
= gdpy
->native
->create_pixmap_surface(gdpy
->native
,
552 target
, gconf
->native
);
554 return _eglError(EGL_BAD_NATIVE_PIXMAP
, "eglCopyBuffers");
556 /* flush if the surface is current */
557 if (ctx
&& ctx
->DrawSurface
== &gsurf
->base
) {
558 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
559 gctx
->stctxi
->flush(gctx
->stctxi
,
560 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
563 /* create a pipe context to copy surfaces */
566 gdpy
->native
->screen
->context_create(gdpy
->native
->screen
, NULL
);
571 ptex
= get_pipe_resource(gdpy
->native
, nsurf
, NATIVE_ATTACHMENT_FRONT_LEFT
);
573 struct pipe_resource
*psrc
= gsurf
->render_texture
;
574 struct pipe_subresource subsrc
, subdst
;
581 gdpy
->pipe
->resource_copy_region(gdpy
->pipe
, ptex
, subdst
, 0, 0, 0,
582 gsurf
->render_texture
, subsrc
, 0, 0, 0, ptex
->width0
, ptex
->height0
);
584 nsurf
->flush_frontbuffer(nsurf
);
587 pipe_resource_reference(&ptex
, NULL
);
590 nsurf
->destroy(nsurf
);
596 egl_g3d_wait_client(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*ctx
)
598 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
599 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
600 struct pipe_screen
*screen
= gdpy
->native
->screen
;
601 struct pipe_fence_handle
*fence
= NULL
;
603 gctx
->stctxi
->flush(gctx
->stctxi
,
604 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, &fence
);
605 screen
->fence_finish(screen
, fence
, 0);
606 screen
->fence_reference(screen
, &fence
, NULL
);
612 egl_g3d_wait_native(_EGLDriver
*drv
, _EGLDisplay
*dpy
, EGLint engine
)
614 _EGLContext
*ctx
= _eglGetCurrentContext();
616 if (engine
!= EGL_CORE_NATIVE_ENGINE
)
617 return _eglError(EGL_BAD_PARAMETER
, "eglWaitNative");
619 if (ctx
&& ctx
->DrawSurface
) {
620 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(ctx
->DrawSurface
);
623 gsurf
->native
->wait(gsurf
->native
);
630 egl_g3d_bind_tex_image(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
631 _EGLSurface
*surf
, EGLint buffer
)
633 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
634 _EGLContext
*es1
= _eglGetAPIContext(EGL_OPENGL_ES_API
);
635 struct egl_g3d_context
*gctx
;
636 enum pipe_format internal_format
;
637 enum st_texture_type target
;
639 if (!gsurf
|| gsurf
->base
.Type
!= EGL_PBUFFER_BIT
)
640 return _eglError(EGL_BAD_SURFACE
, "eglBindTexImage");
641 if (buffer
!= EGL_BACK_BUFFER
)
642 return _eglError(EGL_BAD_PARAMETER
, "eglBindTexImage");
643 if (gsurf
->base
.BoundToTexture
)
644 return _eglError(EGL_BAD_ACCESS
, "eglBindTexImage");
646 switch (gsurf
->base
.TextureFormat
) {
647 case EGL_TEXTURE_RGB
:
648 internal_format
= PIPE_FORMAT_R8G8B8_UNORM
;
650 case EGL_TEXTURE_RGBA
:
651 internal_format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
654 return _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
657 switch (gsurf
->base
.TextureTarget
) {
659 target
= ST_TEXTURE_2D
;
662 return _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
667 if (!gsurf
->render_texture
)
670 /* flush properly if the surface is bound */
671 if (gsurf
->base
.CurrentContext
) {
672 gctx
= egl_g3d_context(gsurf
->base
.CurrentContext
);
673 gctx
->stctxi
->flush(gctx
->stctxi
,
674 PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_FRAME
, NULL
);
677 gctx
= egl_g3d_context(es1
);
678 if (gctx
->stctxi
->teximage
) {
679 if (!gctx
->stctxi
->teximage(gctx
->stctxi
, target
,
680 gsurf
->base
.MipmapLevel
, internal_format
,
681 gsurf
->render_texture
, gsurf
->base
.MipmapTexture
))
683 gsurf
->base
.BoundToTexture
= EGL_TRUE
;
690 egl_g3d_release_tex_image(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
691 _EGLSurface
*surf
, EGLint buffer
)
693 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
695 if (!gsurf
|| gsurf
->base
.Type
!= EGL_PBUFFER_BIT
||
696 !gsurf
->base
.BoundToTexture
)
697 return _eglError(EGL_BAD_SURFACE
, "eglReleaseTexImage");
698 if (buffer
!= EGL_BACK_BUFFER
)
699 return _eglError(EGL_BAD_PARAMETER
, "eglReleaseTexImage");
701 if (gsurf
->render_texture
) {
702 _EGLContext
*ctx
= _eglGetAPIContext(EGL_OPENGL_ES_API
);
703 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
705 /* what if the context the surface binds to is no longer current? */
707 gctx
->stctxi
->teximage(gctx
->stctxi
, ST_TEXTURE_2D
,
708 gsurf
->base
.MipmapLevel
, PIPE_FORMAT_NONE
, NULL
, FALSE
);
712 gsurf
->base
.BoundToTexture
= EGL_FALSE
;
717 #ifdef EGL_MESA_screen_surface
720 egl_g3d_create_screen_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
721 _EGLConfig
*conf
, const EGLint
*attribs
)
723 struct egl_g3d_create_surface_arg arg
;
725 memset(&arg
, 0, sizeof(arg
));
726 arg
.type
= EGL_SCREEN_BIT_MESA
;
728 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
732 egl_g3d_show_screen_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
733 _EGLScreen
*scr
, _EGLSurface
*surf
,
736 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
737 struct egl_g3d_screen
*gscr
= egl_g3d_screen(scr
);
738 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
739 struct native_surface
*nsurf
;
740 const struct native_mode
*nmode
;
747 return _eglError(EGL_BAD_MATCH
, "eglShowSurfaceMESA");
748 if (gsurf
->base
.Type
!= EGL_SCREEN_BIT_MESA
)
749 return _eglError(EGL_BAD_SURFACE
, "eglShowScreenSurfaceMESA");
750 if (gsurf
->base
.Width
< mode
->Width
|| gsurf
->base
.Height
< mode
->Height
)
751 return _eglError(EGL_BAD_MATCH
,
752 "eglShowSurfaceMESA(surface smaller than mode size)");
754 /* find the index of the mode */
755 for (idx
= 0; idx
< gscr
->base
.NumModes
; idx
++)
756 if (mode
== &gscr
->base
.Modes
[idx
])
758 if (idx
>= gscr
->base
.NumModes
) {
759 return _eglError(EGL_BAD_MODE_MESA
,
760 "eglShowSurfaceMESA(unknown mode)");
763 nsurf
= gsurf
->native
;
764 nmode
= gscr
->native_modes
[idx
];
768 return _eglError(EGL_BAD_MATCH
, "eglShowSurfaceMESA");
770 /* disable the screen */
775 /* TODO surface panning by CRTC choosing */
776 changed
= gdpy
->native
->modeset
->program(gdpy
->native
, 0, nsurf
,
777 gscr
->base
.OriginX
, gscr
->base
.OriginY
, &gscr
->native
, 1, nmode
);
779 gscr
->base
.CurrentSurface
= &gsurf
->base
;
780 gscr
->base
.CurrentMode
= mode
;
786 #endif /* EGL_MESA_screen_surface */
789 * Find a config that supports the pixmap.
792 egl_g3d_find_pixmap_config(_EGLDisplay
*dpy
, EGLNativePixmapType pix
)
794 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
795 struct egl_g3d_config
*gconf
;
798 for (i
= 0; i
< dpy
->Configs
->Size
; i
++) {
799 gconf
= egl_g3d_config((_EGLConfig
*) dpy
->Configs
->Elements
[i
]);
800 if (gdpy
->native
->is_pixmap_supported(gdpy
->native
, pix
, gconf
->native
))
804 return (i
< dpy
->Configs
->Size
) ? &gconf
->base
: NULL
;
808 egl_g3d_init_driver_api(_EGLDriver
*drv
)
810 _eglInitDriverFallbacks(drv
);
812 drv
->API
.CreateContext
= egl_g3d_create_context
;
813 drv
->API
.DestroyContext
= egl_g3d_destroy_context
;
814 drv
->API
.CreateWindowSurface
= egl_g3d_create_window_surface
;
815 drv
->API
.CreatePixmapSurface
= egl_g3d_create_pixmap_surface
;
816 drv
->API
.CreatePbufferSurface
= egl_g3d_create_pbuffer_surface
;
817 drv
->API
.CreatePbufferFromClientBuffer
= egl_g3d_create_pbuffer_from_client_buffer
;
818 drv
->API
.DestroySurface
= egl_g3d_destroy_surface
;
819 drv
->API
.MakeCurrent
= egl_g3d_make_current
;
820 drv
->API
.SwapBuffers
= egl_g3d_swap_buffers
;
821 drv
->API
.CopyBuffers
= egl_g3d_copy_buffers
;
822 drv
->API
.WaitClient
= egl_g3d_wait_client
;
823 drv
->API
.WaitNative
= egl_g3d_wait_native
;
825 drv
->API
.BindTexImage
= egl_g3d_bind_tex_image
;
826 drv
->API
.ReleaseTexImage
= egl_g3d_release_tex_image
;
828 drv
->API
.CreateImageKHR
= egl_g3d_create_image
;
829 drv
->API
.DestroyImageKHR
= egl_g3d_destroy_image
;
830 #ifdef EGL_MESA_drm_image
831 drv
->API
.CreateDRMImageMESA
= egl_g3d_create_drm_image
;
832 drv
->API
.ExportDRMImageMESA
= egl_g3d_export_drm_image
;
835 #ifdef EGL_KHR_reusable_sync
836 drv
->API
.CreateSyncKHR
= egl_g3d_create_sync
;
837 drv
->API
.DestroySyncKHR
= egl_g3d_destroy_sync
;
838 drv
->API
.ClientWaitSyncKHR
= egl_g3d_client_wait_sync
;
839 drv
->API
.SignalSyncKHR
= egl_g3d_signal_sync
;
842 #ifdef EGL_MESA_screen_surface
843 drv
->API
.CreateScreenSurfaceMESA
= egl_g3d_create_screen_surface
;
844 drv
->API
.ShowScreenSurfaceMESA
= egl_g3d_show_screen_surface
;