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