2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/integration-api/bitmap.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/gl-abstraction.h>
24 #include <dali/integration-api/gl-defines.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-compressed.h>
28 #include <dali/internal/event/images/bitmap-packed-pixel.h>
34 using namespace Dali::Pixel;
36 void ConvertToGlFormat(Format pixelformat, unsigned& pixelDataType, unsigned& internalFormat)
38 // Compressed textures have no pixelDataType, so init to an invalid value:
45 pixelDataType = GL_UNSIGNED_BYTE;
46 internalFormat = GL_ALPHA;
52 pixelDataType = GL_UNSIGNED_BYTE;
53 internalFormat = GL_LUMINANCE;
59 pixelDataType = GL_UNSIGNED_BYTE;
60 internalFormat = GL_LUMINANCE_ALPHA;
66 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
67 internalFormat = GL_RGB;
73 DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
74 pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
76 internalFormat = GL_BGRA_EXT; // alpha is reserved but not used
78 internalFormat = GL_RGBA; // alpha is reserved but not used
85 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
86 internalFormat = GL_RGBA;
92 DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
93 pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
95 internalFormat = GL_BGRA_EXT; // alpha is reserved but not used
97 internalFormat = GL_RGBA; // alpha is reserved but not used
104 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
105 internalFormat = GL_RGBA;
111 DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
112 pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
114 internalFormat = GL_BGRA_EXT; // alpha is reserved but not used
116 internalFormat = GL_RGBA; // alpha is reserved but not used
123 pixelDataType = GL_UNSIGNED_BYTE;
124 internalFormat = GL_RGB;
130 pixelDataType = GL_UNSIGNED_BYTE;
131 internalFormat = GL_RGBA; // alpha is reserved but not used
137 pixelDataType = GL_UNSIGNED_BYTE;
139 internalFormat = GL_BGRA_EXT; // alpha is reserved but not used
141 internalFormat = GL_RGBA; // alpha is reserved but not used
148 pixelDataType = GL_UNSIGNED_BYTE;
149 internalFormat = GL_RGBA;
155 pixelDataType = GL_UNSIGNED_BYTE;
157 internalFormat = GL_BGRA_EXT; // alpha is reserved but not used
159 internalFormat = GL_RGBA; // alpha is reserved but not used
164 // GLES 2 extension compressed formats:
165 case COMPRESSED_RGB8_ETC1:
167 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n");
168 internalFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
171 case COMPRESSED_RGB_PVRTC_4BPPV1:
173 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n");
174 internalFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
178 // GLES 3.0 standard compressed formats:
179 case COMPRESSED_R11_EAC:
181 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
182 internalFormat = GL_COMPRESSED_R11_EAC;
185 case COMPRESSED_SIGNED_R11_EAC:
187 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n");
188 internalFormat = GL_COMPRESSED_SIGNED_R11_EAC;
191 case COMPRESSED_RG11_EAC:
193 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n");
194 internalFormat = GL_COMPRESSED_RG11_EAC;
197 case COMPRESSED_SIGNED_RG11_EAC:
199 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n");
200 internalFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
203 case COMPRESSED_RGB8_ETC2:
205 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n");
206 internalFormat = GL_COMPRESSED_RGB8_ETC2;
209 case COMPRESSED_SRGB8_ETC2:
211 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n");
212 internalFormat = GL_COMPRESSED_SRGB8_ETC2;
215 case COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
217 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n");
218 internalFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
221 case COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
223 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n");
224 internalFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
227 case COMPRESSED_RGBA8_ETC2_EAC:
229 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n");
230 internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
233 case COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
235 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n");
236 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
240 // GLES 3.1 extension compressed formats:
241 case COMPRESSED_RGBA_ASTC_4x4_KHR:
243 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n");
244 internalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
247 case COMPRESSED_RGBA_ASTC_5x4_KHR:
249 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n");
250 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
253 case COMPRESSED_RGBA_ASTC_5x5_KHR:
255 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n");
256 internalFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
259 case COMPRESSED_RGBA_ASTC_6x5_KHR:
261 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n");
262 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
265 case COMPRESSED_RGBA_ASTC_6x6_KHR:
267 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n");
268 internalFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
271 case COMPRESSED_RGBA_ASTC_8x5_KHR:
273 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n");
274 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
277 case COMPRESSED_RGBA_ASTC_8x6_KHR:
279 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n");
280 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
283 case COMPRESSED_RGBA_ASTC_8x8_KHR:
285 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n");
286 internalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
289 case COMPRESSED_RGBA_ASTC_10x5_KHR:
291 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n");
292 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
295 case COMPRESSED_RGBA_ASTC_10x6_KHR:
297 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n");
298 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
301 case COMPRESSED_RGBA_ASTC_10x8_KHR:
303 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n");
304 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
307 case COMPRESSED_RGBA_ASTC_10x10_KHR:
309 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n");
310 internalFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
313 case COMPRESSED_RGBA_ASTC_12x10_KHR:
315 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n");
316 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
319 case COMPRESSED_RGBA_ASTC_12x12_KHR:
321 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n");
322 internalFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
325 case COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
327 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n");
328 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
331 case COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
333 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n");
334 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
337 case COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
339 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n");
340 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
343 case COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
345 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n");
346 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
349 case COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
351 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n");
352 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
355 case COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
357 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n");
358 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
361 case COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
363 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n");
364 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
367 case COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
369 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n");
370 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
373 case COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
375 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n");
376 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
379 case COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
381 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n");
382 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
385 case COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
387 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n");
388 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
391 case COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
393 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n");
394 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
397 case COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
399 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n");
400 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
403 case COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
405 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n");
406 internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
410 // GLES 3.0 floating point formats.
413 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 GLES 3.0 floating point format.\n");
414 pixelDataType = GL_HALF_FLOAT;
415 internalFormat = GL_RGB;
420 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 GLES 3.0 floating point format.\n");
421 pixelDataType = GL_FLOAT;
422 internalFormat = GL_RGB;
426 // GLES 3.0 depth and stencil formats
427 case Pixel::DEPTH_UNSIGNED_INT:
429 pixelDataType = GL_UNSIGNED_INT;
430 internalFormat = GL_DEPTH_COMPONENT;
433 case Pixel::DEPTH_FLOAT:
435 pixelDataType = GL_FLOAT;
436 internalFormat = GL_DEPTH_COMPONENT;
439 case Pixel::DEPTH_STENCIL:
441 pixelDataType = GL_UNSIGNED_INT_24_8;
442 internalFormat = GL_DEPTH_STENCIL;
448 DALI_LOG_ERROR("Invalid pixel format for bitmap\n");
455 Bitmap* Bitmap::New(const Profile profile = BITMAP_2D_PACKED_PIXELS,
456 ResourcePolicy::Discardable discardable = ResourcePolicy::OWNED_DISCARD)
458 DALI_ASSERT_DEBUG(profile == BITMAP_2D_PACKED_PIXELS || profile == BITMAP_COMPRESSED);
462 /** A 2D array of pixels where each pixel is a whole number of bytes
463 * and each scanline of the backing memory buffer may have additional
464 * bytes off the right edge if requested, and there may be additional
465 * scanlines past the bottom of the image in the buffer if requested.*/
466 case BITMAP_2D_PACKED_PIXELS:
468 Bitmap* const bitmap = new Dali::Internal::BitmapPackedPixel(discardable);
472 /** The data for the bitmap is buffered in an opaque form.*/
473 case BITMAP_COMPRESSED:
475 return new Dali::Internal::BitmapCompressed(discardable);
481 Bitmap::Bitmap(ResourcePolicy::Discardable discardable, Dali::Integration::PixelBuffer* pixBuf)
484 mPixelFormat(Pixel::RGBA8888),
485 mHasAlphaChannel(true),
486 mAlphaChannelUsed(true),
488 mDiscardable(discardable)
492 PixelBuffer* Bitmap::GetBufferOwnership()
494 PixelBuffer* buffer = mData;
499 void Bitmap::DiscardBuffer()
501 if(mDiscardable == ResourcePolicy::OWNED_DISCARD)
509 DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
515 void Bitmap::DeletePixelBuffer()
525 void Bitmap::Initialize(Pixel::Format pixelFormat,
529 DALI_ASSERT_DEBUG(width * height < (32 * 1024) * (32 * 1024) && "The total area of the bitmap is too great.\n");
531 mImageHeight = height;
532 mPixelFormat = pixelFormat;
534 mHasAlphaChannel = Pixel::HasAlpha(pixelFormat);
537 } //namespace Integration