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
);
65 * Parse attribute list. Different kinds of surfaces support different
68 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
69 switch (attrib_list
[i
]) {
71 if (type
== EGL_PBUFFER_BIT
|| type
== EGL_SCREEN_BIT_MESA
) {
72 width
= attrib_list
[++i
];
75 _eglError(EGL_BAD_ATTRIBUTE
, func
);
80 if (type
== EGL_PBUFFER_BIT
|| type
== EGL_SCREEN_BIT_MESA
) {
81 height
= attrib_list
[++i
];
84 _eglError(EGL_BAD_ATTRIBUTE
, func
);
88 case EGL_LARGEST_PBUFFER
:
89 if (type
== EGL_PBUFFER_BIT
) {
90 largest
= attrib_list
[++i
];
93 _eglError(EGL_BAD_ATTRIBUTE
, func
);
97 case EGL_TEXTURE_FORMAT
:
98 if (type
== EGL_PBUFFER_BIT
) {
99 texFormat
= attrib_list
[++i
];
102 _eglError(EGL_BAD_ATTRIBUTE
, func
);
106 case EGL_TEXTURE_TARGET
:
107 if (type
== EGL_PBUFFER_BIT
) {
108 texTarget
= attrib_list
[++i
];
111 _eglError(EGL_BAD_ATTRIBUTE
, func
);
115 case EGL_MIPMAP_TEXTURE
:
116 if (type
== EGL_PBUFFER_BIT
) {
117 mipmapTex
= attrib_list
[++i
];
120 _eglError(EGL_BAD_ATTRIBUTE
, func
);
124 #ifdef EGL_VERSION_1_2
125 case EGL_RENDER_BUFFER
:
126 if (type
== EGL_WINDOW_BIT
) {
127 renderBuffer
= attrib_list
[++i
];
128 if (renderBuffer
!= EGL_BACK_BUFFER
&&
129 renderBuffer
!= EGL_SINGLE_BUFFER
) {
130 _eglError(EGL_BAD_ATTRIBUTE
, func
);
135 _eglError(EGL_BAD_ATTRIBUTE
, func
);
140 if (type
== EGL_WINDOW_BIT
||
141 type
== EGL_PBUFFER_BIT
||
142 type
== EGL_PIXMAP_BIT
) {
143 colorspace
= attrib_list
[++i
];
144 if (colorspace
!= EGL_COLORSPACE_sRGB
&&
145 colorspace
!= EGL_COLORSPACE_LINEAR
) {
146 _eglError(EGL_BAD_ATTRIBUTE
, func
);
151 _eglError(EGL_BAD_ATTRIBUTE
, func
);
155 case EGL_ALPHA_FORMAT
:
156 if (type
== EGL_WINDOW_BIT
||
157 type
== EGL_PBUFFER_BIT
||
158 type
== EGL_PIXMAP_BIT
) {
159 alphaFormat
= attrib_list
[++i
];
160 if (alphaFormat
!= EGL_ALPHA_FORMAT_NONPRE
&&
161 alphaFormat
!= EGL_ALPHA_FORMAT_PRE
) {
162 _eglError(EGL_BAD_ATTRIBUTE
, func
);
167 _eglError(EGL_BAD_ATTRIBUTE
, func
);
172 #endif /* EGL_VERSION_1_2 */
174 _eglError(EGL_BAD_ATTRIBUTE
, func
);
179 if (width
< 0 || height
< 0) {
180 _eglError(EGL_BAD_ATTRIBUTE
, func
);
184 memset(surf
, 0, sizeof(_EGLSurface
));
188 surf
->Height
= height
;
189 surf
->TextureFormat
= texFormat
;
190 surf
->TextureTarget
= texTarget
;
191 surf
->MipmapTexture
= mipmapTex
;
192 surf
->MipmapLevel
= 0;
193 surf
->SwapInterval
= 0;
194 #ifdef EGL_VERSION_1_2
195 surf
->SwapBehavior
= EGL_BUFFER_DESTROYED
; /* XXX ok? */
196 surf
->HorizontalResolution
= EGL_UNKNOWN
; /* set by caller */
197 surf
->VerticalResolution
= EGL_UNKNOWN
; /* set by caller */
198 surf
->AspectRatio
= EGL_UNKNOWN
; /* set by caller */
199 surf
->RenderBuffer
= renderBuffer
;
200 surf
->AlphaFormat
= alphaFormat
;
201 surf
->Colorspace
= colorspace
;
209 _eglSaveSurface(_EGLSurface
*surf
)
211 EGLuint key
= _eglHashGenKey(_eglGlobal
.Surfaces
);
213 assert(!surf
->Handle
);
214 surf
->Handle
= (EGLSurface
) key
;
215 assert(surf
->Handle
);
216 _eglHashInsert(_eglGlobal
.Surfaces
, key
, surf
);
221 _eglRemoveSurface(_EGLSurface
*surf
)
223 _eglHashRemove(_eglGlobal
.Surfaces
, (EGLuint
) surf
->Handle
);
229 * Return the public handle for an internal _EGLSurface.
230 * This is the inverse of _eglLookupSurface().
233 _eglGetSurfaceHandle(_EGLSurface
*surface
)
236 return surface
->Handle
;
238 return EGL_NO_SURFACE
;
243 * Return the private _EGLSurface which corresponds to a public EGLSurface
245 * This is the inverse of _eglGetSurfaceHandle().
248 _eglLookupSurface(EGLSurface surf
)
250 _EGLSurface
*c
= (_EGLSurface
*) _eglHashLookup(_eglGlobal
.Surfaces
,
257 _eglGetCurrentSurface(EGLint readdraw
)
259 _EGLContext
*ctx
= _eglGetCurrentContext();
263 return ctx
->DrawSurface
;
265 return ctx
->ReadSurface
;
275 _eglSwapBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface draw
)
277 /* Basically just do error checking here. Drivers have to do the
278 * actual buffer swap.
280 _EGLContext
*context
= _eglGetCurrentContext();
281 _EGLSurface
*surface
= _eglLookupSurface(draw
);
282 if (context
&& context
->DrawSurface
!= surface
) {
283 _eglError(EGL_BAD_SURFACE
, "eglSwapBuffers");
286 if (surface
== NULL
) {
287 _eglError(EGL_BAD_SURFACE
, "eglSwapBuffers");
295 _eglCopyBuffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
,
296 NativePixmapType target
)
298 /* copy surface to native pixmap */
299 /* All implementation burdon for this is in the device driver */
305 _eglQuerySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
,
306 EGLint attribute
, EGLint
*value
)
308 _EGLSurface
*surface
= _eglLookupSurface(surf
);
309 if (surface
== NULL
) {
310 _eglError(EGL_BAD_SURFACE
, "eglQuerySurface");
315 *value
= surface
->Width
;
318 *value
= surface
->Height
;
321 *value
= GET_CONFIG_ATTRIB(surface
->Config
, EGL_CONFIG_ID
);
323 case EGL_LARGEST_PBUFFER
:
324 *value
= drv
->LargestPbuffer
;
326 case EGL_SURFACE_TYPE
:
327 *value
= surface
->Type
;
329 #ifdef EGL_VERSION_1_1
330 case EGL_TEXTURE_FORMAT
:
331 /* texture attributes: only for pbuffers, no error otherwise */
332 if (surface
->Type
== EGL_PBUFFER_BIT
)
333 *value
= surface
->TextureFormat
;
335 case EGL_TEXTURE_TARGET
:
336 if (surface
->Type
== EGL_PBUFFER_BIT
)
337 *value
= surface
->TextureTarget
;
339 case EGL_MIPMAP_TEXTURE
:
340 if (surface
->Type
== EGL_PBUFFER_BIT
)
341 *value
= surface
->MipmapTexture
;
343 case EGL_MIPMAP_LEVEL
:
344 if (surface
->Type
== EGL_PBUFFER_BIT
)
345 *value
= surface
->MipmapLevel
;
347 #endif /* EGL_VERSION_1_1 */
348 #ifdef EGL_VERSION_1_2
349 case EGL_SWAP_BEHAVIOR
:
350 *value
= surface
->SwapBehavior
;
352 case EGL_RENDER_BUFFER
:
353 *value
= surface
->RenderBuffer
;
355 case EGL_PIXEL_ASPECT_RATIO
:
356 *value
= surface
->AspectRatio
;
358 case EGL_HORIZONTAL_RESOLUTION
:
359 *value
= surface
->HorizontalResolution
;
361 case EGL_VERTICAL_RESOLUTION
:
362 *value
= surface
->VerticalResolution
;
364 case EGL_ALPHA_FORMAT
:
365 *value
= surface
->AlphaFormat
;
368 *value
= surface
->Colorspace
;
370 #endif /* EGL_VERSION_1_2 */
372 _eglError(EGL_BAD_ATTRIBUTE
, "eglQuerySurface");
379 * Example function - drivers should do a proper implementation.
382 _eglCreateWindowSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
383 NativeWindowType window
, const EGLint
*attrib_list
)
385 #if 0 /* THIS IS JUST EXAMPLE CODE */
388 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
390 return EGL_NO_SURFACE
;
392 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_WINDOW_BIT
, config
, attrib_list
)) {
394 return EGL_NO_SURFACE
;
397 _eglSaveSurface(surf
);
401 return EGL_NO_SURFACE
;
406 * Example function - drivers should do a proper implementation.
409 _eglCreatePixmapSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
410 NativePixmapType pixmap
, const EGLint
*attrib_list
)
412 #if 0 /* THIS IS JUST EXAMPLE CODE */
415 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
417 return EGL_NO_SURFACE
;
419 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_PIXMAP_BIT
, config
, attrib_list
)) {
421 return EGL_NO_SURFACE
;
424 _eglSaveSurface(surf
);
428 return EGL_NO_SURFACE
;
433 * Example function - drivers should do a proper implementation.
436 _eglCreatePbufferSurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
437 const EGLint
*attrib_list
)
439 #if 0 /* THIS IS JUST EXAMPLE CODE */
442 surf
= (_EGLSurface
*) calloc(1, sizeof(_EGLSurface
));
444 return EGL_NO_SURFACE
;
446 if (!_eglInitSurface(drv
, dpy
, surf
, EGL_PBUFFER_BIT
, config
, attrib_list
)) {
448 return EGL_NO_SURFACE
;
451 _eglSaveSurface(surf
);
455 return EGL_NO_SURFACE
;
460 * Default fallback routine - drivers should usually override this.
463 _eglDestroySurface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
)
465 _EGLSurface
*surf
= _eglLookupSurface(surface
);
467 _eglHashRemove(_eglGlobal
.Surfaces
, (EGLuint
) surface
);
469 surf
->DeletePending
= EGL_TRUE
;
477 _eglError(EGL_BAD_SURFACE
, "eglDestroySurface");
484 * Default fallback routine - drivers might override this.
487 _eglSurfaceAttrib(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surf
, EGLint attribute
, EGLint value
)
489 _EGLSurface
*surface
= _eglLookupSurface(surf
);
491 if (surface
== NULL
) {
492 _eglError(EGL_BAD_SURFACE
, "eglSurfaceAttrib");
497 case EGL_MIPMAP_LEVEL
:
498 surface
->MipmapLevel
= value
;
501 _eglError(EGL_BAD_ATTRIBUTE
, "eglSurfaceAttrib");
509 _eglBindTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
517 _eglReleaseTexImage(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
, EGLint buffer
)
525 _eglSwapInterval(_EGLDriver
*drv
, EGLDisplay dpy
, EGLint interval
)
527 _EGLSurface
*surf
= _eglGetCurrentSurface(EGL_DRAW
);
529 _eglError(EGL_BAD_SURFACE
, "eglSwapInterval");
532 surf
->SwapInterval
= interval
;
537 #ifdef EGL_VERSION_1_2
540 * Example function - drivers should do a proper implementation.
543 _eglCreatePbufferFromClientBuffer(_EGLDriver
*drv
, EGLDisplay dpy
,
544 EGLenum buftype
, EGLClientBuffer buffer
,
545 EGLConfig config
, const EGLint
*attrib_list
)
547 if (buftype
!= EGL_OPENVG_IMAGE
) {
548 _eglError(EGL_BAD_PARAMETER
, "eglCreatePbufferFromClientBuffer");
549 return EGL_NO_SURFACE
;
552 return EGL_NO_SURFACE
;
555 #endif /* EGL_VERSION_1_2 */