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
33 // These match the GL specification
34 const GLint GL_MINIFY_DEFAULT = GL_NEAREST_MIPMAP_LINEAR;
35 const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR;
36 const GLint GL_WRAP_DEFAULT = GL_CLAMP_TO_EDGE;
38 // These are the Dali defaults
39 const GLint DALI_MINIFY_DEFAULT = GL_LINEAR;
40 const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
43 * @brief Convert a FilterMode to its corresponding GL type.
45 * @param[in] filterMode The FilterMode type.
46 * @param[in] daliDefault The filter mode to use if filterMode is DEFAULT.
47 * @param[in] glDefault The filter mode to use if filterMode is NONE.
48 * @return the equivalent GL filter mode.
50 GLint FilterModeToGL( FilterMode::Type filterMode, GLint daliDefault, GLint glDefault )
54 case FilterMode::NEAREST:
58 case FilterMode::LINEAR:
62 case FilterMode::NONE:
66 case FilterMode::NEAREST_MIPMAP_NEAREST:
68 return GL_NEAREST_MIPMAP_NEAREST;
70 case FilterMode::LINEAR_MIPMAP_NEAREST:
72 return GL_LINEAR_MIPMAP_NEAREST;
74 case FilterMode::NEAREST_MIPMAP_LINEAR:
76 return GL_NEAREST_MIPMAP_LINEAR;
78 case FilterMode::LINEAR_MIPMAP_LINEAR:
80 return GL_LINEAR_MIPMAP_LINEAR;
82 case FilterMode::DEFAULT:
92 * @brief Convert from a WrapMode to its corresponding GL enumeration
93 * @param[in] wrapMode The wrap mode
94 * @param[in] defaultWrapMode The mode to use if WrapMode is Default
95 * @return The equivalent GL wrap mode
97 GLint WrapModeToGL( WrapMode::Type wrapMode, GLint defaultWrapMode )
101 case WrapMode::CLAMP_TO_EDGE:
103 return GL_CLAMP_TO_EDGE;
105 case WrapMode::REPEAT:
109 case WrapMode::MIRRORED_REPEAT:
111 return GL_MIRRORED_REPEAT;
113 case WrapMode::DEFAULT:
115 return defaultWrapMode;
119 return defaultWrapMode;
123 * @brief Retrive GL internal format and pixel data type from a Pixel::Format
124 * @param[in] pixelFormat The pixel format
125 * @param[out] pixelDataType The data type of the pixel data
126 * @param[out] internalFormat The internal format
128 void PixelFormatToGl( Pixel::Format pixelformat, unsigned& pixelDataType, unsigned& internalFormat )
130 // Compressed textures have no pixelDataType, so init to an invalid value:
133 switch( pixelformat )
137 pixelDataType = GL_UNSIGNED_BYTE;
138 internalFormat= GL_ALPHA;
144 pixelDataType = GL_UNSIGNED_BYTE;
145 internalFormat= GL_LUMINANCE;
151 pixelDataType = GL_UNSIGNED_BYTE;
152 internalFormat= GL_LUMINANCE_ALPHA;
158 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
159 internalFormat= GL_RGB;
165 DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
166 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
168 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
170 internalFormat= GL_RGBA; // alpha is reserved but not used
175 case Pixel::RGBA4444:
177 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
178 internalFormat= GL_RGBA;
182 case Pixel::BGRA4444:
184 DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
185 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
187 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
189 internalFormat= GL_RGBA; // alpha is reserved but not used
194 case Pixel::RGBA5551:
196 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
197 internalFormat= GL_RGBA;
201 case Pixel::BGRA5551:
203 DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
204 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
206 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
208 internalFormat= GL_RGBA; // alpha is reserved but not used
215 pixelDataType = GL_UNSIGNED_BYTE;
216 internalFormat= GL_RGB;
222 pixelDataType = GL_UNSIGNED_BYTE;
223 internalFormat= GL_RGBA; // alpha is reserved but not used
229 pixelDataType = GL_UNSIGNED_BYTE;
231 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
233 internalFormat= GL_RGBA; // alpha is reserved but not used
238 case Pixel::RGBA8888:
240 pixelDataType = GL_UNSIGNED_BYTE;
241 internalFormat= GL_RGBA;
245 case Pixel::BGRA8888:
247 pixelDataType = GL_UNSIGNED_BYTE;
249 internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
251 internalFormat= GL_RGBA; // alpha is reserved but not used
256 // GLES 2 extension compressed formats:
257 case Pixel::COMPRESSED_RGB8_ETC1:
259 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n" );
260 internalFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
263 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
265 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n" );
266 internalFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
270 // GLES 3.0 standard compressed formats:
271 case Pixel::COMPRESSED_R11_EAC:
273 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
274 internalFormat = GL_COMPRESSED_R11_EAC;
277 case Pixel::COMPRESSED_SIGNED_R11_EAC:
279 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n" );
280 internalFormat = GL_COMPRESSED_SIGNED_R11_EAC;
283 case Pixel::COMPRESSED_RG11_EAC:
285 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n" );
286 internalFormat = GL_COMPRESSED_RG11_EAC;
289 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
291 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n" );
292 internalFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
295 case Pixel::COMPRESSED_RGB8_ETC2:
297 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n" );
298 internalFormat = GL_COMPRESSED_RGB8_ETC2;
301 case Pixel::COMPRESSED_SRGB8_ETC2:
303 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n" );
304 internalFormat = GL_COMPRESSED_SRGB8_ETC2;
307 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
309 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
310 internalFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
313 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
315 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
316 internalFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
319 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
321 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n" );
322 internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
325 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
327 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n" );
328 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
332 // GLES 3.1 extension compressed formats:
333 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
335 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n" );
336 internalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
339 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
341 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n" );
342 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
345 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
347 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n" );
348 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
351 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
353 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n" );
354 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
357 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
359 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n" );
360 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
363 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
365 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n" );
366 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
369 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
371 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n" );
372 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
375 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
377 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n" );
378 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
381 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
383 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n" );
384 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
387 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
389 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n" );
390 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
393 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
395 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n" );
396 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
399 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
401 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n" );
402 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
405 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
407 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n" );
408 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
411 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
413 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n" );
414 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
417 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
419 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n" );
420 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
423 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
425 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n" );
426 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
429 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
431 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n" );
432 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
435 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
437 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n" );
438 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
441 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
443 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n" );
444 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
447 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
449 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n" );
450 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
453 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
455 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n" );
456 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
459 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
461 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n" );
462 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
465 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
467 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n" );
468 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
471 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
473 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n" );
474 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
477 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
479 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n" );
480 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
483 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
485 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n" );
486 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
489 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
491 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n" );
492 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
495 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
497 DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n" );
498 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
504 DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
512 * @brief Whether specified pixel format is compressed.
514 * @param [in] pixelformat Pixel format
515 * @return true if format is compressed, false otherwise
517 bool IsCompressedFormat(Pixel::Format pixelFormat)
525 case Pixel::RGBA4444:
526 case Pixel::RGBA5551:
528 case Pixel::BGRA4444:
529 case Pixel::BGRA5551:
533 case Pixel::RGBA8888:
534 case Pixel::BGRA8888:
540 case Pixel::COMPRESSED_R11_EAC:
541 case Pixel::COMPRESSED_SIGNED_R11_EAC:
542 case Pixel::COMPRESSED_RG11_EAC:
543 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
544 case Pixel::COMPRESSED_RGB8_ETC2:
545 case Pixel::COMPRESSED_SRGB8_ETC2:
546 case Pixel::COMPRESSED_RGB8_ETC1:
547 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
548 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
549 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
550 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
551 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
552 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
553 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
554 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
555 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
556 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
557 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
558 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
559 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
560 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
561 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
562 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
563 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
564 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
565 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
566 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
567 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
568 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
569 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
570 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
571 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
572 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
573 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
574 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
575 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
576 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
577 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
578 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
579 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
588 } //Unnamed namespace
591 NewTexture::NewTexture( Type type, Pixel::Format format, unsigned int width, unsigned int height )
596 mInternalFormat(GL_RGB),
597 mPixelDataType(GL_UNSIGNED_BYTE),
600 mHasAlpha( HasAlpha( format ) ),
601 mIsCompressed( IsCompressedFormat( format ) )
603 PixelFormatToGl( format, mPixelDataType, mInternalFormat );
606 NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface )
608 mType( TextureType::TEXTURE_2D ),
610 mNativeImage( nativeImageInterface ),
611 mInternalFormat(GL_RGB),
612 mPixelDataType(GL_UNSIGNED_BYTE),
613 mWidth( nativeImageInterface->GetWidth() ),
614 mHeight( nativeImageInterface->GetHeight() ),
615 mHasAlpha( nativeImageInterface->RequiresBlending() ),
616 mIsCompressed( false )
620 NewTexture::~NewTexture()
623 void NewTexture::Destroy( Context& context )
627 context.DeleteTextures( 1, &mId );
631 mNativeImage->GlExtensionDestroy();
636 void NewTexture::Initialize(Context& context)
640 if( mNativeImage->GlExtensionCreate() )
642 context.GenTextures( 1, &mId );
643 context.Bind2dTexture( mId );
644 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
646 //Apply default sampling parameters
647 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
648 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
649 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
650 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
652 // platform specific implementation decides on what GL extension to use
653 if( mNativeImage->TargetTexture() != 0u )
655 context.DeleteTextures( 1, &mId );
656 mNativeImage->GlExtensionDestroy();
663 context.GenTextures( 1, &mId );
665 if( mType == TextureType::TEXTURE_2D )
667 //Creates the texture and reserves memory for the first mipmap level.
668 context.Bind2dTexture( mId );
672 context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
676 context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
679 //Apply default sampling parameters
680 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
681 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
682 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
683 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
685 else if( mType == TextureType::TEXTURE_CUBE )
687 //Creates the texture and reserves memory for the first mipmap level.
688 context.BindCubeMapTexture( mId );
692 for( unsigned int i(0); i<6; ++i )
694 context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
699 for( unsigned int i(0); i<6; ++i )
701 context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
705 //Apply default sampling parameters
706 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
707 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
708 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
709 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
710 context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
715 void NewTexture::Upload( Context& context, PixelDataPtr pixelData, const Internal::NewTexture::UploadParams& params )
717 DALI_ASSERT_ALWAYS( mNativeImage == NULL );
719 //Get pointer to the data of the PixelData object
720 unsigned char* buffer( pixelData->GetBuffer() );
722 //This buffer is only used if manually converting from RGB to RGBA
723 unsigned char* tempBuffer(0);
725 //Get pixel format and data type of the data contained in the PixelData object
726 GLenum pixelDataFormat, pixelDataElementType;
727 PixelFormatToGl( pixelData->GetPixelFormat(), pixelDataElementType, pixelDataFormat );
729 #if DALI_GLES_VERSION < 30
730 if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA )
732 //Convert manually from RGB to RGBA if GLES < 3 ( GLES 3 can do the conversion automatically when uploading )
733 size_t dataSize = static_cast< size_t >( params.width ) * params.height;
734 tempBuffer = new unsigned char[dataSize*4u];
735 for( size_t i(0u); i<dataSize; i++ )
737 tempBuffer[i*4u] = buffer[i*3u];
738 tempBuffer[i*4u+1] = buffer[i*3u+1];
739 tempBuffer[i*4u+2] = buffer[i*3u+2];
740 tempBuffer[i*4u+3] = 0xFF;
744 pixelDataFormat = mInternalFormat;
748 //Upload data to the texture
749 GLenum target( GL_NONE );
750 if( mType == TextureType::TEXTURE_2D )
752 context.Bind2dTexture( mId );
753 target = GL_TEXTURE_2D;
755 else if( mType == TextureType::TEXTURE_CUBE )
757 context.BindCubeMapTexture( mId );
758 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
761 context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
763 if( params.xOffset == 0 && params.yOffset == 0 &&
764 params.width == ( mWidth / (1<<params.mipmap) ) &&
765 params.height == ( mHeight / (1<<params.mipmap) ) )
767 //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
770 context.TexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelDataFormat, pixelDataElementType, buffer );
774 context.CompressedTexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelData->GetBufferSize(), buffer );
779 //Specifying part of the image for the mipmap
782 context.TexSubImage2D( target, params.mipmap,
783 params.xOffset, params.yOffset, params.width, params.height,
784 pixelDataFormat, pixelDataElementType, buffer );
788 context.CompressedTexSubImage2D( target, params.mipmap,
789 params.xOffset, params.yOffset, params.width, params.height,
790 pixelDataFormat, pixelData->GetBufferSize(), buffer );
795 //Destroy temp buffer used for conversion RGB->RGBA
799 bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
803 context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
805 if( mType == TextureType::TEXTURE_2D )
807 context.Bind2dTexture( mId );
809 else if( mType == TextureType::TEXTURE_CUBE )
811 context.BindCubeMapTexture( mId );
814 ApplySampler( context, sampler );
818 //Allow implementation specific operations after binding the texture
819 mNativeImage->PrepareTexture();
828 void NewTexture::ApplySampler( Context& context, Render::Sampler* sampler )
830 Render::Sampler oldSampler = mSampler;
831 mSampler = sampler ? *sampler : Sampler();
833 if( mSampler.mBitfield != oldSampler.mBitfield )
835 if( mSampler.mMinificationFilter != oldSampler.mMinificationFilter )
837 GLint glFilterMode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
838 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilterMode );
841 if( mSampler.mMagnificationFilter != oldSampler.mMagnificationFilter )
843 GLint glFilterMode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
844 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFilterMode );
847 if( mSampler.mSWrapMode != oldSampler.mSWrapMode )
849 GLint glWrapMode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
850 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapMode );
853 if( mSampler.mTWrapMode != oldSampler.mTWrapMode )
855 GLint glWrapMode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
856 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapMode );
859 if( mType == TextureType::TEXTURE_CUBE && mSampler.mRWrapMode != oldSampler.mRWrapMode )
861 GLint glWrapMode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
862 context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, glWrapMode );
867 bool NewTexture::HasAlphaChannel()
872 void NewTexture::GenerateMipmaps( Context& context )
874 if( mType == TextureType::TEXTURE_2D )
876 context.Bind2dTexture( mId );
877 context.GenerateMipmap( GL_TEXTURE_2D );
879 else if( mType == TextureType::TEXTURE_CUBE )
881 context.BindCubeMapTexture( mId );
882 context.GenerateMipmap( GL_TEXTURE_CUBE_MAP );