Implemented Upload methods in Texture to upload data from PixelData objects
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-texture.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 // CLASS HEADER
18 #include <dali/internal/render/renderers/render-texture.h>
19
20 // EXTERNAL INCLUDES
21 #include <math.h>   //floor, log2
22
23 //INTERNAL INCLUDES
24 #include <dali/devel-api/rendering/texture.h>  // Dali::Texture
25
26 namespace Dali
27 {
28 namespace Internal
29 {
30 namespace Render
31 {
32
33 namespace
34 {
35
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;
40
41 // These are the Dali defaults
42 const GLint DALI_MINIFY_DEFAULT  = GL_LINEAR;
43 const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
44
45 /**
46  * @brief Convert a FilterMode to its corresponding GL type.
47  *
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.
52  */
53 GLint FilterModeToGL( FilterMode::Type filterMode, GLint daliDefault, GLint glDefault )
54 {
55   switch( filterMode )
56   {
57     case FilterMode::NEAREST:
58     {
59       return GL_NEAREST;
60     }
61     case FilterMode::LINEAR:
62     {
63       return GL_LINEAR;
64     }
65     case FilterMode::NONE:
66     {
67       return glDefault;
68     }
69     case FilterMode::NEAREST_MIPMAP_NEAREST:
70     {
71       return GL_NEAREST_MIPMAP_NEAREST;
72     }
73     case FilterMode::LINEAR_MIPMAP_NEAREST:
74     {
75       return GL_LINEAR_MIPMAP_NEAREST;
76     }
77     case FilterMode::NEAREST_MIPMAP_LINEAR:
78     {
79       return GL_NEAREST_MIPMAP_LINEAR;
80     }
81     case FilterMode::LINEAR_MIPMAP_LINEAR:
82     {
83       return GL_LINEAR_MIPMAP_LINEAR;
84     }
85     case FilterMode::DEFAULT:
86     {
87       return daliDefault;
88     }
89   }
90
91   return daliDefault;
92 }
93
94 /**
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
99  */
100 GLint WrapModeToGL( WrapMode::Type wrapMode, GLint defaultWrapMode )
101 {
102   switch( wrapMode )
103   {
104     case WrapMode::CLAMP_TO_EDGE:
105     {
106       return GL_CLAMP_TO_EDGE;
107     }
108     case WrapMode::REPEAT:
109     {
110       return GL_REPEAT;
111     }
112     case WrapMode::MIRRORED_REPEAT:
113     {
114       return GL_MIRRORED_REPEAT;
115     }
116     case WrapMode::DEFAULT:
117     {
118       return defaultWrapMode;
119     }
120   }
121
122   return defaultWrapMode;
123 }
124
125 /**
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
130  */
131 void PixelFormatToGl( Pixel::Format pixelformat, unsigned& pixelDataType, unsigned& internalFormat )
132 {
133   // Compressed textures have no pixelDataType, so init to an invalid value:
134   pixelDataType  = -1;
135
136   switch( pixelformat )
137   {
138     case Pixel::A8:
139     {
140       pixelDataType = GL_UNSIGNED_BYTE;
141       internalFormat= GL_ALPHA;
142       break;
143     }
144
145     case Pixel::L8:
146     {
147       pixelDataType = GL_UNSIGNED_BYTE;
148       internalFormat= GL_LUMINANCE;
149       break;
150     }
151
152     case Pixel::LA88:
153     {
154       pixelDataType = GL_UNSIGNED_BYTE;
155       internalFormat= GL_LUMINANCE_ALPHA;
156       break;
157     }
158
159     case Pixel::RGB565:
160     {
161       pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
162       internalFormat= GL_RGB;
163       break;
164     }
165
166     case Pixel::BGR565:
167     {
168       DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
169       pixelDataType  = GL_UNSIGNED_SHORT_5_6_5;
170 #ifdef _ARCH_ARM_
171       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
172 #else
173       internalFormat= GL_RGBA;     // alpha is reserved but not used
174 #endif
175       break;
176     }
177
178     case Pixel::RGBA4444:
179     {
180       pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
181       internalFormat= GL_RGBA;
182       break;
183     }
184
185     case Pixel::BGRA4444:
186     {
187       DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
188       pixelDataType  = GL_UNSIGNED_SHORT_4_4_4_4;
189 #ifdef _ARCH_ARM_
190       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
191 #else
192       internalFormat= GL_RGBA;     // alpha is reserved but not used
193 #endif
194       break;
195     }
196
197     case Pixel::RGBA5551:
198     {
199       pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
200       internalFormat= GL_RGBA;
201       break;
202     }
203
204     case Pixel::BGRA5551:
205     {
206       DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
207       pixelDataType  = GL_UNSIGNED_SHORT_5_5_5_1;
208 #ifdef _ARCH_ARM_
209       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
210 #else
211       internalFormat= GL_RGBA;     // alpha is reserved but not used
212 #endif
213       break;
214     }
215
216     case Pixel::RGB888:
217     {
218       pixelDataType = GL_UNSIGNED_BYTE;
219       internalFormat= GL_RGB;
220       break;
221     }
222
223     case Pixel::RGB8888:
224     {
225       pixelDataType = GL_UNSIGNED_BYTE;
226       internalFormat= GL_RGBA;     // alpha is reserved but not used
227       break;
228     }
229
230     case Pixel::BGR8888:
231     {
232       pixelDataType = GL_UNSIGNED_BYTE;
233 #ifdef GL_BGRA_EXT
234       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
235 #else
236       internalFormat= GL_RGBA;     // alpha is reserved but not used
237 #endif
238     break;
239     }
240
241     case Pixel::RGBA8888:
242     {
243       pixelDataType = GL_UNSIGNED_BYTE;
244       internalFormat= GL_RGBA;
245       break;
246     }
247
248     case Pixel::BGRA8888:
249     {
250       pixelDataType = GL_UNSIGNED_BYTE;
251 #ifdef GL_BGRA_EXT
252       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
253 #else
254       internalFormat= GL_RGBA;     // alpha is reserved but not used
255 #endif
256       break;
257     }
258
259     // GLES 2 extension compressed formats:
260     case Pixel::COMPRESSED_RGB8_ETC1:
261     {
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.
264       break;
265     }
266     case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
267     {
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.
270       break;
271     }
272
273     // GLES 3.0 standard compressed formats:
274     case Pixel::COMPRESSED_R11_EAC:
275     {
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;
278       break;
279     }
280     case Pixel::COMPRESSED_SIGNED_R11_EAC:
281     {
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;
284       break;
285     }
286     case Pixel::COMPRESSED_RG11_EAC:
287     {
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;
290       break;
291     }
292     case Pixel::COMPRESSED_SIGNED_RG11_EAC:
293     {
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;
296       break;
297     }
298     case Pixel::COMPRESSED_RGB8_ETC2:
299     {
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;
302       break;
303     }
304     case Pixel::COMPRESSED_SRGB8_ETC2:
305     {
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;
308       break;
309     }
310     case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
311     {
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;
314       break;
315     }
316     case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
317     {
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;
320       break;
321     }
322     case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
323     {
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;
326       break;
327     }
328     case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
329     {
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;
332       break;
333     }
334
335     // GLES 3.1 extension compressed formats:
336     case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
337     {
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;
340       break;
341     }
342     case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
343     {
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;
346       break;
347     }
348     case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
349     {
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;
352       break;
353     }
354     case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
355     {
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;
358       break;
359     }
360     case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
361     {
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;
364       break;
365     }
366     case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
367     {
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;
370       break;
371     }
372     case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
373     {
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;
376       break;
377     }
378     case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
379     {
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;
382       break;
383     }
384     case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
385     {
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;
388       break;
389     }
390     case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
391     {
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;
394       break;
395     }
396     case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
397     {
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;
400       break;
401     }
402     case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
403     {
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;
406       break;
407     }
408     case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
409     {
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;
412       break;
413     }
414     case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
415     {
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;
418       break;
419     }
420     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
421     {
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;
424       break;
425     }
426     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
427     {
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;
430       break;
431     }
432     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
433     {
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;
436       break;
437     }
438     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
439     {
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;
442       break;
443     }
444     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
445     {
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;
448       break;
449     }
450     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
451     {
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;
454       break;
455     }
456     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
457     {
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;
460       break;
461     }
462     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
463     {
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;
466       break;
467     }
468     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
469     {
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;
472       break;
473     }
474     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
475     {
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;
478       break;
479     }
480     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
481     {
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;
484       break;
485     }
486     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
487     {
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;
490       break;
491     }
492     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
493     {
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;
496       break;
497     }
498     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
499     {
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;
502       break;
503     }
504
505     case Pixel::INVALID:
506     {
507       DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
508       internalFormat = 0;
509       break;
510     }
511   }
512 }
513
514
515 } //Unnamed namespace
516
517
518 NewTexture::NewTexture( Type type, Pixel::Format format, unsigned int width, unsigned int height )
519 :mId( 0 ),
520  mType( type ),
521  mSampler(),
522  mNativeImage(),
523  mInternalFormat(GL_RGB),
524  mPixelDataType(GL_UNSIGNED_BYTE),
525  mWidth( width ),
526  mHeight( height ),
527  mHasAlpha( HasAlpha( format ) )
528 {
529   PixelFormatToGl( format, mPixelDataType, mInternalFormat );
530 }
531
532 NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface )
533 :mId( 0 ),
534  mType( TextureType::TEXTURE_2D ),
535  mSampler(),
536  mNativeImage( nativeImageInterface ),
537  mInternalFormat(GL_RGB),
538  mPixelDataType(GL_UNSIGNED_BYTE),
539  mWidth( nativeImageInterface->GetWidth() ),
540  mHeight( nativeImageInterface->GetHeight() ),
541  mHasAlpha( nativeImageInterface->RequiresBlending() )
542 {
543 }
544
545 NewTexture::~NewTexture()
546 {}
547
548 void NewTexture::Destroy( Context& context )
549 {
550   if( mId )
551   {
552     context.DeleteTextures( 1, &mId );
553   }
554 }
555
556 void NewTexture::Initialize(Context& context)
557 {
558   if( mNativeImage )
559   {
560     if( mNativeImage->GlExtensionCreate() )
561     {
562       context.GenTextures( 1, &mId );
563       context.Bind2dTexture( mId );
564       context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
565
566       //Apply default sampling parameters
567       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
568       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
569       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
570       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
571
572       // platform specific implementation decides on what GL extension to use
573       mNativeImage->TargetTexture();
574     }
575   }
576   else
577   {
578     context.GenTextures( 1, &mId );
579
580     if( mType == TextureType::TEXTURE_2D )
581     {
582       //Creates the texture and reserves memory for the first mipmap level.
583       context.Bind2dTexture( mId );
584       context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
585
586       //Apply default sampling parameters
587       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
588       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
589       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
590       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
591     }
592     else if( mType == TextureType::TEXTURE_CUBE )
593     {
594       //Creates the texture and reserves memory for the first mipmap level.
595       context.BindCubeMapTexture( mId );
596       for( unsigned int i(0); i<6; ++i )
597       {
598         context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
599       }
600
601       //Apply default sampling parameters
602       context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
603       context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
604       context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
605       context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
606       context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
607     }
608   }
609 }
610
611 void NewTexture::Upload( Context& context, PixelDataPtr pixelData, const Internal::NewTexture::UploadParams& params  )
612 {
613   DALI_ASSERT_ALWAYS( mNativeImage == NULL );
614
615   //Get pointer to the data of the PixelData object
616   unsigned char* buffer( pixelData->GetBuffer() );
617
618   //This buffer is only used if manually converting from RGB to RGBA
619   unsigned char* tempBuffer(0);
620
621   //Get pixel format and data type of the data contained in the PixelData object
622   GLenum pixelDataFormat, pixelDataElementType;
623   PixelFormatToGl( pixelData->GetPixelFormat(), pixelDataElementType, pixelDataFormat );
624
625 #if DALI_GLES_VERSION < 30
626   if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA )
627   {
628     //Convert manually from RGB to RGBA if GLES < 3 ( GLES 3 can do the conversion automatically when uploading )
629     size_t dataSize = params.width * params.height;
630     tempBuffer = new unsigned char[dataSize*4u];
631     for( size_t i(0u); i<dataSize; i++ )
632     {
633       tempBuffer[i*4u]   = buffer[i*3u];
634       tempBuffer[i*4u+1] = buffer[i*3u+1];
635       tempBuffer[i*4u+2] = buffer[i*3u+2];
636       tempBuffer[i*4u+3] = 0xFF;
637     }
638
639     buffer = tempBuffer;
640     pixelDataFormat = mInternalFormat;
641   }
642 #endif
643
644   //Upload data to the texture
645   if( mType == TextureType::TEXTURE_2D )
646   {
647     context.Bind2dTexture( mId );
648     context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
649
650     if( params.xOffset == 0 && params.yOffset == 0 &&
651         params.width  == static_cast<unsigned int>(mWidth  / (1<<params.mipmap)) &&
652         params.height == static_cast<unsigned int>(mHeight / (1<<params.mipmap)) )
653     {
654       //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
655       context.TexImage2D(GL_TEXTURE_2D, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelDataFormat, pixelDataElementType, buffer );
656     }
657     else
658     {
659       //Specifying part of the image for the mipmap
660       context.TexSubImage2D( GL_TEXTURE_2D, params.mipmap, params.xOffset, params.yOffset, params.width, params.height, pixelDataFormat, pixelDataElementType, buffer );
661     }
662   }
663   else if( mType == TextureType::TEXTURE_CUBE )
664   {
665     context.BindCubeMapTexture( mId );
666     context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
667
668     if( params.xOffset == 0 && params.yOffset == 0 &&
669         params.width  == static_cast<unsigned int>(mWidth  / (1<<params.mipmap)) &&
670         params.height == static_cast<unsigned int>(mHeight / (1<<params.mipmap)) )
671     {
672       //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
673       context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer, params.mipmap, mInternalFormat,
674                          params.width, params.height, 0,
675                          pixelDataFormat, pixelDataElementType, buffer );
676     }
677     else
678     {
679       //Specifying part of the image for the mipmap
680       context.TexSubImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer, params.mipmap,
681                              params.xOffset, params.yOffset, params.width, params.height,
682                              pixelDataFormat, pixelDataElementType, buffer );
683     }
684   }
685
686   //Destroy temp buffer used for conversion RGB->RGBA
687   delete[] tempBuffer;
688 }
689
690 bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
691 {
692   if( mId != 0 )
693   {
694     context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
695
696     if( mType == TextureType::TEXTURE_2D )
697     {
698       context.Bind2dTexture( mId );
699     }
700     else if( mType == TextureType::TEXTURE_CUBE )
701     {
702       context.BindCubeMapTexture( mId );
703     }
704
705     ApplySampler( context, sampler );
706
707     return true;
708   }
709
710   return false;
711 }
712
713 void NewTexture::ApplySampler( Context& context, Render::Sampler* sampler )
714 {
715   Render::Sampler oldSampler = mSampler;
716   mSampler = sampler ? *sampler : Sampler();
717
718   if( mSampler.mBitfield != oldSampler.mBitfield )
719   {
720     if( mSampler.mMinificationFilter != oldSampler.mMinificationFilter )
721     {
722       GLint glFilterMode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
723       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilterMode );
724     }
725
726     if( mSampler.mMagnificationFilter != oldSampler.mMagnificationFilter )
727     {
728       GLint glFilterMode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
729       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFilterMode );
730     }
731
732     if( mSampler.mSWrapMode != oldSampler.mSWrapMode )
733     {
734       GLint glWrapMode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
735       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapMode );
736     }
737
738     if( mSampler.mTWrapMode != oldSampler.mTWrapMode )
739     {
740       GLint glWrapMode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
741       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapMode );
742     }
743
744     if( mType == TextureType::TEXTURE_CUBE && mSampler.mRWrapMode != oldSampler.mRWrapMode )
745     {
746       GLint glWrapMode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
747       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, glWrapMode );
748     }
749   }
750 }
751
752 bool NewTexture::HasAlphaChannel()
753 {
754   return mHasAlpha;
755 }
756
757 void NewTexture::GenerateMipmaps( Context& context )
758 {
759   if( mType == TextureType::TEXTURE_2D )
760   {
761     context.Bind2dTexture( mId );
762     context.GenerateMipmap( GL_TEXTURE_2D );
763   }
764   else if( mType == TextureType::TEXTURE_CUBE )
765   {
766     context.BindCubeMapTexture( mId );
767     context.GenerateMipmap( GL_TEXTURE_CUBE_MAP );
768   }
769 }
770
771 } //Render
772
773 } //Internal
774
775 } //Dali