egl: Clean up header inclusions.
[mesa.git] / src / egl / main / eglsurface.c
1 /**
2 * Surface-related functions.
3 */
4
5
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"
15
16
17 static void
18 _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
19 {
20 EGLint bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MAX_SWAP_INTERVAL);
21 if (interval >= bound) {
22 interval = bound;
23 }
24 else {
25 bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MIN_SWAP_INTERVAL);
26 if (interval < bound)
27 interval = bound;
28 }
29 surf->SwapInterval = interval;
30 }
31
32
33 /**
34 * Do error check on parameters and initialize the given _EGLSurface object.
35 * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
36 */
37 EGLBoolean
38 _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
39 _EGLConfig *conf, const EGLint *attrib_list)
40 {
41 const char *func;
42 EGLint width = 0, height = 0, largest = 0;
43 EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE;
44 EGLint mipmapTex = EGL_FALSE;
45 EGLint renderBuffer = EGL_BACK_BUFFER;
46 #ifdef EGL_VERSION_1_2
47 EGLint colorspace = EGL_COLORSPACE_sRGB;
48 EGLint alphaFormat = EGL_ALPHA_FORMAT_NONPRE;
49 #endif
50 EGLint i;
51
52 switch (type) {
53 case EGL_WINDOW_BIT:
54 func = "eglCreateWindowSurface";
55 break;
56 case EGL_PIXMAP_BIT:
57 func = "eglCreatePixmapSurface";
58 renderBuffer = EGL_SINGLE_BUFFER;
59 break;
60 case EGL_PBUFFER_BIT:
61 func = "eglCreatePBufferSurface";
62 break;
63 case EGL_SCREEN_BIT_MESA:
64 func = "eglCreateScreenSurface";
65 renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
66 break;
67 default:
68 _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
69 return EGL_FALSE;
70 }
71
72 if (!conf) {
73 _eglError(EGL_BAD_CONFIG, func);
74 return EGL_FALSE;
75 }
76
77 if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) {
78 /* The config can't be used to create a surface of this type */
79 _eglError(EGL_BAD_CONFIG, func);
80 return EGL_FALSE;
81 }
82
83 /*
84 * Parse attribute list. Different kinds of surfaces support different
85 * attributes.
86 */
87 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
88 switch (attrib_list[i]) {
89 case EGL_WIDTH:
90 if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
91 width = attrib_list[++i];
92 }
93 else {
94 _eglError(EGL_BAD_ATTRIBUTE, func);
95 return EGL_FALSE;
96 }
97 break;
98 case EGL_HEIGHT:
99 if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
100 height = attrib_list[++i];
101 }
102 else {
103 _eglError(EGL_BAD_ATTRIBUTE, func);
104 return EGL_FALSE;
105 }
106 break;
107 case EGL_LARGEST_PBUFFER:
108 if (type == EGL_PBUFFER_BIT) {
109 largest = attrib_list[++i];
110 }
111 else {
112 _eglError(EGL_BAD_ATTRIBUTE, func);
113 return EGL_FALSE;
114 }
115 break;
116 case EGL_TEXTURE_FORMAT:
117 if (type == EGL_PBUFFER_BIT) {
118 texFormat = attrib_list[++i];
119 }
120 else {
121 _eglError(EGL_BAD_ATTRIBUTE, func);
122 return EGL_FALSE;
123 }
124 break;
125 case EGL_TEXTURE_TARGET:
126 if (type == EGL_PBUFFER_BIT) {
127 texTarget = attrib_list[++i];
128 }
129 else {
130 _eglError(EGL_BAD_ATTRIBUTE, func);
131 return EGL_FALSE;
132 }
133 break;
134 case EGL_MIPMAP_TEXTURE:
135 if (type == EGL_PBUFFER_BIT) {
136 mipmapTex = attrib_list[++i];
137 }
138 else {
139 _eglError(EGL_BAD_ATTRIBUTE, func);
140 return EGL_FALSE;
141 }
142 break;
143 #ifdef EGL_VERSION_1_2
144 case EGL_RENDER_BUFFER:
145 if (type == EGL_WINDOW_BIT) {
146 renderBuffer = attrib_list[++i];
147 if (renderBuffer != EGL_BACK_BUFFER &&
148 renderBuffer != EGL_SINGLE_BUFFER) {
149 _eglError(EGL_BAD_ATTRIBUTE, func);
150 return EGL_FALSE;
151 }
152 }
153 else {
154 _eglError(EGL_BAD_ATTRIBUTE, func);
155 return EGL_FALSE;
156 }
157 break;
158 case EGL_COLORSPACE:
159 if (type == EGL_WINDOW_BIT ||
160 type == EGL_PBUFFER_BIT ||
161 type == EGL_PIXMAP_BIT) {
162 colorspace = attrib_list[++i];
163 if (colorspace != EGL_COLORSPACE_sRGB &&
164 colorspace != EGL_COLORSPACE_LINEAR) {
165 _eglError(EGL_BAD_ATTRIBUTE, func);
166 return EGL_FALSE;
167 }
168 }
169 else {
170 _eglError(EGL_BAD_ATTRIBUTE, func);
171 return EGL_FALSE;
172 }
173 break;
174 case EGL_ALPHA_FORMAT:
175 if (type == EGL_WINDOW_BIT ||
176 type == EGL_PBUFFER_BIT ||
177 type == EGL_PIXMAP_BIT) {
178 alphaFormat = attrib_list[++i];
179 if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE &&
180 alphaFormat != EGL_ALPHA_FORMAT_PRE) {
181 _eglError(EGL_BAD_ATTRIBUTE, func);
182 return EGL_FALSE;
183 }
184 }
185 else {
186 _eglError(EGL_BAD_ATTRIBUTE, func);
187 return EGL_FALSE;
188 }
189 break;
190
191 #endif /* EGL_VERSION_1_2 */
192 default:
193 _eglError(EGL_BAD_ATTRIBUTE, func);
194 return EGL_FALSE;
195 }
196 }
197
198 if (width < 0 || height < 0) {
199 _eglError(EGL_BAD_ATTRIBUTE, func);
200 return EGL_FALSE;
201 }
202
203 memset(surf, 0, sizeof(_EGLSurface));
204 surf->Config = conf;
205 surf->Type = type;
206 surf->Width = width;
207 surf->Height = height;
208 surf->TextureFormat = texFormat;
209 surf->TextureTarget = texTarget;
210 surf->MipmapTexture = mipmapTex;
211 surf->MipmapLevel = 0;
212 /* the default swap interval is 1 */
213 _eglClampSwapInterval(surf, 1);
214
215 #ifdef EGL_VERSION_1_2
216 surf->SwapBehavior = EGL_BUFFER_DESTROYED; /* XXX ok? */
217 surf->HorizontalResolution = EGL_UNKNOWN; /* set by caller */
218 surf->VerticalResolution = EGL_UNKNOWN; /* set by caller */
219 surf->AspectRatio = EGL_UNKNOWN; /* set by caller */
220 surf->RenderBuffer = renderBuffer;
221 surf->AlphaFormat = alphaFormat;
222 surf->Colorspace = colorspace;
223 #endif
224
225 return EGL_TRUE;
226 }
227
228
229 EGLBoolean
230 _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
231 {
232 /* Drivers have to do the actual buffer swap. */
233 return EGL_TRUE;
234 }
235
236
237 EGLBoolean
238 _eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
239 EGLNativePixmapType target)
240 {
241 /* copy surface to native pixmap */
242 /* All implementation burdon for this is in the device driver */
243 return EGL_FALSE;
244 }
245
246
247 EGLBoolean
248 _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
249 EGLint attribute, EGLint *value)
250 {
251 switch (attribute) {
252 case EGL_WIDTH:
253 *value = surface->Width;
254 return EGL_TRUE;
255 case EGL_HEIGHT:
256 *value = surface->Height;
257 return EGL_TRUE;
258 case EGL_CONFIG_ID:
259 *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
260 return EGL_TRUE;
261 case EGL_LARGEST_PBUFFER:
262 *value = dpy->LargestPbuffer;
263 return EGL_TRUE;
264 case EGL_SURFACE_TYPE:
265 *value = surface->Type;
266 return EGL_TRUE;
267 #ifdef EGL_VERSION_1_1
268 case EGL_TEXTURE_FORMAT:
269 /* texture attributes: only for pbuffers, no error otherwise */
270 if (surface->Type == EGL_PBUFFER_BIT)
271 *value = surface->TextureFormat;
272 return EGL_TRUE;
273 case EGL_TEXTURE_TARGET:
274 if (surface->Type == EGL_PBUFFER_BIT)
275 *value = surface->TextureTarget;
276 return EGL_TRUE;
277 case EGL_MIPMAP_TEXTURE:
278 if (surface->Type == EGL_PBUFFER_BIT)
279 *value = surface->MipmapTexture;
280 return EGL_TRUE;
281 case EGL_MIPMAP_LEVEL:
282 if (surface->Type == EGL_PBUFFER_BIT)
283 *value = surface->MipmapLevel;
284 return EGL_TRUE;
285 #endif /* EGL_VERSION_1_1 */
286 #ifdef EGL_VERSION_1_2
287 case EGL_SWAP_BEHAVIOR:
288 *value = surface->SwapBehavior;
289 return EGL_TRUE;
290 case EGL_RENDER_BUFFER:
291 *value = surface->RenderBuffer;
292 return EGL_TRUE;
293 case EGL_PIXEL_ASPECT_RATIO:
294 *value = surface->AspectRatio;
295 return EGL_TRUE;
296 case EGL_HORIZONTAL_RESOLUTION:
297 *value = surface->HorizontalResolution;
298 return EGL_TRUE;
299 case EGL_VERTICAL_RESOLUTION:
300 *value = surface->VerticalResolution;
301 return EGL_TRUE;
302 case EGL_ALPHA_FORMAT:
303 *value = surface->AlphaFormat;
304 return EGL_TRUE;
305 case EGL_COLORSPACE:
306 *value = surface->Colorspace;
307 return EGL_TRUE;
308 #endif /* EGL_VERSION_1_2 */
309 default:
310 _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
311 return EGL_FALSE;
312 }
313 }
314
315
316 /**
317 * Example function - drivers should do a proper implementation.
318 */
319 _EGLSurface *
320 _eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
321 EGLNativeWindowType window, const EGLint *attrib_list)
322 {
323 #if 0 /* THIS IS JUST EXAMPLE CODE */
324 _EGLSurface *surf;
325
326 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
327 if (!surf)
328 return NULL;
329
330 if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) {
331 free(surf);
332 return NULL;
333 }
334
335 return surf;
336 #endif
337 return NULL;
338 }
339
340
341 /**
342 * Example function - drivers should do a proper implementation.
343 */
344 _EGLSurface *
345 _eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
346 EGLNativePixmapType pixmap, const EGLint *attrib_list)
347 {
348 #if 0 /* THIS IS JUST EXAMPLE CODE */
349 _EGLSurface *surf;
350
351 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
352 if (!surf)
353 return NULL;
354
355 if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) {
356 free(surf);
357 return NULL;
358 }
359
360 return surf;
361 #endif
362 return NULL;
363 }
364
365
366 /**
367 * Example function - drivers should do a proper implementation.
368 */
369 _EGLSurface *
370 _eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
371 const EGLint *attrib_list)
372 {
373 #if 0 /* THIS IS JUST EXAMPLE CODE */
374 _EGLSurface *surf;
375
376 surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
377 if (!surf)
378 return NULL;
379
380 if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) {
381 free(surf);
382 return NULL;
383 }
384
385 return NULL;
386 #endif
387 return NULL;
388 }
389
390
391 /**
392 * Default fallback routine - drivers should usually override this.
393 */
394 EGLBoolean
395 _eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
396 {
397 if (!_eglIsSurfaceBound(surf))
398 free(surf);
399 return EGL_TRUE;
400 }
401
402
403 /**
404 * Default fallback routine - drivers might override this.
405 */
406 EGLBoolean
407 _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
408 EGLint attribute, EGLint value)
409 {
410 switch (attribute) {
411 case EGL_MIPMAP_LEVEL:
412 surface->MipmapLevel = value;
413 break;
414 default:
415 _eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib");
416 return EGL_FALSE;
417 }
418 return EGL_TRUE;
419 }
420
421
422 EGLBoolean
423 _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
424 EGLint buffer)
425 {
426 /* Just do basic error checking and return success/fail.
427 * Drivers must implement the real stuff.
428 */
429
430 if (surface->Type != EGL_PBUFFER_BIT) {
431 _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
432 return EGL_FALSE;
433 }
434
435 if (surface->TextureFormat == EGL_NO_TEXTURE) {
436 _eglError(EGL_BAD_MATCH, "eglBindTexImage");
437 return EGL_FALSE;
438 }
439
440 if (buffer != EGL_BACK_BUFFER) {
441 _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
442 return EGL_FALSE;
443 }
444
445 surface->BoundToTexture = EGL_TRUE;
446
447 return EGL_TRUE;
448 }
449
450
451 EGLBoolean
452 _eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
453 EGLint buffer)
454 {
455 /* Just do basic error checking and return success/fail.
456 * Drivers must implement the real stuff.
457 */
458
459 if (surface->Type != EGL_PBUFFER_BIT) {
460 _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
461 return EGL_FALSE;
462 }
463
464 if (surface->TextureFormat == EGL_NO_TEXTURE) {
465 _eglError(EGL_BAD_MATCH, "eglBindTexImage");
466 return EGL_FALSE;
467 }
468
469 if (buffer != EGL_BACK_BUFFER) {
470 _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
471 return EGL_FALSE;
472 }
473
474 if (!surface->BoundToTexture) {
475 _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
476 return EGL_FALSE;
477 }
478
479 surface->BoundToTexture = EGL_FALSE;
480
481 return EGL_TRUE;
482 }
483
484
485 EGLBoolean
486 _eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
487 EGLint interval)
488 {
489 _eglClampSwapInterval(surf, interval);
490 return EGL_TRUE;
491 }
492
493
494 #ifdef EGL_VERSION_1_2
495
496 /**
497 * Example function - drivers should do a proper implementation.
498 */
499 _EGLSurface *
500 _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
501 EGLenum buftype, EGLClientBuffer buffer,
502 _EGLConfig *conf, const EGLint *attrib_list)
503 {
504 if (buftype != EGL_OPENVG_IMAGE) {
505 _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
506 return NULL;
507 }
508
509 return NULL;
510 }
511
512 #endif /* EGL_VERSION_1_2 */