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 _eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
265 /* Basically just do error checking here. Drivers have to do the
266 * actual buffer swap.
268 _EGLSurface *surface = _eglLookupSurface(draw);
269 if (surface == NULL) {
270 _eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
278 _eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
279 NativePixmapType target)
281 /* copy surface to native pixmap */
282 /* All implementation burdon for this is in the device driver */
288 _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
289 EGLint attribute, EGLint *value)
291 _EGLSurface *surface = _eglLookupSurface(surf);
292 if (surface == NULL) {
293 _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
298 *value = surface->Width;
301 *value = surface->Height;
304 *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
306 case EGL_LARGEST_PBUFFER:
307 *value = drv->LargestPbuffer;
309 case EGL_SURFACE_TYPE:
310 *value = surface->Type;
312 #ifdef EGL_VERSION_1_1
313 case EGL_TEXTURE_FORMAT:
314 /* texture attributes: only for pbuffers, no error otherwise */
315 if (surface->Type == EGL_PBUFFER_BIT)
316 *value = surface->TextureFormat;
318 case EGL_TEXTURE_TARGET:
319 if (surface->Type == EGL_PBUFFER_BIT)
320 *value = surface->TextureTarget;
322 case EGL_MIPMAP_TEXTURE:
323 if (surface->Type == EGL_PBUFFER_BIT)
324 *value = surface->MipmapTexture;
326 case EGL_MIPMAP_LEVEL:
327 if (surface->Type == EGL_PBUFFER_BIT)
328 *value = surface->MipmapLevel;
330 #endif /* EGL_VERSION_1_1 */
331 #ifdef EGL_VERSION_1_2
332 case EGL_SWAP_BEHAVIOR:
333 *value = surface->SwapBehavior;
335 case EGL_RENDER_BUFFER:
336 *value = surface->RenderBuffer;
338 case EGL_PIXEL_ASPECT_RATIO:
339 *value = surface->AspectRatio;
341 case EGL_HORIZONTAL_RESOLUTION:
342 *value = surface->HorizontalResolution;
344 case EGL_VERTICAL_RESOLUTION:
345 *value = surface->VerticalResolution;
347 case EGL_ALPHA_FORMAT:
348 *value = surface->AlphaFormat;
351 *value = surface->Colorspace;
353 #endif /* EGL_VERSION_1_2 */
355 _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
362 * Example function - drivers should do a proper implementation.
365 _eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
366 NativeWindowType window, const EGLint *attrib_list)
368 #if 0 /* THIS IS JUST EXAMPLE CODE */
371 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
373 return EGL_NO_SURFACE;
375 if (!_eglInitSurface(drv, dpy, surf, EGL_WINDOW_BIT, config, attrib_list)) {
377 return EGL_NO_SURFACE;
380 _eglSaveSurface(surf);
384 return EGL_NO_SURFACE;
389 * Example function - drivers should do a proper implementation.
392 _eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
393 NativePixmapType pixmap, const EGLint *attrib_list)
395 #if 0 /* THIS IS JUST EXAMPLE CODE */
398 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
400 return EGL_NO_SURFACE;
402 if (!_eglInitSurface(drv, dpy, surf, EGL_PIXMAP_BIT, config, attrib_list)) {
404 return EGL_NO_SURFACE;
407 _eglSaveSurface(surf);
411 return EGL_NO_SURFACE;
416 * Example function - drivers should do a proper implementation.
419 _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
420 const EGLint *attrib_list)
422 #if 0 /* THIS IS JUST EXAMPLE CODE */
425 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
427 return EGL_NO_SURFACE;
429 if (!_eglInitSurface(drv, dpy, surf, EGL_PBUFFER_BIT, config, attrib_list)) {
431 return EGL_NO_SURFACE;
434 _eglSaveSurface(surf);
438 return EGL_NO_SURFACE;
443 * Default fallback routine - drivers should usually override this.
446 _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
448 _EGLSurface *surf = _eglLookupSurface(surface);
450 _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
452 surf->DeletePending = EGL_TRUE;
460 _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
467 * Default fallback routine - drivers might override this.
470 _eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
471 EGLint attribute, EGLint value)
473 _EGLSurface *surface = _eglLookupSurface(surf);
475 if (surface == NULL) {
476 _eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib");
481 case EGL_MIPMAP_LEVEL:
482 surface->MipmapLevel = value;
485 _eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib");
493 _eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
496 /* Just do basic error checking and return success/fail.
497 * Drivers must implement the real stuff.
499 _EGLSurface *surface = _eglLookupSurface(surf);
501 if (!surface || surface->Type != EGL_PBUFFER_BIT) {
502 _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
506 if (surface->TextureFormat == EGL_NO_TEXTURE) {
507 _eglError(EGL_BAD_MATCH, "eglBindTexImage");
511 if (buffer != EGL_BACK_BUFFER) {
512 _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
516 surface->BoundToTexture = EGL_TRUE;
523 _eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
526 /* Just do basic error checking and return success/fail.
527 * Drivers must implement the real stuff.
529 _EGLSurface *surface = _eglLookupSurface(surf);
531 if (!surface || surface->Type != EGL_PBUFFER_BIT) {
532 _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
536 if (surface->TextureFormat == EGL_NO_TEXTURE) {
537 _eglError(EGL_BAD_MATCH, "eglBindTexImage");
541 if (buffer != EGL_BACK_BUFFER) {
542 _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
546 if (!surface->BoundToTexture) {
547 _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
551 surface->BoundToTexture = EGL_FALSE;
558 _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
560 _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
562 _eglError(EGL_BAD_SURFACE, "eglSwapInterval");
565 surf->SwapInterval = interval;
570 #ifdef EGL_VERSION_1_2
573 * Example function - drivers should do a proper implementation.
576 _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
577 EGLenum buftype, EGLClientBuffer buffer,
578 EGLConfig config, const EGLint *attrib_list)
580 if (buftype != EGL_OPENVG_IMAGE) {
581 _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
582 return EGL_NO_SURFACE;
585 return EGL_NO_SURFACE;
588 #endif /* EGL_VERSION_1_2 */