egl: handle EGL_IMAGE_EXTERNAL_FLUSH_EXT
[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 *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 default:
62 return EGL_BAD_PARAMETER;
63 }
64
65 return EGL_SUCCESS;
66 }
67
68 static EGLint
69 _eglParseMESADrmImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
70 EGLint attr, EGLint val)
71 {
72 if (!disp->Extensions.MESA_drm_image)
73 return EGL_BAD_PARAMETER;
74
75 switch (attr) {
76 case EGL_WIDTH:
77 attrs->Width = val;
78 break;
79 case EGL_HEIGHT:
80 attrs->Height = val;
81 break;
82 case EGL_DRM_BUFFER_FORMAT_MESA:
83 attrs->DRMBufferFormatMESA = val;
84 break;
85 case EGL_DRM_BUFFER_USE_MESA:
86 attrs->DRMBufferUseMESA = val;
87 break;
88 case EGL_DRM_BUFFER_STRIDE_MESA:
89 attrs->DRMBufferStrideMESA = val;
90 break;
91 default:
92 return EGL_BAD_PARAMETER;
93 }
94
95 return EGL_SUCCESS;
96 }
97
98 static EGLint
99 _eglParseWLBindWaylandDisplayAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
100 EGLint attr, EGLint val)
101 {
102 if (!disp->Extensions.WL_bind_wayland_display)
103 return EGL_BAD_PARAMETER;
104
105 switch (attr) {
106 case EGL_WAYLAND_PLANE_WL:
107 attrs->PlaneWL = val;
108 break;
109 default:
110 return EGL_BAD_PARAMETER;
111 }
112
113 return EGL_SUCCESS;
114 }
115
116 static EGLint
117 _eglParseEXTImageDmaBufImportAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
118 EGLint attr, EGLint val)
119 {
120 if (!disp->Extensions.EXT_image_dma_buf_import)
121 return EGL_BAD_PARAMETER;
122
123 switch (attr) {
124 case EGL_WIDTH:
125 attrs->Width = val;
126 break;
127 case EGL_HEIGHT:
128 attrs->Height = val;
129 break;
130 case EGL_LINUX_DRM_FOURCC_EXT:
131 attrs->DMABufFourCC.Value = val;
132 attrs->DMABufFourCC.IsPresent = EGL_TRUE;
133 break;
134 case EGL_DMA_BUF_PLANE0_FD_EXT:
135 attrs->DMABufPlaneFds[0].Value = val;
136 attrs->DMABufPlaneFds[0].IsPresent = EGL_TRUE;
137 break;
138 case EGL_DMA_BUF_PLANE0_OFFSET_EXT:
139 attrs->DMABufPlaneOffsets[0].Value = val;
140 attrs->DMABufPlaneOffsets[0].IsPresent = EGL_TRUE;
141 break;
142 case EGL_DMA_BUF_PLANE0_PITCH_EXT:
143 attrs->DMABufPlanePitches[0].Value = val;
144 attrs->DMABufPlanePitches[0].IsPresent = EGL_TRUE;
145 break;
146 case EGL_DMA_BUF_PLANE1_FD_EXT:
147 attrs->DMABufPlaneFds[1].Value = val;
148 attrs->DMABufPlaneFds[1].IsPresent = EGL_TRUE;
149 break;
150 case EGL_DMA_BUF_PLANE1_OFFSET_EXT:
151 attrs->DMABufPlaneOffsets[1].Value = val;
152 attrs->DMABufPlaneOffsets[1].IsPresent = EGL_TRUE;
153 break;
154 case EGL_DMA_BUF_PLANE1_PITCH_EXT:
155 attrs->DMABufPlanePitches[1].Value = val;
156 attrs->DMABufPlanePitches[1].IsPresent = EGL_TRUE;
157 break;
158 case EGL_DMA_BUF_PLANE2_FD_EXT:
159 attrs->DMABufPlaneFds[2].Value = val;
160 attrs->DMABufPlaneFds[2].IsPresent = EGL_TRUE;
161 break;
162 case EGL_DMA_BUF_PLANE2_OFFSET_EXT:
163 attrs->DMABufPlaneOffsets[2].Value = val;
164 attrs->DMABufPlaneOffsets[2].IsPresent = EGL_TRUE;
165 break;
166 case EGL_DMA_BUF_PLANE2_PITCH_EXT:
167 attrs->DMABufPlanePitches[2].Value = val;
168 attrs->DMABufPlanePitches[2].IsPresent = EGL_TRUE;
169 break;
170 case EGL_YUV_COLOR_SPACE_HINT_EXT:
171 if (val != EGL_ITU_REC601_EXT && val != EGL_ITU_REC709_EXT &&
172 val != EGL_ITU_REC2020_EXT)
173 return EGL_BAD_ATTRIBUTE;
174
175 attrs->DMABufYuvColorSpaceHint.Value = val;
176 attrs->DMABufYuvColorSpaceHint.IsPresent = EGL_TRUE;
177 break;
178 case EGL_SAMPLE_RANGE_HINT_EXT:
179 if (val != EGL_YUV_FULL_RANGE_EXT && val != EGL_YUV_NARROW_RANGE_EXT)
180 return EGL_BAD_ATTRIBUTE;
181
182 attrs->DMABufSampleRangeHint.Value = val;
183 attrs->DMABufSampleRangeHint.IsPresent = EGL_TRUE;
184 break;
185 case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT:
186 if (val != EGL_YUV_CHROMA_SITING_0_EXT &&
187 val != EGL_YUV_CHROMA_SITING_0_5_EXT)
188 return EGL_BAD_ATTRIBUTE;
189
190 attrs->DMABufChromaHorizontalSiting.Value = val;
191 attrs->DMABufChromaHorizontalSiting.IsPresent = EGL_TRUE;
192 break;
193 case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT:
194 if (val != EGL_YUV_CHROMA_SITING_0_EXT &&
195 val != EGL_YUV_CHROMA_SITING_0_5_EXT)
196 return EGL_BAD_ATTRIBUTE;
197
198 attrs->DMABufChromaVerticalSiting.Value = val;
199 attrs->DMABufChromaVerticalSiting.IsPresent = EGL_TRUE;
200 break;
201 default:
202 return EGL_BAD_PARAMETER;
203 }
204
205 return EGL_SUCCESS;
206 }
207
208 static EGLint
209 _eglParseEXTImageDmaBufImportModifiersAttribs(_EGLImageAttribs *attrs,
210 _EGLDisplay *disp,
211 EGLint attr, EGLint val)
212 {
213 if (!disp->Extensions.EXT_image_dma_buf_import_modifiers)
214 return EGL_BAD_PARAMETER;
215
216 switch (attr) {
217 case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
218 attrs->DMABufPlaneModifiersLo[0].Value = val;
219 attrs->DMABufPlaneModifiersLo[0].IsPresent = EGL_TRUE;
220 break;
221 case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
222 attrs->DMABufPlaneModifiersHi[0].Value = val;
223 attrs->DMABufPlaneModifiersHi[0].IsPresent = EGL_TRUE;
224 break;
225 case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
226 attrs->DMABufPlaneModifiersLo[1].Value = val;
227 attrs->DMABufPlaneModifiersLo[1].IsPresent = EGL_TRUE;
228 break;
229 case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
230 attrs->DMABufPlaneModifiersHi[1].Value = val;
231 attrs->DMABufPlaneModifiersHi[1].IsPresent = EGL_TRUE;
232 break;
233 case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
234 attrs->DMABufPlaneModifiersLo[2].Value = val;
235 attrs->DMABufPlaneModifiersLo[2].IsPresent = EGL_TRUE;
236 break;
237 case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
238 attrs->DMABufPlaneModifiersHi[2].Value = val;
239 attrs->DMABufPlaneModifiersHi[2].IsPresent = EGL_TRUE;
240 break;
241 case EGL_DMA_BUF_PLANE3_FD_EXT:
242 attrs->DMABufPlaneFds[3].Value = val;
243 attrs->DMABufPlaneFds[3].IsPresent = EGL_TRUE;
244 break;
245 case EGL_DMA_BUF_PLANE3_OFFSET_EXT:
246 attrs->DMABufPlaneOffsets[3].Value = val;
247 attrs->DMABufPlaneOffsets[3].IsPresent = EGL_TRUE;
248 break;
249 case EGL_DMA_BUF_PLANE3_PITCH_EXT:
250 attrs->DMABufPlanePitches[3].Value = val;
251 attrs->DMABufPlanePitches[3].IsPresent = EGL_TRUE;
252 break;
253 case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
254 attrs->DMABufPlaneModifiersLo[3].Value = val;
255 attrs->DMABufPlaneModifiersLo[3].IsPresent = EGL_TRUE;
256 break;
257 case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT:
258 attrs->DMABufPlaneModifiersHi[3].Value = val;
259 attrs->DMABufPlaneModifiersHi[3].IsPresent = EGL_TRUE;
260 break;
261 default:
262 return EGL_BAD_PARAMETER;
263 }
264
265 return EGL_SUCCESS;
266 }
267
268 static EGLint
269 _eglParseEXTImageFlushExternalAttribs(_EGLImageAttribs *attrs,
270 _EGLDisplay *disp,
271 EGLint attr, EGLint val)
272 {
273 if (!disp->Extensions.EXT_image_flush_external)
274 return EGL_BAD_PARAMETER;
275
276 switch (attr) {
277 case EGL_IMAGE_EXTERNAL_FLUSH_EXT:
278 attrs->ImageFlushExternal = val;
279 break;
280 default:
281 return EGL_BAD_PARAMETER;
282 }
283
284 return EGL_SUCCESS;
285 }
286
287 /**
288 * Parse the list of image attributes.
289 *
290 * Returns EGL_TRUE on success and EGL_FALSE otherwise.
291 * Function calls _eglError to set the correct error code.
292 */
293 EGLBoolean
294 _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *disp,
295 const EGLint *attrib_list)
296 {
297 EGLint i, err;
298
299 memset(attrs, 0, sizeof(*attrs));
300
301 if (!attrib_list)
302 return EGL_TRUE;
303
304 for (i = 0; attrib_list[i] != EGL_NONE; i++) {
305 EGLint attr = attrib_list[i++];
306 EGLint val = attrib_list[i];
307
308 err = _eglParseEXTImageFlushExternalAttribs(attrs, disp, attr, val);
309 if (err == EGL_SUCCESS)
310 continue;
311
312 err = _eglParseKHRImageAttribs(attrs, disp, attr, val);
313 if (err == EGL_SUCCESS)
314 continue;
315
316 err = _eglParseMESADrmImageAttribs(attrs, disp, attr, val);
317 if (err == EGL_SUCCESS)
318 continue;
319
320 err = _eglParseWLBindWaylandDisplayAttribs(attrs, disp, attr, val);
321 if (err == EGL_SUCCESS)
322 continue;
323
324 err = _eglParseEXTImageDmaBufImportAttribs(attrs, disp, attr, val);
325 if (err == EGL_SUCCESS)
326 continue;
327
328 /* EXT_image_dma_buf_import states that if invalid value is provided for
329 * its attributes, we should return EGL_BAD_ATTRIBUTE.
330 * Bail out ASAP, since follow-up calls can return another EGL_BAD error.
331 */
332 if (err == EGL_BAD_ATTRIBUTE)
333 return _eglError(err, __func__);
334
335 err = _eglParseEXTImageDmaBufImportModifiersAttribs(attrs, disp, attr, val);
336 if (err == EGL_SUCCESS)
337 continue;
338
339 return _eglError(err, __func__);
340 }
341
342 return EGL_TRUE;
343 }