BufferImage mirrors an external Pixel Buffer on creation.
[platform/core/uifw/dali-core.git] / dali / integration-api / bitmap.cpp
1 /*
2  * Copyright (c) 2015 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/integration-api/gl-abstraction.h>
28 #include <dali/integration-api/gl-defines.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,
245                      ResourcePolicy::Discardable discardable = ResourcePolicy::OWNED_DISCARD )
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( discardable );
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( discardable );
265     }
266   }
267   return 0;
268 }
269
270
271 Bitmap::Bitmap( ResourcePolicy::Discardable discardable, Dali::Integration::PixelBuffer* pixBuf)
272 : mImageWidth(0),
273   mImageHeight(0),
274   mPixelFormat(Pixel::RGBA8888),
275   mHasAlphaChannel(true),
276   mAlphaChannelUsed(true),
277   mData(pixBuf),
278   mDiscardable(discardable)
279 {
280 }
281
282 void Bitmap::DiscardBuffer()
283 {
284   if( mDiscardable == ResourcePolicy::OWNED_DISCARD )
285   {
286     DeletePixelBuffer();
287   }
288 }
289
290 Bitmap::~Bitmap()
291 {
292   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
293   DeletePixelBuffer();
294 }
295
296 /**
297  * */
298 void Bitmap::DeletePixelBuffer()
299 {
300   if( !mData )
301   {
302     return;
303   }
304   free ( mData );
305   mData = NULL;
306 }
307
308
309 void Bitmap::Initialize( Pixel::Format pixelFormat,
310                           unsigned int width,
311                           unsigned int height)
312 {
313   DALI_ASSERT_DEBUG(width * height < (32 * 1024) * (32 * 1024) && "The total area of the bitmap is too great.\n");
314   mImageWidth   = width;
315   mImageHeight  = height;
316   mPixelFormat  = pixelFormat;
317
318   mHasAlphaChannel = Pixel::HasAlpha(pixelFormat);
319 }
320
321 } //namespace Integration
322
323 } //namespace Dali