2 * Copyright (c) 2022 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:
39 pixelDataType = GL_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;
427 DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 GLES 3.0 floating point format.\n");
428 pixelDataType = GL_FLOAT;
429 internalFormat = GL_R11F_G11F_B10F;
433 // GLES 3.0 depth and stencil formats
434 case Pixel::DEPTH_UNSIGNED_INT:
436 pixelDataType = GL_UNSIGNED_INT;
437 internalFormat = GL_DEPTH_COMPONENT;
440 case Pixel::DEPTH_FLOAT:
442 pixelDataType = GL_FLOAT;
443 internalFormat = GL_DEPTH_COMPONENT;
446 case Pixel::DEPTH_STENCIL:
448 pixelDataType = GL_UNSIGNED_INT_24_8;
449 internalFormat = GL_DEPTH_STENCIL;
453 // Chrominance formats
454 case Pixel::CHROMINANCE_U:
456 pixelDataType = GL_UNSIGNED_BYTE;
457 internalFormat = GL_LUMINANCE; // GL doesn't support chrominance format. We should convert it in the shader.
460 case Pixel::CHROMINANCE_V:
462 pixelDataType = GL_UNSIGNED_BYTE;
463 internalFormat = GL_LUMINANCE; // GL doesn't support chrominance format. We should convert it in the shader.
469 DALI_LOG_ERROR("Invalid pixel format for bitmap\n");
476 Bitmap* Bitmap::New(const Profile profile = BITMAP_2D_PACKED_PIXELS,
477 ResourcePolicy::Discardable discardable = ResourcePolicy::OWNED_DISCARD)
479 DALI_ASSERT_DEBUG(profile == BITMAP_2D_PACKED_PIXELS || profile == BITMAP_COMPRESSED);
483 /** A 2D array of pixels where each pixel is a whole number of bytes
484 * and each scanline of the backing memory buffer may have additional
485 * bytes off the right edge if requested, and there may be additional
486 * scanlines past the bottom of the image in the buffer if requested.*/
487 case BITMAP_2D_PACKED_PIXELS:
489 Bitmap* const bitmap = new Dali::Internal::BitmapPackedPixel(discardable);
493 /** The data for the bitmap is buffered in an opaque form.*/
494 case BITMAP_COMPRESSED:
496 return new Dali::Internal::BitmapCompressed(discardable);
502 Bitmap::Bitmap(ResourcePolicy::Discardable discardable, Dali::Integration::PixelBuffer* pixBuf)
505 mPixelFormat(Pixel::RGBA8888),
506 mHasAlphaChannel(true),
507 mAlphaChannelUsed(true),
509 mDiscardable(discardable)
513 PixelBuffer* Bitmap::GetBufferOwnership()
515 PixelBuffer* buffer = mData;
520 void Bitmap::DiscardBuffer()
522 if(mDiscardable == ResourcePolicy::OWNED_DISCARD)
530 DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
536 void Bitmap::DeletePixelBuffer()
546 void Bitmap::Initialize(Pixel::Format pixelFormat,
550 DALI_ASSERT_DEBUG(width * height < (32 * 1024) * (32 * 1024) && "The total area of the bitmap is too great.\n");
552 mImageHeight = height;
553 mPixelFormat = pixelFormat;
555 mHasAlphaChannel = Pixel::HasAlpha(pixelFormat);
558 } //namespace Integration