2 * Copyright (c) 2018 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;
522 DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
528 switch( pixelFormat )
531 case Pixel::RGB32F: // FALL THROUGH
533 glInternalFormat = GL_R11F_G11F_B10F;
538 glInternalFormat = glFormat;
546 * @brief Whether specified pixel format is compressed.
548 * @param [in] pixelformat Pixel format
549 * @return true if format is compressed, false otherwise
551 bool IsCompressedFormat(Pixel::Format pixelFormat)
559 case Pixel::RGBA4444:
560 case Pixel::RGBA5551:
562 case Pixel::BGRA4444:
563 case Pixel::BGRA5551:
567 case Pixel::RGBA8888:
568 case Pixel::BGRA8888:
576 case Pixel::COMPRESSED_R11_EAC:
577 case Pixel::COMPRESSED_SIGNED_R11_EAC:
578 case Pixel::COMPRESSED_RG11_EAC:
579 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
580 case Pixel::COMPRESSED_RGB8_ETC2:
581 case Pixel::COMPRESSED_SRGB8_ETC2:
582 case Pixel::COMPRESSED_RGB8_ETC1:
583 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
584 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
585 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
586 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
587 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
588 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
589 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
590 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
591 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
592 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
593 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
594 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
595 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
596 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
597 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
598 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
599 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
600 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
601 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
602 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
603 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
604 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
605 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
606 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
607 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
608 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
609 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
610 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
611 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
612 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
613 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
614 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
615 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
624 } //Unnamed namespace
627 Texture::Texture( Type type, Pixel::Format format, ImageDimensions size )
631 mTarget( ( type == TextureType::TEXTURE_2D ) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP ),
632 mGlInternalFormat( GL_RGB ),
634 mPixelDataType( GL_UNSIGNED_BYTE ),
635 mWidth( size.GetWidth() ),
636 mHeight( size.GetHeight() ),
637 mMaxMipMapLevel( 0 ),
639 mHasAlpha( HasAlpha( format ) ),
640 mIsCompressed( IsCompressedFormat( format ) )
642 PixelFormatToGl( format,
648 Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
649 : mNativeImage( nativeImageInterface ),
652 mTarget( GL_TEXTURE_2D ),
653 mGlInternalFormat( GL_RGB ),
655 mPixelDataType( GL_UNSIGNED_BYTE ),
656 mWidth( static_cast<uint16_t >( nativeImageInterface->GetWidth() ) ), // ignoring overflow, not happening in practice
657 mHeight( static_cast<uint16_t >( nativeImageInterface->GetHeight() ) ), // ignoring overflow, not happening in practice
658 mMaxMipMapLevel( 0 ),
659 mType( TextureType::TEXTURE_2D ),
660 mHasAlpha( nativeImageInterface->RequiresBlending() ),
661 mIsCompressed( false )
668 void Texture::Destroy( Context& context )
672 context.DeleteTextures( 1, &mId );
676 mNativeImage->GlExtensionDestroy();
681 void Texture::GlContextDestroyed()
686 void Texture::Initialize(Context& context)
690 if( mNativeImage->GlExtensionCreate() )
692 NativeImageInterface::Extension* extension = mNativeImage->GetExtension();
695 mTarget = extension->GetEglImageTextureTarget();
698 context.GenTextures( 1, &mId );
699 context.BindTexture( mTarget, mId );
700 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
702 //Apply default sampling parameters
703 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
704 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
705 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
706 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
708 // platform specific implementation decides on what GL extension to use
709 if( mNativeImage->TargetTexture() != 0u )
711 context.DeleteTextures( 1, &mId );
712 mNativeImage->GlExtensionDestroy();
719 //Create the texture and reserve memory for the first mipmap level.
720 context.GenTextures( 1, &mId );
721 context.BindTexture( mTarget, mId );
722 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
724 //Apply default sampling parameters
725 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
726 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
727 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
728 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
730 if( mType == TextureType::TEXTURE_2D )
734 context.TexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
738 context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
741 else if( mType == TextureType::TEXTURE_CUBE )
745 for( uint32_t i(0); i<6; ++i )
747 context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
752 for( uint32_t i(0); i<6; ++i )
754 context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
757 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
762 void Texture::Upload( Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params )
764 DALI_ASSERT_ALWAYS( mNativeImage == NULL );
766 //Get pointer to the data of the PixelData object
767 uint8_t* buffer( pixelData->GetBuffer() );
769 //This buffer is only used if manually converting from RGB to RGBA
770 uint8_t* tempBuffer(0);
772 //Retrieves the pixel data element type, the gl format and gl internal format of the data contained in the PixelData object.
774 GLint glInternalFormat;
775 GLenum pixelDataElementType;
776 PixelFormatToGl( pixelData->GetPixelFormat(), glFormat, glInternalFormat, pixelDataElementType );
778 //Get the maximum mipmap level to set GL_TEXTURE_MAX_LEVEL parameter in GLES3x because is not
779 //necessary to upload all the mipmap levels
780 mMaxMipMapLevel = ( mMaxMipMapLevel > params.mipmap ) ? mMaxMipMapLevel : params.mipmap;
782 const bool isSubImage = ( ( params.xOffset != 0 ) ||
783 ( params.yOffset != 0 ) ||
784 ( params.width != ( mWidth / ( 1 << params.mipmap ) ) ) ||
785 ( params.height != ( mHeight / ( 1 << params.mipmap ) ) ) );
787 bool convert = ( ( glFormat == GL_RGB ) && ( mGlFormat == GL_RGBA ) );
788 #if DALI_GLES_VERSION >= 30
789 // Don't convert manually from RGB to RGBA if GLES >= 3.0 and a sub-image is uploaded.
790 convert = convert && !isSubImage;
795 uint32_t dataSize = static_cast< uint32_t >( params.width ) * params.height;
796 tempBuffer = new uint8_t[dataSize*4u];
797 for( uint32_t i = 0u; i < dataSize; ++i )
799 tempBuffer[i*4u] = buffer[i*3u];
800 tempBuffer[i*4u+1] = buffer[i*3u+1];
801 tempBuffer[i*4u+2] = buffer[i*3u+2];
802 tempBuffer[i*4u+3] = 0xFF;
806 glFormat = mGlFormat; // Set the glFormat to GL_RGBA
809 //Upload data to the texture
811 context.BindTexture( mTarget, mId );
812 GLenum target( mTarget );
813 if( mType == TextureType::TEXTURE_CUBE )
815 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
818 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
822 //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
825 context.TexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, glFormat, pixelDataElementType, buffer );
829 context.CompressedTexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, static_cast<GLsizei>( pixelData->GetBufferSize() ), buffer );
834 //Specifying part of the image for the mipmap
837 context.TexSubImage2D( target, params.mipmap,
838 params.xOffset, params.yOffset, params.width, params.height,
839 glFormat, pixelDataElementType, buffer );
843 context.CompressedTexSubImage2D( target, params.mipmap,
844 params.xOffset, params.yOffset, params.width, params.height,
845 glFormat, static_cast<GLsizei>( pixelData->GetBufferSize() ), buffer );
850 //Destroy temp buffer used for conversion RGB->RGBA
854 bool Texture::Bind( Context& context, uint32_t textureUnit, Render::Sampler* sampler )
856 if( mNativeImage && mId == 0 )
858 Initialize( context );
863 context.BindTextureForUnit( static_cast<TextureUnit>( textureUnit ), mTarget, mId );
864 ApplySampler( context, sampler );
868 mNativeImage->PrepareTexture();
877 void Texture::ApplySampler( Context& context, Render::Sampler* sampler )
879 Render::Sampler oldSampler = mSampler;
880 mSampler = sampler ? *sampler : Sampler();
882 if( mSampler != oldSampler )
884 GLint mode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
885 if( mode != FilterModeToGL( oldSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT ) )
887 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, mode );
890 mode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
891 if( mode != FilterModeToGL( oldSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT ) )
893 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, mode );
896 mode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
897 if( mode != WrapModeToGL( oldSampler.mSWrapMode, GL_WRAP_DEFAULT ) )
899 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, mode );
902 mode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
903 if( mode != WrapModeToGL( oldSampler.mTWrapMode, GL_WRAP_DEFAULT ) )
905 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, mode );
908 if( mType == TextureType::TEXTURE_CUBE )
910 mode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
911 if( mode != WrapModeToGL( oldSampler.mRWrapMode, GL_WRAP_DEFAULT ) )
913 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, mode );
917 #if DALI_GLES_VERSION >= 30
918 //In GLES 3.0 we do not need to upload all of the mipmap levels, but GL_TEXTURE_MAX_LEVEL must be set
921 context.TexParameteri( mTarget, GL_TEXTURE_MAX_LEVEL, mMaxMipMapLevel );
928 bool Texture::HasAlphaChannel()
933 void Texture::GenerateMipmaps( Context& context )
935 //GL_TEXTURE_MAX_LEVEL does not need to be set when mipmaps are generated by GL
937 context.BindTexture( mTarget, mId );
938 context.GenerateMipmap( mTarget );