2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali/internal/render/renderers/render-texture.h>
21 #include <math.h> //floor, log2
24 #include <dali/devel-api/images/native-image-interface-extension.h>
36 // These match the GL specification
37 const GLint GL_MINIFY_DEFAULT = GL_NEAREST_MIPMAP_LINEAR;
38 const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR;
39 const GLint GL_WRAP_DEFAULT = GL_CLAMP_TO_EDGE;
41 // These are the Dali defaults
42 const GLint DALI_MINIFY_DEFAULT = GL_LINEAR;
43 const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
46 * @brief Convert a FilterMode to its corresponding GL type.
48 * @param[in] filterMode The FilterMode type.
49 * @param[in] daliDefault The filter mode to use if filterMode is DEFAULT.
50 * @param[in] glDefault The filter mode to use if filterMode is NONE.
51 * @return the equivalent GL filter mode.
53 GLint FilterModeToGL( FilterMode::Type filterMode, GLint daliDefault, GLint glDefault )
57 case FilterMode::NEAREST:
61 case FilterMode::LINEAR:
65 case FilterMode::NONE:
69 case FilterMode::NEAREST_MIPMAP_NEAREST:
71 return GL_NEAREST_MIPMAP_NEAREST;
73 case FilterMode::LINEAR_MIPMAP_NEAREST:
75 return GL_LINEAR_MIPMAP_NEAREST;
77 case FilterMode::NEAREST_MIPMAP_LINEAR:
79 return GL_NEAREST_MIPMAP_LINEAR;
81 case FilterMode::LINEAR_MIPMAP_LINEAR:
83 return GL_LINEAR_MIPMAP_LINEAR;
85 case FilterMode::DEFAULT:
95 * @brief Convert from a WrapMode to its corresponding GL enumeration
96 * @param[in] wrapMode The wrap mode
97 * @param[in] defaultWrapMode The mode to use if WrapMode is Default
98 * @return The equivalent GL wrap mode
100 GLint WrapModeToGL( WrapMode::Type wrapMode, GLint defaultWrapMode )
104 case WrapMode::CLAMP_TO_EDGE:
106 return GL_CLAMP_TO_EDGE;
108 case WrapMode::REPEAT:
112 case WrapMode::MIRRORED_REPEAT:
114 return GL_MIRRORED_REPEAT;
116 case WrapMode::DEFAULT:
118 return defaultWrapMode;
122 return defaultWrapMode;
126 * @brief Retrives the GL format, GL internal format and pixel data type from a Pixel::Format
127 * @param[in] pixelFormat The pixel format.
128 * @param[out] glFormat The gl format.
129 * @param[out] glInternalFormat The gl internal format.
130 * @param[out] pixelDataType The data type of the pixel data.
132 void PixelFormatToGl( Pixel::Format pixelFormat, GLenum& glFormat, GLint& glInternalFormat, GLenum& pixelDataType )
134 // Compressed textures have no pixelDataType, so init to an invalid value:
137 switch( pixelFormat )
141 pixelDataType = GL_UNSIGNED_BYTE;
148 pixelDataType = GL_UNSIGNED_BYTE;
149 glFormat= GL_LUMINANCE;
155 pixelDataType = GL_UNSIGNED_BYTE;
156 glFormat= GL_LUMINANCE_ALPHA;
162 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
169 DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
170 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
172 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
174 glFormat= GL_RGBA; // alpha is reserved but not used
179 case Pixel::RGBA4444:
181 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
186 case Pixel::BGRA4444:
188 DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
189 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
191 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
193 glFormat= GL_RGBA; // alpha is reserved but not used
198 case Pixel::RGBA5551:
200 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
205 case Pixel::BGRA5551:
207 DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
208 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
210 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
212 glFormat= GL_RGBA; // alpha is reserved but not used
219 pixelDataType = GL_UNSIGNED_BYTE;
226 pixelDataType = GL_UNSIGNED_BYTE;
227 glFormat= GL_RGBA; // alpha is reserved but not used
233 pixelDataType = GL_UNSIGNED_BYTE;
235 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
237 glFormat= GL_RGBA; // alpha is reserved but not used
242 case Pixel::RGBA8888:
244 pixelDataType = GL_UNSIGNED_BYTE;
249 case Pixel::BGRA8888:
251 pixelDataType = GL_UNSIGNED_BYTE;
253 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
255 glFormat= GL_RGBA; // alpha is reserved but not used
260 // GLES 2 extension compressed formats:
261 case Pixel::COMPRESSED_RGB8_ETC1:
263 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n" );
264 glFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
267 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
269 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n" );
270 glFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
274 // GLES 3.0 standard compressed formats:
275 case Pixel::COMPRESSED_R11_EAC:
277 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
278 glFormat = GL_COMPRESSED_R11_EAC;
281 case Pixel::COMPRESSED_SIGNED_R11_EAC:
283 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n" );
284 glFormat = GL_COMPRESSED_SIGNED_R11_EAC;
287 case Pixel::COMPRESSED_RG11_EAC:
289 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n" );
290 glFormat = GL_COMPRESSED_RG11_EAC;
293 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
295 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n" );
296 glFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
299 case Pixel::COMPRESSED_RGB8_ETC2:
301 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n" );
302 glFormat = GL_COMPRESSED_RGB8_ETC2;
305 case Pixel::COMPRESSED_SRGB8_ETC2:
307 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n" );
308 glFormat = GL_COMPRESSED_SRGB8_ETC2;
311 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
313 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
314 glFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
317 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
319 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
320 glFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
323 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
325 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n" );
326 glFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
329 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
331 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n" );
332 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
336 // GLES 3.1 extension compressed formats:
337 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
339 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n" );
340 glFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
343 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
345 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n" );
346 glFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
349 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
351 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n" );
352 glFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
355 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
357 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n" );
358 glFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
361 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
363 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n" );
364 glFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
367 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
369 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n" );
370 glFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
373 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
375 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n" );
376 glFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
379 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
381 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n" );
382 glFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
385 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
387 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n" );
388 glFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
391 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
393 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n" );
394 glFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
397 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
399 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n" );
400 glFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
403 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
405 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n" );
406 glFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
409 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
411 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n" );
412 glFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
415 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
417 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n" );
418 glFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
421 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
423 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n" );
424 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
427 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
429 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n" );
430 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
433 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
435 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n" );
436 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
439 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
441 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n" );
442 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
445 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
447 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n" );
448 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
451 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
453 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n" );
454 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
457 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
459 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n" );
460 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
463 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
465 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n" );
466 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
469 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
471 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n" );
472 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
475 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
477 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n" );
478 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
481 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
483 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n" );
484 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
487 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
489 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n" );
490 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
493 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
495 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n" );
496 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
499 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
501 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n" );
502 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
506 // GLES 3.0 floating point formats.
510 pixelDataType = GL_HALF_FLOAT;
516 pixelDataType = GL_FLOAT;
520 // GLES 3.0 depth and stencil formats
521 case Pixel::DEPTH_UNSIGNED_INT:
523 glFormat = GL_DEPTH_COMPONENT;
524 pixelDataType = GL_UNSIGNED_INT;
528 case Pixel::DEPTH_FLOAT:
530 glFormat = GL_DEPTH_COMPONENT;
531 pixelDataType = GL_FLOAT;
535 case Pixel::DEPTH_STENCIL:
537 glFormat = GL_DEPTH_STENCIL;
538 pixelDataType = GL_UNSIGNED_INT_24_8;
544 DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
550 switch( pixelFormat )
553 case Pixel::RGB32F: // FALL THROUGH
555 glInternalFormat = GL_R11F_G11F_B10F;
558 case Pixel::DEPTH_FLOAT:
560 glInternalFormat = GL_DEPTH_COMPONENT32F;
563 case Pixel::DEPTH_STENCIL:
565 glInternalFormat = GL_DEPTH24_STENCIL8;
570 glInternalFormat = glFormat;
578 * @brief Whether specified pixel format is compressed.
580 * @param [in] pixelformat Pixel format
581 * @return true if format is compressed, false otherwise
583 bool IsCompressedFormat(Pixel::Format pixelFormat)
591 case Pixel::RGBA4444:
592 case Pixel::RGBA5551:
594 case Pixel::BGRA4444:
595 case Pixel::BGRA5551:
599 case Pixel::RGBA8888:
600 case Pixel::BGRA8888:
603 case Pixel::DEPTH_UNSIGNED_INT:
604 case Pixel::DEPTH_FLOAT:
605 case Pixel::DEPTH_STENCIL:
611 case Pixel::COMPRESSED_R11_EAC:
612 case Pixel::COMPRESSED_SIGNED_R11_EAC:
613 case Pixel::COMPRESSED_RG11_EAC:
614 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
615 case Pixel::COMPRESSED_RGB8_ETC2:
616 case Pixel::COMPRESSED_SRGB8_ETC2:
617 case Pixel::COMPRESSED_RGB8_ETC1:
618 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
619 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
620 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
621 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
622 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
623 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
624 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
625 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
626 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
627 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
628 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
629 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
630 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
631 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
632 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
633 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
634 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
635 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
636 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
637 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
638 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
639 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
640 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
641 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
642 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
643 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
644 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
645 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
646 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
647 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
648 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
649 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
650 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
659 } //Unnamed namespace
662 Texture::Texture( Type type, Pixel::Format format, ImageDimensions size )
666 mTarget( ( type == TextureType::TEXTURE_2D ) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP ),
667 mGlInternalFormat( GL_RGB ),
669 mPixelDataType( GL_UNSIGNED_BYTE ),
670 mWidth( size.GetWidth() ),
671 mHeight( size.GetHeight() ),
672 mMaxMipMapLevel( 0 ),
674 mHasAlpha( HasAlpha( format ) ),
675 mIsCompressed( IsCompressedFormat( format ) )
677 PixelFormatToGl( format,
683 Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
684 : mNativeImage( nativeImageInterface ),
687 mTarget( GL_TEXTURE_2D ),
688 mGlInternalFormat( GL_RGB ),
690 mPixelDataType( GL_UNSIGNED_BYTE ),
691 mWidth( static_cast<uint16_t >( nativeImageInterface->GetWidth() ) ), // ignoring overflow, not happening in practice
692 mHeight( static_cast<uint16_t >( nativeImageInterface->GetHeight() ) ), // ignoring overflow, not happening in practice
693 mMaxMipMapLevel( 0 ),
694 mType( TextureType::TEXTURE_2D ),
695 mHasAlpha( nativeImageInterface->RequiresBlending() ),
696 mIsCompressed( false )
703 void Texture::Destroy( Context& context )
707 context.DeleteTextures( 1, &mId );
711 mNativeImage->GlExtensionDestroy();
716 void Texture::GlContextDestroyed()
721 void Texture::Initialize(Context& context)
725 if( mNativeImage->GlExtensionCreate() )
727 NativeImageInterface::Extension* extension = mNativeImage->GetExtension();
730 mTarget = extension->GetEglImageTextureTarget();
733 context.GenTextures( 1, &mId );
734 context.BindTexture( mTarget, mId );
735 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
737 //Apply default sampling parameters
738 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
739 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
740 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
741 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
743 // platform specific implementation decides on what GL extension to use
744 if( mNativeImage->TargetTexture() != 0u )
746 context.DeleteTextures( 1, &mId );
747 mNativeImage->GlExtensionDestroy();
754 //Create the texture and reserve memory for the first mipmap level.
755 context.GenTextures( 1, &mId );
756 context.BindTexture( mTarget, mId );
757 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
759 //Apply default sampling parameters
760 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
761 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
762 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
763 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
765 if( mType == TextureType::TEXTURE_2D )
769 context.TexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
773 context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
776 else if( mType == TextureType::TEXTURE_CUBE )
780 for( uint32_t i(0); i<6; ++i )
782 context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
787 for( uint32_t i(0); i<6; ++i )
789 context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
792 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
797 void Texture::Upload( Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params )
799 DALI_ASSERT_ALWAYS( mNativeImage == NULL );
801 //Get pointer to the data of the PixelData object
802 uint8_t* buffer( pixelData->GetBuffer() );
804 //This buffer is only used if manually converting from RGB to RGBA
805 std::vector< uint8_t > tempBuffer;
807 //Retrieves the pixel data element type, the gl format and gl internal format of the data contained in the PixelData object.
809 GLint glInternalFormat;
810 GLenum pixelDataElementType;
811 PixelFormatToGl( pixelData->GetPixelFormat(), glFormat, glInternalFormat, pixelDataElementType );
813 //Get the maximum mipmap level to set GL_TEXTURE_MAX_LEVEL parameter in GLES3x because is not
814 //necessary to upload all the mipmap levels
815 mMaxMipMapLevel = ( mMaxMipMapLevel > params.mipmap ) ? mMaxMipMapLevel : params.mipmap;
817 const bool isSubImage = ( ( params.xOffset != 0 ) ||
818 ( params.yOffset != 0 ) ||
819 ( params.width != ( mWidth / ( 1 << params.mipmap ) ) ) ||
820 ( params.height != ( mHeight / ( 1 << params.mipmap ) ) ) );
822 if( context.TextureRequiresConverting( glFormat, mGlFormat, isSubImage ) )
824 uint32_t dataSize = static_cast< uint32_t >( params.width ) * params.height;
825 //reserve() does not allocate the memory on some systems so can crash if not populated using push_back
826 tempBuffer.resize( dataSize * 4u );
827 for( uint32_t i = 0u; i < dataSize; ++i )
829 tempBuffer[i*4u] = buffer[i*3u];
830 tempBuffer[i*4u+1] = buffer[i*3u+1];
831 tempBuffer[i*4u+2] = buffer[i*3u+2];
832 tempBuffer[i*4u+3] = 0xFF;
835 buffer = &tempBuffer[0];
836 glFormat = mGlFormat; // Set the glFormat to GL_RGBA
839 //Upload data to the texture
841 context.BindTexture( mTarget, mId );
842 GLenum target( mTarget );
843 if( mType == TextureType::TEXTURE_CUBE )
845 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
848 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
852 //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
855 context.TexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, glFormat, pixelDataElementType, buffer );
859 context.CompressedTexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, static_cast<GLsizei>( pixelData->GetBufferSize() ), buffer );
864 //Specifying part of the image for the mipmap
867 context.TexSubImage2D( target, params.mipmap,
868 params.xOffset, params.yOffset, params.width, params.height,
869 glFormat, pixelDataElementType, buffer );
873 context.CompressedTexSubImage2D( target, params.mipmap,
874 params.xOffset, params.yOffset, params.width, params.height,
875 glFormat, static_cast<GLsizei>( pixelData->GetBufferSize() ), buffer );
880 bool Texture::Bind( Context& context, uint32_t textureUnit, Render::Sampler* sampler )
882 if( mNativeImage && mId == 0 )
884 Initialize( context );
889 context.BindTextureForUnit( static_cast<TextureUnit>( textureUnit ), mTarget, mId );
890 ApplySampler( context, sampler );
894 mNativeImage->PrepareTexture();
903 void Texture::ApplySampler( Context& context, Render::Sampler* sampler )
905 Render::Sampler oldSampler = mSampler;
906 mSampler = sampler ? *sampler : Sampler();
908 if( mSampler != oldSampler )
910 GLint mode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
911 if( mode != FilterModeToGL( oldSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT ) )
913 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, mode );
916 mode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
917 if( mode != FilterModeToGL( oldSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT ) )
919 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, mode );
922 mode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
923 if( mode != WrapModeToGL( oldSampler.mSWrapMode, GL_WRAP_DEFAULT ) )
925 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, mode );
928 mode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
929 if( mode != WrapModeToGL( oldSampler.mTWrapMode, GL_WRAP_DEFAULT ) )
931 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, mode );
934 if( mType == TextureType::TEXTURE_CUBE )
936 mode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
937 if( mode != WrapModeToGL( oldSampler.mRWrapMode, GL_WRAP_DEFAULT ) )
939 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, mode );
945 context.TexParameteri( mTarget, GL_TEXTURE_MAX_LEVEL, mMaxMipMapLevel );
950 bool Texture::HasAlphaChannel() const
955 void Texture::GenerateMipmaps( Context& context )
957 //GL_TEXTURE_MAX_LEVEL does not need to be set when mipmaps are generated by GL
959 context.BindTexture( mTarget, mId );
960 context.GenerateMipmap( mTarget );