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