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