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