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"
33 #include "util/u_box.h"
36 #include "egl_g3d_api.h"
37 #include "egl_g3d_image.h"
38 #include "egl_g3d_sync.h"
39 #include "egl_g3d_st.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
)
52 *profile
= ST_PROFILE_DEFAULT
;
54 switch (ctx
->ClientAPI
) {
55 case EGL_OPENGL_ES_API
:
56 switch (ctx
->ClientVersion
) {
59 *profile
= ST_PROFILE_OPENGL_ES1
;
63 *profile
= ST_PROFILE_OPENGL_ES2
;
66 _eglLog(_EGL_WARNING
, "unknown client version %d",
78 _eglLog(_EGL_WARNING
, "unknown client API 0x%04x", ctx
->ClientAPI
);
82 stapi
= egl_g3d_get_st_api(drv
, api
);
83 if (stapi
&& !(stapi
->profile_mask
& (1 << *profile
)))
90 egl_g3d_compare_config(const _EGLConfig
*conf1
, const _EGLConfig
*conf2
,
93 const _EGLConfig
*criteria
= (const _EGLConfig
*) priv_data
;
95 /* EGL_NATIVE_VISUAL_TYPE ignored? */
96 return _eglCompareConfigs(conf1
, conf2
, criteria
, EGL_TRUE
);
100 egl_g3d_match_config(const _EGLConfig
*conf
, void *priv_data
)
102 const _EGLConfig
*criteria
= (const _EGLConfig
*) priv_data
;
104 if (!_eglMatchConfig(conf
, criteria
))
107 if (criteria
->MatchNativePixmap
!= EGL_NONE
&&
108 criteria
->MatchNativePixmap
!= EGL_DONT_CARE
) {
109 struct egl_g3d_display
*gdpy
= egl_g3d_display(conf
->Display
);
110 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
111 EGLNativePixmapType pix
=
112 (EGLNativePixmapType
) criteria
->MatchNativePixmap
;
114 if (!gdpy
->native
->is_pixmap_supported(gdpy
->native
, pix
, gconf
->native
))
122 egl_g3d_choose_config(_EGLDriver
*drv
, _EGLDisplay
*dpy
, const EGLint
*attribs
,
123 EGLConfig
*configs
, EGLint size
, EGLint
*num_configs
)
127 if (!_eglParseConfigAttribList(&criteria
, dpy
, attribs
))
128 return _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
130 return _eglFilterConfigArray(dpy
->Configs
, configs
, size
, num_configs
,
131 egl_g3d_match_config
, egl_g3d_compare_config
, &criteria
);
135 egl_g3d_create_context(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
136 _EGLContext
*share
, const EGLint
*attribs
)
138 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
139 struct egl_g3d_context
*gshare
= egl_g3d_context(share
);
140 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
141 struct egl_g3d_context
*gctx
;
142 struct st_context_attribs stattribs
;
144 gctx
= CALLOC_STRUCT(egl_g3d_context
);
146 _eglError(EGL_BAD_ALLOC
, "eglCreateContext");
150 if (!_eglInitContext(&gctx
->base
, dpy
, conf
, attribs
)) {
155 memset(&stattribs
, 0, sizeof(stattribs
));
157 stattribs
.visual
= gconf
->stvis
;
159 gctx
->stapi
= egl_g3d_choose_st(drv
, &gctx
->base
, &stattribs
.profile
);
165 gctx
->stctxi
= gctx
->stapi
->create_context(gctx
->stapi
, gdpy
->smapi
,
166 &stattribs
, (gshare
) ? gshare
->stctxi
: NULL
);
172 gctx
->stctxi
->st_manager_private
= (void *) &gctx
->base
;
181 destroy_context(_EGLDisplay
*dpy
, _EGLContext
*ctx
)
183 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
185 /* FIXME a context might live longer than its display */
186 if (!dpy
->Initialized
)
187 _eglLog(_EGL_FATAL
, "destroy a context with an unitialized display");
189 gctx
->stctxi
->destroy(gctx
->stctxi
);
195 egl_g3d_destroy_context(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*ctx
)
197 if (_eglPutContext(ctx
))
198 destroy_context(dpy
, ctx
);
202 struct egl_g3d_create_surface_arg
{
205 EGLNativeWindowType win
;
206 EGLNativePixmapType pix
;
211 egl_g3d_create_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
212 struct egl_g3d_create_surface_arg
*arg
,
213 const EGLint
*attribs
)
215 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
216 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
217 struct egl_g3d_surface
*gsurf
;
218 struct native_surface
*nsurf
;
223 err
= "eglCreateWindowSurface";
226 err
= "eglCreatePixmapSurface";
228 #ifdef EGL_MESA_screen_surface
229 case EGL_SCREEN_BIT_MESA
:
230 err
= "eglCreateScreenSurface";
234 err
= "eglCreateUnknownSurface";
238 gsurf
= CALLOC_STRUCT(egl_g3d_surface
);
240 _eglError(EGL_BAD_ALLOC
, err
);
244 if (!_eglInitSurface(&gsurf
->base
, dpy
, arg
->type
, conf
, attribs
)) {
249 /* create the native surface */
252 nsurf
= gdpy
->native
->create_window_surface(gdpy
->native
,
253 arg
->u
.win
, gconf
->native
);
256 nsurf
= gdpy
->native
->create_pixmap_surface(gdpy
->native
,
257 arg
->u
.pix
, gconf
->native
);
259 #ifdef EGL_MESA_screen_surface
260 case EGL_SCREEN_BIT_MESA
:
261 /* prefer back buffer (move to _eglInitSurface?) */
262 gsurf
->base
.RenderBuffer
= EGL_BACK_BUFFER
;
263 nsurf
= gdpy
->native
->modeset
->create_scanout_surface(gdpy
->native
,
264 gconf
->native
, gsurf
->base
.Width
, gsurf
->base
.Height
);
276 /* initialize the geometry */
277 if (!nsurf
->validate(nsurf
, 0x0, &gsurf
->sequence_number
, NULL
,
278 &gsurf
->base
.Width
, &gsurf
->base
.Height
)) {
279 nsurf
->destroy(nsurf
);
284 gsurf
->stvis
= gconf
->stvis
;
285 if (gsurf
->base
.RenderBuffer
== EGL_SINGLE_BUFFER
&&
286 gconf
->stvis
.buffer_mask
& ST_ATTACHMENT_FRONT_LEFT_MASK
)
287 gsurf
->stvis
.render_buffer
= ST_ATTACHMENT_FRONT_LEFT
;
289 gsurf
->stfbi
= egl_g3d_create_st_framebuffer(&gsurf
->base
);
291 nsurf
->destroy(nsurf
);
296 nsurf
->user_data
= &gsurf
->base
;
297 gsurf
->native
= nsurf
;
303 egl_g3d_create_window_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
304 _EGLConfig
*conf
, EGLNativeWindowType win
,
305 const EGLint
*attribs
)
307 struct egl_g3d_create_surface_arg arg
;
309 memset(&arg
, 0, sizeof(arg
));
310 arg
.type
= EGL_WINDOW_BIT
;
313 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
317 egl_g3d_create_pixmap_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
318 _EGLConfig
*conf
, EGLNativePixmapType pix
,
319 const EGLint
*attribs
)
321 struct egl_g3d_create_surface_arg arg
;
323 memset(&arg
, 0, sizeof(arg
));
324 arg
.type
= EGL_PIXMAP_BIT
;
327 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
330 static struct egl_g3d_surface
*
331 create_pbuffer_surface(_EGLDisplay
*dpy
, _EGLConfig
*conf
,
332 const EGLint
*attribs
, const char *func
)
334 struct egl_g3d_config
*gconf
= egl_g3d_config(conf
);
335 struct egl_g3d_surface
*gsurf
;
337 gsurf
= CALLOC_STRUCT(egl_g3d_surface
);
339 _eglError(EGL_BAD_ALLOC
, func
);
343 if (!_eglInitSurface(&gsurf
->base
, dpy
, EGL_PBUFFER_BIT
, conf
, attribs
)) {
348 gsurf
->stvis
= gconf
->stvis
;
350 gsurf
->stfbi
= egl_g3d_create_st_framebuffer(&gsurf
->base
);
360 egl_g3d_create_pbuffer_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
361 _EGLConfig
*conf
, const EGLint
*attribs
)
363 struct egl_g3d_surface
*gsurf
;
365 gsurf
= create_pbuffer_surface(dpy
, conf
, attribs
,
366 "eglCreatePbufferSurface");
370 gsurf
->client_buffer_type
= EGL_NONE
;
376 egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
378 EGLClientBuffer buffer
,
380 const EGLint
*attribs
)
382 struct egl_g3d_surface
*gsurf
;
383 struct pipe_resource
*ptex
= NULL
;
384 EGLint pbuffer_attribs
[32];
388 case EGL_OPENVG_IMAGE
:
391 _eglError(EGL_BAD_PARAMETER
, "eglCreatePbufferFromClientBuffer");
396 /* parse the attributes first */
398 for (i
= 0; attribs
&& attribs
[i
] != EGL_NONE
; i
++) {
399 EGLint attr
= attribs
[i
++];
400 EGLint val
= attribs
[i
];
401 EGLint err
= EGL_SUCCESS
;
404 case EGL_TEXTURE_FORMAT
:
405 case EGL_TEXTURE_TARGET
:
406 case EGL_MIPMAP_TEXTURE
:
407 pbuffer_attribs
[count
++] = attr
;
408 pbuffer_attribs
[count
++] = val
;
411 err
= EGL_BAD_ATTRIBUTE
;
415 if (err
!= EGL_SUCCESS
) {
416 _eglError(err
, "eglCreatePbufferFromClientBuffer");
421 pbuffer_attribs
[count
++] = EGL_NONE
;
423 gsurf
= create_pbuffer_surface(dpy
, conf
, pbuffer_attribs
,
424 "eglCreatePbufferFromClientBuffer");
428 gsurf
->client_buffer_type
= buftype
;
429 gsurf
->client_buffer
= buffer
;
431 /* validate now so that it fails if the client buffer is invalid */
432 if (!gsurf
->stfbi
->validate(gsurf
->stfbi
,
433 &gsurf
->stvis
.render_buffer
, 1, &ptex
)) {
434 egl_g3d_destroy_st_framebuffer(gsurf
->stfbi
);
438 pipe_resource_reference(&ptex
, NULL
);
447 destroy_surface(_EGLDisplay
*dpy
, _EGLSurface
*surf
)
449 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
451 /* FIXME a surface might live longer than its display */
452 if (!dpy
->Initialized
)
453 _eglLog(_EGL_FATAL
, "destroy a surface with an unitialized display");
455 pipe_resource_reference(&gsurf
->render_texture
, NULL
);
456 egl_g3d_destroy_st_framebuffer(gsurf
->stfbi
);
458 gsurf
->native
->destroy(gsurf
->native
);
463 egl_g3d_destroy_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
465 if (_eglPutSurface(surf
))
466 destroy_surface(dpy
, surf
);
471 egl_g3d_make_current(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
472 _EGLSurface
*draw
, _EGLSurface
*read
, _EGLContext
*ctx
)
474 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
475 struct egl_g3d_surface
*gdraw
= egl_g3d_surface(draw
);
476 struct egl_g3d_surface
*gread
= egl_g3d_surface(read
);
477 struct egl_g3d_context
*old_gctx
;
478 _EGLContext
*old_ctx
;
479 _EGLSurface
*old_draw
, *old_read
;
480 EGLBoolean ok
= EGL_TRUE
;
482 /* make new bindings */
483 if (!_eglBindContext(ctx
, draw
, read
, &old_ctx
, &old_draw
, &old_read
))
486 old_gctx
= egl_g3d_context(old_ctx
);
488 /* flush old context */
489 old_gctx
->stctxi
->flush(old_gctx
->stctxi
, ST_FLUSH_FRONT
, NULL
);
493 ok
= gctx
->stapi
->make_current(gctx
->stapi
, gctx
->stctxi
,
494 (gdraw
) ? gdraw
->stfbi
: NULL
, (gread
) ? gread
->stfbi
: NULL
);
497 gctx
->stctxi
->notify_invalid_framebuffer(gctx
->stctxi
,
500 if (gdraw
->base
.Type
== EGL_WINDOW_BIT
) {
501 gctx
->base
.WindowRenderBuffer
=
502 (gdraw
->stvis
.render_buffer
== ST_ATTACHMENT_FRONT_LEFT
) ?
503 EGL_SINGLE_BUFFER
: EGL_BACK_BUFFER
;
506 if (gread
&& gread
!= gdraw
) {
507 gctx
->stctxi
->notify_invalid_framebuffer(gctx
->stctxi
,
513 ok
= old_gctx
->stapi
->make_current(old_gctx
->stapi
, NULL
, NULL
, NULL
);
515 old_gctx
->base
.WindowRenderBuffer
= EGL_NONE
;
519 if (_eglPutContext(old_ctx
))
520 destroy_context(dpy
, old_ctx
);
521 if (_eglPutSurface(old_draw
))
522 destroy_surface(dpy
, old_draw
);
523 if (_eglPutSurface(old_read
))
524 destroy_surface(dpy
, old_read
);
527 /* undo the previous _eglBindContext */
528 _eglBindContext(old_ctx
, old_draw
, old_read
, &ctx
, &draw
, &read
);
529 assert(&gctx
->base
== ctx
&&
530 &gdraw
->base
== draw
&&
531 &gread
->base
== read
);
533 _eglPutSurface(draw
);
534 _eglPutSurface(read
);
537 _eglPutSurface(old_draw
);
538 _eglPutSurface(old_read
);
539 _eglPutContext(old_ctx
);
546 egl_g3d_swap_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
548 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
549 _EGLContext
*ctx
= _eglGetCurrentContext();
550 struct egl_g3d_context
*gctx
= NULL
;
552 /* no-op for pixmap or pbuffer surface */
553 if (gsurf
->base
.Type
== EGL_PIXMAP_BIT
||
554 gsurf
->base
.Type
== EGL_PBUFFER_BIT
)
557 /* or when the surface is single-buffered */
558 if (gsurf
->stvis
.render_buffer
== ST_ATTACHMENT_FRONT_LEFT
)
561 if (ctx
&& ctx
->DrawSurface
== surf
)
562 gctx
= egl_g3d_context(ctx
);
564 /* flush if the surface is current */
566 gctx
->stctxi
->flush(gctx
->stctxi
, ST_FLUSH_FRONT
, NULL
);
569 return gsurf
->native
->present(gsurf
->native
,
570 NATIVE_ATTACHMENT_BACK_LEFT
,
571 gsurf
->base
.SwapBehavior
== EGL_BUFFER_PRESERVED
,
572 gsurf
->base
.SwapInterval
);
576 egl_g3d_copy_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
,
577 EGLNativePixmapType target
)
579 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
580 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
581 _EGLContext
*ctx
= _eglGetCurrentContext();
583 if (!gsurf
->render_texture
)
586 /* flush if the surface is current */
587 if (ctx
&& ctx
->DrawSurface
== &gsurf
->base
) {
588 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
589 gctx
->stctxi
->flush(gctx
->stctxi
, ST_FLUSH_FRONT
, NULL
);
592 return gdpy
->native
->copy_to_pixmap(gdpy
->native
,
593 target
, gsurf
->render_texture
);
597 egl_g3d_wait_client(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*ctx
)
599 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
600 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
601 struct pipe_screen
*screen
= gdpy
->native
->screen
;
602 struct pipe_fence_handle
*fence
= NULL
;
604 gctx
->stctxi
->flush(gctx
->stctxi
, ST_FLUSH_FRONT
, &fence
);
606 screen
->fence_finish(screen
, fence
, PIPE_TIMEOUT_INFINITE
);
607 screen
->fence_reference(screen
, &fence
, NULL
);
614 egl_g3d_wait_native(_EGLDriver
*drv
, _EGLDisplay
*dpy
, EGLint engine
)
616 _EGLContext
*ctx
= _eglGetCurrentContext();
618 if (engine
!= EGL_CORE_NATIVE_ENGINE
)
619 return _eglError(EGL_BAD_PARAMETER
, "eglWaitNative");
621 if (ctx
&& ctx
->DrawSurface
) {
622 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(ctx
->DrawSurface
);
625 gsurf
->native
->wait(gsurf
->native
);
632 egl_g3d_bind_tex_image(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
633 _EGLSurface
*surf
, EGLint buffer
)
635 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
636 _EGLContext
*es1
= _eglGetAPIContext(EGL_OPENGL_ES_API
);
637 struct egl_g3d_context
*gctx
;
638 enum pipe_format internal_format
;
639 enum st_texture_type target
;
641 if (!gsurf
|| gsurf
->base
.Type
!= EGL_PBUFFER_BIT
)
642 return _eglError(EGL_BAD_SURFACE
, "eglBindTexImage");
643 if (buffer
!= EGL_BACK_BUFFER
)
644 return _eglError(EGL_BAD_PARAMETER
, "eglBindTexImage");
645 if (gsurf
->base
.BoundToTexture
)
646 return _eglError(EGL_BAD_ACCESS
, "eglBindTexImage");
648 switch (gsurf
->base
.TextureFormat
) {
649 case EGL_TEXTURE_RGB
:
650 internal_format
= PIPE_FORMAT_R8G8B8_UNORM
;
652 case EGL_TEXTURE_RGBA
:
653 internal_format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
656 return _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
659 switch (gsurf
->base
.TextureTarget
) {
661 target
= ST_TEXTURE_2D
;
664 return _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
669 if (!gsurf
->render_texture
)
672 /* flush properly if the surface is bound */
673 if (gsurf
->base
.CurrentContext
) {
674 gctx
= egl_g3d_context(gsurf
->base
.CurrentContext
);
675 gctx
->stctxi
->flush(gctx
->stctxi
, ST_FLUSH_FRONT
, NULL
);
678 gctx
= egl_g3d_context(es1
);
679 if (gctx
->stctxi
->teximage
) {
680 if (!gctx
->stctxi
->teximage(gctx
->stctxi
, target
,
681 gsurf
->base
.MipmapLevel
, internal_format
,
682 gsurf
->render_texture
, gsurf
->base
.MipmapTexture
))
684 gsurf
->base
.BoundToTexture
= EGL_TRUE
;
691 egl_g3d_release_tex_image(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
692 _EGLSurface
*surf
, EGLint buffer
)
694 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
696 if (!gsurf
|| gsurf
->base
.Type
!= EGL_PBUFFER_BIT
||
697 !gsurf
->base
.BoundToTexture
)
698 return _eglError(EGL_BAD_SURFACE
, "eglReleaseTexImage");
699 if (buffer
!= EGL_BACK_BUFFER
)
700 return _eglError(EGL_BAD_PARAMETER
, "eglReleaseTexImage");
702 if (gsurf
->render_texture
) {
703 _EGLContext
*ctx
= _eglGetAPIContext(EGL_OPENGL_ES_API
);
704 struct egl_g3d_context
*gctx
= egl_g3d_context(ctx
);
706 /* what if the context the surface binds to is no longer current? */
708 gctx
->stctxi
->teximage(gctx
->stctxi
, ST_TEXTURE_2D
,
709 gsurf
->base
.MipmapLevel
, PIPE_FORMAT_NONE
, NULL
, FALSE
);
713 gsurf
->base
.BoundToTexture
= EGL_FALSE
;
718 #ifdef EGL_MESA_screen_surface
721 egl_g3d_create_screen_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
722 _EGLConfig
*conf
, const EGLint
*attribs
)
724 struct egl_g3d_create_surface_arg arg
;
726 memset(&arg
, 0, sizeof(arg
));
727 arg
.type
= EGL_SCREEN_BIT_MESA
;
729 return egl_g3d_create_surface(drv
, dpy
, conf
, &arg
, attribs
);
733 egl_g3d_show_screen_surface(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
734 _EGLScreen
*scr
, _EGLSurface
*surf
,
737 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
738 struct egl_g3d_screen
*gscr
= egl_g3d_screen(scr
);
739 struct egl_g3d_surface
*gsurf
= egl_g3d_surface(surf
);
740 struct native_surface
*nsurf
;
741 const struct native_mode
*nmode
;
748 return _eglError(EGL_BAD_MATCH
, "eglShowSurfaceMESA");
749 if (gsurf
->base
.Type
!= EGL_SCREEN_BIT_MESA
)
750 return _eglError(EGL_BAD_SURFACE
, "eglShowScreenSurfaceMESA");
751 if (gsurf
->base
.Width
< mode
->Width
|| gsurf
->base
.Height
< mode
->Height
)
752 return _eglError(EGL_BAD_MATCH
,
753 "eglShowSurfaceMESA(surface smaller than mode size)");
755 /* find the index of the mode */
756 for (idx
= 0; idx
< gscr
->base
.NumModes
; idx
++)
757 if (mode
== &gscr
->base
.Modes
[idx
])
759 if (idx
>= gscr
->base
.NumModes
) {
760 return _eglError(EGL_BAD_MODE_MESA
,
761 "eglShowSurfaceMESA(unknown mode)");
764 nsurf
= gsurf
->native
;
765 nmode
= gscr
->native_modes
[idx
];
769 return _eglError(EGL_BAD_MATCH
, "eglShowSurfaceMESA");
771 /* disable the screen */
776 /* TODO surface panning by CRTC choosing */
777 changed
= gdpy
->native
->modeset
->program(gdpy
->native
, 0, nsurf
,
778 gscr
->base
.OriginX
, gscr
->base
.OriginY
, &gscr
->native
, 1, nmode
);
780 gscr
->base
.CurrentSurface
= &gsurf
->base
;
781 gscr
->base
.CurrentMode
= mode
;
787 #endif /* EGL_MESA_screen_surface */
789 #ifdef EGL_WL_bind_wayland_display
792 egl_g3d_bind_wayland_display_wl(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
793 struct wl_display
*wl_dpy
)
795 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
797 if (!gdpy
->native
->wayland_bufmgr
)
800 return gdpy
->native
->wayland_bufmgr
->bind_display(gdpy
->native
, wl_dpy
);
804 egl_g3d_unbind_wayland_display_wl(_EGLDriver
*drv
, _EGLDisplay
*dpy
,
805 struct wl_display
*wl_dpy
)
807 struct egl_g3d_display
*gdpy
= egl_g3d_display(dpy
);
809 if (!gdpy
->native
->wayland_bufmgr
)
812 return gdpy
->native
->wayland_bufmgr
->unbind_display(gdpy
->native
, wl_dpy
);
815 #endif /* EGL_WL_bind_wayland_display */
818 egl_g3d_init_driver_api(_EGLDriver
*drv
)
820 _eglInitDriverFallbacks(drv
);
822 drv
->API
.ChooseConfig
= egl_g3d_choose_config
;
824 drv
->API
.CreateContext
= egl_g3d_create_context
;
825 drv
->API
.DestroyContext
= egl_g3d_destroy_context
;
826 drv
->API
.CreateWindowSurface
= egl_g3d_create_window_surface
;
827 drv
->API
.CreatePixmapSurface
= egl_g3d_create_pixmap_surface
;
828 drv
->API
.CreatePbufferSurface
= egl_g3d_create_pbuffer_surface
;
829 drv
->API
.CreatePbufferFromClientBuffer
= egl_g3d_create_pbuffer_from_client_buffer
;
830 drv
->API
.DestroySurface
= egl_g3d_destroy_surface
;
831 drv
->API
.MakeCurrent
= egl_g3d_make_current
;
832 drv
->API
.SwapBuffers
= egl_g3d_swap_buffers
;
833 drv
->API
.CopyBuffers
= egl_g3d_copy_buffers
;
834 drv
->API
.WaitClient
= egl_g3d_wait_client
;
835 drv
->API
.WaitNative
= egl_g3d_wait_native
;
837 drv
->API
.BindTexImage
= egl_g3d_bind_tex_image
;
838 drv
->API
.ReleaseTexImage
= egl_g3d_release_tex_image
;
840 drv
->API
.CreateImageKHR
= egl_g3d_create_image
;
841 drv
->API
.DestroyImageKHR
= egl_g3d_destroy_image
;
842 #ifdef EGL_MESA_drm_image
843 drv
->API
.CreateDRMImageMESA
= egl_g3d_create_drm_image
;
844 drv
->API
.ExportDRMImageMESA
= egl_g3d_export_drm_image
;
846 #ifdef EGL_WL_bind_wayland_display
847 drv
->API
.BindWaylandDisplayWL
= egl_g3d_bind_wayland_display_wl
;
848 drv
->API
.UnbindWaylandDisplayWL
= egl_g3d_unbind_wayland_display_wl
;
852 #ifdef EGL_KHR_reusable_sync
853 drv
->API
.CreateSyncKHR
= egl_g3d_create_sync
;
854 drv
->API
.DestroySyncKHR
= egl_g3d_destroy_sync
;
855 drv
->API
.ClientWaitSyncKHR
= egl_g3d_client_wait_sync
;
856 drv
->API
.SignalSyncKHR
= egl_g3d_signal_sync
;
859 #ifdef EGL_MESA_screen_surface
860 drv
->API
.CreateScreenSurfaceMESA
= egl_g3d_create_screen_surface
;
861 drv
->API
.ShowScreenSurfaceMESA
= egl_g3d_show_screen_surface
;