2 * Copyright (c) 2016 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),
602 mHasAlpha( HasAlpha( format ) ),
603 mIsCompressed( IsCompressedFormat( format ) )
605 PixelFormatToGl( format, mPixelDataType, mInternalFormat );
608 Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
610 mTarget( GL_TEXTURE_2D ),
611 mType( TextureType::TEXTURE_2D ),
613 mNativeImage( nativeImageInterface ),
614 mInternalFormat(GL_RGB),
615 mPixelDataType(GL_UNSIGNED_BYTE),
616 mWidth( nativeImageInterface->GetWidth() ),
617 mHeight( nativeImageInterface->GetHeight() ),
618 mHasAlpha( nativeImageInterface->RequiresBlending() ),
619 mIsCompressed( false )
626 void Texture::Destroy( Context& context )
630 context.DeleteTextures( 1, &mId );
634 mNativeImage->GlExtensionDestroy();
639 void Texture::GlContextDestroyed()
644 void Texture::Initialize(Context& context)
648 if( mNativeImage->GlExtensionCreate() )
650 NativeImageInterface::Extension* extension = mNativeImage->GetExtension();
653 mTarget = extension->GetEglImageTextureTarget();
656 context.GenTextures( 1, &mId );
657 context.BindTexture( mTarget, mId );
658 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
660 //Apply default sampling parameters
661 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
662 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
663 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
664 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
666 // platform specific implementation decides on what GL extension to use
667 if( mNativeImage->TargetTexture() != 0u )
669 context.DeleteTextures( 1, &mId );
670 mNativeImage->GlExtensionDestroy();
677 //Create the texture and reserve memory for the first mipmap level.
678 context.GenTextures( 1, &mId );
679 context.BindTexture( mTarget, mId );
680 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
682 //Apply default sampling parameters
683 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
684 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
685 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
686 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
688 if( mType == TextureType::TEXTURE_2D )
692 context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
696 context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
699 else if( mType == TextureType::TEXTURE_CUBE )
703 for( unsigned int i(0); i<6; ++i )
705 context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
710 for( unsigned int i(0); i<6; ++i )
712 context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
715 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
720 void Texture::Upload( Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params )
722 DALI_ASSERT_ALWAYS( mNativeImage == NULL );
724 //Get pointer to the data of the PixelData object
725 unsigned char* buffer( pixelData->GetBuffer() );
727 //This buffer is only used if manually converting from RGB to RGBA
728 unsigned char* tempBuffer(0);
730 //Get pixel format and data type of the data contained in the PixelData object
731 GLenum pixelDataFormat, pixelDataElementType;
732 PixelFormatToGl( pixelData->GetPixelFormat(), pixelDataElementType, pixelDataFormat );
734 #if DALI_GLES_VERSION < 30
735 if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA )
737 //Convert manually from RGB to RGBA if GLES < 3 ( GLES 3 can do the conversion automatically when uploading )
738 size_t dataSize = static_cast< size_t >( params.width ) * params.height;
739 tempBuffer = new unsigned char[dataSize*4u];
740 for( size_t i(0u); i<dataSize; i++ )
742 tempBuffer[i*4u] = buffer[i*3u];
743 tempBuffer[i*4u+1] = buffer[i*3u+1];
744 tempBuffer[i*4u+2] = buffer[i*3u+2];
745 tempBuffer[i*4u+3] = 0xFF;
749 pixelDataFormat = mInternalFormat;
753 //Upload data to the texture
755 context.BindTexture( mTarget, mId );
756 GLenum target( mTarget );
757 if( mType == TextureType::TEXTURE_CUBE )
759 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
762 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
764 if( params.xOffset == 0 && params.yOffset == 0 &&
765 params.width == ( mWidth / (1<<params.mipmap) ) &&
766 params.height == ( mHeight / (1<<params.mipmap) ) )
768 //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
771 context.TexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelDataFormat, pixelDataElementType, buffer );
775 context.CompressedTexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelData->GetBufferSize(), buffer );
780 //Specifying part of the image for the mipmap
783 context.TexSubImage2D( target, params.mipmap,
784 params.xOffset, params.yOffset, params.width, params.height,
785 pixelDataFormat, pixelDataElementType, buffer );
789 context.CompressedTexSubImage2D( target, params.mipmap,
790 params.xOffset, params.yOffset, params.width, params.height,
791 pixelDataFormat, pixelData->GetBufferSize(), buffer );
796 //Destroy temp buffer used for conversion RGB->RGBA
800 bool Texture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
802 if( mNativeImage && mId == 0 )
804 Initialize( context );
809 context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
810 context.BindTexture( mTarget, mId );
811 ApplySampler( context, sampler );
815 mNativeImage->PrepareTexture();
824 void Texture::ApplySampler( Context& context, Render::Sampler* sampler )
826 Render::Sampler oldSampler = mSampler;
827 mSampler = sampler ? *sampler : Sampler();
829 if( mSampler != oldSampler )
831 GLint mode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
832 if( mode != FilterModeToGL( oldSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT ) )
834 context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, mode );
837 mode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
838 if( mode != FilterModeToGL( oldSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT ) )
840 context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, mode );
843 mode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
844 if( mode != WrapModeToGL( oldSampler.mSWrapMode, GL_WRAP_DEFAULT ) )
846 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, mode );
849 mode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
850 if( mode != WrapModeToGL( oldSampler.mTWrapMode, GL_WRAP_DEFAULT ) )
852 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, mode );
855 if( mType == TextureType::TEXTURE_CUBE )
857 mode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
858 if( mode != WrapModeToGL( oldSampler.mRWrapMode, GL_WRAP_DEFAULT ) )
860 context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, mode );
866 bool Texture::HasAlphaChannel()
871 void Texture::GenerateMipmaps( Context& context )
873 context.BindTexture( mTarget, mId );
874 context.GenerateMipmap( mTarget );