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