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