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>
21 #include <math.h> //floor, log2
24 #include <dali/devel-api/rendering/texture.h> // Dali::Texture
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 Retrive GL internal format and pixel data type from a Pixel::Format
127 * @param[in] pixelFormat The pixel format
128 * @param[out] pixelDataType The data type of the pixel data
129 * @param[out] internalFormat The internal format
131 void PixelFormatToGl( Pixel::Format pixelformat, unsigned& pixelDataType, unsigned& internalFormat )
133 // Compressed textures have no pixelDataType, so init to an invalid value:
136 switch( pixelformat )
140 pixelDataType = GL_UNSIGNED_BYTE;
141 internalFormat= GL_ALPHA;
147 pixelDataType = GL_UNSIGNED_BYTE;
148 internalFormat= GL_LUMINANCE;
154 pixelDataType = GL_UNSIGNED_BYTE;
155 internalFormat= GL_LUMINANCE_ALPHA;
161 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
162 internalFormat= GL_RGB;
168 DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
169 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
171 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
173 internalFormat= GL_RGBA; // alpha is reserved but not used
178 case Pixel::RGBA4444:
180 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
181 internalFormat= GL_RGBA;
185 case Pixel::BGRA4444:
187 DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
188 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
190 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
192 internalFormat= GL_RGBA; // alpha is reserved but not used
197 case Pixel::RGBA5551:
199 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
200 internalFormat= GL_RGBA;
204 case Pixel::BGRA5551:
206 DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
207 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
209 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
211 internalFormat= GL_RGBA; // alpha is reserved but not used
218 pixelDataType = GL_UNSIGNED_BYTE;
219 internalFormat= GL_RGB;
225 pixelDataType = GL_UNSIGNED_BYTE;
226 internalFormat= GL_RGBA; // alpha is reserved but not used
232 pixelDataType = GL_UNSIGNED_BYTE;
234 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
236 internalFormat= GL_RGBA; // alpha is reserved but not used
241 case Pixel::RGBA8888:
243 pixelDataType = GL_UNSIGNED_BYTE;
244 internalFormat= GL_RGBA;
248 case Pixel::BGRA8888:
250 pixelDataType = GL_UNSIGNED_BYTE;
252 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
254 internalFormat= GL_RGBA; // alpha is reserved but not used
259 // GLES 2 extension compressed formats:
260 case Pixel::COMPRESSED_RGB8_ETC1:
262 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n" );
263 internalFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
266 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
268 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n" );
269 internalFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
273 // GLES 3.0 standard compressed formats:
274 case Pixel::COMPRESSED_R11_EAC:
276 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
277 internalFormat = GL_COMPRESSED_R11_EAC;
280 case Pixel::COMPRESSED_SIGNED_R11_EAC:
282 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n" );
283 internalFormat = GL_COMPRESSED_SIGNED_R11_EAC;
286 case Pixel::COMPRESSED_RG11_EAC:
288 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n" );
289 internalFormat = GL_COMPRESSED_RG11_EAC;
292 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
294 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n" );
295 internalFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
298 case Pixel::COMPRESSED_RGB8_ETC2:
300 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n" );
301 internalFormat = GL_COMPRESSED_RGB8_ETC2;
304 case Pixel::COMPRESSED_SRGB8_ETC2:
306 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n" );
307 internalFormat = GL_COMPRESSED_SRGB8_ETC2;
310 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
312 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
313 internalFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
316 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
318 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
319 internalFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
322 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
324 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n" );
325 internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
328 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
330 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n" );
331 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
335 // GLES 3.1 extension compressed formats:
336 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
338 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n" );
339 internalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
342 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
344 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n" );
345 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
348 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
350 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n" );
351 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
354 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
356 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n" );
357 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
360 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
362 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n" );
363 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
366 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
368 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n" );
369 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
372 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
374 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n" );
375 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
378 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
380 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n" );
381 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
384 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
386 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n" );
387 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
390 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
392 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n" );
393 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
396 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
398 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n" );
399 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
402 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
404 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n" );
405 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
408 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
410 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n" );
411 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
414 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
416 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n" );
417 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
420 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
422 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n" );
423 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
426 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
428 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n" );
429 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
432 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
434 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n" );
435 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
438 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
440 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n" );
441 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
444 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
446 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n" );
447 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
450 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
452 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n" );
453 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
456 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
458 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n" );
459 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
462 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
464 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n" );
465 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
468 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
470 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n" );
471 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
474 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
476 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n" );
477 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
480 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
482 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n" );
483 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
486 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
488 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n" );
489 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
492 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
494 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n" );
495 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
498 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
500 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n" );
501 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
507 DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
515 * @brief Whether specified pixel format is compressed.
517 * @param [in] pixelformat Pixel format
518 * @return true if format is compressed, false otherwise
520 bool IsCompressedFormat(Pixel::Format pixelFormat)
528 case Pixel::RGBA4444:
529 case Pixel::RGBA5551:
531 case Pixel::BGRA4444:
532 case Pixel::BGRA5551:
536 case Pixel::RGBA8888:
537 case Pixel::BGRA8888:
543 case Pixel::COMPRESSED_R11_EAC:
544 case Pixel::COMPRESSED_SIGNED_R11_EAC:
545 case Pixel::COMPRESSED_RG11_EAC:
546 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
547 case Pixel::COMPRESSED_RGB8_ETC2:
548 case Pixel::COMPRESSED_SRGB8_ETC2:
549 case Pixel::COMPRESSED_RGB8_ETC1:
550 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
551 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
552 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
553 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
554 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
555 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
556 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
557 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
558 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
559 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
560 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
561 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
562 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
563 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
564 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
565 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
566 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
567 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
568 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
569 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
570 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
571 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
572 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
573 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
574 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
575 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
576 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
577 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
578 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
579 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
580 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
581 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
582 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
591 } //Unnamed namespace
594 NewTexture::NewTexture( Type type, Pixel::Format format, unsigned int width, unsigned int height )
599 mInternalFormat(GL_RGB),
600 mPixelDataType(GL_UNSIGNED_BYTE),
603 mHasAlpha( HasAlpha( format ) ),
604 mIsCompressed( IsCompressedFormat( format ) )
606 PixelFormatToGl( format, mPixelDataType, mInternalFormat );
609 NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface )
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 )
623 NewTexture::~NewTexture()
626 void NewTexture::Destroy( Context& context )
630 context.DeleteTextures( 1, &mId );
634 void NewTexture::Initialize(Context& context)
638 if( mNativeImage->GlExtensionCreate() )
640 context.GenTextures( 1, &mId );
641 context.Bind2dTexture( mId );
642 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
644 //Apply default sampling parameters
645 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
646 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
647 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
648 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
650 // platform specific implementation decides on what GL extension to use
651 mNativeImage->TargetTexture();
656 context.GenTextures( 1, &mId );
658 if( mType == TextureType::TEXTURE_2D )
660 //Creates the texture and reserves memory for the first mipmap level.
661 context.Bind2dTexture( mId );
665 context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
669 context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
672 //Apply default sampling parameters
673 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
674 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
675 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
676 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
678 else if( mType == TextureType::TEXTURE_CUBE )
680 //Creates the texture and reserves memory for the first mipmap level.
681 context.BindCubeMapTexture( mId );
685 for( unsigned int i(0); i<6; ++i )
687 context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
692 for( unsigned int i(0); i<6; ++i )
694 context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
698 //Apply default sampling parameters
699 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
700 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
701 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
702 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
703 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
708 void NewTexture::Upload( Context& context, PixelDataPtr pixelData, const Internal::NewTexture::UploadParams& params )
710 DALI_ASSERT_ALWAYS( mNativeImage == NULL );
712 //Get pointer to the data of the PixelData object
713 unsigned char* buffer( pixelData->GetBuffer() );
715 //This buffer is only used if manually converting from RGB to RGBA
716 unsigned char* tempBuffer(0);
718 //Get pixel format and data type of the data contained in the PixelData object
719 GLenum pixelDataFormat, pixelDataElementType;
720 PixelFormatToGl( pixelData->GetPixelFormat(), pixelDataElementType, pixelDataFormat );
722 #if DALI_GLES_VERSION < 30
723 if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA )
725 //Convert manually from RGB to RGBA if GLES < 3 ( GLES 3 can do the conversion automatically when uploading )
726 size_t dataSize = params.width * params.height;
727 tempBuffer = new unsigned char[dataSize*4u];
728 for( size_t i(0u); i<dataSize; i++ )
730 tempBuffer[i*4u] = buffer[i*3u];
731 tempBuffer[i*4u+1] = buffer[i*3u+1];
732 tempBuffer[i*4u+2] = buffer[i*3u+2];
733 tempBuffer[i*4u+3] = 0xFF;
737 pixelDataFormat = mInternalFormat;
741 //Upload data to the texture
742 GLenum target( GL_NONE );
743 if( mType == TextureType::TEXTURE_2D )
745 context.Bind2dTexture( mId );
746 target = GL_TEXTURE_2D;
748 else if( mType == TextureType::TEXTURE_CUBE )
750 context.BindCubeMapTexture( mId );
751 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
754 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
756 if( params.xOffset == 0 && params.yOffset == 0 &&
757 params.width == ( mWidth / (1<<params.mipmap) ) &&
758 params.height == ( mHeight / (1<<params.mipmap) ) )
760 //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
763 context.TexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelDataFormat, pixelDataElementType, buffer );
767 context.CompressedTexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelData->GetBufferSize(), buffer );
772 //Specifying part of the image for the mipmap
775 context.TexSubImage2D( target, params.mipmap,
776 params.xOffset, params.yOffset, params.width, params.height,
777 pixelDataFormat, pixelDataElementType, buffer );
781 context.CompressedTexSubImage2D( target, params.mipmap,
782 params.xOffset, params.yOffset, params.width, params.height,
783 pixelDataFormat, pixelData->GetBufferSize(), buffer );
788 //Destroy temp buffer used for conversion RGB->RGBA
792 bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
796 context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
798 if( mType == TextureType::TEXTURE_2D )
800 context.Bind2dTexture( mId );
802 else if( mType == TextureType::TEXTURE_CUBE )
804 context.BindCubeMapTexture( mId );
807 ApplySampler( context, sampler );
815 void NewTexture::ApplySampler( Context& context, Render::Sampler* sampler )
817 Render::Sampler oldSampler = mSampler;
818 mSampler = sampler ? *sampler : Sampler();
820 if( mSampler.mBitfield != oldSampler.mBitfield )
822 if( mSampler.mMinificationFilter != oldSampler.mMinificationFilter )
824 GLint glFilterMode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
825 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilterMode );
828 if( mSampler.mMagnificationFilter != oldSampler.mMagnificationFilter )
830 GLint glFilterMode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
831 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFilterMode );
834 if( mSampler.mSWrapMode != oldSampler.mSWrapMode )
836 GLint glWrapMode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
837 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapMode );
840 if( mSampler.mTWrapMode != oldSampler.mTWrapMode )
842 GLint glWrapMode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
843 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapMode );
846 if( mType == TextureType::TEXTURE_CUBE && mSampler.mRWrapMode != oldSampler.mRWrapMode )
848 GLint glWrapMode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
849 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, glWrapMode );
854 bool NewTexture::HasAlphaChannel()
859 void NewTexture::GenerateMipmaps( Context& context )
861 if( mType == TextureType::TEXTURE_2D )
863 context.Bind2dTexture( mId );
864 context.GenerateMipmap( GL_TEXTURE_2D );
866 else if( mType == TextureType::TEXTURE_CUBE )
868 context.BindCubeMapTexture( mId );
869 context.GenerateMipmap( GL_TEXTURE_CUBE_MAP );