summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/EGLImage.cpp
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
committermanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
commitbe933ef2241d79558f91796cc5b3a161f72ebf9c (patch)
treefe3ab2f130e20c99001f2d7a81d610c78c96a3f4 /xbmc/utils/EGLImage.cpp
parent5f8335c1e49ce108ef3481863833c98efa00411b (diff)
downloadkodi-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.cpp197
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
16namespace
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)
56std::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
104CEGLImage::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
112bool 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
189void CEGLImage::UploadImage(GLenum textureTarget)
190{
191 m_glEGLImageTargetTexture2DOES(textureTarget, m_image);
192}
193
194void CEGLImage::DestroyImage()
195{
196 m_eglDestroyImageKHR(m_display, m_image);
197}