diff options
| author | manuel <manuel@mausz.at> | 2020-10-19 00:52:24 +0200 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2020-10-19 00:52:24 +0200 |
| commit | be933ef2241d79558f91796cc5b3a161f72ebf9c (patch) | |
| tree | fe3ab2f130e20c99001f2d7a81d610c78c96a3f4 /xbmc/utils/EGLImage.cpp | |
| parent | 5f8335c1e49ce108ef3481863833c98efa00411b (diff) | |
| download | kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.gz kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.bz2 kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.zip | |
sync with upstream
Diffstat (limited to 'xbmc/utils/EGLImage.cpp')
| -rw-r--r-- | xbmc/utils/EGLImage.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/xbmc/utils/EGLImage.cpp b/xbmc/utils/EGLImage.cpp new file mode 100644 index 0000000..633a44d --- /dev/null +++ b/xbmc/utils/EGLImage.cpp | |||
| @@ -0,0 +1,197 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2017-2018 Team Kodi | ||
| 3 | * This file is part of Kodi - https://kodi.tv | ||
| 4 | * | ||
| 5 | * SPDX-License-Identifier: GPL-2.0-or-later | ||
| 6 | * See LICENSES/README.md for more information. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "EGLImage.h" | ||
| 10 | |||
| 11 | #include "EGLUtils.h" | ||
| 12 | #include "log.h" | ||
| 13 | |||
| 14 | #include <map> | ||
| 15 | |||
| 16 | namespace | ||
| 17 | { | ||
| 18 | const EGLint eglDmabufPlaneFdAttr[CEGLImage::MAX_NUM_PLANES] = | ||
| 19 | { | ||
| 20 | EGL_DMA_BUF_PLANE0_FD_EXT, | ||
| 21 | EGL_DMA_BUF_PLANE1_FD_EXT, | ||
| 22 | EGL_DMA_BUF_PLANE2_FD_EXT, | ||
| 23 | }; | ||
| 24 | |||
| 25 | const EGLint eglDmabufPlaneOffsetAttr[CEGLImage::MAX_NUM_PLANES] = | ||
| 26 | { | ||
| 27 | EGL_DMA_BUF_PLANE0_OFFSET_EXT, | ||
| 28 | EGL_DMA_BUF_PLANE1_OFFSET_EXT, | ||
| 29 | EGL_DMA_BUF_PLANE2_OFFSET_EXT, | ||
| 30 | }; | ||
| 31 | |||
| 32 | const EGLint eglDmabufPlanePitchAttr[CEGLImage::MAX_NUM_PLANES] = | ||
| 33 | { | ||
| 34 | EGL_DMA_BUF_PLANE0_PITCH_EXT, | ||
| 35 | EGL_DMA_BUF_PLANE1_PITCH_EXT, | ||
| 36 | EGL_DMA_BUF_PLANE2_PITCH_EXT, | ||
| 37 | }; | ||
| 38 | |||
| 39 | #if defined(EGL_EXT_image_dma_buf_import_modifiers) | ||
| 40 | const EGLint eglDmabufPlaneModifierLoAttr[CEGLImage::MAX_NUM_PLANES] = | ||
| 41 | { | ||
| 42 | EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, | ||
| 43 | EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, | ||
| 44 | EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, | ||
| 45 | }; | ||
| 46 | |||
| 47 | const EGLint eglDmabufPlaneModifierHiAttr[CEGLImage::MAX_NUM_PLANES] = | ||
| 48 | { | ||
| 49 | EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, | ||
| 50 | EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT, | ||
| 51 | EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT, | ||
| 52 | }; | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #define X(VAL) std::make_pair(VAL, #VAL) | ||
| 56 | std::map<EGLint, const char*> eglAttributes = | ||
| 57 | { | ||
| 58 | X(EGL_WIDTH), | ||
| 59 | X(EGL_HEIGHT), | ||
| 60 | |||
| 61 | // please keep attributes in accordance to: | ||
| 62 | // https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import.txt | ||
| 63 | X(EGL_LINUX_DRM_FOURCC_EXT), | ||
| 64 | X(EGL_DMA_BUF_PLANE0_FD_EXT), | ||
| 65 | X(EGL_DMA_BUF_PLANE0_OFFSET_EXT), | ||
| 66 | X(EGL_DMA_BUF_PLANE0_PITCH_EXT), | ||
| 67 | X(EGL_DMA_BUF_PLANE1_FD_EXT), | ||
| 68 | X(EGL_DMA_BUF_PLANE1_OFFSET_EXT), | ||
| 69 | X(EGL_DMA_BUF_PLANE1_PITCH_EXT), | ||
| 70 | X(EGL_DMA_BUF_PLANE2_FD_EXT), | ||
| 71 | X(EGL_DMA_BUF_PLANE2_OFFSET_EXT), | ||
| 72 | X(EGL_DMA_BUF_PLANE2_PITCH_EXT), | ||
| 73 | X(EGL_YUV_COLOR_SPACE_HINT_EXT), | ||
| 74 | X(EGL_SAMPLE_RANGE_HINT_EXT), | ||
| 75 | X(EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT), | ||
| 76 | X(EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT), | ||
| 77 | X(EGL_ITU_REC601_EXT), | ||
| 78 | X(EGL_ITU_REC709_EXT), | ||
| 79 | X(EGL_ITU_REC2020_EXT), | ||
| 80 | X(EGL_YUV_FULL_RANGE_EXT), | ||
| 81 | X(EGL_YUV_NARROW_RANGE_EXT), | ||
| 82 | X(EGL_YUV_CHROMA_SITING_0_EXT), | ||
| 83 | X(EGL_YUV_CHROMA_SITING_0_5_EXT), | ||
| 84 | |||
| 85 | #if defined(EGL_EXT_image_dma_buf_import_modifiers) | ||
| 86 | // please keep attributes in accordance to: | ||
| 87 | // https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt | ||
| 88 | X(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT), | ||
| 89 | X(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT), | ||
| 90 | X(EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT), | ||
| 91 | X(EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT), | ||
| 92 | X(EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT), | ||
| 93 | X(EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT), | ||
| 94 | X(EGL_DMA_BUF_PLANE3_FD_EXT), | ||
| 95 | X(EGL_DMA_BUF_PLANE3_OFFSET_EXT), | ||
| 96 | X(EGL_DMA_BUF_PLANE3_PITCH_EXT), | ||
| 97 | X(EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT), | ||
| 98 | X(EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT), | ||
| 99 | #endif | ||
| 100 | }; | ||
| 101 | |||
| 102 | } // namespace | ||
| 103 | |||
| 104 | CEGLImage::CEGLImage(EGLDisplay display) : | ||
| 105 | m_display(display) | ||
| 106 | { | ||
| 107 | m_eglCreateImageKHR = CEGLUtils::GetRequiredProcAddress<PFNEGLCREATEIMAGEKHRPROC>("eglCreateImageKHR"); | ||
| 108 | m_eglDestroyImageKHR = CEGLUtils::GetRequiredProcAddress<PFNEGLDESTROYIMAGEKHRPROC>("eglDestroyImageKHR"); | ||
| 109 | m_glEGLImageTargetTexture2DOES = CEGLUtils::GetRequiredProcAddress<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>("glEGLImageTargetTexture2DOES"); | ||
| 110 | } | ||
| 111 | |||
| 112 | bool CEGLImage::CreateImage(EglAttrs imageAttrs) | ||
| 113 | { | ||
| 114 | CEGLAttributes<22> attribs; | ||
| 115 | attribs.Add({{EGL_WIDTH, imageAttrs.width}, | ||
| 116 | {EGL_HEIGHT, imageAttrs.height}, | ||
| 117 | {EGL_LINUX_DRM_FOURCC_EXT, static_cast<EGLint>(imageAttrs.format)}}); | ||
| 118 | |||
| 119 | if (imageAttrs.colorSpace != 0 && imageAttrs.colorRange != 0) | ||
| 120 | { | ||
| 121 | attribs.Add({{EGL_YUV_COLOR_SPACE_HINT_EXT, imageAttrs.colorSpace}, | ||
| 122 | {EGL_SAMPLE_RANGE_HINT_EXT, imageAttrs.colorRange}, | ||
| 123 | {EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT, EGL_YUV_CHROMA_SITING_0_EXT}, | ||
| 124 | {EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT, EGL_YUV_CHROMA_SITING_0_EXT}}); | ||
| 125 | } | ||
| 126 | |||
| 127 | for (int i = 0; i < MAX_NUM_PLANES; i++) | ||
| 128 | { | ||
| 129 | if (imageAttrs.planes[i].fd != 0) | ||
| 130 | { | ||
| 131 | attribs.Add({{eglDmabufPlaneFdAttr[i], imageAttrs.planes[i].fd}, | ||
| 132 | {eglDmabufPlaneOffsetAttr[i], imageAttrs.planes[i].offset}, | ||
| 133 | {eglDmabufPlanePitchAttr[i], imageAttrs.planes[i].pitch}}); | ||
| 134 | |||
| 135 | #if defined(EGL_EXT_image_dma_buf_import_modifiers) | ||
| 136 | if (imageAttrs.planes[i].modifier != DRM_FORMAT_MOD_INVALID && imageAttrs.planes[i].modifier != DRM_FORMAT_MOD_LINEAR) | ||
| 137 | attribs.Add({{eglDmabufPlaneModifierLoAttr[i], static_cast<EGLint>(imageAttrs.planes[i].modifier & 0xFFFFFFFF)}, | ||
| 138 | {eglDmabufPlaneModifierHiAttr[i], static_cast<EGLint>(imageAttrs.planes[i].modifier >> 32)}}); | ||
| 139 | #endif | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | m_image = m_eglCreateImageKHR(m_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.Get()); | ||
| 144 | |||
| 145 | if(!m_image) | ||
| 146 | { | ||
| 147 | CLog::Log(LOGERROR, "CEGLImage::{} - failed to import buffer into EGL image: {}", __FUNCTION__, eglGetError()); | ||
| 148 | |||
| 149 | const EGLint* attrs = attribs.Get(); | ||
| 150 | |||
| 151 | std::string eglString; | ||
| 152 | |||
| 153 | for (int i = 0; i < (attribs.Size()); i += 2) | ||
| 154 | { | ||
| 155 | std::string keyStr; | ||
| 156 | std::string valueStr; | ||
| 157 | |||
| 158 | auto eglAttr = eglAttributes.find(attrs[i]); | ||
| 159 | if (eglAttr != eglAttributes.end()) | ||
| 160 | { | ||
| 161 | keyStr = eglAttr->second; | ||
| 162 | } | ||
| 163 | else | ||
| 164 | { | ||
| 165 | keyStr = std::to_string(attrs[i]); | ||
| 166 | } | ||
| 167 | |||
| 168 | eglAttr = eglAttributes.find(attrs[i + 1]); | ||
| 169 | if (eglAttr != eglAttributes.end()) | ||
| 170 | { | ||
| 171 | valueStr = eglAttr->second; | ||
| 172 | } | ||
| 173 | else | ||
| 174 | { | ||
| 175 | valueStr = std::to_string(attrs[i + 1]); | ||
| 176 | } | ||
| 177 | |||
| 178 | eglString.append(StringUtils::Format("%s: %s\n", keyStr, valueStr)); | ||
| 179 | } | ||
| 180 | |||
| 181 | CLog::Log(LOGDEBUG, "CEGLImage::{} - attributes:\n{}", __FUNCTION__, eglString); | ||
| 182 | |||
| 183 | return false; | ||
| 184 | } | ||
| 185 | |||
| 186 | return true; | ||
| 187 | } | ||
| 188 | |||
| 189 | void CEGLImage::UploadImage(GLenum textureTarget) | ||
| 190 | { | ||
| 191 | m_glEGLImageTargetTexture2DOES(textureTarget, m_image); | ||
| 192 | } | ||
| 193 | |||
| 194 | void CEGLImage::DestroyImage() | ||
| 195 | { | ||
| 196 | m_eglDestroyImageKHR(m_display, m_image); | ||
| 197 | } | ||
