1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010 LunarG, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Surface-related functions.
39 #include "egldisplay.h"
40 #include "eglcontext.h"
41 #include "eglconfig.h"
42 #include "eglcurrent.h"
44 #include "eglsurface.h"
48 _eglClampSwapInterval(_EGLSurface
*surf
, EGLint interval
)
50 EGLint bound
= surf
->Config
->MaxSwapInterval
;
51 if (interval
>= bound
) {
55 bound
= surf
->Config
->MinSwapInterval
;
59 surf
->SwapInterval
= interval
;
63 #ifdef EGL_MESA_screen_surface
65 _eglParseScreenSurfaceAttribList(_EGLSurface
*surf
, const EGLint
*attrib_list
)
67 EGLint i
, err
= EGL_SUCCESS
;
72 for (i
= 0; attrib_list
[i
] != EGL_NONE
; i
++) {
73 EGLint attr
= attrib_list
[i
++];
74 EGLint val
= attrib_list
[i
];
79 err
= EGL_BAD_PARAMETER
;
86 err
= EGL_BAD_PARAMETER
;
92 err
= EGL_BAD_ATTRIBUTE
;
96 if (err
!= EGL_SUCCESS
) {
97 _eglLog(_EGL_WARNING
, "bad surface attribute 0x%04x", attr
);
104 #endif /* EGL_MESA_screen_surface */
108 * Parse the list of surface attributes and return the proper error code.
111 _eglParseSurfaceAttribList(_EGLSurface
*surf
, const EGLint
*attrib_list
)
113 _EGLDisplay
*dpy
= surf
->Resource
.Display
;
114 EGLint type
= surf
->Type
;
115 EGLint texture_type
= EGL_PBUFFER_BIT
;
116 EGLint i
, err
= EGL_SUCCESS
;
121 #ifdef EGL_MESA_screen_surface
122 if (type
== EGL_SCREEN_BIT_MESA
)
123 return _eglParseScreenSurfaceAttribList(surf
, attrib_list
);
126 if (dpy
->Extensions
.NOK_texture_from_pixmap
)
127 texture_type
|= EGL_PIXMAP_BIT
;
129 for (i
= 0; attrib_list
[i
] != EGL_NONE
; i
++) {
130 EGLint attr
= attrib_list
[i
++];
131 EGLint val
= attrib_list
[i
];
134 /* common attributes */
135 case EGL_VG_COLORSPACE
:
137 case EGL_VG_COLORSPACE_sRGB
:
138 case EGL_VG_COLORSPACE_LINEAR
:
141 err
= EGL_BAD_ATTRIBUTE
;
144 if (err
!= EGL_SUCCESS
)
146 surf
->VGColorspace
= val
;
148 case EGL_VG_ALPHA_FORMAT
:
150 case EGL_VG_ALPHA_FORMAT_NONPRE
:
151 case EGL_VG_ALPHA_FORMAT_PRE
:
154 err
= EGL_BAD_ATTRIBUTE
;
157 if (err
!= EGL_SUCCESS
)
159 surf
->VGAlphaFormat
= val
;
161 /* window surface attributes */
162 case EGL_RENDER_BUFFER
:
163 if (type
!= EGL_WINDOW_BIT
) {
164 err
= EGL_BAD_ATTRIBUTE
;
167 if (val
!= EGL_BACK_BUFFER
&& val
!= EGL_SINGLE_BUFFER
) {
168 err
= EGL_BAD_ATTRIBUTE
;
171 surf
->RenderBuffer
= val
;
173 /* pbuffer surface attributes */
175 if (type
!= EGL_PBUFFER_BIT
) {
176 err
= EGL_BAD_ATTRIBUTE
;
180 err
= EGL_BAD_PARAMETER
;
186 if (type
!= EGL_PBUFFER_BIT
) {
187 err
= EGL_BAD_ATTRIBUTE
;
191 err
= EGL_BAD_PARAMETER
;
196 case EGL_LARGEST_PBUFFER
:
197 if (type
!= EGL_PBUFFER_BIT
) {
198 err
= EGL_BAD_ATTRIBUTE
;
201 surf
->LargestPbuffer
= !!val
;
203 /* for eglBindTexImage */
204 case EGL_TEXTURE_FORMAT
:
205 if (!(type
& texture_type
)) {
206 err
= EGL_BAD_ATTRIBUTE
;
210 case EGL_TEXTURE_RGB
:
211 case EGL_TEXTURE_RGBA
:
215 err
= EGL_BAD_ATTRIBUTE
;
218 if (err
!= EGL_SUCCESS
)
220 surf
->TextureFormat
= val
;
222 case EGL_TEXTURE_TARGET
:
223 if (!(type
& texture_type
)) {
224 err
= EGL_BAD_ATTRIBUTE
;
232 err
= EGL_BAD_ATTRIBUTE
;
235 if (err
!= EGL_SUCCESS
)
237 surf
->TextureTarget
= val
;
239 case EGL_MIPMAP_TEXTURE
:
240 if (!(type
& texture_type
)) {
241 err
= EGL_BAD_ATTRIBUTE
;
244 surf
->MipmapTexture
= !!val
;
246 /* no pixmap surface specific attributes */
248 err
= EGL_BAD_ATTRIBUTE
;
252 if (err
!= EGL_SUCCESS
) {
253 _eglLog(_EGL_WARNING
, "bad surface attribute 0x%04x", attr
);
263 * Do error check on parameters and initialize the given _EGLSurface object.
264 * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
267 _eglInitSurface(_EGLSurface
*surf
, _EGLDisplay
*dpy
, EGLint type
,
268 _EGLConfig
*conf
, const EGLint
*attrib_list
)
271 EGLint renderBuffer
= EGL_BACK_BUFFER
;
276 func
= "eglCreateWindowSurface";
279 func
= "eglCreatePixmapSurface";
280 renderBuffer
= EGL_SINGLE_BUFFER
;
282 case EGL_PBUFFER_BIT
:
283 func
= "eglCreatePBufferSurface";
285 #ifdef EGL_MESA_screen_surface
286 case EGL_SCREEN_BIT_MESA
:
287 func
= "eglCreateScreenSurface";
288 renderBuffer
= EGL_SINGLE_BUFFER
; /* XXX correct? */
292 _eglLog(_EGL_WARNING
, "Bad type in _eglInitSurface");
296 if ((conf
->SurfaceType
& type
) == 0) {
297 /* The config can't be used to create a surface of this type */
298 _eglError(EGL_BAD_CONFIG
, func
);
302 _eglInitResource(&surf
->Resource
, sizeof(*surf
), dpy
);
308 surf
->TextureFormat
= EGL_NO_TEXTURE
;
309 surf
->TextureTarget
= EGL_NO_TEXTURE
;
310 surf
->MipmapTexture
= EGL_FALSE
;
311 surf
->LargestPbuffer
= EGL_FALSE
;
312 surf
->RenderBuffer
= renderBuffer
;
313 surf
->VGAlphaFormat
= EGL_VG_ALPHA_FORMAT_NONPRE
;
314 surf
->VGColorspace
= EGL_VG_COLORSPACE_sRGB
;
316 surf
->MipmapLevel
= 0;
317 surf
->MultisampleResolve
= EGL_MULTISAMPLE_RESOLVE_DEFAULT
;
318 surf
->SwapBehavior
= EGL_BUFFER_DESTROYED
;
320 surf
->HorizontalResolution
= EGL_UNKNOWN
;
321 surf
->VerticalResolution
= EGL_UNKNOWN
;
322 surf
->AspectRatio
= EGL_UNKNOWN
;
324 /* the default swap interval is 1 */
325 _eglClampSwapInterval(surf
, 1);
327 err
= _eglParseSurfaceAttribList(surf
, attrib_list
);
328 if (err
!= EGL_SUCCESS
)
329 return _eglError(err
, func
);
336 _eglQuerySurface(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surface
,
337 EGLint attribute
, EGLint
*value
)
341 *value
= surface
->Width
;
344 *value
= surface
->Height
;
347 *value
= surface
->Config
->ConfigID
;
349 case EGL_LARGEST_PBUFFER
:
350 *value
= surface
->LargestPbuffer
;
352 case EGL_TEXTURE_FORMAT
:
353 /* texture attributes: only for pbuffers, no error otherwise */
354 if (surface
->Type
== EGL_PBUFFER_BIT
)
355 *value
= surface
->TextureFormat
;
357 case EGL_TEXTURE_TARGET
:
358 if (surface
->Type
== EGL_PBUFFER_BIT
)
359 *value
= surface
->TextureTarget
;
361 case EGL_MIPMAP_TEXTURE
:
362 if (surface
->Type
== EGL_PBUFFER_BIT
)
363 *value
= surface
->MipmapTexture
;
365 case EGL_MIPMAP_LEVEL
:
366 if (surface
->Type
== EGL_PBUFFER_BIT
)
367 *value
= surface
->MipmapLevel
;
369 case EGL_SWAP_BEHAVIOR
:
370 *value
= surface
->SwapBehavior
;
372 case EGL_RENDER_BUFFER
:
373 *value
= surface
->RenderBuffer
;
375 case EGL_PIXEL_ASPECT_RATIO
:
376 *value
= surface
->AspectRatio
;
378 case EGL_HORIZONTAL_RESOLUTION
:
379 *value
= surface
->HorizontalResolution
;
381 case EGL_VERTICAL_RESOLUTION
:
382 *value
= surface
->VerticalResolution
;
384 case EGL_MULTISAMPLE_RESOLVE
:
385 *value
= surface
->MultisampleResolve
;
387 case EGL_VG_ALPHA_FORMAT
:
388 *value
= surface
->VGAlphaFormat
;
390 case EGL_VG_COLORSPACE
:
391 *value
= surface
->VGColorspace
;
394 _eglError(EGL_BAD_ATTRIBUTE
, "eglQuerySurface");
403 * Default fallback routine - drivers might override this.
406 _eglSurfaceAttrib(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surface
,
407 EGLint attribute
, EGLint value
)
410 EGLint err
= EGL_SUCCESS
;
413 case EGL_MIPMAP_LEVEL
:
414 confval
= surface
->Config
->RenderableType
;
415 if (!(confval
& (EGL_OPENGL_ES_BIT
| EGL_OPENGL_ES2_BIT
))) {
416 err
= EGL_BAD_PARAMETER
;
419 surface
->MipmapLevel
= value
;
421 case EGL_MULTISAMPLE_RESOLVE
:
423 case EGL_MULTISAMPLE_RESOLVE_DEFAULT
:
425 case EGL_MULTISAMPLE_RESOLVE_BOX
:
426 confval
= surface
->Config
->SurfaceType
;
427 if (!(confval
& EGL_MULTISAMPLE_RESOLVE_BOX_BIT
))
431 err
= EGL_BAD_ATTRIBUTE
;
434 if (err
!= EGL_SUCCESS
)
436 surface
->MultisampleResolve
= value
;
438 case EGL_SWAP_BEHAVIOR
:
440 case EGL_BUFFER_DESTROYED
:
442 case EGL_BUFFER_PRESERVED
:
443 confval
= surface
->Config
->SurfaceType
;
444 if (!(confval
& EGL_SWAP_BEHAVIOR_PRESERVED_BIT
))
448 err
= EGL_BAD_ATTRIBUTE
;
451 if (err
!= EGL_SUCCESS
)
453 surface
->SwapBehavior
= value
;
456 err
= EGL_BAD_ATTRIBUTE
;
460 if (err
!= EGL_SUCCESS
)
461 return _eglError(err
, "eglSurfaceAttrib");
467 _eglBindTexImage(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surface
,
470 EGLint texture_type
= EGL_PBUFFER_BIT
;
472 /* Just do basic error checking and return success/fail.
473 * Drivers must implement the real stuff.
476 if (dpy
->Extensions
.NOK_texture_from_pixmap
)
477 texture_type
|= EGL_PIXMAP_BIT
;
479 if (!(surface
->Type
& texture_type
)) {
480 _eglError(EGL_BAD_SURFACE
, "eglBindTexImage");
484 if (surface
->TextureFormat
== EGL_NO_TEXTURE
) {
485 _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
489 if (surface
->TextureTarget
== EGL_NO_TEXTURE
) {
490 _eglError(EGL_BAD_MATCH
, "eglBindTexImage");
494 if (buffer
!= EGL_BACK_BUFFER
) {
495 _eglError(EGL_BAD_PARAMETER
, "eglBindTexImage");
499 surface
->BoundToTexture
= EGL_TRUE
;
506 _eglSwapInterval(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
,
509 _eglClampSwapInterval(surf
, interval
);