2 * Copyright (c) 2017 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/pixel-devel.h>
25 #include <dali/devel-api/images/native-image-interface-extension.h>
37 // These match the GL specification
38 const GLint GL_MINIFY_DEFAULT = GL_NEAREST_MIPMAP_LINEAR;
39 const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR;
40 const GLint GL_WRAP_DEFAULT = GL_CLAMP_TO_EDGE;
42 // These are the Dali defaults
43 const GLint DALI_MINIFY_DEFAULT = GL_LINEAR;
44 const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
47 * @brief Convert a FilterMode to its corresponding GL type.
49 * @param[in] filterMode The FilterMode type.
50 * @param[in] daliDefault The filter mode to use if filterMode is DEFAULT.
51 * @param[in] glDefault The filter mode to use if filterMode is NONE.
52 * @return the equivalent GL filter mode.
54 GLint FilterModeToGL( FilterMode::Type filterMode, GLint daliDefault, GLint glDefault )
58 case FilterMode::NEAREST:
62 case FilterMode::LINEAR:
66 case FilterMode::NONE:
70 case FilterMode::NEAREST_MIPMAP_NEAREST:
72 return GL_NEAREST_MIPMAP_NEAREST;
74 case FilterMode::LINEAR_MIPMAP_NEAREST:
76 return GL_LINEAR_MIPMAP_NEAREST;
78 case FilterMode::NEAREST_MIPMAP_LINEAR:
80 return GL_NEAREST_MIPMAP_LINEAR;
82 case FilterMode::LINEAR_MIPMAP_LINEAR:
84 return GL_LINEAR_MIPMAP_LINEAR;
86 case FilterMode::DEFAULT:
96 * @brief Convert from a WrapMode to its corresponding GL enumeration
97 * @param[in] wrapMode The wrap mode
98 * @param[in] defaultWrapMode The mode to use if WrapMode is Default
99 * @return The equivalent GL wrap mode
101 GLint WrapModeToGL( WrapMode::Type wrapMode, GLint defaultWrapMode )
105 case WrapMode::CLAMP_TO_EDGE:
107 return GL_CLAMP_TO_EDGE;
109 case WrapMode::REPEAT:
113 case WrapMode::MIRRORED_REPEAT:
115 return GL_MIRRORED_REPEAT;
117 case WrapMode::DEFAULT:
119 return defaultWrapMode;
123 return defaultWrapMode;
127 * @brief Retrives the GL format, GL internal format and pixel data type from a Pixel::Format
128 * @param[in] pixelFormat The pixel format.
129 * @param[out] glFormat The gl format.
130 * @param[out] glInternalFormat The gl internal format.
131 * @param[out] pixelDataType The data type of the pixel data.
133 void PixelFormatToGl( DevelPixel::Format pixelFormat, GLenum& glFormat, GLint& glInternalFormat, GLenum& pixelDataType )
135 // Compressed textures have no pixelDataType, so init to an invalid value:
138 switch( pixelFormat )
142 pixelDataType = GL_UNSIGNED_BYTE;
149 pixelDataType = GL_UNSIGNED_BYTE;
150 glFormat= GL_LUMINANCE;
156 pixelDataType = GL_UNSIGNED_BYTE;
157 glFormat= GL_LUMINANCE_ALPHA;
163 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
170 DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
171 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
173 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
175 glFormat= GL_RGBA; // alpha is reserved but not used
180 case Pixel::RGBA4444:
182 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
187 case Pixel::BGRA4444:
189 DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
190 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
192 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
194 glFormat= GL_RGBA; // alpha is reserved but not used
199 case Pixel::RGBA5551:
201 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
206 case Pixel::BGRA5551:
208 DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
209 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
211 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
213 glFormat= GL_RGBA; // alpha is reserved but not used
220 pixelDataType = GL_UNSIGNED_BYTE;
227 pixelDataType = GL_UNSIGNED_BYTE;
228 glFormat= GL_RGBA; // alpha is reserved but not used
234 pixelDataType = GL_UNSIGNED_BYTE;
236 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
238 glFormat= GL_RGBA; // alpha is reserved but not used
243 case Pixel::RGBA8888:
245 pixelDataType = GL_UNSIGNED_BYTE;
250 case Pixel::BGRA8888:
252 pixelDataType = GL_UNSIGNED_BYTE;
254 glFormat= GL_BGRA_EXT; // alpha is reserved but not used
256 glFormat= GL_RGBA; // alpha is reserved but not used
261 // GLES 2 extension compressed formats:
262 case Pixel::COMPRESSED_RGB8_ETC1:
264 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n" );
265 glFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
268 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
270 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n" );
271 glFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
275 // GLES 3.0 standard compressed formats:
276 case Pixel::COMPRESSED_R11_EAC:
278 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
279 glFormat = GL_COMPRESSED_R11_EAC;
282 case Pixel::COMPRESSED_SIGNED_R11_EAC:
284 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n" );
285 glFormat = GL_COMPRESSED_SIGNED_R11_EAC;
288 case Pixel::COMPRESSED_RG11_EAC:
290 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n" );
291 glFormat = GL_COMPRESSED_RG11_EAC;
294 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
296 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n" );
297 glFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
300 case Pixel::COMPRESSED_RGB8_ETC2:
302 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n" );
303 glFormat = GL_COMPRESSED_RGB8_ETC2;
306 case Pixel::COMPRESSED_SRGB8_ETC2:
308 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n" );
309 glFormat = GL_COMPRESSED_SRGB8_ETC2;
312 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
314 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
315 glFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
318 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
320 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
321 glFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
324 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
326 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n" );
327 glFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
330 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
332 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n" );
333 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
337 // GLES 3.1 extension compressed formats:
338 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
340 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n" );
341 glFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
344 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
346 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n" );
347 glFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
350 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
352 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n" );
353 glFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
356 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
358 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n" );
359 glFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
362 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
364 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n" );
365 glFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
368 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
370 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n" );
371 glFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
374 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
376 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n" );
377 glFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
380 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
382 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n" );
383 glFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
386 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
388 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n" );
389 glFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
392 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
394 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n" );
395 glFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
398 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
400 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n" );
401 glFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
404 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
406 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n" );
407 glFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
410 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
412 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n" );
413 glFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
416 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
418 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n" );
419 glFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
422 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
424 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n" );
425 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
428 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
430 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n" );
431 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
434 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
436 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n" );
437 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
440 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
442 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n" );
443 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
446 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
448 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n" );
449 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
452 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
454 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n" );
455 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
458 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
460 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n" );
461 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
464 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
466 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n" );
467 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
470 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
472 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n" );
473 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
476 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
478 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n" );
479 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
482 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
484 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n" );
485 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
488 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
490 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n" );
491 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
494 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
496 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n" );
497 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
500 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
502 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n" );
503 glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
507 // GLES 3.0 floating point formats.
508 case DevelPixel::RGB16F:
511 pixelDataType = GL_HALF_FLOAT;
514 case DevelPixel::RGB32F:
517 pixelDataType = GL_FLOAT;
523 DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
529 switch( pixelFormat )
531 case DevelPixel::RGB16F:
532 case DevelPixel::RGB32F: // FALL THROUGH
534 glInternalFormat = GL_R11F_G11F_B10F;
539 glInternalFormat = glFormat;
547 * @brief Whether specified pixel format is compressed.
549 * @param [in] pixelformat Pixel format
550 * @return true if format is compressed, false otherwise
552 bool IsCompressedFormat(Pixel::Format pixelFormat)
560 case Pixel::RGBA4444:
561 case Pixel::RGBA5551:
563 case Pixel::BGRA4444:
564 case Pixel::BGRA5551:
568 case Pixel::RGBA8888:
569 case Pixel::BGRA8888:
575 case Pixel::COMPRESSED_R11_EAC:
576 case Pixel::COMPRESSED_SIGNED_R11_EAC:
577 case Pixel::COMPRESSED_RG11_EAC:
578 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
579 case Pixel::COMPRESSED_RGB8_ETC2:
580 case Pixel::COMPRESSED_SRGB8_ETC2:
581 case Pixel::COMPRESSED_RGB8_ETC1:
582 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
583 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
584 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
585 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
586 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
587 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
588 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
589 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
590 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
591 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
592 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
593 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
594 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
595 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
596 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
597 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
598 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
599 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
600 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
601 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
602 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
603 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
604 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
605 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
606 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
607 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
608 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
609 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
610 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
611 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
612 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
613 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
614 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
623 } //Unnamed namespace
626 Texture::Texture( Type type, Pixel::Format format, ImageDimensions size )
630 mTarget( ( type == TextureType::TEXTURE_2D ) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP ),
631 mGlInternalFormat( GL_RGB ),
633 mPixelDataType( GL_UNSIGNED_BYTE ),
634 mWidth( size.GetWidth() ),
635 mHeight( size.GetHeight() ),
636 mMaxMipMapLevel( 0 ),
638 mHasAlpha( HasAlpha( format ) ),
639 mIsCompressed( IsCompressedFormat( format ) )
641 PixelFormatToGl( static_cast<DevelPixel::Format>( format ),
647 Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
648 : mNativeImage( nativeImageInterface ),
651 mTarget( GL_TEXTURE_2D ),
652 mGlInternalFormat( GL_RGB ),
654 mPixelDataType( GL_UNSIGNED_BYTE ),
655 mWidth( nativeImageInterface->GetWidth() ),
656 mHeight( nativeImageInterface->GetHeight() ),
657 mMaxMipMapLevel( 0 ),
658 mType( TextureType::TEXTURE_2D ),
659 mHasAlpha( nativeImageInterface->RequiresBlending() ),
660 mIsCompressed( false )
667 void Texture::Destroy( Context& context )
671 context.DeleteTextures( 1, &mId );
675 mNativeImage->GlExtensionDestroy();
680 void Texture::GlContextDestroyed()
685 void Texture::Initialize(Context& context)
689 if( mNativeImage->GlExtensionCreate() )
691 NativeImageInterface::Extension* extension = mNativeImage->GetExtension();
694 mTarget = extension->GetEglImageTextureTarget();
697 context.GenTextures( 1, &mId );
698 context.BindTexture( mTarget, mId );
699 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
701 //Apply default sampling parameters
702 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
703 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
704 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
705 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
707 // platform specific implementation decides on what GL extension to use
708 if( mNativeImage->TargetTexture() != 0u )
710 context.DeleteTextures( 1, &mId );
711 mNativeImage->GlExtensionDestroy();
718 //Create the texture and reserve memory for the first mipmap level.
719 context.GenTextures( 1, &mId );
720 context.BindTexture( mTarget, mId );
721 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
723 //Apply default sampling parameters
724 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
725 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
726 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
727 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
729 if( mType == TextureType::TEXTURE_2D )
733 context.TexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
737 context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
740 else if( mType == TextureType::TEXTURE_CUBE )
744 for( unsigned int i(0); i<6; ++i )
746 context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
751 for( unsigned int i(0); i<6; ++i )
753 context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
756 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
761 void Texture::Upload( Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params )
763 DALI_ASSERT_ALWAYS( mNativeImage == NULL );
765 //Get pointer to the data of the PixelData object
766 unsigned char* buffer( pixelData->GetBuffer() );
768 //This buffer is only used if manually converting from RGB to RGBA
769 unsigned char* tempBuffer(0);
771 //Retrieves the pixel data element type, the gl format and gl internal format of the data contained in the PixelData object.
773 GLint glInternalFormat;
774 GLenum pixelDataElementType;
775 PixelFormatToGl( static_cast<DevelPixel::Format>( pixelData->GetPixelFormat() ), glFormat, glInternalFormat, pixelDataElementType );
777 //Get the maximum mipmap level to set GL_TEXTURE_MAX_LEVEL parameter in GLES3x because is not
778 //necessary to upload all the mipmap levels
779 mMaxMipMapLevel = ( mMaxMipMapLevel > params.mipmap ) ? mMaxMipMapLevel : params.mipmap;
781 const bool isSubImage = ( ( params.xOffset != 0 ) ||
782 ( params.yOffset != 0 ) ||
783 ( params.width != ( mWidth / ( 1 << params.mipmap ) ) ) ||
784 ( params.height != ( mHeight / ( 1 << params.mipmap ) ) ) );
786 bool convert = ( ( glFormat == GL_RGB ) && ( mGlFormat == GL_RGBA ) );
787 #if DALI_GLES_VERSION >= 30
788 // Don't convert manually from RGB to RGBA if GLES >= 3.0 and a sub-image is uploaded.
789 convert = convert && !isSubImage;
794 size_t dataSize = static_cast< size_t >( params.width ) * params.height;
795 tempBuffer = new unsigned char[dataSize*4u];
796 for( size_t i(0u); i<dataSize; i++ )
798 tempBuffer[i*4u] = buffer[i*3u];
799 tempBuffer[i*4u+1] = buffer[i*3u+1];
800 tempBuffer[i*4u+2] = buffer[i*3u+2];
801 tempBuffer[i*4u+3] = 0xFF;
805 glFormat = mGlFormat; // Set the glFormat to GL_RGBA
808 //Upload data to the texture
810 context.BindTexture( mTarget, mId );
811 GLenum target( mTarget );
812 if( mType == TextureType::TEXTURE_CUBE )
814 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
817 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
821 //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
824 context.TexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, glFormat, pixelDataElementType, buffer );
828 context.CompressedTexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, pixelData->GetBufferSize(), buffer );
833 //Specifying part of the image for the mipmap
836 context.TexSubImage2D( target, params.mipmap,
837 params.xOffset, params.yOffset, params.width, params.height,
838 glFormat, pixelDataElementType, buffer );
842 context.CompressedTexSubImage2D( target, params.mipmap,
843 params.xOffset, params.yOffset, params.width, params.height,
844 glFormat, pixelData->GetBufferSize(), buffer );
849 //Destroy temp buffer used for conversion RGB->RGBA
853 bool Texture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
855 if( mNativeImage && mId == 0 )
857 Initialize( context );
862 context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
863 context.BindTexture( 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 );