[dali_1.1.41] Merge branch 'devel/master'
[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  * @brief Whether specified pixel format is compressed.
516  *
517  * @param [in] pixelformat Pixel format
518  * @return true if format is compressed, false otherwise
519  */
520 bool IsCompressedFormat(Pixel::Format pixelFormat)
521 {
522   switch (pixelFormat)
523   {
524     case Pixel::L8:
525     case Pixel::A8:
526     case Pixel::LA88:
527     case Pixel::RGB565:
528     case Pixel::RGBA4444:
529     case Pixel::RGBA5551:
530     case Pixel::BGR565:
531     case Pixel::BGRA4444:
532     case Pixel::BGRA5551:
533     case Pixel::RGB888:
534     case Pixel::RGB8888:
535     case Pixel::BGR8888:
536     case Pixel::RGBA8888:
537     case Pixel::BGRA8888:
538     case Pixel::INVALID:
539     {
540       return false;
541     }
542
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:
583     {
584       return true;
585     }
586   }
587
588   return false;
589 }
590
591 } //Unnamed namespace
592
593
594 NewTexture::NewTexture( Type type, Pixel::Format format, unsigned int width, unsigned int height )
595 :mId( 0 ),
596  mType( type ),
597  mSampler(),
598  mNativeImage(),
599  mInternalFormat(GL_RGB),
600  mPixelDataType(GL_UNSIGNED_BYTE),
601  mWidth( width ),
602  mHeight( height ),
603  mHasAlpha( HasAlpha( format ) ),
604  mIsCompressed( IsCompressedFormat( format ) )
605 {
606   PixelFormatToGl( format, mPixelDataType, mInternalFormat );
607 }
608
609 NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface )
610 :mId( 0 ),
611  mType( TextureType::TEXTURE_2D ),
612  mSampler(),
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 )
620 {
621 }
622
623 NewTexture::~NewTexture()
624 {}
625
626 void NewTexture::Destroy( Context& context )
627 {
628   if( mId )
629   {
630     context.DeleteTextures( 1, &mId );
631   }
632 }
633
634 void NewTexture::Initialize(Context& context)
635 {
636   if( mNativeImage )
637   {
638     if( mNativeImage->GlExtensionCreate() )
639     {
640       context.GenTextures( 1, &mId );
641       context.Bind2dTexture( mId );
642       context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
643
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 );
649
650       // platform specific implementation decides on what GL extension to use
651       mNativeImage->TargetTexture();
652     }
653   }
654   else
655   {
656     context.GenTextures( 1, &mId );
657
658     if( mType == TextureType::TEXTURE_2D )
659     {
660       //Creates the texture and reserves memory for the first mipmap level.
661       context.Bind2dTexture( mId );
662
663       if( !mIsCompressed )
664       {
665         context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
666       }
667       else
668       {
669         context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
670       }
671
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 );
677     }
678     else if( mType == TextureType::TEXTURE_CUBE )
679     {
680       //Creates the texture and reserves memory for the first mipmap level.
681       context.BindCubeMapTexture( mId );
682
683       if( !mIsCompressed )
684       {
685         for( unsigned int i(0); i<6; ++i )
686         {
687           context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
688         }
689       }
690       else
691       {
692         for( unsigned int i(0); i<6; ++i )
693         {
694           context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, 0, 0 );
695         }
696       }
697
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 );
704     }
705   }
706 }
707
708 void NewTexture::Upload( Context& context, PixelDataPtr pixelData, const Internal::NewTexture::UploadParams& params  )
709 {
710   DALI_ASSERT_ALWAYS( mNativeImage == NULL );
711
712   //Get pointer to the data of the PixelData object
713   unsigned char* buffer( pixelData->GetBuffer() );
714
715   //This buffer is only used if manually converting from RGB to RGBA
716   unsigned char* tempBuffer(0);
717
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 );
721
722 #if DALI_GLES_VERSION < 30
723   if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA )
724   {
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++ )
729     {
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;
734     }
735
736     buffer = tempBuffer;
737     pixelDataFormat = mInternalFormat;
738   }
739 #endif
740
741   //Upload data to the texture
742   GLenum target( GL_NONE );
743   if( mType == TextureType::TEXTURE_2D )
744   {
745     context.Bind2dTexture( mId );
746     target = GL_TEXTURE_2D;
747   }
748   else if( mType == TextureType::TEXTURE_CUBE )
749   {
750     context.BindCubeMapTexture( mId );
751     target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
752   }
753
754   context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
755
756   if( params.xOffset == 0 && params.yOffset == 0 &&
757       params.width  == ( mWidth  / (1<<params.mipmap) ) &&
758       params.height == ( mHeight / (1<<params.mipmap) ) )
759   {
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
761     if( !mIsCompressed )
762     {
763       context.TexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelDataFormat, pixelDataElementType, buffer );
764     }
765     else
766     {
767       context.CompressedTexImage2D( target, params.mipmap, mInternalFormat, params.width, params.height, 0, pixelData->GetBufferSize(), buffer );
768     }
769   }
770   else
771   {
772     //Specifying part of the image for the mipmap
773     if( !mIsCompressed )
774     {
775       context.TexSubImage2D( target, params.mipmap,
776                              params.xOffset, params.yOffset, params.width, params.height,
777                              pixelDataFormat, pixelDataElementType, buffer );
778     }
779     else
780     {
781       context.CompressedTexSubImage2D( target, params.mipmap,
782                                        params.xOffset, params.yOffset, params.width, params.height,
783                                        pixelDataFormat, pixelData->GetBufferSize(), buffer );
784     }
785   }
786
787
788   //Destroy temp buffer used for conversion RGB->RGBA
789   delete[] tempBuffer;
790 }
791
792 bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
793 {
794   if( mId != 0 )
795   {
796     context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
797
798     if( mType == TextureType::TEXTURE_2D )
799     {
800       context.Bind2dTexture( mId );
801     }
802     else if( mType == TextureType::TEXTURE_CUBE )
803     {
804       context.BindCubeMapTexture( mId );
805     }
806
807     ApplySampler( context, sampler );
808
809     return true;
810   }
811
812   return false;
813 }
814
815 void NewTexture::ApplySampler( Context& context, Render::Sampler* sampler )
816 {
817   Render::Sampler oldSampler = mSampler;
818   mSampler = sampler ? *sampler : Sampler();
819
820   if( mSampler.mBitfield != oldSampler.mBitfield )
821   {
822     if( mSampler.mMinificationFilter != oldSampler.mMinificationFilter )
823     {
824       GLint glFilterMode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
825       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilterMode );
826     }
827
828     if( mSampler.mMagnificationFilter != oldSampler.mMagnificationFilter )
829     {
830       GLint glFilterMode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
831       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glFilterMode );
832     }
833
834     if( mSampler.mSWrapMode != oldSampler.mSWrapMode )
835     {
836       GLint glWrapMode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
837       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapMode );
838     }
839
840     if( mSampler.mTWrapMode != oldSampler.mTWrapMode )
841     {
842       GLint glWrapMode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
843       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapMode );
844     }
845
846     if( mType == TextureType::TEXTURE_CUBE && mSampler.mRWrapMode != oldSampler.mRWrapMode )
847     {
848       GLint glWrapMode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
849       context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, glWrapMode );
850     }
851   }
852 }
853
854 bool NewTexture::HasAlphaChannel()
855 {
856   return mHasAlpha;
857 }
858
859 void NewTexture::GenerateMipmaps( Context& context )
860 {
861   if( mType == TextureType::TEXTURE_2D )
862   {
863     context.Bind2dTexture( mId );
864     context.GenerateMipmap( GL_TEXTURE_2D );
865   }
866   else if( mType == TextureType::TEXTURE_CUBE )
867   {
868     context.BindCubeMapTexture( mId );
869     context.GenerateMipmap( GL_TEXTURE_CUBE_MAP );
870   }
871 }
872
873 } //Render
874
875 } //Internal
876
877 } //Dali