gallium: add target-helpers/wrap_screen.c to C_SOURCES
[mesa/mesa-lb.git] / src / egl / main / eglsurface.c
blob8026a6314d3629e83acd47f1fea527770528b35a
1 /**
2 * Surface-related functions.
3 */
6 #include <assert.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "egldisplay.h"
10 #include "eglcontext.h"
11 #include "eglconfig.h"
12 #include "eglcurrent.h"
13 #include "egllog.h"
14 #include "eglsurface.h"
17 static void
18 _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
20 EGLint bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MAX_SWAP_INTERVAL);
21 if (interval >= bound) {
22 interval = bound;
24 else {
25 bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MIN_SWAP_INTERVAL);
26 if (interval < bound)
27 interval = bound;
29 surf->SwapInterval = interval;
33 /**
34 * Parse the list of surface attributes and return the proper error code.
36 static EGLint
37 _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
39 EGLint type = surf->Type;
40 EGLint i, err = EGL_SUCCESS;
42 if (!attrib_list)
43 return EGL_SUCCESS;
45 for (i = 0; attrib_list[i] != EGL_NONE; i++) {
46 EGLint attr = attrib_list[i++];
47 EGLint val = attrib_list[i];
49 switch (attr) {
50 /* common (except for screen surfaces) attributes */
51 case EGL_VG_COLORSPACE:
52 if (type == EGL_SCREEN_BIT_MESA) {
53 err = EGL_BAD_ATTRIBUTE;
54 break;
56 switch (val) {
57 case EGL_VG_COLORSPACE_sRGB:
58 case EGL_VG_COLORSPACE_LINEAR:
59 break;
60 default:
61 err = EGL_BAD_ATTRIBUTE;
62 break;
64 if (err != EGL_SUCCESS)
65 break;
66 surf->VGColorspace = val;
67 break;
68 case EGL_VG_ALPHA_FORMAT:
69 if (type == EGL_SCREEN_BIT_MESA) {
70 err = EGL_BAD_ATTRIBUTE;
71 break;
73 switch (val) {
74 case EGL_VG_ALPHA_FORMAT_NONPRE:
75 case EGL_VG_ALPHA_FORMAT_PRE:
76 break;
77 default:
78 err = EGL_BAD_ATTRIBUTE;
79 break;
81 if (err != EGL_SUCCESS)
82 break;
83 surf->VGAlphaFormat = val;
84 break;
85 /* window surface attributes */
86 case EGL_RENDER_BUFFER:
87 if (type != EGL_WINDOW_BIT) {
88 err = EGL_BAD_ATTRIBUTE;
89 break;
91 if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
92 err = EGL_BAD_ATTRIBUTE;
93 break;
95 surf->RenderBuffer = val;
96 break;
97 /* pbuffer surface attributes */
98 case EGL_WIDTH:
99 if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) {
100 err = EGL_BAD_ATTRIBUTE;
101 break;
103 if (val < 0) {
104 err = EGL_BAD_PARAMETER;
105 break;
107 surf->Width = val;
108 break;
109 case EGL_HEIGHT:
110 if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) {
111 err = EGL_BAD_ATTRIBUTE;
112 break;
114 if (val < 0) {
115 err = EGL_BAD_PARAMETER;
116 break;
118 surf->Height = val;
119 break;
120 case EGL_LARGEST_PBUFFER:
121 if (type != EGL_PBUFFER_BIT) {
122 err = EGL_BAD_ATTRIBUTE;
123 break;
125 surf->LargestPbuffer = !!val;
126 break;
127 case EGL_TEXTURE_FORMAT:
128 if (type != EGL_PBUFFER_BIT) {
129 err = EGL_BAD_ATTRIBUTE;
130 break;
132 switch (val) {
133 case EGL_TEXTURE_RGB:
134 case EGL_TEXTURE_RGBA:
135 case EGL_NO_TEXTURE:
136 break;
137 default:
138 err = EGL_BAD_ATTRIBUTE;
139 break;
141 if (err != EGL_SUCCESS)
142 break;
143 surf->TextureFormat = val;
144 break;
145 case EGL_TEXTURE_TARGET:
146 if (type != EGL_PBUFFER_BIT) {
147 err = EGL_BAD_ATTRIBUTE;
148 break;
150 switch (val) {
151 case EGL_TEXTURE_2D:
152 case EGL_NO_TEXTURE:
153 break;
154 default:
155 err = EGL_BAD_ATTRIBUTE;
156 break;
158 if (err != EGL_SUCCESS)
159 break;
160 surf->TextureTarget = val;
161 break;
162 case EGL_MIPMAP_TEXTURE:
163 if (type != EGL_PBUFFER_BIT) {
164 err = EGL_BAD_ATTRIBUTE;
165 break;
167 surf->MipmapTexture = !!val;
168 break;
169 /* no pixmap surface specific attributes */
170 default:
171 err = EGL_BAD_ATTRIBUTE;
172 break;
175 if (err != EGL_SUCCESS) {
176 _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
177 break;
181 return err;
186 * Do error check on parameters and initialize the given _EGLSurface object.
187 * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
189 EGLBoolean
190 _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
191 _EGLConfig *conf, const EGLint *attrib_list)
193 const char *func;
194 EGLint renderBuffer = EGL_BACK_BUFFER;
195 EGLint err;
197 switch (type) {
198 case EGL_WINDOW_BIT:
199 func = "eglCreateWindowSurface";
200 break;
201 case EGL_PIXMAP_BIT:
202 func = "eglCreatePixmapSurface";
203 renderBuffer = EGL_SINGLE_BUFFER;
204 break;
205 case EGL_PBUFFER_BIT:
206 func = "eglCreatePBufferSurface";
207 break;
208 case EGL_SCREEN_BIT_MESA:
209 func = "eglCreateScreenSurface";
210 renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
211 break;
212 default:
213 _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
214 return EGL_FALSE;
217 if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) {
218 /* The config can't be used to create a surface of this type */
219 _eglError(EGL_BAD_CONFIG, func);
220 return EGL_FALSE;
223 memset(surf, 0, sizeof(_EGLSurface));
224 surf->Resource.Display = dpy;
225 surf->Type = type;
226 surf->Config = conf;
228 surf->Width = 0;
229 surf->Height = 0;
230 surf->TextureFormat = EGL_NO_TEXTURE;
231 surf->TextureTarget = EGL_NO_TEXTURE;
232 surf->MipmapTexture = EGL_FALSE;
233 surf->LargestPbuffer = EGL_FALSE;
234 surf->RenderBuffer = renderBuffer;
235 surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
236 surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
238 surf->MipmapLevel = 0;
239 surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
240 surf->SwapBehavior = EGL_BUFFER_DESTROYED;
242 surf->HorizontalResolution = EGL_UNKNOWN;
243 surf->VerticalResolution = EGL_UNKNOWN;
244 surf->AspectRatio = EGL_UNKNOWN;
246 /* the default swap interval is 1 */
247 _eglClampSwapInterval(surf, 1);
249 err = _eglParseSurfaceAttribList(surf, attrib_list);
250 if (err != EGL_SUCCESS)
251 return _eglError(err, func);
253 return EGL_TRUE;
257 EGLBoolean
258 _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
260 /* Drivers have to do the actual buffer swap. */
261 return EGL_TRUE;
265 EGLBoolean
266 _eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
267 EGLNativePixmapType target)
269 /* copy surface to native pixmap */
270 /* All implementation burdon for this is in the device driver */
271 return EGL_FALSE;
275 EGLBoolean
276 _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
277 EGLint attribute, EGLint *value)
279 switch (attribute) {
280 case EGL_WIDTH:
281 *value = surface->Width;
282 break;
283 case EGL_HEIGHT:
284 *value = surface->Height;
285 break;
286 case EGL_CONFIG_ID:
287 *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
288 break;
289 case EGL_LARGEST_PBUFFER:
290 *value = surface->LargestPbuffer;
291 break;
292 case EGL_TEXTURE_FORMAT:
293 /* texture attributes: only for pbuffers, no error otherwise */
294 if (surface->Type == EGL_PBUFFER_BIT)
295 *value = surface->TextureFormat;
296 break;
297 case EGL_TEXTURE_TARGET:
298 if (surface->Type == EGL_PBUFFER_BIT)
299 *value = surface->TextureTarget;
300 break;
301 case EGL_MIPMAP_TEXTURE:
302 if (surface->Type == EGL_PBUFFER_BIT)
303 *value = surface->MipmapTexture;
304 break;
305 case EGL_MIPMAP_LEVEL:
306 if (surface->Type == EGL_PBUFFER_BIT)
307 *value = surface->MipmapLevel;
308 break;
309 case EGL_SWAP_BEHAVIOR:
310 *value = surface->SwapBehavior;
311 break;
312 case EGL_RENDER_BUFFER:
313 *value = surface->RenderBuffer;
314 break;
315 case EGL_PIXEL_ASPECT_RATIO:
316 *value = surface->AspectRatio;
317 break;
318 case EGL_HORIZONTAL_RESOLUTION:
319 *value = surface->HorizontalResolution;
320 break;
321 case EGL_VERTICAL_RESOLUTION:
322 *value = surface->VerticalResolution;
323 break;
324 case EGL_MULTISAMPLE_RESOLVE:
325 *value = surface->MultisampleResolve;
326 break;
327 case EGL_VG_ALPHA_FORMAT:
328 *value = surface->VGAlphaFormat;
329 break;
330 case EGL_VG_COLORSPACE:
331 *value = surface->VGColorspace;
332 break;
333 default:
334 _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
335 return EGL_FALSE;
338 return EGL_TRUE;
343 * Drivers should do a proper implementation.
345 _EGLSurface *
346 _eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
347 EGLNativeWindowType window, const EGLint *attrib_list)
349 return NULL;
354 * Drivers should do a proper implementation.
356 _EGLSurface *
357 _eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
358 EGLNativePixmapType pixmap, const EGLint *attrib_list)
360 return NULL;
365 * Drivers should do a proper implementation.
367 _EGLSurface *
368 _eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
369 const EGLint *attrib_list)
371 return NULL;
376 * Default fallback routine - drivers should usually override this.
378 EGLBoolean
379 _eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
381 if (!_eglIsSurfaceBound(surf))
382 free(surf);
383 return EGL_TRUE;
388 * Default fallback routine - drivers might override this.
390 EGLBoolean
391 _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
392 EGLint attribute, EGLint value)
394 EGLint confval;
395 EGLint err = EGL_SUCCESS;
397 switch (attribute) {
398 case EGL_MIPMAP_LEVEL:
399 confval = GET_CONFIG_ATTRIB(surface->Config, EGL_RENDERABLE_TYPE);
400 if (!(confval & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT))) {
401 err = EGL_BAD_PARAMETER;
402 break;
404 surface->MipmapLevel = value;
405 break;
406 case EGL_MULTISAMPLE_RESOLVE:
407 switch (value) {
408 case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
409 break;
410 case EGL_MULTISAMPLE_RESOLVE_BOX:
411 confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE);
412 if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
413 err = EGL_BAD_MATCH;
414 break;
415 default:
416 err = EGL_BAD_ATTRIBUTE;
417 break;
419 if (err != EGL_SUCCESS)
420 break;
421 surface->MultisampleResolve = value;
422 break;
423 case EGL_SWAP_BEHAVIOR:
424 switch (value) {
425 case EGL_BUFFER_DESTROYED:
426 break;
427 case EGL_BUFFER_PRESERVED:
428 confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE);
429 if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
430 err = EGL_BAD_MATCH;
431 break;
432 default:
433 err = EGL_BAD_ATTRIBUTE;
434 break;
436 if (err != EGL_SUCCESS)
437 break;
438 surface->SwapBehavior = value;
439 break;
440 default:
441 err = EGL_BAD_ATTRIBUTE;
442 break;
445 if (err != EGL_SUCCESS)
446 return _eglError(err, "eglSurfaceAttrib");
447 return EGL_TRUE;
451 EGLBoolean
452 _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
453 EGLint buffer)
455 /* Just do basic error checking and return success/fail.
456 * Drivers must implement the real stuff.
459 if (surface->Type != EGL_PBUFFER_BIT) {
460 _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
461 return EGL_FALSE;
464 if (surface->TextureFormat == EGL_NO_TEXTURE) {
465 _eglError(EGL_BAD_MATCH, "eglBindTexImage");
466 return EGL_FALSE;
469 if (buffer != EGL_BACK_BUFFER) {
470 _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
471 return EGL_FALSE;
474 surface->BoundToTexture = EGL_TRUE;
476 return EGL_TRUE;
480 EGLBoolean
481 _eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
482 EGLint buffer)
484 /* Just do basic error checking and return success/fail.
485 * Drivers must implement the real stuff.
488 if (surface->Type != EGL_PBUFFER_BIT) {
489 _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
490 return EGL_FALSE;
493 if (surface->TextureFormat == EGL_NO_TEXTURE) {
494 _eglError(EGL_BAD_MATCH, "eglBindTexImage");
495 return EGL_FALSE;
498 if (buffer != EGL_BACK_BUFFER) {
499 _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
500 return EGL_FALSE;
503 if (!surface->BoundToTexture) {
504 _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
505 return EGL_FALSE;
508 surface->BoundToTexture = EGL_FALSE;
510 return EGL_TRUE;
514 EGLBoolean
515 _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
516 EGLint interval)
518 _eglClampSwapInterval(surf, interval);
519 return EGL_TRUE;
523 #ifdef EGL_VERSION_1_2
526 * Example function - drivers should do a proper implementation.
528 _EGLSurface *
529 _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
530 EGLenum buftype, EGLClientBuffer buffer,
531 _EGLConfig *conf, const EGLint *attrib_list)
533 if (buftype != EGL_OPENVG_IMAGE) {
534 _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
535 return NULL;
538 return NULL;
541 #endif /* EGL_VERSION_1_2 */