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>
19 #include <dali/devel-api/images/native-image-interface-extension.h>
22 #include <math.h> //floor, log2
34 // These match the GL specification
35 const GLint GL_MINIFY_DEFAULT = GL_NEAREST_MIPMAP_LINEAR;
36 const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR;
37 const GLint GL_WRAP_DEFAULT = GL_CLAMP_TO_EDGE;
39 // These are the Dali defaults
40 const GLint DALI_MINIFY_DEFAULT = GL_LINEAR;
41 const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
44 * @brief Convert a FilterMode to its corresponding GL type.
46 * @param[in] filterMode The FilterMode type.
47 * @param[in] daliDefault The filter mode to use if filterMode is DEFAULT.
48 * @param[in] glDefault The filter mode to use if filterMode is NONE.
49 * @return the equivalent GL filter mode.
51 GLint FilterModeToGL( FilterMode::Type filterMode, GLint daliDefault, GLint glDefault )
55 case FilterMode::NEAREST:
59 case FilterMode::LINEAR:
63 case FilterMode::NONE:
67 case FilterMode::NEAREST_MIPMAP_NEAREST:
69 return GL_NEAREST_MIPMAP_NEAREST;
71 case FilterMode::LINEAR_MIPMAP_NEAREST:
73 return GL_LINEAR_MIPMAP_NEAREST;
75 case FilterMode::NEAREST_MIPMAP_LINEAR:
77 return GL_NEAREST_MIPMAP_LINEAR;
79 case FilterMode::LINEAR_MIPMAP_LINEAR:
81 return GL_LINEAR_MIPMAP_LINEAR;
83 case FilterMode::DEFAULT:
93 * @brief Convert from a WrapMode to its corresponding GL enumeration
94 * @param[in] wrapMode The wrap mode
95 * @param[in] defaultWrapMode The mode to use if WrapMode is Default
96 * @return The equivalent GL wrap mode
98 GLint WrapModeToGL( WrapMode::Type wrapMode, GLint defaultWrapMode )
102 case WrapMode::CLAMP_TO_EDGE:
104 return GL_CLAMP_TO_EDGE;
106 case WrapMode::REPEAT:
110 case WrapMode::MIRRORED_REPEAT:
112 return GL_MIRRORED_REPEAT;
114 case WrapMode::DEFAULT:
116 return defaultWrapMode;
120 return defaultWrapMode;
124 * @brief Retrive GL internal format and pixel data type from a Pixel::Format
125 * @param[in] pixelFormat The pixel format
126 * @param[out] pixelDataType The data type of the pixel data
127 * @param[out] internalFormat The internal format
129 void PixelFormatToGl( Pixel::Format pixelformat, unsigned& pixelDataType, unsigned& internalFormat )
131 // Compressed textures have no pixelDataType, so init to an invalid value:
134 switch( pixelformat )
138 pixelDataType = GL_UNSIGNED_BYTE;
139 internalFormat= GL_ALPHA;
145 pixelDataType = GL_UNSIGNED_BYTE;
146 internalFormat= GL_LUMINANCE;
152 pixelDataType = GL_UNSIGNED_BYTE;
153 internalFormat= GL_LUMINANCE_ALPHA;
159 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
160 internalFormat= GL_RGB;
166 DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
167 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
169 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
171 internalFormat= GL_RGBA; // alpha is reserved but not used
176 case Pixel::RGBA4444:
178 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
179 internalFormat= GL_RGBA;
183 case Pixel::BGRA4444:
185 DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
186 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
188 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
190 internalFormat= GL_RGBA; // alpha is reserved but not used
195 case Pixel::RGBA5551:
197 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
198 internalFormat= GL_RGBA;
202 case Pixel::BGRA5551:
204 DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
205 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
207 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
209 internalFormat= GL_RGBA; // alpha is reserved but not used
216 pixelDataType = GL_UNSIGNED_BYTE;
217 internalFormat= GL_RGB;
223 pixelDataType = GL_UNSIGNED_BYTE;
224 internalFormat= GL_RGBA; // alpha is reserved but not used
230 pixelDataType = GL_UNSIGNED_BYTE;
232 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
234 internalFormat= GL_RGBA; // alpha is reserved but not used
239 case Pixel::RGBA8888:
241 pixelDataType = GL_UNSIGNED_BYTE;
242 internalFormat= GL_RGBA;
246 case Pixel::BGRA8888:
248 pixelDataType = GL_UNSIGNED_BYTE;
250 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
252 internalFormat= GL_RGBA; // alpha is reserved but not used
257 // GLES 2 extension compressed formats:
258 case Pixel::COMPRESSED_RGB8_ETC1:
260 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n" );
261 internalFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
264 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
266 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n" );
267 internalFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
271 // GLES 3.0 standard compressed formats:
272 case Pixel::COMPRESSED_R11_EAC:
274 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
275 internalFormat = GL_COMPRESSED_R11_EAC;
278 case Pixel::COMPRESSED_SIGNED_R11_EAC:
280 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n" );
281 internalFormat = GL_COMPRESSED_SIGNED_R11_EAC;
284 case Pixel::COMPRESSED_RG11_EAC:
286 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n" );
287 internalFormat = GL_COMPRESSED_RG11_EAC;
290 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
292 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n" );
293 internalFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
296 case Pixel::COMPRESSED_RGB8_ETC2:
298 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n" );
299 internalFormat = GL_COMPRESSED_RGB8_ETC2;
302 case Pixel::COMPRESSED_SRGB8_ETC2:
304 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n" );
305 internalFormat = GL_COMPRESSED_SRGB8_ETC2;
308 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
310 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
311 internalFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
314 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
316 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
317 internalFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
320 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
322 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n" );
323 internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
326 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
328 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n" );
329 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
333 // GLES 3.1 extension compressed formats:
334 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
336 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n" );
337 internalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
340 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
342 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n" );
343 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
346 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
348 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n" );
349 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
352 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
354 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n" );
355 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
358 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
360 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n" );
361 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
364 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
366 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n" );
367 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
370 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
372 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n" );
373 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
376 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
378 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n" );
379 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
382 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
384 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n" );
385 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
388 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
390 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n" );
391 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
394 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
396 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n" );
397 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
400 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
402 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n" );
403 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
406 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
408 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n" );
409 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
412 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
414 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n" );
415 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
418 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
420 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n" );
421 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
424 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
426 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n" );
427 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
430 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
432 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n" );
433 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
436 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
438 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n" );
439 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
442 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
444 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n" );
445 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
448 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
450 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n" );
451 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
454 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
456 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n" );
457 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
460 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
462 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n" );
463 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
466 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
468 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n" );
469 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
472 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
474 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n" );
475 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
478 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
480 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n" );
481 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
484 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
486 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n" );
487 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
490 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
492 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n" );
493 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
496 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
498 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n" );
499 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
505 DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
513 * @brief Whether specified pixel format is compressed.
515 * @param [in] pixelformat Pixel format
516 * @return true if format is compressed, false otherwise
518 bool IsCompressedFormat(Pixel::Format pixelFormat)
526 case Pixel::RGBA4444:
527 case Pixel::RGBA5551:
529 case Pixel::BGRA4444:
530 case Pixel::BGRA5551:
534 case Pixel::RGBA8888:
535 case Pixel::BGRA8888:
541 case Pixel::COMPRESSED_R11_EAC:
542 case Pixel::COMPRESSED_SIGNED_R11_EAC:
543 case Pixel::COMPRESSED_RG11_EAC:
544 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
545 case Pixel::COMPRESSED_RGB8_ETC2:
546 case Pixel::COMPRESSED_SRGB8_ETC2:
547 case Pixel::COMPRESSED_RGB8_ETC1:
548 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
549 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
550 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
551 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
552 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
553 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
554 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
555 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
556 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
557 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
558 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
559 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
560 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
561 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
562 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
563 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
564 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
565 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
566 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
567 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
568 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
569 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
570 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
571 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
572 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
573 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
574 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
575 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
576 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
577 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
578 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
579 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
580 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
589 } //Unnamed namespace
592 Texture::Texture( Type type, Pixel::Format format, unsigned int width, unsigned int height )
594 mTarget( (type == TextureType::TEXTURE_2D)? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP ),
598 mInternalFormat(GL_RGB),
599 mPixelDataType(GL_UNSIGNED_BYTE),
603 mHasAlpha( HasAlpha( format ) ),
604 mIsCompressed( IsCompressedFormat( format ) )
606 PixelFormatToGl( format, mPixelDataType, mInternalFormat );
609 Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
611 mTarget( GL_TEXTURE_2D ),
612 mType( TextureType::TEXTURE_2D ),
614 mNativeImage( nativeImageInterface ),
615 mInternalFormat(GL_RGB),
616 mPixelDataType(GL_UNSIGNED_BYTE),
617 mWidth( nativeImageInterface->GetWidth() ),
618 mHeight( nativeImageInterface->GetHeight() ),
620 mHasAlpha( nativeImageInterface->RequiresBlending() ),
621 mIsCompressed( false )
628 void Texture::Destroy( Context& context )
632 context.DeleteTextures( 1, &mId );
636 mNativeImage->GlExtensionDestroy();
641 void Texture::GlContextDestroyed()
646 void Texture::Initialize(Context& context)
650 if( mNativeImage->GlExtensionCreate() )
652 NativeImageInterface::Extension* extension = mNativeImage->GetExtension();
655 mTarget = extension->GetEglImageTextureTarget();
658 context.GenTextures( 1, &mId );
659 context.BindTexture( mTarget, mId );
660 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
662 //Apply default sampling parameters
663 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
664 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
665 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
666 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
668 // platform specific implementation decides on what GL extension to use
669 if( mNativeImage->TargetTexture() != 0u )
671 context.DeleteTextures( 1, &mId );
672 mNativeImage->GlExtensionDestroy();
679 //Create the texture and reserve memory for the first mipmap level.
680 context.GenTextures( 1, &mId );
681 context.BindTexture( mTarget, mId );
682 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
684 //Apply default sampling parameters
685 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
686 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
687 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
688 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
690 if( mType == TextureType::TEXTURE_2D )
694 context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
698 context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
701 else if( mType == TextureType::TEXTURE_CUBE )
705 for( unsigned int i(0); i<6; ++i )
707 context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
712 for( unsigned int i(0); i<6; ++i )
714 context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
717 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
722 void Texture::Upload( Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params )
724 DALI_ASSERT_ALWAYS( mNativeImage == NULL );
726 //Get pointer to the data of the PixelData object
727 unsigned char* buffer( pixelData->GetBuffer() );
729 //This buffer is only used if manually converting from RGB to RGBA
730 unsigned char* tempBuffer(0);
732 //Get pixel format and data type of the data contained in the PixelData object
733 GLenum pixelDataFormat, pixelDataElementType;
734 PixelFormatToGl( pixelData->GetPixelFormat(), pixelDataElementType, pixelDataFormat );
736 //Get the maximum mipmap level to set GL_TEXTURE_MAX_LEVEL parameter in GLES3x because is not
737 //necessary to upload all the mipmap levels
738 mMaxMipMapLevel = ( mMaxMipMapLevel > params.mipmap ) ? mMaxMipMapLevel : params.mipmap;
740 #if DALI_GLES_VERSION < 30
741 if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA )
743 //Convert manually from RGB to RGBA if GLES < 3 ( GLES 3 can do the conversion automatically when uploading )
744 size_t dataSize = static_cast< size_t >( params.width ) * params.height;
745 tempBuffer = new unsigned char[dataSize*4u];
746 for( size_t i(0u); i<dataSize; i++ )
748 tempBuffer[i*4u] = buffer[i*3u];
749 tempBuffer[i*4u+1] = buffer[i*3u+1];
750 tempBuffer[i*4u+2] = buffer[i*3u+2];
751 tempBuffer[i*4u+3] = 0xFF;
755 pixelDataFormat = mInternalFormat;
759 //Upload data to the texture
761 context.BindTexture( mTarget, mId );
762 GLenum target( mTarget );
763 if( mType == TextureType::TEXTURE_CUBE )
765 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
768 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
770 if( params.xOffset == 0 && params.yOffset == 0 &&
771 params.width == ( mWidth / (1<<params.mipmap) ) &&
772 params.height == ( mHeight / (1<<params.mipmap) ) )
774 //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
777 context.TexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelDataFormat, pixelDataElementType, buffer );
781 context.CompressedTexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelData->GetBufferSize(), buffer );
786 //Specifying part of the image for the mipmap
789 context.TexSubImage2D( target, params.mipmap,
790 params.xOffset, params.yOffset, params.width, params.height,
791 pixelDataFormat, pixelDataElementType, buffer );
795 context.CompressedTexSubImage2D( target, params.mipmap,
796 params.xOffset, params.yOffset, params.width, params.height,
797 pixelDataFormat, pixelData->GetBufferSize(), buffer );
802 //Destroy temp buffer used for conversion RGB->RGBA
806 bool Texture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
808 if( mNativeImage && mId == 0 )
810 Initialize( context );
815 context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
816 context.BindTexture( mTarget, mId );
817 ApplySampler( context, sampler );
821 mNativeImage->PrepareTexture();
830 void Texture::ApplySampler( Context& context, Render::Sampler* sampler )
832 Render::Sampler oldSampler = mSampler;
833 mSampler = sampler ? *sampler : Sampler();
835 if( mSampler != oldSampler )
837 GLint mode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
838 if( mode != FilterModeToGL( oldSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT ) )
840 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, mode );
843 mode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
844 if( mode != FilterModeToGL( oldSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT ) )
846 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, mode );
849 mode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
850 if( mode != WrapModeToGL( oldSampler.mSWrapMode, GL_WRAP_DEFAULT ) )
852 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, mode );
855 mode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
856 if( mode != WrapModeToGL( oldSampler.mTWrapMode, GL_WRAP_DEFAULT ) )
858 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, mode );
861 if( mType == TextureType::TEXTURE_CUBE )
863 mode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
864 if( mode != WrapModeToGL( oldSampler.mRWrapMode, GL_WRAP_DEFAULT ) )
866 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, mode );
870 #if DALI_GLES_VERSION >= 30
871 //In GLES 3.0 we do not need to upload all of the mipmap levels, but GL_TEXTURE_MAX_LEVEL must be set
874 context.TexParameteri( mTarget, GL_TEXTURE_MAX_LEVEL, mMaxMipMapLevel );
881 bool Texture::HasAlphaChannel()
886 void Texture::GenerateMipmaps( Context& context )
888 //GL_TEXTURE_MAX_LEVEL does not need to be set when mipmaps are generated by GL
890 context.BindTexture( mTarget, mId );
891 context.GenerateMipmap( mTarget );