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.
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"
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
}},
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
}},
42 {KD_TEX_FMT_SDR_RGB8
, {GL_RGB
}},
43 {KD_TEX_FMT_SDR_RGBA8
, {GL_RGBA
}},
46 #if defined(GL_EXT_texture_format_BGRA8888) || (GL_IMG_texture_format_BGRA8888)
47 {KD_TEX_FMT_SDR_BGRA8
, {GL_BGRA_EXT
}},
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
}},
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
}},
57 #if defined(GL_OES_compressed_ETC1_RGB8_texture)
58 {KD_TEX_FMT_ETC1_RGB8
, {GL_ETC1_RGB8_OES
}},
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
}},
70 {KD_TEX_FMT_SDR_R8
, {GL_R8
, GL_FALSE
, GL_RED
}},
71 {KD_TEX_FMT_SDR_RG8
, {GL_RG8
, GL_FALSE
, GL_RG
}},
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
}},
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
}},
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
}},
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
}},
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
}},
173 std::unique_ptr
<CTexture
> CTexture::CreateTexture(unsigned int width
,
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;
190 CGLESTexture::~CGLESTexture()
192 DestroyTextureObject();
195 void CGLESTexture::CreateTextureObject()
197 glGenTextures(1, (GLuint
*)&m_texture
);
200 void CGLESTexture::DestroyTextureObject()
203 CServiceBroker::GetGUI()->GetTextureManager().ReleaseHwTexture(m_texture
);
206 void CGLESTexture::LoadToGPU()
210 // nothing to load - probably same image (no change)
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
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
);
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"))
245 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiAnisotropicFiltering
;
247 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAX_ANISOTROPY_EXT
, aniso
);
251 unsigned int maxSize
= CServiceBroker::GetRenderSystem()->GetMaxTextureSize();
253 if (m_textureHeight
> maxSize
)
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
)
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
;
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
;
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
;
300 glesFormat
= GetFormatGLES30(textureFormat
);
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;
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
);
321 glCompressedTexImage2D(GL_TEXTURE_2D
, 0, glesFormat
.internalFormat
, m_textureWidth
,
322 m_textureHeight
, 0, GetPitch() * GetRows(), m_pixels
);
326 glGenerateMipmap(GL_TEXTURE_2D
);
329 #if defined(GL_UNPACK_ROW_LENGTH)
330 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
337 KODI::MEMORY::AlignedFree(m_pixels
);
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
)
357 if (textureFormat
== KD_TEX_FMT_SDR_R8
&& textureSwizzle
== KD_TEX_SWIZ_RRR1
)
360 // GL_LUMINANCE_ALPHA;
361 if (textureFormat
== KD_TEX_FMT_SDR_RG8
&& textureSwizzle
== KD_TEX_SWIZ_RRRG
)
364 // Shader based swizzling;
365 if (textureSwizzle
== KD_TEX_SWIZ_111R
)
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)
377 const auto it
= SwizzleMapGLES
.find(m_textureSwizzle
);
378 if (it
!= SwizzleMapGLES
.cend())
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
);
396 void CGLESTexture::SwapBlueRedSwizzle(GLint
& component
)
398 if (component
== GL_RED
)
400 else if (component
== GL_BLUE
)
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
;
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
;
449 const auto it
= TextureMappingGLESExtensions
.find(textureFormat
);
450 if (it
!= TextureMappingGLESExtensions
.cend())
451 glFormat
= it
->second
;
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
;
468 const auto it
= TextureMappingGLES20
.find(textureFormat
);
469 if (it
!= TextureMappingGLES20
.cend())
470 glFormat
= it
->second
;
471 glFormat
.format
= glFormat
.internalFormat
;
476 const auto it
= TextureMappingGLESExtensions
.find(textureFormat
);
477 if (it
!= TextureMappingGLESExtensions
.cend())
478 glFormat
= it
->second
;