xref: /third_party/mesa3d/src/egl/main/eglimage.c (revision bf215546)
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
37static 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   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
74static EGLint
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
104static EGLint
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
122static EGLint
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
214static EGLint
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 */
280EGLBoolean
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