Merge "Doxygen grouping" into devel/master
[platform/core/uifw/dali-core.git] / dali / integration-api / bitmap.cpp
1 /*
2  * Copyright (c) 2014 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
18 // CLASS HEADER
19 #include <dali/integration-api/bitmap.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/platform-abstraction.h>
24 #include <dali/internal/event/common/thread-local-storage.h>
25 #include <dali/internal/event/images/bitmap-packed-pixel.h>
26 #include <dali/internal/event/images/bitmap-compressed.h>
27 #include <dali/internal/event/images/bitmap-external.h>
28 #include <dali/integration-api/gl-abstraction.h>
29 #include <dali/integration-api/gl-defines.h>
30
31 namespace Dali
32 {
33
34 namespace Integration
35 {
36 using namespace Dali::Pixel;
37
38 void ConvertToGlFormat( Format pixelformat, unsigned& pixelDataType, unsigned& internalFormat )
39 {
40   // Compressed textures have no pixelDataType, so init to an invalid value:
41   pixelDataType  = -1;
42
43   switch( pixelformat )
44   {
45     case A8:
46     {
47       pixelDataType = GL_UNSIGNED_BYTE;
48       internalFormat= GL_ALPHA;
49       break;
50     }
51
52     case L8:
53     {
54       pixelDataType = GL_UNSIGNED_BYTE;
55       internalFormat= GL_LUMINANCE;
56       break;
57     }
58
59     case LA88:
60     {
61       pixelDataType = GL_UNSIGNED_BYTE;
62       internalFormat= GL_LUMINANCE_ALPHA;
63       break;
64     }
65
66     case RGB565:
67     {
68       pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
69       internalFormat= GL_RGB;
70       break;
71     }
72
73     case BGR565:
74     {
75       DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
76       pixelDataType  = GL_UNSIGNED_SHORT_5_6_5;
77 #ifdef _ARCH_ARM_
78       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
79 #else
80       internalFormat= GL_RGBA;     // alpha is reserved but not used
81 #endif
82       break;
83     }
84
85     case RGBA4444:
86     {
87       pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
88       internalFormat= GL_RGBA;
89       break;
90     }
91
92     case BGRA4444:
93     {
94       DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
95       pixelDataType  = GL_UNSIGNED_SHORT_4_4_4_4;
96 #ifdef _ARCH_ARM_
97       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
98 #else
99       internalFormat= GL_RGBA;     // alpha is reserved but not used
100 #endif
101       break;
102     }
103
104     case RGBA5551:
105     {
106       pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
107       internalFormat= GL_RGBA;
108       break;
109     }
110
111     case BGRA5551:
112     {
113       DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
114       pixelDataType  = GL_UNSIGNED_SHORT_5_5_5_1;
115 #ifdef _ARCH_ARM_
116       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
117 #else
118       internalFormat= GL_RGBA;     // alpha is reserved but not used
119 #endif
120       break;
121     }
122
123     case RGB888:
124     {
125       pixelDataType = GL_UNSIGNED_BYTE;
126       internalFormat= GL_RGB;
127       break;
128     }
129
130     case RGB8888:
131     {
132       pixelDataType = GL_UNSIGNED_BYTE;
133       internalFormat= GL_RGBA;     // alpha is reserved but not used
134       break;
135     }
136
137     case BGR8888:
138     {
139       pixelDataType = GL_UNSIGNED_BYTE;
140 #ifdef GL_BGRA_EXT
141       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
142 #else
143       internalFormat= GL_RGBA;     // alpha is reserved but not used
144 #endif
145     break;
146     }
147
148     case RGBA8888:
149     {
150       pixelDataType = GL_UNSIGNED_BYTE;
151       internalFormat= GL_RGBA;
152       break;
153     }
154
155     case BGRA8888:
156     {
157       pixelDataType = GL_UNSIGNED_BYTE;
158 #ifdef GL_BGRA_EXT
159       internalFormat= GL_BGRA_EXT; // alpha is reserved but not used
160 #else
161       internalFormat= GL_RGBA;     // alpha is reserved but not used
162 #endif
163       break;
164     }
165
166     // GLES 3.0 standard compressed formats:
167     case COMPRESSED_R11_EAC:
168     {
169       DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
170       internalFormat = 0x9270; ///! < Hardcoded until we move to GLES 3.0 or greater.
171       break;
172     }
173     case COMPRESSED_SIGNED_R11_EAC:
174     {
175       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n" );
176       internalFormat = 0x9271; ///! < Hardcoded until we move to GLES 3.0 or greater.
177       ;
178       break;
179     }
180     case COMPRESSED_RG11_EAC:
181     {
182       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n" );
183       internalFormat = 0x9272; ///! < Hardcoded until we move to GLES 3.0 or greater.
184       break;
185     }
186     case COMPRESSED_SIGNED_RG11_EAC:
187     {
188       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n" );
189       internalFormat = 0x9273; ///! < Hardcoded until we move to GLES 3.0 or greater.
190       break;
191     }
192     case COMPRESSED_RGB8_ETC2:
193     {
194       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n" );
195       internalFormat = 0x9274; ///! < Hardcoded until we move to GLES 3.0 or greater.
196       break;
197     }
198     case COMPRESSED_SRGB8_ETC2:
199     {
200       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n" );
201       internalFormat = 0x9275; ///! < Hardcoded until we move to GLES 3.0 or greater.
202       break;
203     }
204     case COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
205     {
206       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
207       internalFormat = 0x9276; ///! < Hardcoded until we move to GLES 3.0 or greater.
208       break;
209     }
210     case COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
211     {
212       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n" );
213       internalFormat = 0x9277; ///! < Hardcoded until we move to GLES 3.0 or greater.
214       break;
215     }
216     case COMPRESSED_RGBA8_ETC2_EAC:
217     {
218       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n" );
219       internalFormat = 0x9278; ///! < Hardcoded until we move to GLES 3.0 or greater.
220       break;
221     }
222     case COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
223     {
224       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n" );
225       internalFormat = 0x9279; ///! < Hardcoded until we move to GLES 3.0 or greater.
226       break;
227     }
228
229     // GLES 2 extension compressed formats:
230     case COMPRESSED_RGB8_ETC1:
231     {
232       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n" );
233       internalFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
234       break;
235     }
236     case COMPRESSED_RGB_PVRTC_4BPPV1:
237     {
238       DALI_LOG_INFO( Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n" );
239       internalFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
240       break;
241     }
242   }
243 }
244
245 Bitmap* Bitmap::New( const Profile profile = BITMAP_2D_PACKED_PIXELS,
246                      ResourcePolicy::Discardable discardable = ResourcePolicy::OWNED_DISCARD )
247 {
248   DALI_ASSERT_DEBUG(profile == BITMAP_2D_PACKED_PIXELS || profile == BITMAP_COMPRESSED);
249
250   switch( profile )
251   {
252     /** A 2D array of pixels where each pixel is a whole number of bytes
253      * and each scanline of the backing memory buffer may have additional
254      * bytes off the right edge if requested, and there may be additional
255      * scanlines past the bottom of the image in the buffer if requested.*/
256     case BITMAP_2D_PACKED_PIXELS:
257     {
258       Bitmap * const bitmap = new Dali::Internal::BitmapPackedPixel( discardable );
259       return bitmap;
260     }
261
262     /** The data for the bitmap is buffered in an opaque form.*/
263     case BITMAP_COMPRESSED:
264     {
265       return new Dali::Internal::BitmapCompressed( discardable );
266     }
267   }
268   return 0;
269 }
270
271
272 Bitmap::Bitmap( ResourcePolicy::Discardable discardable, Dali::Integration::PixelBuffer* pixBuf)
273 : mImageWidth(0),
274   mImageHeight(0),
275   mPixelFormat(Pixel::RGBA8888),
276   mHasAlphaChannel(true),
277   mAlphaChannelUsed(true),
278   mData(pixBuf),
279   mDiscardable(discardable)
280 {
281 }
282
283 void Bitmap::DiscardBuffer()
284 {
285   if( mDiscardable == ResourcePolicy::OWNED_DISCARD )
286   {
287     DeletePixelBuffer();
288   }
289 }
290
291 Bitmap::~Bitmap()
292 {
293   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
294
295   // If owned
296   if( mDiscardable == ResourcePolicy::OWNED_DISCARD ||
297       mDiscardable == ResourcePolicy::OWNED_RETAIN )
298   {
299     DeletePixelBuffer();
300   }
301 }
302
303 /**
304  * */
305 void Bitmap::DeletePixelBuffer()
306 {
307   if( !mData )
308   {
309     return;
310   }
311   free ( mData );
312   mData = NULL;
313 }
314
315
316 void Bitmap::Initialize( Pixel::Format pixelFormat,
317                           unsigned int width,
318                           unsigned int height)
319 {
320   DALI_ASSERT_DEBUG(width * height < (32 * 1024) * (32 * 1024) && "The total area of the bitmap is too great.\n");
321   mImageWidth   = width;
322   mImageHeight  = height;
323   mPixelFormat  = pixelFormat;
324
325   mHasAlphaChannel = Pixel::HasAlpha(pixelFormat);
326 }
327
328 } //namespace Integration
329
330 } //namespace Dali