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