2 * Surface-related functions.
9 #include "eglcontext.h"
10 #include "eglconfig.h"
11 #include "eglglobals.h"
14 #include "eglsurface.h"
18 * Do error check on parameters and initialize the given _EGLSurface object.
19 * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
22 _eglInitSurface(_EGLDriver
*drv
, EGLDisplay dpy
,
23 _EGLSurface
*surf
, EGLint type
, EGLConfig config
,
24 const EGLint
*attrib_list
)
28 EGLint width
= 0, height
= 0, largest
= 0;
29 EGLint texFormat
= 0, texTarget
= 0, mipmapTex
= 0;
30 EGLint renderBuffer
= EGL_BACK_BUFFER
;
31 #ifdef EGL_VERSION_1_2
32 EGLint colorspace
= EGL_COLORSPACE_sRGB
;
33 EGLint alphaFormat
= EGL_ALPHA_FORMAT_NONPRE
;
39 func
= "eglCreateWindowSurface";
42 func
= "eglCreatePixmapSurface";
43 renderBuffer
= EGL_SINGLE_BUFFER
;
46 func
= "eglCreatePBufferSurface";
48 case EGL_SCREEN_BIT_MESA
:
49 func
= "eglCreateScreenSurface";
50 renderBuffer
= EGL_SINGLE_BUFFER
; /* XXX correct? */
53 _eglLog(_EGL_WARNING
, "Bad type in _eglInitSurface");
57 conf
= _eglLookupConfig(drv
, dpy
, config
);
59 _eglError(EGL_BAD_CONFIG
, func
);
64 * Parse attribute list. Different kinds of surfaces support different
67 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
68 switch (attrib_list
[i
]) {
70 if (type
== EGL_PBUFFER_BIT
|| type
== EGL_SCREEN_BIT_MESA
) {
71 width
= attrib_list
[++i
];
74 _eglError(EGL_BAD_ATTRIBUTE
, func
);
79 if (type
== EGL_PBUFFER_BIT
|| type
== EGL_SCREEN_BIT_MESA
) {
80 height
= attrib_list
[++i
];
83 _eglError(EGL_BAD_ATTRIBUTE
, func
);
87 case EGL_LARGEST_PBUFFER
:
88 if (type
== EGL_PBUFFER_BIT
) {
89 largest
= attrib_list
[++i
];
92 _eglError(EGL_BAD_ATTRIBUTE
, func
);
96 case EGL_TEXTURE_FORMAT
:
97 if (type
== EGL_PBUFFER_BIT
) {
98 texFormat
= attrib_list
[++i
];
101 _eglError(EGL_BAD_ATTRIBUTE
, func
);
105 case EGL_TEXTURE_TARGET
:
106 if (type
== EGL_PBUFFER_BIT
) {
107 texTarget
= attrib_list
[++i
];
110 _eglError(EGL_BAD_ATTRIBUTE
, func
);
114 case EGL_MIPMAP_TEXTURE
:
115 if (type
== EGL_PBUFFER_BIT
) {
116 mipmapTex
= attrib_list
[++i
];
119 _eglError(EGL_BAD_ATTRIBUTE
, func
);
123 #ifdef EGL_VERSION_1_2
124 case EGL_RENDER_BUFFER
:
125 if (type
== EGL_WINDOW_BIT
) {
126 renderBuffer
= attrib_list
[++i
];
127 if (renderBuffer
!= EGL_BACK_BUFFER
&&
128 renderBuffer
!= EGL_SINGLE_BUFFER
) {
129 _eglError(EGL_BAD_ATTRIBUTE
, func
);
134 _eglError(EGL_BAD_ATTRIBUTE
, func
);
139 if (type
== EGL_WINDOW_BIT
||
140 type
== EGL_PBUFFER_BIT
||
141 type
== EGL_PIXMAP_BIT
) {
142 colorspace
= attrib_list
[++i
];
143 if (colorspace
!= EGL_COLORSPACE_sRGB
&&
144 colorspace
!= EGL_COLORSPACE_LINEAR
) {
145 _eglError(EGL_BAD_ATTRIBUTE
, func
);
150 _eglError(EGL_BAD_ATTRIBUTE
, func
);
154 case EGL_ALPHA_FORMAT
:
155 if (type
== EGL_WINDOW_BIT
||
156 type
== EGL_PBUFFER_BIT
||
157 type
== EGL_PIXMAP_BIT
) {
158 alphaFormat
= attrib_list
[++i
];
159 if (alphaFormat
!= EGL_ALPHA_FORMAT_NONPRE
&&
160 alphaFormat
!= EGL_ALPHA_FORMAT_PRE
) {
161 _eglError(EGL_BAD_ATTRIBUTE
, func
);
166 _eglError(EGL_BAD_ATTRIBUTE
, func
);
171 #endif /* EGL_VERSION_1_2 */
173 _eglError(EGL_BAD_ATTRIBUTE
, func
);
178 if (width
< 0 || height
< 0) {
179 _eglError(EGL_BAD_ATTRIBUTE
, func
);
183 memset(surf
, 0, sizeof(_EGLSurface
));
187 surf
->Height
= height
;
188 surf
->TextureFormat
= texFormat
;
189 surf
->TextureTarget
= texTarget
;
190 surf
->MipmapTexture
= mipmapTex
;
191 surf
->MipmapLevel
= 0;
192 surf
->SwapInterval
= 0;
193 #ifdef EGL_VERSION_1_2
194 surf
->SwapBehavior
= EGL_BUFFER_DESTROYED
; /* XXX ok? */
195 surf
->HorizontalResolution
= EGL_UNKNOWN
; /* set by caller */
196 surf
->VerticalResolution
= EGL_UNKNOWN
; /* set by caller */
197 surf
->AspectRatio
= EGL_UNKNOWN
; /* set by caller */
198 surf
->RenderBuffer
= renderBuffer
;
199 surf
->AlphaFormat
= alphaFormat
;
200 surf
->Colorspace
= colorspace
;
208 _eglSaveSurface(_EGLSurface
*surf
)
210 EGLuint key
= _eglHashGenKey(_eglGlobal
.Surfaces
);
212 assert(!surf
->Handle
);
213 surf
->Handle
= (EGLSurface
) key
;
214 assert(surf
->Handle
);
215 _eglHashInsert(_eglGlobal
.Surfaces
, key
, surf
);
220 _eglRemoveSurface(_EGLSurface
*surf
)
222 _eglHashRemove(_eglGlobal
.Surfaces
, (EGLuint
) surf
->Handle
);
228 * Return the public handle for an internal _EGLSurface.
229 * This is the inverse of _eglLookupSurface().
232 _eglGetSurfaceHandle(_EGLSurface
*surface
)
235 return surface
->Handle
;
237 return EGL_NO_SURFACE
;
242 * Return the private _EGLSurface which corresponds to a public EGLSurface
244 * This is the inverse of _eglGetSurfaceHandle().
247 _eglLookupSurface(EGLSurface surf
)
249 _EGLSurface
*c
= (_EGLSurface
*) _eglHashLookup(_eglGlobal
.Surfaces
,
256 _eglGetCurrentSurface(EGLint readdraw
)
258 _EGLContext
*ctx
= _eglGetCurrentContext();
262 return ctx
->DrawSurface
;
264 return ctx
->ReadSurface
;
274 _eglSwapBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface draw
)
276 /* Basically just do error checking here. Drivers have to do the
277 * actual buffer swap.
279 _EGLContext
*context
= _eglGetCurrentContext();
280 _EGLSurface
*surface
= _eglLookupSurface(draw
);
281 if (context
&& context
->DrawSurface
!= surface
) {
282 _eglError(EGL_BAD_SURFACE
, "eglSwapBuffers");
285 if (surface
== NULL
) {
286 _eglError(EGL_BAD_SURFACE
, "eglSwapBuffers");
294 _eglCopyBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
,
295 NativePixmapType target
)
297 /* copy surface to native pixmap */
298 /* All implementation burdon for this is in the device driver */
304 _eglQuerySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
,
305 EGLint attribute
, EGLint
*value
)
307 _EGLSurface
*surface
= _eglLookupSurface(surf
);
308 if (surface
== NULL
) {
309 _eglError(EGL_BAD_SURFACE
, "eglQuerySurface");
314 *value
= surface
->Width
;
317 *value
= surface
->Height
;
320 *value
= GET_CONFIG_ATTRIB(surface
->Config
, EGL_CONFIG_ID
);
322 /*XXX case EGL_LARGEST_PBUFFER:*/
323 case EGL_SURFACE_TYPE
:
324 *value
= surface
->Type
;
326 #ifdef EGL_VERSION_1_1
327 case EGL_TEXTURE_FORMAT
:
328 /* texture attributes: only for pbuffers, no error otherwise */
329 if (surface
->Type
== EGL_PBUFFER_BIT
)
330 *value
= surface
->TextureFormat
;
332 case EGL_TEXTURE_TARGET
:
333 if (surface
->Type
== EGL_PBUFFER_BIT
)
334 *value
= surface
->TextureTarget
;
336 case EGL_MIPMAP_TEXTURE
:
337 if (surface
->Type
== EGL_PBUFFER_BIT
)
338 *value
= surface
->MipmapTexture
;
340 case EGL_MIPMAP_LEVEL
:
341 if (surface
->Type
== EGL_PBUFFER_BIT
)
342 *value
= surface
->MipmapLevel
;
344 #endif /* EGL_VERSION_1_1 */
345 #ifdef EGL_VERSION_1_2
346 case EGL_SWAP_BEHAVIOR
:
347 *value
= surface
->SwapBehavior
;
349 case EGL_RENDER_BUFFER
:
350 *value
= surface
->RenderBuffer
;
352 case EGL_PIXEL_ASPECT_RATIO
:
353 *value
= surface
->AspectRatio
;
355 case EGL_HORIZONTAL_RESOLUTION
:
356 *value
= surface
->HorizontalResolution
;
358 case EGL_VERTICAL_RESOLUTION
:
359 *value
= surface
->VerticalResolution
;
361 case EGL_ALPHA_FORMAT
:
362 *value
= surface
->AlphaFormat
;
365 *value
= surface
->Colorspace
;
367 #endif /* EGL_VERSION_1_2 */
369 _eglError(EGL_BAD_ATTRIBUTE
, "eglQuerySurface");
376 * Example function - drivers should do a proper implementation.
379 _eglCreateWindowSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
380 NativeWindowType window
, const EGLint
*attrib_list
)
382 #if 0 /* THIS IS JUST EXAMPLE CODE */
385 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
387 return EGL_NO_SURFACE
;
389 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_WINDOW_BIT
, config
, attrib_list
)) {
391 return EGL_NO_SURFACE
;
394 _eglSaveSurface(surf
);
398 return EGL_NO_SURFACE
;
403 * Example function - drivers should do a proper implementation.
406 _eglCreatePixmapSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
407 NativePixmapType pixmap
, const EGLint
*attrib_list
)
409 #if 0 /* THIS IS JUST EXAMPLE CODE */
412 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
414 return EGL_NO_SURFACE
;
416 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_PIXMAP_BIT
, config
, attrib_list
)) {
418 return EGL_NO_SURFACE
;
421 _eglSaveSurface(surf
);
425 return EGL_NO_SURFACE
;
430 * Example function - drivers should do a proper implementation.
433 _eglCreatePbufferSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
434 const EGLint
*attrib_list
)
436 #if 0 /* THIS IS JUST EXAMPLE CODE */
439 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
441 return EGL_NO_SURFACE
;
443 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_PBUFFER_BIT
, config
, attrib_list
)) {
445 return EGL_NO_SURFACE
;
448 _eglSaveSurface(surf
);
452 return EGL_NO_SURFACE
;
457 * Default fallback routine - drivers should usually override this.
460 _eglDestroySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
)
462 _EGLSurface
*surf
= _eglLookupSurface(surface
);
464 _eglHashRemove(_eglGlobal
.Surfaces
, (EGLuint
) surface
);
466 surf
->DeletePending
= EGL_TRUE
;
474 _eglError(EGL_BAD_SURFACE
, "eglDestroySurface");
481 * Default fallback routine - drivers might override this.
484 _eglSurfaceAttrib(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
, EGLint attribute
, EGLint value
)
486 _EGLSurface
*surface
= _eglLookupSurface(surf
);
488 if (surface
== NULL
) {
489 _eglError(EGL_BAD_SURFACE
, "eglSurfaceAttrib");
494 case EGL_MIPMAP_LEVEL
:
495 surface
->MipmapLevel
= value
;
498 _eglError(EGL_BAD_ATTRIBUTE
, "eglSurfaceAttrib");
506 _eglBindTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
514 _eglReleaseTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
522 _eglSwapInterval(_EGLDriver
*drv
, EGLDisplay dpy
, EGLint interval
)
524 _EGLSurface
*surf
= _eglGetCurrentSurface(EGL_DRAW
);
526 _eglError(EGL_BAD_SURFACE
, "eglSwapInterval");
529 surf
->SwapInterval
= interval
;
534 #ifdef EGL_VERSION_1_2
537 * Example function - drivers should do a proper implementation.
540 _eglCreatePbufferFromClientBuffer(_EGLDriver
*drv
, EGLDisplay dpy
,
541 EGLenum buftype
, EGLClientBuffer buffer
,
542 EGLConfig config
, const EGLint
*attrib_list
)
544 if (buftype
!= EGL_OPENVG_IMAGE
) {
545 _eglError(EGL_BAD_PARAMETER
, "eglCreatePbufferFromClientBuffer");
546 return EGL_NO_SURFACE
;
549 return EGL_NO_SURFACE
;
552 #endif /* EGL_VERSION_1_2 */