1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2008 VMware, Inc.
4848b8605Smrg * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5848b8605Smrg * Copyright 2010 LunarG, Inc.
6848b8605Smrg * All Rights Reserved.
7848b8605Smrg *
8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9848b8605Smrg * copy of this software and associated documentation files (the
10848b8605Smrg * "Software"), to deal in the Software without restriction, including
11848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
12848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
13848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
14848b8605Smrg * the following conditions:
15848b8605Smrg *
16848b8605Smrg * The above copyright notice and this permission notice (including the
17848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
18848b8605Smrg * of the Software.
19848b8605Smrg *
20848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26848b8605Smrg * DEALINGS IN THE SOFTWARE.
27848b8605Smrg *
28848b8605Smrg **************************************************************************/
29848b8605Smrg
30848b8605Smrg
31848b8605Smrg/**
32848b8605Smrg * Surface-related functions.
33848b8605Smrg */
34848b8605Smrg
35848b8605Smrg
36848b8605Smrg#include <assert.h>
37848b8605Smrg#include <stdlib.h>
38848b8605Smrg#include <string.h>
39b8e80941Smrg#include "egldefines.h"
40848b8605Smrg#include "egldisplay.h"
41848b8605Smrg#include "egldriver.h"
42848b8605Smrg#include "eglcontext.h"
43848b8605Smrg#include "eglconfig.h"
44848b8605Smrg#include "eglcurrent.h"
45848b8605Smrg#include "egllog.h"
46848b8605Smrg#include "eglsurface.h"
47848b8605Smrg
48b8e80941Smrg#include "util/macros.h"
49848b8605Smrg
50848b8605Smrg/**
51848b8605Smrg * Parse the list of surface attributes and return the proper error code.
52848b8605Smrg */
53848b8605Smrgstatic EGLint
54848b8605Smrg_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
55848b8605Smrg{
56b8e80941Smrg   _EGLDisplay *disp = surf->Resource.Display;
57848b8605Smrg   EGLint type = surf->Type;
58848b8605Smrg   EGLint texture_type = EGL_PBUFFER_BIT;
59848b8605Smrg   EGLint i, err = EGL_SUCCESS;
60b8e80941Smrg   EGLint attr = EGL_NONE;
61b8e80941Smrg   EGLint val = EGL_NONE;
62848b8605Smrg
63848b8605Smrg   if (!attrib_list)
64848b8605Smrg      return EGL_SUCCESS;
65848b8605Smrg
66b8e80941Smrg   if (disp->Extensions.NOK_texture_from_pixmap)
67848b8605Smrg      texture_type |= EGL_PIXMAP_BIT;
68848b8605Smrg
69848b8605Smrg   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
70b8e80941Smrg      attr = attrib_list[i++];
71b8e80941Smrg      val = attrib_list[i];
72848b8605Smrg
73848b8605Smrg      switch (attr) {
74848b8605Smrg      /* common attributes */
75b8e80941Smrg      case EGL_GL_COLORSPACE_KHR:
76b8e80941Smrg         if (!disp->Extensions.KHR_gl_colorspace) {
77b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
78b8e80941Smrg            break;
79b8e80941Smrg         }
80b8e80941Smrg         switch (val) {
81b8e80941Smrg         case EGL_GL_COLORSPACE_SRGB_KHR:
82b8e80941Smrg         case EGL_GL_COLORSPACE_LINEAR_KHR:
83b8e80941Smrg            break;
84b8e80941Smrg         default:
85b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
86b8e80941Smrg         }
87b8e80941Smrg         if (err != EGL_SUCCESS)
88b8e80941Smrg            break;
89b8e80941Smrg         surf->GLColorspace = val;
90b8e80941Smrg         break;
91b8e80941Smrg      case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
92b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
93b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
94b8e80941Smrg            break;
95b8e80941Smrg         }
96b8e80941Smrg         surf->HdrMetadata.display_primary_r.x = val;
97b8e80941Smrg         break;
98b8e80941Smrg      case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
99b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
100b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
101b8e80941Smrg            break;
102b8e80941Smrg         }
103b8e80941Smrg         surf->HdrMetadata.display_primary_r.y = val;
104b8e80941Smrg         break;
105b8e80941Smrg      case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
106b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
107b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
108b8e80941Smrg            break;
109b8e80941Smrg         }
110b8e80941Smrg         surf->HdrMetadata.display_primary_g.x = val;
111b8e80941Smrg         break;
112b8e80941Smrg      case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
113b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
114b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
115b8e80941Smrg            break;
116b8e80941Smrg         }
117b8e80941Smrg         surf->HdrMetadata.display_primary_g.y = val;
118b8e80941Smrg         break;
119b8e80941Smrg      case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
120b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
121b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
122b8e80941Smrg            break;
123b8e80941Smrg         }
124b8e80941Smrg         surf->HdrMetadata.display_primary_b.x = val;
125b8e80941Smrg         break;
126b8e80941Smrg      case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
127b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
128b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
129b8e80941Smrg            break;
130b8e80941Smrg         }
131b8e80941Smrg         surf->HdrMetadata.display_primary_b.y = val;
132b8e80941Smrg         break;
133b8e80941Smrg      case EGL_SMPTE2086_WHITE_POINT_X_EXT:
134b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
135b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
136b8e80941Smrg            break;
137b8e80941Smrg         }
138b8e80941Smrg         surf->HdrMetadata.white_point.x = val;
139b8e80941Smrg         break;
140b8e80941Smrg      case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
141b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
142b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
143b8e80941Smrg            break;
144b8e80941Smrg         }
145b8e80941Smrg         surf->HdrMetadata.white_point.y = val;
146b8e80941Smrg         break;
147b8e80941Smrg      case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
148b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
149b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
150b8e80941Smrg            break;
151b8e80941Smrg         }
152b8e80941Smrg         surf->HdrMetadata.max_luminance = val;
153b8e80941Smrg         break;
154b8e80941Smrg      case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
155b8e80941Smrg         if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
156b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
157b8e80941Smrg            break;
158b8e80941Smrg         }
159b8e80941Smrg         surf->HdrMetadata.min_luminance = val;
160b8e80941Smrg         break;
161b8e80941Smrg      case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
162b8e80941Smrg         if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
163b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
164b8e80941Smrg            break;
165b8e80941Smrg         }
166b8e80941Smrg         surf->HdrMetadata.max_cll = val;
167b8e80941Smrg         break;
168b8e80941Smrg      case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
169b8e80941Smrg         if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
170b8e80941Smrg            err = EGL_BAD_ATTRIBUTE;
171b8e80941Smrg            break;
172b8e80941Smrg         }
173b8e80941Smrg         surf->HdrMetadata.max_fall = val;
174b8e80941Smrg         break;
175848b8605Smrg      case EGL_VG_COLORSPACE:
176848b8605Smrg         switch (val) {
177848b8605Smrg         case EGL_VG_COLORSPACE_sRGB:
178848b8605Smrg         case EGL_VG_COLORSPACE_LINEAR:
179848b8605Smrg            break;
180848b8605Smrg         default:
181848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
182848b8605Smrg            break;
183848b8605Smrg         }
184848b8605Smrg         if (err != EGL_SUCCESS)
185848b8605Smrg            break;
186848b8605Smrg         surf->VGColorspace = val;
187848b8605Smrg         break;
188848b8605Smrg      case EGL_VG_ALPHA_FORMAT:
189848b8605Smrg         switch (val) {
190848b8605Smrg         case EGL_VG_ALPHA_FORMAT_NONPRE:
191848b8605Smrg         case EGL_VG_ALPHA_FORMAT_PRE:
192848b8605Smrg            break;
193848b8605Smrg         default:
194848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
195848b8605Smrg            break;
196848b8605Smrg         }
197848b8605Smrg         if (err != EGL_SUCCESS)
198848b8605Smrg            break;
199848b8605Smrg         surf->VGAlphaFormat = val;
200848b8605Smrg         break;
201848b8605Smrg      /* window surface attributes */
202848b8605Smrg      case EGL_RENDER_BUFFER:
203848b8605Smrg         if (type != EGL_WINDOW_BIT) {
204848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
205848b8605Smrg            break;
206848b8605Smrg         }
207848b8605Smrg         if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
208848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
209848b8605Smrg            break;
210848b8605Smrg         }
211b8e80941Smrg         surf->RequestedRenderBuffer = val;
212b8e80941Smrg         if (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) {
213b8e80941Smrg            /* Unlike normal EGLSurfaces, one with a mutable render buffer
214b8e80941Smrg             * uses the application-chosen render buffer.
215b8e80941Smrg             */
216b8e80941Smrg            surf->ActiveRenderBuffer = val;
217b8e80941Smrg         }
218848b8605Smrg         break;
219848b8605Smrg      case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
220b8e80941Smrg         if (!disp->Extensions.NV_post_sub_buffer ||
221848b8605Smrg             type != EGL_WINDOW_BIT) {
222848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
223848b8605Smrg            break;
224848b8605Smrg         }
225848b8605Smrg         if (val != EGL_TRUE && val != EGL_FALSE) {
226848b8605Smrg            err = EGL_BAD_PARAMETER;
227848b8605Smrg            break;
228848b8605Smrg         }
229848b8605Smrg         surf->PostSubBufferSupportedNV = val;
230848b8605Smrg         break;
231848b8605Smrg      /* pbuffer surface attributes */
232848b8605Smrg      case EGL_WIDTH:
233848b8605Smrg         if (type != EGL_PBUFFER_BIT) {
234848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
235848b8605Smrg            break;
236848b8605Smrg         }
237848b8605Smrg         if (val < 0) {
238848b8605Smrg            err = EGL_BAD_PARAMETER;
239848b8605Smrg            break;
240848b8605Smrg         }
241848b8605Smrg         surf->Width = val;
242848b8605Smrg         break;
243848b8605Smrg      case EGL_HEIGHT:
244848b8605Smrg         if (type != EGL_PBUFFER_BIT) {
245848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
246848b8605Smrg            break;
247848b8605Smrg         }
248848b8605Smrg         if (val < 0) {
249848b8605Smrg            err = EGL_BAD_PARAMETER;
250848b8605Smrg            break;
251848b8605Smrg         }
252848b8605Smrg         surf->Height = val;
253848b8605Smrg         break;
254848b8605Smrg      case EGL_LARGEST_PBUFFER:
255848b8605Smrg         if (type != EGL_PBUFFER_BIT) {
256848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
257848b8605Smrg            break;
258848b8605Smrg         }
259848b8605Smrg         surf->LargestPbuffer = !!val;
260848b8605Smrg         break;
261848b8605Smrg      /* for eglBindTexImage */
262848b8605Smrg      case EGL_TEXTURE_FORMAT:
263848b8605Smrg         if (!(type & texture_type)) {
264848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
265848b8605Smrg            break;
266848b8605Smrg         }
267b8e80941Smrg
268848b8605Smrg         switch (val) {
269848b8605Smrg         case EGL_TEXTURE_RGB:
270848b8605Smrg         case EGL_TEXTURE_RGBA:
271848b8605Smrg         case EGL_NO_TEXTURE:
272848b8605Smrg            break;
273848b8605Smrg         default:
274848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
275848b8605Smrg            break;
276848b8605Smrg         }
277848b8605Smrg         if (err != EGL_SUCCESS)
278848b8605Smrg            break;
279848b8605Smrg         surf->TextureFormat = val;
280848b8605Smrg         break;
281848b8605Smrg      case EGL_TEXTURE_TARGET:
282848b8605Smrg         if (!(type & texture_type)) {
283848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
284848b8605Smrg            break;
285848b8605Smrg         }
286b8e80941Smrg
287848b8605Smrg         switch (val) {
288848b8605Smrg         case EGL_TEXTURE_2D:
289848b8605Smrg         case EGL_NO_TEXTURE:
290848b8605Smrg            break;
291848b8605Smrg         default:
292848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
293848b8605Smrg            break;
294848b8605Smrg         }
295848b8605Smrg         if (err != EGL_SUCCESS)
296848b8605Smrg            break;
297848b8605Smrg         surf->TextureTarget = val;
298848b8605Smrg         break;
299848b8605Smrg      case EGL_MIPMAP_TEXTURE:
300848b8605Smrg         if (!(type & texture_type)) {
301848b8605Smrg            err = EGL_BAD_ATTRIBUTE;
302848b8605Smrg            break;
303848b8605Smrg         }
304848b8605Smrg         surf->MipmapTexture = !!val;
305848b8605Smrg         break;
306848b8605Smrg      /* no pixmap surface specific attributes */
307848b8605Smrg      default:
308848b8605Smrg         err = EGL_BAD_ATTRIBUTE;
309848b8605Smrg         break;
310848b8605Smrg      }
311848b8605Smrg
312b8e80941Smrg      if (err != EGL_SUCCESS)
313848b8605Smrg         break;
314b8e80941Smrg   }
315b8e80941Smrg
316b8e80941Smrg   if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) {
317b8e80941Smrg      if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) ||
318b8e80941Smrg          (surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) {
319b8e80941Smrg         attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT;
320b8e80941Smrg         err = EGL_BAD_MATCH;
321848b8605Smrg      }
322848b8605Smrg   }
323848b8605Smrg
324b8e80941Smrg   if (err != EGL_SUCCESS)
325b8e80941Smrg      _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
326b8e80941Smrg
327848b8605Smrg   return err;
328848b8605Smrg}
329848b8605Smrg
330848b8605Smrg
331848b8605Smrg/**
332848b8605Smrg * Do error check on parameters and initialize the given _EGLSurface object.
333848b8605Smrg * \return EGL_TRUE if no errors, EGL_FALSE otherwise.
334848b8605Smrg */
335848b8605SmrgEGLBoolean
336b8e80941Smrg_eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type,
337848b8605Smrg                _EGLConfig *conf, const EGLint *attrib_list)
338848b8605Smrg{
339848b8605Smrg   const char *func;
340848b8605Smrg   EGLint renderBuffer = EGL_BACK_BUFFER;
341b8e80941Smrg   EGLint swapBehavior = EGL_BUFFER_DESTROYED;
342848b8605Smrg   EGLint err;
343848b8605Smrg
344b8e80941Smrg   /* Swap behavior can be preserved only if config supports this. */
345b8e80941Smrg   if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
346b8e80941Smrg      swapBehavior = EGL_BUFFER_PRESERVED;
347b8e80941Smrg
348848b8605Smrg   switch (type) {
349848b8605Smrg   case EGL_WINDOW_BIT:
350848b8605Smrg      func = "eglCreateWindowSurface";
351848b8605Smrg      swapBehavior = EGL_BUFFER_DESTROYED;
352848b8605Smrg      break;
353848b8605Smrg   case EGL_PIXMAP_BIT:
354848b8605Smrg      func = "eglCreatePixmapSurface";
355848b8605Smrg      renderBuffer = EGL_SINGLE_BUFFER;
356848b8605Smrg      break;
357848b8605Smrg   case EGL_PBUFFER_BIT:
358848b8605Smrg      func = "eglCreatePBufferSurface";
359848b8605Smrg      break;
360848b8605Smrg   default:
361848b8605Smrg      _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
362848b8605Smrg      return EGL_FALSE;
363848b8605Smrg   }
364848b8605Smrg
365b8e80941Smrg   if ((conf->SurfaceType & type) == 0)
366848b8605Smrg      /* The config can't be used to create a surface of this type */
367b8e80941Smrg      return _eglError(EGL_BAD_MATCH, func);
368848b8605Smrg
369b8e80941Smrg   _eglInitResource(&surf->Resource, sizeof(*surf), disp);
370848b8605Smrg   surf->Type = type;
371848b8605Smrg   surf->Config = conf;
372b8e80941Smrg   surf->Lost = EGL_FALSE;
373848b8605Smrg
374848b8605Smrg   surf->Width = 0;
375848b8605Smrg   surf->Height = 0;
376848b8605Smrg   surf->TextureFormat = EGL_NO_TEXTURE;
377848b8605Smrg   surf->TextureTarget = EGL_NO_TEXTURE;
378848b8605Smrg   surf->MipmapTexture = EGL_FALSE;
379848b8605Smrg   surf->LargestPbuffer = EGL_FALSE;
380b8e80941Smrg   surf->RequestedRenderBuffer = renderBuffer;
381b8e80941Smrg   surf->ActiveRenderBuffer = renderBuffer;
382848b8605Smrg   surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
383848b8605Smrg   surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
384b8e80941Smrg   surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
385848b8605Smrg
386848b8605Smrg   surf->MipmapLevel = 0;
387848b8605Smrg   surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
388848b8605Smrg   surf->SwapBehavior = swapBehavior;
389848b8605Smrg
390848b8605Smrg   surf->HorizontalResolution = EGL_UNKNOWN;
391848b8605Smrg   surf->VerticalResolution = EGL_UNKNOWN;
392848b8605Smrg   surf->AspectRatio = EGL_UNKNOWN;
393848b8605Smrg
394848b8605Smrg   surf->PostSubBufferSupportedNV = EGL_FALSE;
395b8e80941Smrg   surf->SetDamageRegionCalled = EGL_FALSE;
396b8e80941Smrg   surf->BufferAgeRead = EGL_FALSE;
397848b8605Smrg
398848b8605Smrg   /* the default swap interval is 1 */
399b8e80941Smrg   surf->SwapInterval = 1;
400b8e80941Smrg
401b8e80941Smrg   surf->HdrMetadata.display_primary_r.x = EGL_DONT_CARE;
402b8e80941Smrg   surf->HdrMetadata.display_primary_r.y = EGL_DONT_CARE;
403b8e80941Smrg   surf->HdrMetadata.display_primary_g.x = EGL_DONT_CARE;
404b8e80941Smrg   surf->HdrMetadata.display_primary_g.y = EGL_DONT_CARE;
405b8e80941Smrg   surf->HdrMetadata.display_primary_b.x = EGL_DONT_CARE;
406b8e80941Smrg   surf->HdrMetadata.display_primary_b.y = EGL_DONT_CARE;
407b8e80941Smrg   surf->HdrMetadata.white_point.x = EGL_DONT_CARE;
408b8e80941Smrg   surf->HdrMetadata.white_point.y = EGL_DONT_CARE;
409b8e80941Smrg   surf->HdrMetadata.max_luminance = EGL_DONT_CARE;
410b8e80941Smrg   surf->HdrMetadata.min_luminance = EGL_DONT_CARE;
411b8e80941Smrg   surf->HdrMetadata.max_cll = EGL_DONT_CARE;
412b8e80941Smrg   surf->HdrMetadata.max_fall = EGL_DONT_CARE;
413848b8605Smrg
414848b8605Smrg   err = _eglParseSurfaceAttribList(surf, attrib_list);
415848b8605Smrg   if (err != EGL_SUCCESS)
416848b8605Smrg      return _eglError(err, func);
417848b8605Smrg
418b8e80941Smrg   /* if EGL_LARGEST_PBUFFER in use, clamp width and height */
419b8e80941Smrg   if (surf->LargestPbuffer) {
420b8e80941Smrg      surf->Width = MIN2(surf->Width, _EGL_MAX_PBUFFER_WIDTH);
421b8e80941Smrg      surf->Height = MIN2(surf->Height, _EGL_MAX_PBUFFER_HEIGHT);
422b8e80941Smrg   }
423b8e80941Smrg
424848b8605Smrg   return EGL_TRUE;
425848b8605Smrg}
426848b8605Smrg
427848b8605Smrg
428848b8605SmrgEGLBoolean
429b8e80941Smrg_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
430848b8605Smrg                 EGLint attribute, EGLint *value)
431848b8605Smrg{
432848b8605Smrg   switch (attribute) {
433848b8605Smrg   case EGL_WIDTH:
434848b8605Smrg      *value = surface->Width;
435848b8605Smrg      break;
436848b8605Smrg   case EGL_HEIGHT:
437848b8605Smrg      *value = surface->Height;
438848b8605Smrg      break;
439848b8605Smrg   case EGL_CONFIG_ID:
440848b8605Smrg      *value = surface->Config->ConfigID;
441848b8605Smrg      break;
442848b8605Smrg   case EGL_LARGEST_PBUFFER:
443b8e80941Smrg      if (surface->Type == EGL_PBUFFER_BIT)
444b8e80941Smrg         *value = surface->LargestPbuffer;
445848b8605Smrg      break;
446848b8605Smrg   case EGL_TEXTURE_FORMAT:
447848b8605Smrg      /* texture attributes: only for pbuffers, no error otherwise */
448848b8605Smrg      if (surface->Type == EGL_PBUFFER_BIT)
449848b8605Smrg         *value = surface->TextureFormat;
450848b8605Smrg      break;
451848b8605Smrg   case EGL_TEXTURE_TARGET:
452848b8605Smrg      if (surface->Type == EGL_PBUFFER_BIT)
453848b8605Smrg         *value = surface->TextureTarget;
454848b8605Smrg      break;
455848b8605Smrg   case EGL_MIPMAP_TEXTURE:
456848b8605Smrg      if (surface->Type == EGL_PBUFFER_BIT)
457848b8605Smrg         *value = surface->MipmapTexture;
458848b8605Smrg      break;
459848b8605Smrg   case EGL_MIPMAP_LEVEL:
460848b8605Smrg      if (surface->Type == EGL_PBUFFER_BIT)
461848b8605Smrg         *value = surface->MipmapLevel;
462848b8605Smrg      break;
463848b8605Smrg   case EGL_SWAP_BEHAVIOR:
464848b8605Smrg      *value = surface->SwapBehavior;
465848b8605Smrg      break;
466848b8605Smrg   case EGL_RENDER_BUFFER:
467b8e80941Smrg      /* From the EGL_KHR_mutable_render_buffer spec (v12):
468b8e80941Smrg       *
469b8e80941Smrg       *    Querying EGL_RENDER_BUFFER returns the buffer which client API
470b8e80941Smrg       *    rendering is requested to use. For a window surface, this is the
471b8e80941Smrg       *    attribute value specified when the surface was created or last set
472b8e80941Smrg       *    via eglSurfaceAttrib.
473b8e80941Smrg       *
474b8e80941Smrg       * In other words, querying a window surface returns the value most
475b8e80941Smrg       * recently *requested* by the user.
476b8e80941Smrg       *
477b8e80941Smrg       * The paragraph continues in the EGL 1.5 spec (2014.08.27):
478b8e80941Smrg       *
479b8e80941Smrg       *    For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
480b8e80941Smrg       *    surface, it is always EGL_SINGLE_BUFFER . To determine the actual
481b8e80941Smrg       *    buffer being rendered to by a context, call eglQueryContext.
482b8e80941Smrg       */
483b8e80941Smrg      switch (surface->Type) {
484b8e80941Smrg      default:
485b8e80941Smrg         unreachable("bad EGLSurface type");
486b8e80941Smrg      case EGL_WINDOW_BIT:
487b8e80941Smrg         *value = surface->RequestedRenderBuffer;
488b8e80941Smrg         break;
489b8e80941Smrg      case EGL_PBUFFER_BIT:
490b8e80941Smrg         *value = EGL_BACK_BUFFER;
491b8e80941Smrg         break;
492b8e80941Smrg      case EGL_PIXMAP_BIT:
493b8e80941Smrg         *value = EGL_SINGLE_BUFFER;
494b8e80941Smrg         break;
495b8e80941Smrg      }
496848b8605Smrg      break;
497848b8605Smrg   case EGL_PIXEL_ASPECT_RATIO:
498848b8605Smrg      *value = surface->AspectRatio;
499848b8605Smrg      break;
500848b8605Smrg   case EGL_HORIZONTAL_RESOLUTION:
501848b8605Smrg      *value = surface->HorizontalResolution;
502848b8605Smrg      break;
503848b8605Smrg   case EGL_VERTICAL_RESOLUTION:
504848b8605Smrg      *value = surface->VerticalResolution;
505848b8605Smrg      break;
506848b8605Smrg   case EGL_MULTISAMPLE_RESOLVE:
507848b8605Smrg      *value = surface->MultisampleResolve;
508848b8605Smrg      break;
509848b8605Smrg   case EGL_VG_ALPHA_FORMAT:
510848b8605Smrg      *value = surface->VGAlphaFormat;
511848b8605Smrg      break;
512848b8605Smrg   case EGL_VG_COLORSPACE:
513848b8605Smrg      *value = surface->VGColorspace;
514848b8605Smrg      break;
515b8e80941Smrg   case EGL_GL_COLORSPACE_KHR:
516b8e80941Smrg      if (!disp->Extensions.KHR_gl_colorspace)
517b8e80941Smrg         return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
518b8e80941Smrg
519b8e80941Smrg      *value = surface->GLColorspace;
520b8e80941Smrg      break;
521848b8605Smrg   case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
522848b8605Smrg      *value = surface->PostSubBufferSupportedNV;
523848b8605Smrg      break;
524848b8605Smrg   case EGL_BUFFER_AGE_EXT:
525b8e80941Smrg      /* Both EXT_buffer_age and KHR_partial_update accept EGL_BUFFER_AGE_EXT.
526b8e80941Smrg       * To be precise, the KHR one accepts EGL_BUFFER_AGE_KHR which is an
527b8e80941Smrg       * alias with the same numeric value.
528b8e80941Smrg       */
529b8e80941Smrg      if (!disp->Extensions.EXT_buffer_age &&
530b8e80941Smrg          !disp->Extensions.KHR_partial_update)
531b8e80941Smrg         return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
532b8e80941Smrg
533b8e80941Smrg      _EGLContext *ctx = _eglGetCurrentContext();
534b8e80941Smrg      EGLint result = drv->API.QueryBufferAge(drv, disp, surface);
535b8e80941Smrg      /* error happened */
536b8e80941Smrg      if (result < 0)
537848b8605Smrg         return EGL_FALSE;
538b8e80941Smrg      if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
539b8e80941Smrg          ctx->DrawSurface != surface)
540b8e80941Smrg         return _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
541b8e80941Smrg
542b8e80941Smrg      *value = result;
543b8e80941Smrg      surface->BufferAgeRead = EGL_TRUE;
544b8e80941Smrg      break;
545b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
546b8e80941Smrg      *value = surface->HdrMetadata.display_primary_r.x;
547b8e80941Smrg      break;
548b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
549b8e80941Smrg      *value = surface->HdrMetadata.display_primary_r.y;
550b8e80941Smrg      break;
551b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
552b8e80941Smrg      *value = surface->HdrMetadata.display_primary_g.x;
553b8e80941Smrg      break;
554b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
555b8e80941Smrg      *value = surface->HdrMetadata.display_primary_g.y;
556b8e80941Smrg      break;
557b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
558b8e80941Smrg      *value = surface->HdrMetadata.display_primary_b.x;
559b8e80941Smrg      break;
560b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
561b8e80941Smrg      *value = surface->HdrMetadata.display_primary_b.y;
562b8e80941Smrg      break;
563b8e80941Smrg   case EGL_SMPTE2086_WHITE_POINT_X_EXT:
564b8e80941Smrg      *value = surface->HdrMetadata.white_point.x;
565b8e80941Smrg      break;
566b8e80941Smrg   case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
567b8e80941Smrg      *value = surface->HdrMetadata.white_point.y;
568b8e80941Smrg      break;
569b8e80941Smrg   case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
570b8e80941Smrg      *value = surface->HdrMetadata.max_luminance;
571b8e80941Smrg      break;
572b8e80941Smrg   case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
573b8e80941Smrg      *value = surface->HdrMetadata.min_luminance;
574b8e80941Smrg      break;
575b8e80941Smrg   case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
576b8e80941Smrg      *value = surface->HdrMetadata.max_cll;
577b8e80941Smrg      break;
578b8e80941Smrg   case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
579b8e80941Smrg      *value = surface->HdrMetadata.max_fall;
580848b8605Smrg      break;
581848b8605Smrg   default:
582b8e80941Smrg      return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
583848b8605Smrg   }
584848b8605Smrg
585848b8605Smrg   return EGL_TRUE;
586848b8605Smrg}
587848b8605Smrg
588848b8605Smrg
589848b8605Smrg/**
590848b8605Smrg * Default fallback routine - drivers might override this.
591848b8605Smrg */
592848b8605SmrgEGLBoolean
593b8e80941Smrg_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
594848b8605Smrg                  EGLint attribute, EGLint value)
595848b8605Smrg{
596848b8605Smrg   EGLint confval;
597848b8605Smrg   EGLint err = EGL_SUCCESS;
598848b8605Smrg   EGLint all_es_bits = EGL_OPENGL_ES_BIT |
599848b8605Smrg                        EGL_OPENGL_ES2_BIT |
600848b8605Smrg                        EGL_OPENGL_ES3_BIT_KHR;
601848b8605Smrg
602848b8605Smrg   switch (attribute) {
603848b8605Smrg   case EGL_MIPMAP_LEVEL:
604848b8605Smrg      confval = surface->Config->RenderableType;
605848b8605Smrg      if (!(confval & all_es_bits)) {
606848b8605Smrg         err = EGL_BAD_PARAMETER;
607848b8605Smrg         break;
608848b8605Smrg      }
609848b8605Smrg      surface->MipmapLevel = value;
610848b8605Smrg      break;
611848b8605Smrg   case EGL_MULTISAMPLE_RESOLVE:
612848b8605Smrg      switch (value) {
613848b8605Smrg      case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
614848b8605Smrg         break;
615848b8605Smrg      case EGL_MULTISAMPLE_RESOLVE_BOX:
616848b8605Smrg         confval = surface->Config->SurfaceType;
617848b8605Smrg         if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
618848b8605Smrg            err = EGL_BAD_MATCH;
619848b8605Smrg         break;
620848b8605Smrg      default:
621848b8605Smrg         err = EGL_BAD_ATTRIBUTE;
622848b8605Smrg         break;
623848b8605Smrg      }
624848b8605Smrg      if (err != EGL_SUCCESS)
625848b8605Smrg         break;
626848b8605Smrg      surface->MultisampleResolve = value;
627848b8605Smrg      break;
628b8e80941Smrg   case EGL_RENDER_BUFFER:
629b8e80941Smrg      if (!disp->Extensions.KHR_mutable_render_buffer) {
630b8e80941Smrg         err = EGL_BAD_ATTRIBUTE;
631b8e80941Smrg         break;
632b8e80941Smrg      }
633b8e80941Smrg
634b8e80941Smrg      if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) {
635b8e80941Smrg         err = EGL_BAD_PARAMETER;
636b8e80941Smrg         break;
637b8e80941Smrg      }
638b8e80941Smrg
639b8e80941Smrg      /* From the EGL_KHR_mutable_render_buffer spec (v12):
640b8e80941Smrg       *
641b8e80941Smrg       *    If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE
642b8e80941Smrg       *    attribute of the EGLConfig used to create surface does not contain
643b8e80941Smrg       *    EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is
644b8e80941Smrg       *    generated [...].
645b8e80941Smrg       */
646b8e80941Smrg      if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) {
647b8e80941Smrg         err = EGL_BAD_MATCH;
648b8e80941Smrg         break;
649b8e80941Smrg      }
650b8e80941Smrg
651b8e80941Smrg      surface->RequestedRenderBuffer = value;
652b8e80941Smrg      break;
653848b8605Smrg   case EGL_SWAP_BEHAVIOR:
654848b8605Smrg      switch (value) {
655848b8605Smrg      case EGL_BUFFER_DESTROYED:
656848b8605Smrg         break;
657848b8605Smrg      case EGL_BUFFER_PRESERVED:
658848b8605Smrg         confval = surface->Config->SurfaceType;
659848b8605Smrg         if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
660848b8605Smrg            err = EGL_BAD_MATCH;
661848b8605Smrg         break;
662848b8605Smrg      default:
663848b8605Smrg         err = EGL_BAD_ATTRIBUTE;
664848b8605Smrg         break;
665848b8605Smrg      }
666848b8605Smrg      if (err != EGL_SUCCESS)
667848b8605Smrg         break;
668848b8605Smrg      surface->SwapBehavior = value;
669848b8605Smrg      break;
670b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
671b8e80941Smrg      surface->HdrMetadata.display_primary_r.x = value;
672b8e80941Smrg      break;
673b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
674b8e80941Smrg      surface->HdrMetadata.display_primary_r.y = value;
675b8e80941Smrg      break;
676b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
677b8e80941Smrg      surface->HdrMetadata.display_primary_g.x = value;
678b8e80941Smrg      break;
679b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
680b8e80941Smrg      surface->HdrMetadata.display_primary_g.y = value;
681b8e80941Smrg      break;
682b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
683b8e80941Smrg      surface->HdrMetadata.display_primary_b.x = value;
684b8e80941Smrg      break;
685b8e80941Smrg   case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
686b8e80941Smrg      surface->HdrMetadata.display_primary_b.y = value;
687b8e80941Smrg      break;
688b8e80941Smrg   case EGL_SMPTE2086_WHITE_POINT_X_EXT:
689b8e80941Smrg      surface->HdrMetadata.white_point.x = value;
690b8e80941Smrg      break;
691b8e80941Smrg   case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
692b8e80941Smrg      surface->HdrMetadata.white_point.y = value;
693b8e80941Smrg      break;
694b8e80941Smrg   case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
695b8e80941Smrg      surface->HdrMetadata.max_luminance = value;
696b8e80941Smrg      break;
697b8e80941Smrg   case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
698b8e80941Smrg      surface->HdrMetadata.min_luminance = value;
699b8e80941Smrg      break;
700b8e80941Smrg   case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
701b8e80941Smrg      surface->HdrMetadata.max_cll = value;
702b8e80941Smrg      break;
703b8e80941Smrg   case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
704b8e80941Smrg      surface->HdrMetadata.max_fall = value;
705b8e80941Smrg      break;
706848b8605Smrg   default:
707848b8605Smrg      err = EGL_BAD_ATTRIBUTE;
708848b8605Smrg      break;
709848b8605Smrg   }
710848b8605Smrg
711848b8605Smrg   if (err != EGL_SUCCESS)
712848b8605Smrg      return _eglError(err, "eglSurfaceAttrib");
713848b8605Smrg   return EGL_TRUE;
714848b8605Smrg}
715848b8605Smrg
716848b8605Smrg
717848b8605SmrgEGLBoolean
718b8e80941Smrg_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
719848b8605Smrg                 EGLint buffer)
720848b8605Smrg{
721848b8605Smrg   EGLint texture_type = EGL_PBUFFER_BIT;
722848b8605Smrg
723848b8605Smrg   /* Just do basic error checking and return success/fail.
724848b8605Smrg    * Drivers must implement the real stuff.
725848b8605Smrg    */
726848b8605Smrg
727b8e80941Smrg   if (disp->Extensions.NOK_texture_from_pixmap)
728848b8605Smrg      texture_type |= EGL_PIXMAP_BIT;
729848b8605Smrg
730b8e80941Smrg   if (!(surface->Type & texture_type))
731b8e80941Smrg      return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
732848b8605Smrg
733b8e80941Smrg   if (surface->TextureFormat == EGL_NO_TEXTURE)
734b8e80941Smrg      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
735848b8605Smrg
736b8e80941Smrg   if (surface->TextureTarget == EGL_NO_TEXTURE)
737b8e80941Smrg      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
738848b8605Smrg
739b8e80941Smrg   if (buffer != EGL_BACK_BUFFER)
740b8e80941Smrg      return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
741848b8605Smrg
742848b8605Smrg   surface->BoundToTexture = EGL_TRUE;
743848b8605Smrg
744848b8605Smrg   return EGL_TRUE;
745848b8605Smrg}
746848b8605Smrg
747848b8605SmrgEGLBoolean
748848b8605Smrg_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
749848b8605Smrg                    EGLint buffer)
750848b8605Smrg{
751b8e80941Smrg   /* Just do basic error checking and return success/fail.
752848b8605Smrg    * Drivers must implement the real stuff.
753848b8605Smrg    */
754848b8605Smrg
755b8e80941Smrg   EGLint texture_type = EGL_PBUFFER_BIT;
756b8e80941Smrg
757b8e80941Smrg   if (surf == EGL_NO_SURFACE)
758b8e80941Smrg      return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
759b8e80941Smrg
760b8e80941Smrg   if (!surf->BoundToTexture)
761b8e80941Smrg   {
762b8e80941Smrg      /* Not an error, simply nothing to do */
763b8e80941Smrg      return EGL_TRUE;
764b8e80941Smrg   }
765b8e80941Smrg
766b8e80941Smrg   if (surf->TextureFormat == EGL_NO_TEXTURE)
767b8e80941Smrg      return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage");
768b8e80941Smrg
769b8e80941Smrg   if (buffer != EGL_BACK_BUFFER)
770b8e80941Smrg      return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
771b8e80941Smrg
772b8e80941Smrg   if (disp->Extensions.NOK_texture_from_pixmap)
773b8e80941Smrg      texture_type |= EGL_PIXMAP_BIT;
774b8e80941Smrg
775b8e80941Smrg   if (!(surf->Type & texture_type))
776b8e80941Smrg      return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
777b8e80941Smrg
778b8e80941Smrg   surf->BoundToTexture = EGL_FALSE;
779b8e80941Smrg
780b8e80941Smrg   return EGL_TRUE;
781848b8605Smrg}
782848b8605Smrg
783848b8605Smrg
784848b8605SmrgEGLBoolean
785b8e80941Smrg_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
786848b8605Smrg                 EGLint interval)
787848b8605Smrg{
788848b8605Smrg   return EGL_TRUE;
789848b8605Smrg}
790b8e80941Smrg
791b8e80941SmrgEGLBoolean
792b8e80941Smrg_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf)
793b8e80941Smrg{
794b8e80941Smrg   return surf->Type == EGL_WINDOW_BIT &&
795b8e80941Smrg          surf->Config &&
796b8e80941Smrg          (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR);
797b8e80941Smrg}
798b8e80941Smrg
799b8e80941SmrgEGLBoolean
800b8e80941Smrg_eglSurfaceInSharedBufferMode(_EGLSurface *surf)
801b8e80941Smrg{
802b8e80941Smrg   return _eglSurfaceHasMutableRenderBuffer(surf) &&
803b8e80941Smrg          surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER;
804b8e80941Smrg}
805