Split GlAbstraction to prevent double definition of GL constants
[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 #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, const bool managePixelBuffer = true)
246 {
247   DALI_ASSERT_DEBUG(profile == BITMAP_2D_PACKED_PIXELS || profile == BITMAP_COMPRESSED);
248
249   switch( profile )
250   {
251     /** A 2D array of pixels where each pixel is a whole number of bytes
252      * and each scanline of the backing memory buffer may have additional
253      * bytes off the right edge if requested, and there may be additional
254      * scanlines past the bottom of the image in the buffer if requested.*/
255     case BITMAP_2D_PACKED_PIXELS:
256     {
257       Bitmap * const bitmap = new Dali::Internal::BitmapPackedPixel(managePixelBuffer);
258       return bitmap;
259     }
260
261     /** The data for the bitmap is buffered in an opaque form.*/
262     case BITMAP_COMPRESSED:
263     {
264       return new Dali::Internal::BitmapCompressed(managePixelBuffer);
265     }
266   }
267   return 0;
268 }
269
270 Bitmap::Bitmap( bool discardable, Dali::Integration::PixelBuffer* pixBuf)
271 : mImageWidth(0),
272   mImageHeight(0),
273   mPixelFormat(Pixel::RGBA8888),
274   mHasAlphaChannel(true),
275   mAlphaChannelUsed(true),
276   mData(pixBuf),
277   mDiscardable(discardable)
278 {
279 }
280
281 void Bitmap::DiscardBuffer()
282 {
283   if ( mDiscardable )
284   {
285     DeletePixelBuffer();
286   }
287 }
288
289 PixelBuffer* Bitmap::ReleaseBuffer()
290 {
291   PixelBuffer* const data = mData;
292
293   // Ownership of mData has been transferred, so indicate that mData pointer is no longer valid:
294   mData = NULL;
295
296   return data;
297 }
298
299 Bitmap::~Bitmap()
300 {
301   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
302   DeletePixelBuffer();
303 }
304
305 /**
306  * */
307 void Bitmap::DeletePixelBuffer()
308 {
309   if( !mData )
310   {
311     return;
312   }
313   delete [] mData;
314   mData = NULL;
315 }
316
317
318 void Bitmap::Initialize( Pixel::Format pixelFormat,
319                           unsigned int width,
320                           unsigned int height)
321 {
322   DALI_ASSERT_DEBUG(width * height < (32 * 1024) * (32 * 1024) && "The total area of the bitmap is too great.\n");
323   mImageWidth   = width;
324   mImageHeight  = height;
325   mPixelFormat  = pixelFormat;
326
327   mHasAlphaChannel = Pixel::HasAlpha(pixelFormat);
328 }
329
330 } //namespace Integration
331
332 } //namespace Dali
333