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