1 /**************************************************************************
2 *
3 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
4 * Copyright 2010-2011 LunarG, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29
30 #include <assert.h>
31 #include <string.h>
32
33 #include "eglcurrent.h"
34 #include "eglimage.h"
35 #include "egllog.h"
36
37 static EGLint
_eglParseKHRImageAttribs(_EGLImageAttribs * attrs,_EGLDisplay * disp,EGLint attr,EGLint val)38 _eglParseKHRImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
39 EGLint attr, EGLint val)
40 {
41 switch (attr) {
42 case EGL_IMAGE_PRESERVED_KHR:
43 if (!disp->Extensions.KHR_image_base)
44 return EGL_BAD_PARAMETER;
45
46 attrs->ImagePreserved = val;
47 break;
48
49 case EGL_GL_TEXTURE_LEVEL_KHR:
50 if (!disp->Extensions.KHR_gl_texture_2D_image)
51 return EGL_BAD_PARAMETER;
52
53 attrs->GLTextureLevel = val;
54 break;
55 case EGL_GL_TEXTURE_ZOFFSET_KHR:
56 if (!disp->Extensions.KHR_gl_texture_3D_image)
57 return EGL_BAD_PARAMETER;
58
59 attrs->GLTextureZOffset = val;
60 break;
61 case EGL_PROTECTED_CONTENT_EXT:
62 if (!disp->Extensions.EXT_protected_surface)
63 return EGL_BAD_PARAMETER;
64
65 attrs->ProtectedContent = val;
66 break;
67 default:
68 return EGL_BAD_PARAMETER;
69 }
70
71 return EGL_SUCCESS;
72 }
73
74 static EGLint
_eglParseMESADrmImageAttribs(_EGLImageAttribs * attrs,_EGLDisplay * disp,EGLint attr,EGLint val)75 _eglParseMESADrmImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
76 EGLint attr, EGLint val)
77 {
78 if (!disp->Extensions.MESA_drm_image)
79 return EGL_BAD_PARAMETER;
80
81 switch (attr) {
82 case EGL_WIDTH:
83 attrs->Width = val;
84 break;
85 case EGL_HEIGHT:
86 attrs->Height = val;
87 break;
88 case EGL_DRM_BUFFER_FORMAT_MESA:
89 attrs->DRMBufferFormatMESA = val;
90 break;
91 case EGL_DRM_BUFFER_USE_MESA:
92 attrs->DRMBufferUseMESA = val;
93 break;
94 case EGL_DRM_BUFFER_STRIDE_MESA:
95 attrs->DRMBufferStrideMESA = val;
96 break;
97 default:
98 return EGL_BAD_PARAMETER;
99 }
100
101 return EGL_SUCCESS;
102 }
103
104 static EGLint
_eglParseWLBindWaylandDisplayAttribs(_EGLImageAttribs * attrs,_EGLDisplay * disp,EGLint attr,EGLint val)105 _eglParseWLBindWaylandDisplayAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
106 EGLint attr, EGLint val)
107 {
108 if (!disp->Extensions.WL_bind_wayland_display)
109 return EGL_BAD_PARAMETER;
110
111 switch (attr) {
112 case EGL_WAYLAND_PLANE_WL:
113 attrs->PlaneWL = val;
114 break;
115 default:
116 return EGL_BAD_PARAMETER;
117 }
118
119 return EGL_SUCCESS;
120 }
121
122 static EGLint
_eglParseEXTImageDmaBufImportAttribs(_EGLImageAttribs * attrs,_EGLDisplay * disp,EGLint attr,EGLint val)123 _eglParseEXTImageDmaBufImportAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
124 EGLint attr, EGLint val)
125 {
126 if (!disp->Extensions.EXT_image_dma_buf_import)
127 return EGL_BAD_PARAMETER;
128
129 switch (attr) {
130 case EGL_WIDTH:
131 attrs->Width = val;
132 break;
133 case EGL_HEIGHT:
134 attrs->Height = val;
135 break;
136 case EGL_LINUX_DRM_FOURCC_EXT:
137 attrs->DMABufFourCC.Value = val;
138 attrs->DMABufFourCC.IsPresent = EGL_TRUE;
139 break;
140 case EGL_DMA_BUF_PLANE0_FD_EXT:
141 attrs->DMABufPlaneFds[0].Value = val;
142 attrs->DMABufPlaneFds[0].IsPresent = EGL_TRUE;
143 break;
144 case EGL_DMA_BUF_PLANE0_OFFSET_EXT:
145 attrs->DMABufPlaneOffsets[0].Value = val;
146 attrs->DMABufPlaneOffsets[0].IsPresent = EGL_TRUE;
147 break;
148 case EGL_DMA_BUF_PLANE0_PITCH_EXT:
149 attrs->DMABufPlanePitches[0].Value = val;
150 attrs->DMABufPlanePitches[0].IsPresent = EGL_TRUE;
151 break;
152 case EGL_DMA_BUF_PLANE1_FD_EXT:
153 attrs->DMABufPlaneFds[1].Value = val;
154 attrs->DMABufPlaneFds[1].IsPresent = EGL_TRUE;
155 break;
156 case EGL_DMA_BUF_PLANE1_OFFSET_EXT:
157 attrs->DMABufPlaneOffsets[1].Value = val;
158 attrs->DMABufPlaneOffsets[1].IsPresent = EGL_TRUE;
159 break;
160 case EGL_DMA_BUF_PLANE1_PITCH_EXT:
161 attrs->DMABufPlanePitches[1].Value = val;
162 attrs->DMABufPlanePitches[1].IsPresent = EGL_TRUE;
163 break;
164 case EGL_DMA_BUF_PLANE2_FD_EXT:
165 attrs->DMABufPlaneFds[2].Value = val;
166 attrs->DMABufPlaneFds[2].IsPresent = EGL_TRUE;
167 break;
168 case EGL_DMA_BUF_PLANE2_OFFSET_EXT:
169 attrs->DMABufPlaneOffsets[2].Value = val;
170 attrs->DMABufPlaneOffsets[2].IsPresent = EGL_TRUE;
171 break;
172 case EGL_DMA_BUF_PLANE2_PITCH_EXT:
173 attrs->DMABufPlanePitches[2].Value = val;
174 attrs->DMABufPlanePitches[2].IsPresent = EGL_TRUE;
175 break;
176 case EGL_YUV_COLOR_SPACE_HINT_EXT:
177 if (val != EGL_ITU_REC601_EXT && val != EGL_ITU_REC709_EXT &&
178 val != EGL_ITU_REC2020_EXT)
179 return EGL_BAD_ATTRIBUTE;
180
181 attrs->DMABufYuvColorSpaceHint.Value = val;
182 attrs->DMABufYuvColorSpaceHint.IsPresent = EGL_TRUE;
183 break;
184 case EGL_SAMPLE_RANGE_HINT_EXT:
185 if (val != EGL_YUV_FULL_RANGE_EXT && val != EGL_YUV_NARROW_RANGE_EXT)
186 return EGL_BAD_ATTRIBUTE;
187
188 attrs->DMABufSampleRangeHint.Value = val;
189 attrs->DMABufSampleRangeHint.IsPresent = EGL_TRUE;
190 break;
191 case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT:
192 if (val != EGL_YUV_CHROMA_SITING_0_EXT &&
193 val != EGL_YUV_CHROMA_SITING_0_5_EXT)
194 return EGL_BAD_ATTRIBUTE;
195
196 attrs->DMABufChromaHorizontalSiting.Value = val;
197 attrs->DMABufChromaHorizontalSiting.IsPresent = EGL_TRUE;
198 break;
199 case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT:
200 if (val != EGL_YUV_CHROMA_SITING_0_EXT &&
201 val != EGL_YUV_CHROMA_SITING_0_5_EXT)
202 return EGL_BAD_ATTRIBUTE;
203
204 attrs->DMABufChromaVerticalSiting.Value = val;
205 attrs->DMABufChromaVerticalSiting.IsPresent = EGL_TRUE;
206 break;
207 default:
208 return EGL_BAD_PARAMETER;
209 }
210
211 return EGL_SUCCESS;
212 }
213
214 static EGLint
_eglParseEXTImageDmaBufImportModifiersAttribs(_EGLImageAttribs * attrs,_EGLDisplay * disp,EGLint attr,EGLint val)215 _eglParseEXTImageDmaBufImportModifiersAttribs(_EGLImageAttribs *attrs,
216 _EGLDisplay *disp,
217 EGLint attr, EGLint val)
218 {
219 if (!disp->Extensions.EXT_image_dma_buf_import_modifiers)
220 return EGL_BAD_PARAMETER;
221
222 switch (attr) {
223 case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
224 attrs->DMABufPlaneModifiersLo[0].Value = val;
225 attrs->DMABufPlaneModifiersLo[0].IsPresent = EGL_TRUE;
226 break;
227 case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
228 attrs->DMABufPlaneModifiersHi[0].Value = val;
229 attrs->DMABufPlaneModifiersHi[0].IsPresent = EGL_TRUE;
230 break;
231 case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
232 attrs->DMABufPlaneModifiersLo[1].Value = val;
233 attrs->DMABufPlaneModifiersLo[1].IsPresent = EGL_TRUE;
234 break;
235 case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
236 attrs->DMABufPlaneModifiersHi[1].Value = val;
237 attrs->DMABufPlaneModifiersHi[1].IsPresent = EGL_TRUE;
238 break;
239 case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
240 attrs->DMABufPlaneModifiersLo[2].Value = val;
241 attrs->DMABufPlaneModifiersLo[2].IsPresent = EGL_TRUE;
242 break;
243 case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
244 attrs->DMABufPlaneModifiersHi[2].Value = val;
245 attrs->DMABufPlaneModifiersHi[2].IsPresent = EGL_TRUE;
246 break;
247 case EGL_DMA_BUF_PLANE3_FD_EXT:
248 attrs->DMABufPlaneFds[3].Value = val;
249 attrs->DMABufPlaneFds[3].IsPresent = EGL_TRUE;
250 break;
251 case EGL_DMA_BUF_PLANE3_OFFSET_EXT:
252 attrs->DMABufPlaneOffsets[3].Value = val;
253 attrs->DMABufPlaneOffsets[3].IsPresent = EGL_TRUE;
254 break;
255 case EGL_DMA_BUF_PLANE3_PITCH_EXT:
256 attrs->DMABufPlanePitches[3].Value = val;
257 attrs->DMABufPlanePitches[3].IsPresent = EGL_TRUE;
258 break;
259 case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
260 attrs->DMABufPlaneModifiersLo[3].Value = val;
261 attrs->DMABufPlaneModifiersLo[3].IsPresent = EGL_TRUE;
262 break;
263 case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT:
264 attrs->DMABufPlaneModifiersHi[3].Value = val;
265 attrs->DMABufPlaneModifiersHi[3].IsPresent = EGL_TRUE;
266 break;
267 default:
268 return EGL_BAD_PARAMETER;
269 }
270
271 return EGL_SUCCESS;
272 }
273
274 /**
275 * Parse the list of image attributes.
276 *
277 * Returns EGL_TRUE on success and EGL_FALSE otherwise.
278 * Function calls _eglError to set the correct error code.
279 */
280 EGLBoolean
_eglParseImageAttribList(_EGLImageAttribs * attrs,_EGLDisplay * disp,const EGLint * attrib_list)281 _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *disp,
282 const EGLint *attrib_list)
283 {
284 EGLint i, err;
285
286 memset(attrs, 0, sizeof(*attrs));
287
288 if (!attrib_list)
289 return EGL_TRUE;
290
291 for (i = 0; attrib_list[i] != EGL_NONE; i++) {
292 EGLint attr = attrib_list[i++];
293 EGLint val = attrib_list[i];
294
295 err = _eglParseKHRImageAttribs(attrs, disp, attr, val);
296 if (err == EGL_SUCCESS)
297 continue;
298
299 err = _eglParseMESADrmImageAttribs(attrs, disp, attr, val);
300 if (err == EGL_SUCCESS)
301 continue;
302
303 err = _eglParseWLBindWaylandDisplayAttribs(attrs, disp, attr, val);
304 if (err == EGL_SUCCESS)
305 continue;
306
307 err = _eglParseEXTImageDmaBufImportAttribs(attrs, disp, attr, val);
308 if (err == EGL_SUCCESS)
309 continue;
310
311 /* EXT_image_dma_buf_import states that if invalid value is provided for
312 * its attributes, we should return EGL_BAD_ATTRIBUTE.
313 * Bail out ASAP, since follow-up calls can return another EGL_BAD error.
314 */
315 if (err == EGL_BAD_ATTRIBUTE)
316 return _eglError(err, __func__);
317
318 err = _eglParseEXTImageDmaBufImportModifiersAttribs(attrs, disp, attr, val);
319 if (err == EGL_SUCCESS)
320 continue;
321
322 return _eglError(err, __func__);
323 }
324
325 return EGL_TRUE;
326 }
327