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 default: 62 return EGL_BAD_PARAMETER; 63 } 64 65 return EGL_SUCCESS; 66} 67 68static 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 98static 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 116static 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 208static 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/** 269 * Parse the list of image attributes. 270 * 271 * Returns EGL_TRUE on success and EGL_FALSE otherwise. 272 * Function calls _eglError to set the correct error code. 273 */ 274EGLBoolean 275_eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *disp, 276 const EGLint *attrib_list) 277{ 278 EGLint i, err; 279 280 memset(attrs, 0, sizeof(*attrs)); 281 282 if (!attrib_list) 283 return EGL_TRUE; 284 285 for (i = 0; attrib_list[i] != EGL_NONE; i++) { 286 EGLint attr = attrib_list[i++]; 287 EGLint val = attrib_list[i]; 288 289 err = _eglParseKHRImageAttribs(attrs, disp, attr, val); 290 if (err == EGL_SUCCESS) 291 continue; 292 293 err = _eglParseMESADrmImageAttribs(attrs, disp, attr, val); 294 if (err == EGL_SUCCESS) 295 continue; 296 297 err = _eglParseWLBindWaylandDisplayAttribs(attrs, disp, attr, val); 298 if (err == EGL_SUCCESS) 299 continue; 300 301 err = _eglParseEXTImageDmaBufImportAttribs(attrs, disp, attr, val); 302 if (err == EGL_SUCCESS) 303 continue; 304 305 /* EXT_image_dma_buf_import states that if invalid value is provided for 306 * its attributes, we should return EGL_BAD_ATTRIBUTE. 307 * Bail out ASAP, since follow-up calls can return another EGL_BAD error. 308 */ 309 if (err == EGL_BAD_ATTRIBUTE) 310 return _eglError(err, __func__); 311 312 err = _eglParseEXTImageDmaBufImportModifiersAttribs(attrs, disp, attr, val); 313 if (err == EGL_SUCCESS) 314 continue; 315 316 return _eglError(err, __func__); 317 } 318 319 return EGL_TRUE; 320} 321