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