Merge pull request #26350 from jjd-uk/estuary_media_align
[xbmc.git] / xbmc / guilib / TextureGLES.cpp
bloba3af57df6f054043282371b7bb74591567e376ac
1 /*
2 * Copyright (C) 2024 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "TextureGLES.h"
11 #include "ServiceBroker.h"
12 #include "guilib/TextureFormats.h"
13 #include "guilib/TextureManager.h"
14 #include "rendering/RenderSystem.h"
15 #include "settings/AdvancedSettings.h"
16 #include "settings/SettingsComponent.h"
17 #include "utils/GLUtils.h"
18 #include "utils/MemUtils.h"
19 #include "utils/log.h"
21 #include <memory>
23 namespace
25 // clang-format off
26 // GLES 2.0 texture formats.
27 // Any extension used here is in the core 3.0 profile (except BGRA)
28 // format = (unsized) internalFormat (with core 2.0)
29 static const std::map<KD_TEX_FMT, TextureFormat> TextureMappingGLES20
31 #if defined(GL_EXT_texture_rg)
32 {KD_TEX_FMT_SDR_R8, {GL_RED_EXT}},
33 {KD_TEX_FMT_SDR_RG8, {GL_RG_EXT}},
34 #endif
35 {KD_TEX_FMT_SDR_R5G6B5, {GL_RGB, GL_FALSE, GL_FALSE, GL_UNSIGNED_SHORT_5_6_5}},
36 {KD_TEX_FMT_SDR_RGB5_A1, {GL_RGBA, GL_FALSE, GL_FALSE, GL_UNSIGNED_SHORT_5_5_5_1}},
37 {KD_TEX_FMT_SDR_RGBA4, {GL_RGBA, GL_FALSE, GL_FALSE, GL_UNSIGNED_SHORT_4_4_4_4}},
38 #if defined(GL_EXT_sRGB)
39 {KD_TEX_FMT_SDR_RGB8, {GL_RGB, GL_SRGB_EXT}},
40 {KD_TEX_FMT_SDR_RGBA8, {GL_RGBA, GL_SRGB_ALPHA_EXT}},
41 #else
42 {KD_TEX_FMT_SDR_RGB8, {GL_RGB}},
43 {KD_TEX_FMT_SDR_RGBA8, {GL_RGBA}},
44 #endif
46 #if defined(GL_EXT_texture_format_BGRA8888) || (GL_IMG_texture_format_BGRA8888)
47 {KD_TEX_FMT_SDR_BGRA8, {GL_BGRA_EXT}},
48 #endif
50 #if defined(GL_EXT_texture_type_2_10_10_10_REV)
51 {KD_TEX_FMT_HDR_RGB10_A2, {GL_RGBA, GL_FALSE, GL_FALSE, GL_UNSIGNED_INT_2_10_10_10_REV_EXT}},
52 #endif
53 #if defined(GL_OES_texture_half_float_linear)
54 {KD_TEX_FMT_HDR_RGBA16f, {GL_RGBA, GL_FALSE, GL_FALSE, GL_HALF_FLOAT_OES}},
55 #endif
57 #if defined(GL_OES_compressed_ETC1_RGB8_texture)
58 {KD_TEX_FMT_ETC1_RGB8, {GL_ETC1_RGB8_OES}},
59 #endif
62 // GLES 3.0 texture formats.
63 #if defined(GL_ES_VERSION_3_0)
64 std::map<KD_TEX_FMT, TextureFormat> TextureMappingGLES30
66 #if defined(GL_EXT_texture_sRGB_R8) && (GL_EXT_texture_sRGB_RG8) // in gl2ext.h, but spec says >= 3.0
67 {KD_TEX_FMT_SDR_R8, {GL_R8, GL_SR8_EXT, GL_RED}},
68 {KD_TEX_FMT_SDR_RG8, {GL_RG8, GL_SRG8_EXT, GL_RG}},
69 #else
70 {KD_TEX_FMT_SDR_R8, {GL_R8, GL_FALSE, GL_RED}},
71 {KD_TEX_FMT_SDR_RG8, {GL_RG8, GL_FALSE, GL_RG}},
72 #endif
73 {KD_TEX_FMT_SDR_R5G6B5, {GL_RGB565, GL_FALSE, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}},
74 {KD_TEX_FMT_SDR_RGB5_A1, {GL_RGB5_A1, GL_FALSE, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}},
75 {KD_TEX_FMT_SDR_RGBA4, {GL_RGBA4, GL_FALSE, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}},
76 {KD_TEX_FMT_SDR_RGB8, {GL_RGB8, GL_SRGB8, GL_RGB}},
77 {KD_TEX_FMT_SDR_RGBA8, {GL_RGBA8, GL_SRGB8_ALPHA8, GL_RGBA}},
79 {KD_TEX_FMT_HDR_R16f, {GL_R16F, GL_FALSE, GL_RED, GL_HALF_FLOAT}},
80 {KD_TEX_FMT_HDR_RG16f, {GL_RG16F, GL_FALSE, GL_RG, GL_HALF_FLOAT}},
81 {KD_TEX_FMT_HDR_R11F_G11F_B10F, {GL_R11F_G11F_B10F, GL_FALSE, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV}},
82 {KD_TEX_FMT_HDR_RGB9_E5, {GL_RGB9_E5, GL_FALSE, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV}},
83 {KD_TEX_FMT_HDR_RGB10_A2, {GL_RGB10_A2, GL_FALSE, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}},
84 {KD_TEX_FMT_HDR_RGBA16f, {GL_RGBA16F, GL_FALSE, GL_RGBA, GL_HALF_FLOAT}},
86 {KD_TEX_FMT_ETC1_RGB8, {GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2}},
88 {KD_TEX_FMT_ETC2_R11, {GL_COMPRESSED_R11_EAC}},
89 {KD_TEX_FMT_ETC2_RG11, {GL_COMPRESSED_RG11_EAC}},
90 {KD_TEX_FMT_ETC2_RGB8, {GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2}},
91 {KD_TEX_FMT_ETC2_RGB8_A1, {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}},
92 {KD_TEX_FMT_ETC2_RGBA8, {GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}},
94 #endif // GL_ES_VERSION_3_0
96 // Common GLES extensions (texture compression)
97 static const std::map<KD_TEX_FMT, TextureFormat> TextureMappingGLESExtensions
99 #if defined(GL_EXT_texture_compression_s3tc) && (GL_EXT_texture_compression_s3tc_srgb)
100 {KD_TEX_FMT_S3TC_RGB8, {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}},
101 {KD_TEX_FMT_S3TC_RGB8_A1, {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}},
102 {KD_TEX_FMT_S3TC_RGB8_A4, {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}},
103 {KD_TEX_FMT_S3TC_RGBA8, {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}},
104 #elif defined(GL_EXT_texture_compression_s3tc)
105 {KD_TEX_FMT_S3TC_RGB8, {GL_COMPRESSED_RGB_S3TC_DXT1_EXT}},
106 {KD_TEX_FMT_S3TC_RGB8_A1, {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}},
107 {KD_TEX_FMT_S3TC_RGB8_A4, {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}},
108 {KD_TEX_FMT_S3TC_RGBA8, {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}},
109 #elif defined(GL_EXT_texture_compression_dxt1)
110 {KD_TEX_FMT_S3TC_RGB8, {GL_COMPRESSED_RGB_S3TC_DXT1_EXT}},
111 {KD_TEX_FMT_S3TC_RGB8_A1, {GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}},
112 #endif
114 #if defined(GL_EXT_texture_compression_rgtc)
115 {KD_TEX_FMT_RGTC_R11, {GL_COMPRESSED_RED_RGTC1_EXT}},
116 {KD_TEX_FMT_RGTC_RG11, {GL_COMPRESSED_RED_GREEN_RGTC2_EXT}},
117 #endif
119 #if defined(GL_EXT_texture_compression_bptc)
120 {KD_TEX_FMT_BPTC_RGB16F, {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT}},
121 {KD_TEX_FMT_BPTC_RGBA8, {GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT}},
122 #endif
124 #if defined(GL_KHR_texture_compression_astc_ldr) || (GL_KHR_texture_compression_astc_hdr)
125 {KD_TEX_FMT_ASTC_LDR_4x4, {GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}},
126 {KD_TEX_FMT_ASTC_LDR_5x4, {GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR}},
127 {KD_TEX_FMT_ASTC_LDR_5x5, {GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR}},
128 {KD_TEX_FMT_ASTC_LDR_6x5, {GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR}},
129 {KD_TEX_FMT_ASTC_LDR_6x6, {GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}},
130 {KD_TEX_FMT_ASTC_LDR_8x5, {GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}},
131 {KD_TEX_FMT_ASTC_LDR_8x6, {GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR}},
132 {KD_TEX_FMT_ASTC_LDR_8x8, {GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}},
133 {KD_TEX_FMT_ASTC_LDR_10x5, {GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR}},
134 {KD_TEX_FMT_ASTC_LDR_10x6, {GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR}},
135 {KD_TEX_FMT_ASTC_LDR_10x8, {GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR}},
136 {KD_TEX_FMT_ASTC_LDR_10x10, {GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}},
137 {KD_TEX_FMT_ASTC_LDR_12x10, {GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR}},
138 {KD_TEX_FMT_ASTC_LDR_12x12, {GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}},
140 {KD_TEX_FMT_ASTC_HDR_4x4, {GL_COMPRESSED_RGBA_ASTC_4x4_KHR}},
141 {KD_TEX_FMT_ASTC_HDR_5x4, {GL_COMPRESSED_RGBA_ASTC_5x4_KHR}},
142 {KD_TEX_FMT_ASTC_HDR_5x5, {GL_COMPRESSED_RGBA_ASTC_5x5_KHR}},
143 {KD_TEX_FMT_ASTC_HDR_6x5, {GL_COMPRESSED_RGBA_ASTC_6x5_KHR}},
144 {KD_TEX_FMT_ASTC_HDR_6x6, {GL_COMPRESSED_RGBA_ASTC_6x6_KHR}},
145 {KD_TEX_FMT_ASTC_HDR_8x5, {GL_COMPRESSED_RGBA_ASTC_8x5_KHR}},
146 {KD_TEX_FMT_ASTC_HDR_8x6, {GL_COMPRESSED_RGBA_ASTC_8x6_KHR}},
147 {KD_TEX_FMT_ASTC_HDR_8x8, {GL_COMPRESSED_RGBA_ASTC_8x8_KHR}},
148 {KD_TEX_FMT_ASTC_HDR_10x5, {GL_COMPRESSED_RGBA_ASTC_10x5_KHR}},
149 {KD_TEX_FMT_ASTC_HDR_10x6, {GL_COMPRESSED_RGBA_ASTC_10x6_KHR}},
150 {KD_TEX_FMT_ASTC_HDR_10x8, {GL_COMPRESSED_RGBA_ASTC_10x8_KHR}},
151 {KD_TEX_FMT_ASTC_HDR_10x10, {GL_COMPRESSED_RGBA_ASTC_10x10_KHR}},
152 {KD_TEX_FMT_ASTC_HDR_12x10, {GL_COMPRESSED_RGBA_ASTC_12x10_KHR}},
153 {KD_TEX_FMT_ASTC_HDR_12x12, {GL_COMPRESSED_RGBA_ASTC_12x12_KHR}},
154 #endif
157 static const std::map<KD_TEX_SWIZ, TextureSwizzle> SwizzleMapGLES
159 {KD_TEX_SWIZ_RGBA, {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}},
160 {KD_TEX_SWIZ_RGB1, {GL_RED, GL_GREEN, GL_BLUE, GL_ONE}},
161 {KD_TEX_SWIZ_RRR1, {GL_RED, GL_RED, GL_RED, GL_ONE}},
162 {KD_TEX_SWIZ_111R, {GL_ONE, GL_ONE, GL_ONE, GL_RED}},
163 {KD_TEX_SWIZ_RRRG, {GL_RED, GL_RED, GL_RED, GL_GREEN}},
164 {KD_TEX_SWIZ_RRRR, {GL_RED, GL_RED, GL_RED, GL_RED}},
165 {KD_TEX_SWIZ_GGG1, {GL_GREEN, GL_GREEN, GL_GREEN, GL_ONE}},
166 {KD_TEX_SWIZ_111G, {GL_ONE, GL_ONE, GL_ONE, GL_GREEN}},
167 {KD_TEX_SWIZ_GGGA, {GL_GREEN, GL_GREEN, GL_GREEN, GL_ALPHA}},
168 {KD_TEX_SWIZ_GGGG, {GL_GREEN, GL_GREEN, GL_GREEN, GL_GREEN}},
170 // clang-format on
171 } // namespace
173 std::unique_ptr<CTexture> CTexture::CreateTexture(unsigned int width,
174 unsigned int height,
175 XB_FMT format)
177 return std::make_unique<CGLESTexture>(width, height, format);
180 CGLESTexture::CGLESTexture(unsigned int width, unsigned int height, XB_FMT format)
181 : CTexture(width, height, format)
183 unsigned int major, minor;
184 CServiceBroker::GetRenderSystem()->GetRenderVersion(major, minor);
185 #if defined(GL_ES_VERSION_3_0)
186 m_isGLESVersion30orNewer = major >= 3;
187 #endif
190 CGLESTexture::~CGLESTexture()
192 DestroyTextureObject();
195 void CGLESTexture::CreateTextureObject()
197 glGenTextures(1, (GLuint*)&m_texture);
200 void CGLESTexture::DestroyTextureObject()
202 if (m_texture)
203 CServiceBroker::GetGUI()->GetTextureManager().ReleaseHwTexture(m_texture);
206 void CGLESTexture::LoadToGPU()
208 if (!m_pixels)
210 // nothing to load - probably same image (no change)
211 return;
213 if (m_texture == 0)
215 // Have OpenGL generate a texture object handle for us
216 // this happens only one time - the first time the texture is loaded
217 CreateTextureObject();
220 // Bind the texture object
221 glBindTexture(GL_TEXTURE_2D, m_texture);
223 GLenum filter = (m_scalingMethod == TEXTURE_SCALING::NEAREST ? GL_NEAREST : GL_LINEAR);
225 // Set the texture's stretching properties
226 if (IsMipmapped())
228 GLenum mipmapFilter = (m_scalingMethod == TEXTURE_SCALING::NEAREST ? GL_LINEAR_MIPMAP_NEAREST
229 : GL_LINEAR_MIPMAP_LINEAR);
230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmapFilter);
232 else
234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
241 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
242 if (CServiceBroker::GetRenderSystem()->IsExtSupported("GL_EXT_texture_filter_anisotropic"))
244 int32_t aniso =
245 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiAnisotropicFiltering;
246 if (aniso > 1)
247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
249 #endif
251 unsigned int maxSize = CServiceBroker::GetRenderSystem()->GetMaxTextureSize();
253 if (m_textureHeight > maxSize)
255 CLog::LogF(LOGERROR,
256 "Image height {} too big to fit into single texture unit, truncating to {}",
257 m_textureHeight, maxSize);
258 m_textureHeight = maxSize;
261 if (m_textureWidth > maxSize)
263 #if defined(GL_PACK_ROW_LENGTH)
264 if (m_isGLESVersion30orNewer)
266 CLog::LogF(LOGERROR,
267 "Image width {} too big to fit into single texture unit, truncating to {}",
268 m_textureWidth, maxSize);
270 glPixelStorei(GL_UNPACK_ROW_LENGTH, m_textureWidth);
272 m_textureWidth = maxSize;
274 else
275 #endif
277 CLog::LogF(LOGERROR, "Image width {} too big, upload to GPU will fail", m_textureWidth);
281 // there might not be any padding for the following formats, so we have to
282 // read one/two bytes at the time.
283 if (m_textureFormat == KD_TEX_FMT_SDR_R8)
284 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
285 if (m_textureFormat == KD_TEX_FMT_SDR_RG8)
286 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
288 TextureFormat glesFormat;
289 if (m_isGLESVersion30orNewer)
291 KD_TEX_FMT textureFormat = m_textureFormat;
292 bool swapRB = false;
293 // Support for BGRA is hit and miss, swizzle instead
294 if (textureFormat == KD_TEX_FMT_SDR_BGRA8)
296 textureFormat = KD_TEX_FMT_SDR_RGBA8;
297 swapRB = true;
299 SetSwizzle(swapRB);
300 glesFormat = GetFormatGLES30(textureFormat);
302 else
304 glesFormat = GetFormatGLES20(m_textureFormat);
307 if (glesFormat.internalFormat == GL_FALSE)
309 CLog::LogF(LOGDEBUG, "Failed to load texture. Unsupported format {}", m_textureFormat);
310 m_loadedToGPU = true;
311 return;
314 if ((m_textureFormat & KD_TEX_FMT_SDR) || (m_textureFormat & KD_TEX_FMT_HDR))
316 glTexImage2D(GL_TEXTURE_2D, 0, glesFormat.internalFormat, m_textureWidth, m_textureHeight, 0,
317 glesFormat.format, glesFormat.type, m_pixels);
319 else
321 glCompressedTexImage2D(GL_TEXTURE_2D, 0, glesFormat.internalFormat, m_textureWidth,
322 m_textureHeight, 0, GetPitch() * GetRows(), m_pixels);
324 if (IsMipmapped())
326 glGenerateMipmap(GL_TEXTURE_2D);
329 #if defined(GL_UNPACK_ROW_LENGTH)
330 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
331 #endif
333 VerifyGLState();
335 if (!m_bCacheMemory)
337 KODI::MEMORY::AlignedFree(m_pixels);
338 m_pixels = NULL;
341 m_loadedToGPU = true;
344 void CGLESTexture::BindToUnit(unsigned int unit)
346 glActiveTexture(GL_TEXTURE0 + unit);
347 glBindTexture(GL_TEXTURE_2D, m_texture);
350 bool CGLESTexture::SupportsFormat(KD_TEX_FMT textureFormat, KD_TEX_SWIZ textureSwizzle)
352 // GLES 3.0 supports swizzles
353 if (m_isGLESVersion30orNewer)
354 return true;
356 // GL_LUMINANCE;
357 if (textureFormat == KD_TEX_FMT_SDR_R8 && textureSwizzle == KD_TEX_SWIZ_RRR1)
358 return true;
360 // GL_LUMINANCE_ALPHA;
361 if (textureFormat == KD_TEX_FMT_SDR_RG8 && textureSwizzle == KD_TEX_SWIZ_RRRG)
362 return true;
364 // Shader based swizzling;
365 if (textureSwizzle == KD_TEX_SWIZ_111R)
366 return true;
368 // all other GLES 2.0 swizzles would need separate shaders
369 return textureSwizzle == KD_TEX_SWIZ_RGBA;
372 void CGLESTexture::SetSwizzle(bool swapRB)
374 #if defined(GL_ES_VERSION_3_0)
375 TextureSwizzle swiz;
377 const auto it = SwizzleMapGLES.find(m_textureSwizzle);
378 if (it != SwizzleMapGLES.cend())
379 swiz = it->second;
381 if (swapRB)
383 SwapBlueRedSwizzle(swiz.r);
384 SwapBlueRedSwizzle(swiz.g);
385 SwapBlueRedSwizzle(swiz.b);
386 SwapBlueRedSwizzle(swiz.a);
389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, swiz.r);
390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, swiz.g);
391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, swiz.b);
392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, swiz.a);
393 #endif
396 void CGLESTexture::SwapBlueRedSwizzle(GLint& component)
398 if (component == GL_RED)
399 component = GL_BLUE;
400 else if (component == GL_BLUE)
401 component = GL_RED;
404 TextureFormat CGLESTexture::GetFormatGLES20(KD_TEX_FMT textureFormat)
406 TextureFormat glFormat;
408 // GLES 2.0 does not support swizzling. But for some Kodi formats+swizzles,
409 // we can map GLES formats (Luminance, Luminance-Alpha, BGRA). The swizzle
410 // "111R" is supported via fragment shaders. Other swizzles would need
411 // additional specialized shaders, or format conversions.
413 if (m_textureFormat == KD_TEX_FMT_SDR_R8 &&
414 (m_textureSwizzle == KD_TEX_SWIZ_RRR1 || m_textureSwizzle == KD_TEX_SWIZ_111R))
416 glFormat.format = glFormat.internalFormat = GL_LUMINANCE;
418 else if (m_textureFormat == KD_TEX_FMT_SDR_RG8 && m_textureSwizzle == KD_TEX_SWIZ_RRRG)
420 glFormat.format = glFormat.internalFormat = GL_LUMINANCE_ALPHA;
422 else if (m_textureFormat == KD_TEX_FMT_SDR_BGRA8 && m_textureSwizzle == KD_TEX_SWIZ_RGBA &&
423 !CServiceBroker::GetRenderSystem()->IsExtSupported("GL_EXT_texture_format_BGRA8888") &&
424 !CServiceBroker::GetRenderSystem()->IsExtSupported("GL_IMG_texture_format_BGRA8888"))
426 #if defined(GL_APPLE_texture_format_BGRA8888)
427 if (CServiceBroker::GetRenderSystem()->IsExtSupported("GL_APPLE_texture_format_BGRA8888"))
429 glFormat.internalFormat = GL_RGBA;
430 glFormat.format = GL_BGRA_EXT;
432 else
433 #endif
435 SwapBlueRed(m_pixels, m_textureHeight, GetPitch());
436 glFormat.format = glFormat.internalFormat = GL_RGBA;
439 else if (textureFormat & KD_TEX_FMT_SDR || textureFormat & KD_TEX_FMT_HDR ||
440 textureFormat & KD_TEX_FMT_ETC1)
442 const auto it = TextureMappingGLES20.find(textureFormat);
443 if (it != TextureMappingGLES20.cend())
444 glFormat = it->second;
445 glFormat.format = glFormat.internalFormat;
447 else
449 const auto it = TextureMappingGLESExtensions.find(textureFormat);
450 if (it != TextureMappingGLESExtensions.cend())
451 glFormat = it->second;
454 return glFormat;
457 TextureFormat CGLESTexture::GetFormatGLES30(KD_TEX_FMT textureFormat)
459 TextureFormat glFormat;
461 if (textureFormat & KD_TEX_FMT_SDR || textureFormat & KD_TEX_FMT_HDR)
463 #if defined(GL_ES_VERSION_3_0)
464 const auto it = TextureMappingGLES30.find(textureFormat);
465 if (it != TextureMappingGLES30.cend())
466 glFormat = it->second;
467 #else
468 const auto it = TextureMappingGLES20.find(textureFormat);
469 if (it != TextureMappingGLES20.cend())
470 glFormat = it->second;
471 glFormat.format = glFormat.internalFormat;
472 #endif
474 else
476 const auto it = TextureMappingGLESExtensions.find(textureFormat);
477 if (it != TextureMappingGLESExtensions.cend())
478 glFormat = it->second;
481 return glFormat;