egl: split _eglParseImageAttribList into per extension functions
[mesa.git] / src / egl / main / eglimage.c
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
38 _eglParseKHRImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
39 EGLint attr, EGLint val)
40 {
41 switch (attr) {
42 /* EGL_KHR_image_base */
43 case EGL_IMAGE_PRESERVED_KHR:
44 attrs->ImagePreserved = val;
45 break;
46
47 /* EGL_KHR_gl_image */
48 case EGL_GL_TEXTURE_LEVEL_KHR:
49 attrs->GLTextureLevel = val;
50 break;
51 case EGL_GL_TEXTURE_ZOFFSET_KHR:
52 attrs->GLTextureZOffset = val;
53 break;
54 default:
55 return EGL_BAD_PARAMETER;
56 }
57
58 return EGL_SUCCESS;
59 }
60
61 static EGLint
62 _eglParseMESADrmImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
63 EGLint attr, EGLint val)
64 {
65 switch (attr) {
66 /* EGL_MESA_drm_image */
67 case EGL_WIDTH:
68 attrs->Width = val;
69 break;
70 case EGL_HEIGHT:
71 attrs->Height = val;
72 break;
73 case EGL_DRM_BUFFER_FORMAT_MESA:
74 attrs->DRMBufferFormatMESA = val;
75 break;
76 case EGL_DRM_BUFFER_USE_MESA:
77 attrs->DRMBufferUseMESA = val;
78 break;
79 case EGL_DRM_BUFFER_STRIDE_MESA:
80 attrs->DRMBufferStrideMESA = val;
81 break;
82 default:
83 return EGL_BAD_PARAMETER;
84 }
85
86 return EGL_SUCCESS;
87 }
88
89 static EGLint
90 _eglParseWLBindWaylandDisplayAttribs(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
91 EGLint attr, EGLint val)
92 {
93 switch (attr) {
94 /* EGL_WL_bind_wayland_display */
95 case EGL_WAYLAND_PLANE_WL:
96 attrs->PlaneWL = val;
97 break;
98 default:
99 return EGL_BAD_PARAMETER;
100 }
101
102 return EGL_SUCCESS;
103 }
104
105 static EGLint
106 _eglParseEXTImageDmaBufImportAttribs(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
107 EGLint attr, EGLint val)
108 {
109 EGLint err = EGL_SUCCESS;
110
111 switch (attr) {
112 case EGL_LINUX_DRM_FOURCC_EXT:
113 attrs->DMABufFourCC.Value = val;
114 attrs->DMABufFourCC.IsPresent = EGL_TRUE;
115 break;
116 case EGL_DMA_BUF_PLANE0_FD_EXT:
117 attrs->DMABufPlaneFds[0].Value = val;
118 attrs->DMABufPlaneFds[0].IsPresent = EGL_TRUE;
119 break;
120 case EGL_DMA_BUF_PLANE0_OFFSET_EXT:
121 attrs->DMABufPlaneOffsets[0].Value = val;
122 attrs->DMABufPlaneOffsets[0].IsPresent = EGL_TRUE;
123 break;
124 case EGL_DMA_BUF_PLANE0_PITCH_EXT:
125 attrs->DMABufPlanePitches[0].Value = val;
126 attrs->DMABufPlanePitches[0].IsPresent = EGL_TRUE;
127 break;
128 case EGL_DMA_BUF_PLANE1_FD_EXT:
129 attrs->DMABufPlaneFds[1].Value = val;
130 attrs->DMABufPlaneFds[1].IsPresent = EGL_TRUE;
131 break;
132 case EGL_DMA_BUF_PLANE1_OFFSET_EXT:
133 attrs->DMABufPlaneOffsets[1].Value = val;
134 attrs->DMABufPlaneOffsets[1].IsPresent = EGL_TRUE;
135 break;
136 case EGL_DMA_BUF_PLANE1_PITCH_EXT:
137 attrs->DMABufPlanePitches[1].Value = val;
138 attrs->DMABufPlanePitches[1].IsPresent = EGL_TRUE;
139 break;
140 case EGL_DMA_BUF_PLANE2_FD_EXT:
141 attrs->DMABufPlaneFds[2].Value = val;
142 attrs->DMABufPlaneFds[2].IsPresent = EGL_TRUE;
143 break;
144 case EGL_DMA_BUF_PLANE2_OFFSET_EXT:
145 attrs->DMABufPlaneOffsets[2].Value = val;
146 attrs->DMABufPlaneOffsets[2].IsPresent = EGL_TRUE;
147 break;
148 case EGL_DMA_BUF_PLANE2_PITCH_EXT:
149 attrs->DMABufPlanePitches[2].Value = val;
150 attrs->DMABufPlanePitches[2].IsPresent = EGL_TRUE;
151 break;
152 case EGL_YUV_COLOR_SPACE_HINT_EXT:
153 if (val != EGL_ITU_REC601_EXT && val != EGL_ITU_REC709_EXT &&
154 val != EGL_ITU_REC2020_EXT) {
155 err = EGL_BAD_ATTRIBUTE;
156 } else {
157 attrs->DMABufYuvColorSpaceHint.Value = val;
158 attrs->DMABufYuvColorSpaceHint.IsPresent = EGL_TRUE;
159 }
160 break;
161 case EGL_SAMPLE_RANGE_HINT_EXT:
162 if (val != EGL_YUV_FULL_RANGE_EXT && val != EGL_YUV_NARROW_RANGE_EXT) {
163 err = EGL_BAD_ATTRIBUTE;
164 } else {
165 attrs->DMABufSampleRangeHint.Value = val;
166 attrs->DMABufSampleRangeHint.IsPresent = EGL_TRUE;
167 }
168 break;
169 case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT:
170 if (val != EGL_YUV_CHROMA_SITING_0_EXT &&
171 val != EGL_YUV_CHROMA_SITING_0_5_EXT) {
172 err = EGL_BAD_ATTRIBUTE;
173 } else {
174 attrs->DMABufChromaHorizontalSiting.Value = val;
175 attrs->DMABufChromaHorizontalSiting.IsPresent = EGL_TRUE;
176 }
177 break;
178 case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT:
179 if (val != EGL_YUV_CHROMA_SITING_0_EXT &&
180 val != EGL_YUV_CHROMA_SITING_0_5_EXT) {
181 err = EGL_BAD_ATTRIBUTE;
182 } else {
183 attrs->DMABufChromaVerticalSiting.Value = val;
184 attrs->DMABufChromaVerticalSiting.IsPresent = EGL_TRUE;
185 }
186 break;
187 default:
188 err = EGL_BAD_PARAMETER;
189 break;
190 }
191
192 return err;
193 }
194
195 static EGLint
196 _eglParseEXTImageDmaBufImportModifiersAttribs(_EGLImageAttribs *attrs,
197 _EGLDisplay *dpy,
198 EGLint attr, EGLint val)
199 {
200 EGLint err = EGL_SUCCESS;
201
202 switch (attr) {
203 case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
204 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
205 err = EGL_BAD_PARAMETER;
206 attrs->DMABufPlaneModifiersLo[0].Value = val;
207 attrs->DMABufPlaneModifiersLo[0].IsPresent = EGL_TRUE;
208 break;
209 case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
210 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
211 err = EGL_BAD_PARAMETER;
212 attrs->DMABufPlaneModifiersHi[0].Value = val;
213 attrs->DMABufPlaneModifiersHi[0].IsPresent = EGL_TRUE;
214 break;
215 case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
216 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
217 err = EGL_BAD_PARAMETER;
218 attrs->DMABufPlaneModifiersLo[1].Value = val;
219 attrs->DMABufPlaneModifiersLo[1].IsPresent = EGL_TRUE;
220 break;
221 case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
222 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
223 err = EGL_BAD_PARAMETER;
224 attrs->DMABufPlaneModifiersHi[1].Value = val;
225 attrs->DMABufPlaneModifiersHi[1].IsPresent = EGL_TRUE;
226 break;
227 case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
228 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
229 err = EGL_BAD_PARAMETER;
230 attrs->DMABufPlaneModifiersLo[2].Value = val;
231 attrs->DMABufPlaneModifiersLo[2].IsPresent = EGL_TRUE;
232 break;
233 case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
234 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
235 err = EGL_BAD_PARAMETER;
236 attrs->DMABufPlaneModifiersHi[2].Value = val;
237 attrs->DMABufPlaneModifiersHi[2].IsPresent = EGL_TRUE;
238 break;
239 case EGL_DMA_BUF_PLANE3_FD_EXT:
240 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
241 err = EGL_BAD_PARAMETER;
242 attrs->DMABufPlaneFds[3].Value = val;
243 attrs->DMABufPlaneFds[3].IsPresent = EGL_TRUE;
244 break;
245 case EGL_DMA_BUF_PLANE3_OFFSET_EXT:
246 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
247 err = EGL_BAD_PARAMETER;
248 attrs->DMABufPlaneOffsets[3].Value = val;
249 attrs->DMABufPlaneOffsets[3].IsPresent = EGL_TRUE;
250 break;
251 case EGL_DMA_BUF_PLANE3_PITCH_EXT:
252 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
253 err = EGL_BAD_PARAMETER;
254 attrs->DMABufPlanePitches[3].Value = val;
255 attrs->DMABufPlanePitches[3].IsPresent = EGL_TRUE;
256 break;
257 case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
258 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
259 err = EGL_BAD_PARAMETER;
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 if (!dpy->Extensions.EXT_image_dma_buf_import_modifiers)
265 err = EGL_BAD_PARAMETER;
266 attrs->DMABufPlaneModifiersHi[3].Value = val;
267 attrs->DMABufPlaneModifiersHi[3].IsPresent = EGL_TRUE;
268 break;
269 default:
270 err = EGL_BAD_PARAMETER;
271 break;
272 }
273
274 return err;
275 }
276
277 /**
278 * Parse the list of image attributes.
279 *
280 * Returns EGL_TRUE on success and EGL_FALSE otherwise.
281 * Function calls _eglError to set the correct error code.
282 */
283 EGLBoolean
284 _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
285 const EGLint *attrib_list)
286 {
287 EGLint i, err;
288
289 memset(attrs, 0, sizeof(*attrs));
290
291 if (!attrib_list)
292 return EGL_TRUE;
293
294 for (i = 0; attrib_list[i] != EGL_NONE; i++) {
295 EGLint attr = attrib_list[i++];
296 EGLint val = attrib_list[i];
297
298 err = _eglParseKHRImageAttribs(attrs, dpy, attr, val);
299 if (err == EGL_SUCCESS)
300 continue;
301
302 err = _eglParseMESADrmImageAttribs(attrs, dpy, attr, val);
303 if (err == EGL_SUCCESS)
304 continue;
305
306 err = _eglParseWLBindWaylandDisplayAttribs(attrs, dpy, attr, val);
307 if (err == EGL_SUCCESS)
308 continue;
309
310 err = _eglParseEXTImageDmaBufImportAttribs(attrs, dpy, attr, val);
311 if (err == EGL_SUCCESS)
312 continue;
313
314 err = _eglParseEXTImageDmaBufImportModifiersAttribs(attrs, dpy, attr, val);
315 if (err == EGL_SUCCESS)
316 continue;
317
318 return _eglError(err, __func__);
319 }
320
321 return EGL_TRUE;
322 }