b4646d5c5c13728af608c35e5c661631e724eb92
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-texture.cpp
1 /*
2  * Copyright (c) 2017 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 // INTERNAL INCLUDES
21 #include <dali/devel-api/images/pixel-devel.h>
22 #include <dali/devel-api/images/native-image-interface-extension.h>
23
24 // EXTERNAL INCLUDES
25 #include <math.h>   //floor, log2
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31 namespace Render
32 {
33
34 namespace
35 {
36
37 // These match the GL specification
38 const GLint GL_MINIFY_DEFAULT  = GL_NEAREST_MIPMAP_LINEAR;
39 const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR;
40 const GLint GL_WRAP_DEFAULT  = GL_CLAMP_TO_EDGE;
41
42 // These are the Dali defaults
43 const GLint DALI_MINIFY_DEFAULT  = GL_LINEAR;
44 const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
45
46 /**
47  * @brief Convert a FilterMode to its corresponding GL type.
48  *
49  * @param[in] filterMode The FilterMode type.
50  * @param[in] daliDefault The filter mode to use if filterMode is DEFAULT.
51  * @param[in] glDefault The filter mode to use if filterMode is NONE.
52  * @return the equivalent GL filter mode.
53  */
54 GLint FilterModeToGL( FilterMode::Type filterMode, GLint daliDefault, GLint glDefault )
55 {
56   switch( filterMode )
57   {
58     case FilterMode::NEAREST:
59     {
60       return GL_NEAREST;
61     }
62     case FilterMode::LINEAR:
63     {
64       return GL_LINEAR;
65     }
66     case FilterMode::NONE:
67     {
68       return glDefault;
69     }
70     case FilterMode::NEAREST_MIPMAP_NEAREST:
71     {
72       return GL_NEAREST_MIPMAP_NEAREST;
73     }
74     case FilterMode::LINEAR_MIPMAP_NEAREST:
75     {
76       return GL_LINEAR_MIPMAP_NEAREST;
77     }
78     case FilterMode::NEAREST_MIPMAP_LINEAR:
79     {
80       return GL_NEAREST_MIPMAP_LINEAR;
81     }
82     case FilterMode::LINEAR_MIPMAP_LINEAR:
83     {
84       return GL_LINEAR_MIPMAP_LINEAR;
85     }
86     case FilterMode::DEFAULT:
87     {
88       return daliDefault;
89     }
90   }
91
92   return daliDefault;
93 }
94
95 /**
96  * @brief Convert from a WrapMode to its corresponding GL enumeration
97  * @param[in] wrapMode The wrap mode
98  * @param[in] defaultWrapMode The mode to use if WrapMode is Default
99  * @return The equivalent GL wrap mode
100  */
101 GLint WrapModeToGL( WrapMode::Type wrapMode, GLint defaultWrapMode )
102 {
103   switch( wrapMode )
104   {
105     case WrapMode::CLAMP_TO_EDGE:
106     {
107       return GL_CLAMP_TO_EDGE;
108     }
109     case WrapMode::REPEAT:
110     {
111       return GL_REPEAT;
112     }
113     case WrapMode::MIRRORED_REPEAT:
114     {
115       return GL_MIRRORED_REPEAT;
116     }
117     case WrapMode::DEFAULT:
118     {
119       return defaultWrapMode;
120     }
121   }
122
123   return defaultWrapMode;
124 }
125
126 /**
127  * @brief Retrives the GL format, GL internal format and pixel data type from a Pixel::Format
128  * @param[in] pixelFormat The pixel format.
129  * @param[out] glFormat The gl format.
130  * @param[out] glInternalFormat The gl internal format.
131  * @param[out] pixelDataType The data type of the pixel data.
132  */
133 void PixelFormatToGl( DevelPixel::Format pixelFormat, GLenum& glFormat, GLint& glInternalFormat, GLenum& pixelDataType )
134 {
135   // Compressed textures have no pixelDataType, so init to an invalid value:
136   pixelDataType  = -1;
137
138   switch( pixelFormat )
139   {
140     case Pixel::A8:
141     {
142       pixelDataType = GL_UNSIGNED_BYTE;
143       glFormat= GL_ALPHA;
144       break;
145     }
146
147     case Pixel::L8:
148     {
149       pixelDataType = GL_UNSIGNED_BYTE;
150       glFormat= GL_LUMINANCE;
151       break;
152     }
153
154     case Pixel::LA88:
155     {
156       pixelDataType = GL_UNSIGNED_BYTE;
157       glFormat= GL_LUMINANCE_ALPHA;
158       break;
159     }
160
161     case Pixel::RGB565:
162     {
163       pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
164       glFormat= GL_RGB;
165       break;
166     }
167
168     case Pixel::BGR565:
169     {
170       DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
171       pixelDataType  = GL_UNSIGNED_SHORT_5_6_5;
172 #ifdef _ARCH_ARM_
173       glFormat= GL_BGRA_EXT; // alpha is reserved but not used
174 #else
175       glFormat= GL_RGBA;     // alpha is reserved but not used
176 #endif
177       break;
178     }
179
180     case Pixel::RGBA4444:
181     {
182       pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
183       glFormat= GL_RGBA;
184       break;
185     }
186
187     case Pixel::BGRA4444:
188     {
189       DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
190       pixelDataType  = GL_UNSIGNED_SHORT_4_4_4_4;
191 #ifdef _ARCH_ARM_
192       glFormat= GL_BGRA_EXT; // alpha is reserved but not used
193 #else
194       glFormat= GL_RGBA;     // alpha is reserved but not used
195 #endif
196       break;
197     }
198
199     case Pixel::RGBA5551:
200     {
201       pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
202       glFormat= GL_RGBA;
203       break;
204     }
205
206     case Pixel::BGRA5551:
207     {
208       DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
209       pixelDataType  = GL_UNSIGNED_SHORT_5_5_5_1;
210 #ifdef _ARCH_ARM_
211       glFormat= GL_BGRA_EXT; // alpha is reserved but not used
212 #else
213       glFormat= GL_RGBA;     // alpha is reserved but not used
214 #endif
215       break;
216     }
217
218     case Pixel::RGB888:
219     {
220       pixelDataType = GL_UNSIGNED_BYTE;
221       glFormat= GL_RGB;
222       break;
223     }
224
225     case Pixel::RGB8888:
226     {
227       pixelDataType = GL_UNSIGNED_BYTE;
228       glFormat= GL_RGBA;     // alpha is reserved but not used
229       break;
230     }
231
232     case Pixel::BGR8888:
233     {
234       pixelDataType = GL_UNSIGNED_BYTE;
235 #ifdef GL_BGRA_EXT
236       glFormat= GL_BGRA_EXT; // alpha is reserved but not used
237 #else
238       glFormat= GL_RGBA;     // alpha is reserved but not used
239 #endif
240     break;
241     }
242
243     case Pixel::RGBA8888:
244     {
245       pixelDataType = GL_UNSIGNED_BYTE;
246       glFormat= GL_RGBA;
247       break;
248     }
249
250     case Pixel::BGRA8888:
251     {
252       pixelDataType = GL_UNSIGNED_BYTE;
253 #ifdef GL_BGRA_EXT
254       glFormat= GL_BGRA_EXT; // alpha is reserved but not used
255 #else
256       glFormat= GL_RGBA;     // alpha is reserved but not used
257 #endif
258       break;
259     }
260
261     // GLES 2 extension compressed formats:
262     case Pixel::COMPRESSED_RGB8_ETC1:
263     {
264       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n" );
265       glFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
266       break;
267     }
268     case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
269     {
270       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n" );
271       glFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
272       break;
273     }
274
275     // GLES 3.0 standard compressed formats:
276     case Pixel::COMPRESSED_R11_EAC:
277     {
278       DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
279       glFormat = GL_COMPRESSED_R11_EAC;
280       break;
281     }
282     case Pixel::COMPRESSED_SIGNED_R11_EAC:
283     {
284       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n" );
285       glFormat = GL_COMPRESSED_SIGNED_R11_EAC;
286       break;
287     }
288     case Pixel::COMPRESSED_RG11_EAC:
289     {
290       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n" );
291       glFormat = GL_COMPRESSED_RG11_EAC;
292       break;
293     }
294     case Pixel::COMPRESSED_SIGNED_RG11_EAC:
295     {
296       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n" );
297       glFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
298       break;
299     }
300     case Pixel::COMPRESSED_RGB8_ETC2:
301     {
302       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n" );
303       glFormat = GL_COMPRESSED_RGB8_ETC2;
304       break;
305     }
306     case Pixel::COMPRESSED_SRGB8_ETC2:
307     {
308       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n" );
309       glFormat = GL_COMPRESSED_SRGB8_ETC2;
310       break;
311     }
312     case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
313     {
314       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
315       glFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
316       break;
317     }
318     case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
319     {
320       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
321       glFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
322       break;
323     }
324     case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
325     {
326       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n" );
327       glFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
328       break;
329     }
330     case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
331     {
332       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n" );
333       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
334       break;
335     }
336
337     // GLES 3.1 extension compressed formats:
338     case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
339     {
340       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n" );
341       glFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
342       break;
343     }
344     case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
345     {
346       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n" );
347       glFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
348       break;
349     }
350     case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
351     {
352       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n" );
353       glFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
354       break;
355     }
356     case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
357     {
358       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n" );
359       glFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
360       break;
361     }
362     case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
363     {
364       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n" );
365       glFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
366       break;
367     }
368     case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
369     {
370       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n" );
371       glFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
372       break;
373     }
374     case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
375     {
376       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n" );
377       glFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
378       break;
379     }
380     case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
381     {
382       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n" );
383       glFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
384       break;
385     }
386     case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
387     {
388       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n" );
389       glFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
390       break;
391     }
392     case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
393     {
394       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n" );
395       glFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
396       break;
397     }
398     case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
399     {
400       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n" );
401       glFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
402       break;
403     }
404     case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
405     {
406       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n" );
407       glFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
408       break;
409     }
410     case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
411     {
412       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n" );
413       glFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
414       break;
415     }
416     case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
417     {
418       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n" );
419       glFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
420       break;
421     }
422     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
423     {
424       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n" );
425       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
426       break;
427     }
428     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
429     {
430       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n" );
431       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
432       break;
433     }
434     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
435     {
436       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n" );
437       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
438       break;
439     }
440     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
441     {
442       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n" );
443       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
444       break;
445     }
446     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
447     {
448       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n" );
449       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
450       break;
451     }
452     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
453     {
454       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n" );
455       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
456       break;
457     }
458     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
459     {
460       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n" );
461       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
462       break;
463     }
464     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
465     {
466       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n" );
467       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
468       break;
469     }
470     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
471     {
472       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n" );
473       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
474       break;
475     }
476     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
477     {
478       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n" );
479       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
480       break;
481     }
482     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
483     {
484       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n" );
485       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
486       break;
487     }
488     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
489     {
490       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n" );
491       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
492       break;
493     }
494     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
495     {
496       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n" );
497       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
498       break;
499     }
500     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
501     {
502       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n" );
503       glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
504       break;
505     }
506
507     // GLES 3.0 floating point formats.
508     case DevelPixel::RGB16F:
509     {
510       glFormat = GL_RGB;
511       pixelDataType = GL_HALF_FLOAT;
512       break;
513     }
514     case DevelPixel::RGB32F:
515     {
516       glFormat = GL_RGB;
517       pixelDataType = GL_FLOAT;
518       break;
519     }
520
521     case Pixel::INVALID:
522     {
523       DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
524       glFormat = 0;
525       break;
526     }
527   }
528
529   switch( pixelFormat )
530   {
531     case DevelPixel::RGB16F:
532     case DevelPixel::RGB32F: // FALL THROUGH
533     {
534       glInternalFormat = GL_R11F_G11F_B10F;
535       break;
536     }
537     default:
538     {
539       glInternalFormat = glFormat;
540     }
541   }
542
543 }
544
545
546 /**
547  * @brief Whether specified pixel format is compressed.
548  *
549  * @param [in] pixelformat Pixel format
550  * @return true if format is compressed, false otherwise
551  */
552 bool IsCompressedFormat(Pixel::Format pixelFormat)
553 {
554   switch (pixelFormat)
555   {
556     case Pixel::L8:
557     case Pixel::A8:
558     case Pixel::LA88:
559     case Pixel::RGB565:
560     case Pixel::RGBA4444:
561     case Pixel::RGBA5551:
562     case Pixel::BGR565:
563     case Pixel::BGRA4444:
564     case Pixel::BGRA5551:
565     case Pixel::RGB888:
566     case Pixel::RGB8888:
567     case Pixel::BGR8888:
568     case Pixel::RGBA8888:
569     case Pixel::BGRA8888:
570     case Pixel::INVALID:
571     {
572       return false;
573     }
574
575     case Pixel::COMPRESSED_R11_EAC:
576     case Pixel::COMPRESSED_SIGNED_R11_EAC:
577     case Pixel::COMPRESSED_RG11_EAC:
578     case Pixel::COMPRESSED_SIGNED_RG11_EAC:
579     case Pixel::COMPRESSED_RGB8_ETC2:
580     case Pixel::COMPRESSED_SRGB8_ETC2:
581     case Pixel::COMPRESSED_RGB8_ETC1:
582     case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
583     case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
584     case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
585     case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
586     case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
587     case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
588     case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
589     case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
590     case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
591     case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
592     case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
593     case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
594     case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
595     case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
596     case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
597     case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
598     case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
599     case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
600     case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
601     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
602     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
603     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
604     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
605     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
606     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
607     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
608     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
609     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
610     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
611     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
612     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
613     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
614     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
615     {
616       return true;
617     }
618   }
619
620   return false;
621 }
622
623 } //Unnamed namespace
624
625
626 Texture::Texture( Type type, Pixel::Format format, ImageDimensions size )
627 : mNativeImage(),
628   mSampler(),
629   mId( 0 ),
630   mTarget( ( type == TextureType::TEXTURE_2D ) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP ),
631   mGlInternalFormat( GL_RGB ),
632   mGlFormat( GL_RGB ),
633   mPixelDataType( GL_UNSIGNED_BYTE ),
634   mWidth( size.GetWidth() ),
635   mHeight( size.GetHeight() ),
636   mMaxMipMapLevel( 0 ),
637   mType( type ),
638   mHasAlpha( HasAlpha( format ) ),
639   mIsCompressed( IsCompressedFormat( format ) )
640 {
641   PixelFormatToGl( static_cast<DevelPixel::Format>( format ),
642                    mGlFormat,
643                    mGlInternalFormat,
644                    mPixelDataType );
645 }
646
647 Texture::Texture( NativeImageInterfacePtr nativeImageInterface )
648 : mNativeImage( nativeImageInterface ),
649   mSampler(),
650   mId( 0 ),
651   mTarget( GL_TEXTURE_2D ),
652   mGlInternalFormat( GL_RGB ),
653   mGlFormat( GL_RGB ),
654   mPixelDataType( GL_UNSIGNED_BYTE ),
655   mWidth( nativeImageInterface->GetWidth() ),
656   mHeight( nativeImageInterface->GetHeight() ),
657   mMaxMipMapLevel( 0 ),
658   mType( TextureType::TEXTURE_2D ),
659   mHasAlpha( nativeImageInterface->RequiresBlending() ),
660   mIsCompressed( false )
661 {
662 }
663
664 Texture::~Texture()
665 {}
666
667 void Texture::Destroy( Context& context )
668 {
669   if( mId )
670   {
671     context.DeleteTextures( 1, &mId );
672
673     if( mNativeImage )
674     {
675       mNativeImage->GlExtensionDestroy();
676     }
677   }
678 }
679
680 void Texture::GlContextDestroyed()
681 {
682   mId = 0u;
683 }
684
685 void Texture::Initialize(Context& context)
686 {
687   if( mNativeImage )
688   {
689     if( mNativeImage->GlExtensionCreate() )
690     {
691       NativeImageInterface::Extension* extension = mNativeImage->GetExtension();
692       if( extension )
693       {
694         mTarget = extension->GetEglImageTextureTarget();
695       }
696
697       context.GenTextures( 1, &mId );
698       context.BindTexture( mTarget, mId );
699       context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
700
701       //Apply default sampling parameters
702       context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
703       context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
704       context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
705       context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
706
707       // platform specific implementation decides on what GL extension to use
708       if( mNativeImage->TargetTexture() != 0u )
709       {
710         context.DeleteTextures( 1, &mId );
711         mNativeImage->GlExtensionDestroy();
712         mId = 0u;
713       }
714     }
715   }
716   else
717   {
718     //Create the texture and reserve memory for the first mipmap level.
719     context.GenTextures( 1, &mId );
720     context.BindTexture( mTarget, mId );
721     context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
722
723     //Apply default sampling parameters
724     context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
725     context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
726     context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
727     context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
728
729     if( mType == TextureType::TEXTURE_2D )
730     {
731       if( !mIsCompressed )
732       {
733         context.TexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
734       }
735       else
736       {
737         context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
738       }
739     }
740     else if( mType == TextureType::TEXTURE_CUBE )
741     {
742       if( !mIsCompressed )
743       {
744         for( unsigned int i(0); i<6; ++i )
745         {
746           context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, 0 );
747         }
748       }
749       else
750       {
751         for( unsigned int i(0); i<6; ++i )
752         {
753           context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, 0 );
754         }
755       }
756       context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
757     }
758   }
759 }
760
761 void Texture::Upload( Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params  )
762 {
763   DALI_ASSERT_ALWAYS( mNativeImage == NULL );
764
765   //Get pointer to the data of the PixelData object
766   unsigned char* buffer( pixelData->GetBuffer() );
767
768   //This buffer is only used if manually converting from RGB to RGBA
769   unsigned char* tempBuffer(0);
770
771   //Retrieves the pixel data element type, the gl format and gl internal format of the data contained in the PixelData object.
772   GLenum glFormat;
773   GLint glInternalFormat;
774   GLenum pixelDataElementType;
775   PixelFormatToGl( static_cast<DevelPixel::Format>( pixelData->GetPixelFormat() ), glFormat, glInternalFormat, pixelDataElementType );
776
777   //Get the maximum mipmap level to set GL_TEXTURE_MAX_LEVEL parameter in GLES3x because is not
778   //necessary to upload all the mipmap levels
779   mMaxMipMapLevel = ( mMaxMipMapLevel > params.mipmap ) ? mMaxMipMapLevel : params.mipmap;
780
781   const bool isSubImage = ( ( params.xOffset != 0 ) ||
782                             ( params.yOffset != 0 ) ||
783                             ( params.width  != ( mWidth  / ( 1 << params.mipmap ) ) ) ||
784                             ( params.height != ( mHeight / ( 1 << params.mipmap ) ) ) );
785
786   bool convert = ( ( glFormat == GL_RGB ) && ( mGlFormat == GL_RGBA ) );
787 #if DALI_GLES_VERSION >= 30
788   // Don't convert manually from RGB to RGBA if GLES >= 3.0 and a sub-image is uploaded.
789   convert = convert && !isSubImage;
790 #endif
791
792   if( convert )
793   {
794     size_t dataSize = static_cast< size_t >( params.width ) * params.height;
795     tempBuffer = new unsigned char[dataSize*4u];
796     for( size_t i(0u); i<dataSize; i++ )
797     {
798       tempBuffer[i*4u]   = buffer[i*3u];
799       tempBuffer[i*4u+1] = buffer[i*3u+1];
800       tempBuffer[i*4u+2] = buffer[i*3u+2];
801       tempBuffer[i*4u+3] = 0xFF;
802     }
803
804     buffer = tempBuffer;
805     glFormat = mGlFormat; // Set the glFormat to GL_RGBA
806   }
807
808   //Upload data to the texture
809
810   context.BindTexture( mTarget, mId );
811   GLenum target( mTarget );
812   if( mType == TextureType::TEXTURE_CUBE )
813   {
814     target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
815   }
816
817   context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
818
819   if( !isSubImage )
820   {
821     //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
822     if( !mIsCompressed )
823     {
824       context.TexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, glFormat, pixelDataElementType, buffer );
825     }
826     else
827     {
828       context.CompressedTexImage2D( target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, pixelData->GetBufferSize(), buffer );
829     }
830   }
831   else
832   {
833     //Specifying part of the image for the mipmap
834     if( !mIsCompressed )
835     {
836       context.TexSubImage2D( target, params.mipmap,
837                              params.xOffset, params.yOffset, params.width, params.height,
838                              glFormat, pixelDataElementType, buffer );
839     }
840     else
841     {
842       context.CompressedTexSubImage2D( target, params.mipmap,
843                                        params.xOffset, params.yOffset, params.width, params.height,
844                                        glFormat, pixelData->GetBufferSize(), buffer );
845     }
846   }
847
848
849   //Destroy temp buffer used for conversion RGB->RGBA
850   delete[] tempBuffer;
851 }
852
853 bool Texture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
854 {
855   if( mNativeImage && mId == 0 )
856   {
857     Initialize( context );
858   }
859
860   if( mId != 0 )
861   {
862     context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
863     context.BindTexture( mTarget, mId );
864     ApplySampler( context, sampler );
865
866     if( mNativeImage )
867     {
868       mNativeImage->PrepareTexture();
869     }
870
871     return true;
872   }
873
874   return false;
875 }
876
877 void Texture::ApplySampler( Context& context, Render::Sampler* sampler )
878 {
879   Render::Sampler oldSampler = mSampler;
880   mSampler = sampler ? *sampler : Sampler();
881
882   if( mSampler != oldSampler )
883   {
884     GLint mode = FilterModeToGL( mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT );
885     if( mode != FilterModeToGL( oldSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT ) )
886     {
887       context.TexParameteri( mTarget, GL_TEXTURE_MIN_FILTER, mode );
888     }
889
890     mode = FilterModeToGL( mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT );
891     if( mode != FilterModeToGL( oldSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT ) )
892     {
893       context.TexParameteri( mTarget, GL_TEXTURE_MAG_FILTER, mode );
894     }
895
896     mode = WrapModeToGL( mSampler.mSWrapMode, GL_WRAP_DEFAULT );
897     if( mode != WrapModeToGL( oldSampler.mSWrapMode, GL_WRAP_DEFAULT ) )
898     {
899       context.TexParameteri( mTarget, GL_TEXTURE_WRAP_S, mode );
900     }
901
902     mode = WrapModeToGL( mSampler.mTWrapMode, GL_WRAP_DEFAULT );
903     if( mode != WrapModeToGL( oldSampler.mTWrapMode, GL_WRAP_DEFAULT ) )
904     {
905       context.TexParameteri( mTarget, GL_TEXTURE_WRAP_T, mode );
906     }
907
908     if( mType == TextureType::TEXTURE_CUBE )
909     {
910       mode = WrapModeToGL( mSampler.mRWrapMode, GL_WRAP_DEFAULT );
911       if( mode != WrapModeToGL( oldSampler.mRWrapMode, GL_WRAP_DEFAULT ) )
912       {
913         context.TexParameteri( mTarget, GL_TEXTURE_WRAP_R, mode );
914       }
915     }
916
917 #if DALI_GLES_VERSION >= 30
918     //In GLES 3.0 we do not need to upload all of the mipmap levels, but GL_TEXTURE_MAX_LEVEL must be set
919     if(mMaxMipMapLevel)
920     {
921       context.TexParameteri( mTarget, GL_TEXTURE_MAX_LEVEL, mMaxMipMapLevel );
922     }
923 #endif
924
925   }
926 }
927
928 bool Texture::HasAlphaChannel()
929 {
930   return mHasAlpha;
931 }
932
933 void Texture::GenerateMipmaps( Context& context )
934 {
935   //GL_TEXTURE_MAX_LEVEL does not need to be set when mipmaps are generated by GL
936   mMaxMipMapLevel = 0;
937   context.BindTexture( mTarget, mId );
938   context.GenerateMipmap( mTarget );
939 }
940
941 } //Render
942
943 } //Internal
944
945 } //Dali