2 * Surface-related functions.
9 #include "eglcontext.h"
10 #include "eglconfig.h"
11 #include "egldriver.h"
12 #include "eglglobals.h"
15 #include "eglsurface.h"
19 * Do error check on parameters and initialize the given _EGLSurface object.
20 * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
23 _eglInitSurface(_EGLDriver
*drv
, EGLDisplay dpy
,
24 _EGLSurface
*surf
, EGLint type
, EGLConfig config
,
25 const EGLint
*attrib_list
)
29 EGLint width
= 0, height
= 0, largest
= 0;
30 EGLint texFormat
= 0, texTarget
= 0, mipmapTex
= 0;
31 EGLint renderBuffer
= EGL_BACK_BUFFER
;
32 #ifdef EGL_VERSION_1_2
33 EGLint colorspace
= EGL_COLORSPACE_sRGB
;
34 EGLint alphaFormat
= EGL_ALPHA_FORMAT_NONPRE
;
40 func
= "eglCreateWindowSurface";
43 func
= "eglCreatePixmapSurface";
44 renderBuffer
= EGL_SINGLE_BUFFER
;
47 func
= "eglCreatePBufferSurface";
49 case EGL_SCREEN_BIT_MESA
:
50 func
= "eglCreateScreenSurface";
51 renderBuffer
= EGL_SINGLE_BUFFER
; /* XXX correct? */
54 _eglLog(_EGL_WARNING
, "Bad type in _eglInitSurface");
58 conf
= _eglLookupConfig(drv
, dpy
, config
);
60 _eglError(EGL_BAD_CONFIG
, func
);
64 if ((GET_CONFIG_ATTRIB(conf
, EGL_SURFACE_TYPE
) & type
) == 0) {
65 /* The config can't be used to create a surface of this type */
66 _eglError(EGL_BAD_CONFIG
, func
);
71 * Parse attribute list. Different kinds of surfaces support different
74 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
75 switch (attrib_list
[i
]) {
77 if (type
== EGL_PBUFFER_BIT
|| type
== EGL_SCREEN_BIT_MESA
) {
78 width
= attrib_list
[++i
];
81 _eglError(EGL_BAD_ATTRIBUTE
, func
);
86 if (type
== EGL_PBUFFER_BIT
|| type
== EGL_SCREEN_BIT_MESA
) {
87 height
= attrib_list
[++i
];
90 _eglError(EGL_BAD_ATTRIBUTE
, func
);
94 case EGL_LARGEST_PBUFFER
:
95 if (type
== EGL_PBUFFER_BIT
) {
96 largest
= attrib_list
[++i
];
99 _eglError(EGL_BAD_ATTRIBUTE
, func
);
103 case EGL_TEXTURE_FORMAT
:
104 if (type
== EGL_PBUFFER_BIT
) {
105 texFormat
= attrib_list
[++i
];
108 _eglError(EGL_BAD_ATTRIBUTE
, func
);
112 case EGL_TEXTURE_TARGET
:
113 if (type
== EGL_PBUFFER_BIT
) {
114 texTarget
= attrib_list
[++i
];
117 _eglError(EGL_BAD_ATTRIBUTE
, func
);
121 case EGL_MIPMAP_TEXTURE
:
122 if (type
== EGL_PBUFFER_BIT
) {
123 mipmapTex
= attrib_list
[++i
];
126 _eglError(EGL_BAD_ATTRIBUTE
, func
);
130 #ifdef EGL_VERSION_1_2
131 case EGL_RENDER_BUFFER
:
132 if (type
== EGL_WINDOW_BIT
) {
133 renderBuffer
= attrib_list
[++i
];
134 if (renderBuffer
!= EGL_BACK_BUFFER
&&
135 renderBuffer
!= EGL_SINGLE_BUFFER
) {
136 _eglError(EGL_BAD_ATTRIBUTE
, func
);
141 _eglError(EGL_BAD_ATTRIBUTE
, func
);
146 if (type
== EGL_WINDOW_BIT
||
147 type
== EGL_PBUFFER_BIT
||
148 type
== EGL_PIXMAP_BIT
) {
149 colorspace
= attrib_list
[++i
];
150 if (colorspace
!= EGL_COLORSPACE_sRGB
&&
151 colorspace
!= EGL_COLORSPACE_LINEAR
) {
152 _eglError(EGL_BAD_ATTRIBUTE
, func
);
157 _eglError(EGL_BAD_ATTRIBUTE
, func
);
161 case EGL_ALPHA_FORMAT
:
162 if (type
== EGL_WINDOW_BIT
||
163 type
== EGL_PBUFFER_BIT
||
164 type
== EGL_PIXMAP_BIT
) {
165 alphaFormat
= attrib_list
[++i
];
166 if (alphaFormat
!= EGL_ALPHA_FORMAT_NONPRE
&&
167 alphaFormat
!= EGL_ALPHA_FORMAT_PRE
) {
168 _eglError(EGL_BAD_ATTRIBUTE
, func
);
173 _eglError(EGL_BAD_ATTRIBUTE
, func
);
178 #endif /* EGL_VERSION_1_2 */
180 _eglError(EGL_BAD_ATTRIBUTE
, func
);
185 if (width
< 0 || height
< 0) {
186 _eglError(EGL_BAD_ATTRIBUTE
, func
);
190 memset(surf
, 0, sizeof(_EGLSurface
));
194 surf
->Height
= height
;
195 surf
->TextureFormat
= texFormat
;
196 surf
->TextureTarget
= texTarget
;
197 surf
->MipmapTexture
= mipmapTex
;
198 surf
->MipmapLevel
= 0;
199 surf
->SwapInterval
= 0;
200 #ifdef EGL_VERSION_1_2
201 surf
->SwapBehavior
= EGL_BUFFER_DESTROYED
; /* XXX ok? */
202 surf
->HorizontalResolution
= EGL_UNKNOWN
; /* set by caller */
203 surf
->VerticalResolution
= EGL_UNKNOWN
; /* set by caller */
204 surf
->AspectRatio
= EGL_UNKNOWN
; /* set by caller */
205 surf
->RenderBuffer
= renderBuffer
;
206 surf
->AlphaFormat
= alphaFormat
;
207 surf
->Colorspace
= colorspace
;
215 _eglSaveSurface(_EGLSurface
*surf
)
217 EGLuint key
= _eglHashGenKey(_eglGlobal
.Surfaces
);
219 assert(!surf
->Handle
);
220 surf
->Handle
= (EGLSurface
) key
;
221 assert(surf
->Handle
);
222 _eglHashInsert(_eglGlobal
.Surfaces
, key
, surf
);
227 _eglRemoveSurface(_EGLSurface
*surf
)
229 _eglHashRemove(_eglGlobal
.Surfaces
, (EGLuint
) surf
->Handle
);
235 * Return the public handle for an internal _EGLSurface.
236 * This is the inverse of _eglLookupSurface().
239 _eglGetSurfaceHandle(_EGLSurface
*surface
)
242 return surface
->Handle
;
244 return EGL_NO_SURFACE
;
249 * Return the private _EGLSurface which corresponds to a public EGLSurface
251 * This is the inverse of _eglGetSurfaceHandle().
254 _eglLookupSurface(EGLSurface surf
)
256 _EGLSurface
*c
= (_EGLSurface
*) _eglHashLookup(_eglGlobal
.Surfaces
,
263 _eglGetCurrentSurface(EGLint readdraw
)
265 _EGLContext
*ctx
= _eglGetCurrentContext();
269 return ctx
->DrawSurface
;
271 return ctx
->ReadSurface
;
281 _eglSwapBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface draw
)
283 /* Basically just do error checking here. Drivers have to do the
284 * actual buffer swap.
286 _EGLSurface
*surface
= _eglLookupSurface(draw
);
287 if (surface
== NULL
) {
288 _eglError(EGL_BAD_SURFACE
, "eglSwapBuffers");
296 _eglCopyBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
,
297 NativePixmapType target
)
299 /* copy surface to native pixmap */
300 /* All implementation burdon for this is in the device driver */
306 _eglQuerySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
,
307 EGLint attribute
, EGLint
*value
)
309 _EGLSurface
*surface
= _eglLookupSurface(surf
);
310 if (surface
== NULL
) {
311 _eglError(EGL_BAD_SURFACE
, "eglQuerySurface");
316 *value
= surface
->Width
;
319 *value
= surface
->Height
;
322 *value
= GET_CONFIG_ATTRIB(surface
->Config
, EGL_CONFIG_ID
);
324 case EGL_LARGEST_PBUFFER
:
325 *value
= drv
->LargestPbuffer
;
327 case EGL_SURFACE_TYPE
:
328 *value
= surface
->Type
;
330 #ifdef EGL_VERSION_1_1
331 case EGL_TEXTURE_FORMAT
:
332 /* texture attributes: only for pbuffers, no error otherwise */
333 if (surface
->Type
== EGL_PBUFFER_BIT
)
334 *value
= surface
->TextureFormat
;
336 case EGL_TEXTURE_TARGET
:
337 if (surface
->Type
== EGL_PBUFFER_BIT
)
338 *value
= surface
->TextureTarget
;
340 case EGL_MIPMAP_TEXTURE
:
341 if (surface
->Type
== EGL_PBUFFER_BIT
)
342 *value
= surface
->MipmapTexture
;
344 case EGL_MIPMAP_LEVEL
:
345 if (surface
->Type
== EGL_PBUFFER_BIT
)
346 *value
= surface
->MipmapLevel
;
348 #endif /* EGL_VERSION_1_1 */
349 #ifdef EGL_VERSION_1_2
350 case EGL_SWAP_BEHAVIOR
:
351 *value
= surface
->SwapBehavior
;
353 case EGL_RENDER_BUFFER
:
354 *value
= surface
->RenderBuffer
;
356 case EGL_PIXEL_ASPECT_RATIO
:
357 *value
= surface
->AspectRatio
;
359 case EGL_HORIZONTAL_RESOLUTION
:
360 *value
= surface
->HorizontalResolution
;
362 case EGL_VERTICAL_RESOLUTION
:
363 *value
= surface
->VerticalResolution
;
365 case EGL_ALPHA_FORMAT
:
366 *value
= surface
->AlphaFormat
;
369 *value
= surface
->Colorspace
;
371 #endif /* EGL_VERSION_1_2 */
373 _eglError(EGL_BAD_ATTRIBUTE
, "eglQuerySurface");
380 * Example function - drivers should do a proper implementation.
383 _eglCreateWindowSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
384 NativeWindowType window
, const EGLint
*attrib_list
)
386 #if 0 /* THIS IS JUST EXAMPLE CODE */
389 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
391 return EGL_NO_SURFACE
;
393 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_WINDOW_BIT
, config
, attrib_list
)) {
395 return EGL_NO_SURFACE
;
398 _eglSaveSurface(surf
);
402 return EGL_NO_SURFACE
;
407 * Example function - drivers should do a proper implementation.
410 _eglCreatePixmapSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
411 NativePixmapType pixmap
, const EGLint
*attrib_list
)
413 #if 0 /* THIS IS JUST EXAMPLE CODE */
416 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
418 return EGL_NO_SURFACE
;
420 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_PIXMAP_BIT
, config
, attrib_list
)) {
422 return EGL_NO_SURFACE
;
425 _eglSaveSurface(surf
);
429 return EGL_NO_SURFACE
;
434 * Example function - drivers should do a proper implementation.
437 _eglCreatePbufferSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
438 const EGLint
*attrib_list
)
440 #if 0 /* THIS IS JUST EXAMPLE CODE */
443 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
445 return EGL_NO_SURFACE
;
447 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_PBUFFER_BIT
, config
, attrib_list
)) {
449 return EGL_NO_SURFACE
;
452 _eglSaveSurface(surf
);
456 return EGL_NO_SURFACE
;
461 * Default fallback routine - drivers should usually override this.
464 _eglDestroySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
)
466 _EGLSurface
*surf
= _eglLookupSurface(surface
);
468 _eglHashRemove(_eglGlobal
.Surfaces
, (EGLuint
) surface
);
470 surf
->DeletePending
= EGL_TRUE
;
478 _eglError(EGL_BAD_SURFACE
, "eglDestroySurface");
485 * Default fallback routine - drivers might override this.
488 _eglSurfaceAttrib(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
,
489 EGLint attribute
, EGLint value
)
491 _EGLSurface
*surface
= _eglLookupSurface(surf
);
493 if (surface
== NULL
) {
494 _eglError(EGL_BAD_SURFACE
, "eglSurfaceAttrib");
499 case EGL_MIPMAP_LEVEL
:
500 surface
->MipmapLevel
= value
;
503 _eglError(EGL_BAD_ATTRIBUTE
, "eglSurfaceAttrib");
511 _eglBindTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
,
514 /* Just do basic error checking and return success/fail.
515 * Drivers must implement the real stuff.
517 _EGLSurface
*surface
= _eglLookupSurface(surf
);
519 if (!surface
|| surface
->Type
!= EGL_PBUFFER_BIT
) {
520 _eglError(EGL_BAD_SURFACE
, "eglBindTexImage");
524 if (surface
->TextureFormat
== EGL_NO_TEXTURE
) {
525 _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
529 if (buffer
!= EGL_BACK_BUFFER
) {
530 _eglError(EGL_BAD_PARAMETER
, "eglBindTexImage");
534 surface
->BoundToTexture
= EGL_TRUE
;
541 _eglReleaseTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
,
544 /* Just do basic error checking and return success/fail.
545 * Drivers must implement the real stuff.
547 _EGLSurface
*surface
= _eglLookupSurface(surf
);
549 if (!surface
|| surface
->Type
!= EGL_PBUFFER_BIT
) {
550 _eglError(EGL_BAD_SURFACE
, "eglBindTexImage");
554 if (surface
->TextureFormat
== EGL_NO_TEXTURE
) {
555 _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
559 if (buffer
!= EGL_BACK_BUFFER
) {
560 _eglError(EGL_BAD_PARAMETER
, "eglReleaseTexImage");
564 if (!surface
->BoundToTexture
) {
565 _eglError(EGL_BAD_SURFACE
, "eglReleaseTexImage");
569 surface
->BoundToTexture
= EGL_FALSE
;
576 _eglSwapInterval(_EGLDriver
*drv
, EGLDisplay dpy
, EGLint interval
)
578 _EGLSurface
*surf
= _eglGetCurrentSurface(EGL_DRAW
);
580 _eglError(EGL_BAD_SURFACE
, "eglSwapInterval");
583 surf
->SwapInterval
= interval
;
588 #ifdef EGL_VERSION_1_2
591 * Example function - drivers should do a proper implementation.
594 _eglCreatePbufferFromClientBuffer(_EGLDriver
*drv
, EGLDisplay dpy
,
595 EGLenum buftype
, EGLClientBuffer buffer
,
596 EGLConfig config
, const EGLint
*attrib_list
)
598 if (buftype
!= EGL_OPENVG_IMAGE
) {
599 _eglError(EGL_BAD_PARAMETER
, "eglCreatePbufferFromClientBuffer");
600 return EGL_NO_SURFACE
;
603 return EGL_NO_SURFACE
;
606 #endif /* EGL_VERSION_1_2 */