2 * Copyright (c) 2021 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.
18 #include <dali/internal/render/renderers/render-texture.h>
21 #include <math.h> //floor, log2
24 #include <dali/integration-api/debug.h>
34 #if defined(DEBUG_ENABLED)
35 Debug::Filter* gTextureFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TEXTURE");
39 * Converts DALi pixel format to Graphics::Format
43 constexpr Graphics::Format ConvertPixelFormat(Pixel::Format format)
48 return Graphics::Format::UNDEFINED;
50 return Graphics::Format::R8_UNORM;
53 return Graphics::Format::L8;
55 return Graphics::Format::L8A8;
57 return Graphics::Format::R5G6B5_UNORM_PACK16;
59 return Graphics::Format::B5G6R5_UNORM_PACK16;
61 return Graphics::Format::R4G4B4A4_UNORM_PACK16;
64 return Graphics::Format::B4G4R4A4_UNORM_PACK16;
66 return Graphics::Format::R5G5B5A1_UNORM_PACK16;
68 return Graphics::Format::B5G5R5A1_UNORM_PACK16;
70 return Graphics::Format::R8G8B8_UNORM;
72 return Graphics::Format::R8G8B8A8_UNORM;
74 return Graphics::Format::B8G8R8A8_UNORM;
76 return Graphics::Format::R8G8B8A8_UNORM;
78 return Graphics::Format::B8G8R8A8_UNORM;
80 case Pixel::DEPTH_UNSIGNED_INT:
81 return Graphics::Format::D16_UNORM;
82 case Pixel::DEPTH_FLOAT:
83 return Graphics::Format::D32_SFLOAT;
84 case Pixel::DEPTH_STENCIL:
85 return Graphics::Format::D24_UNORM_S8_UINT;
88 case Pixel::COMPRESSED_R11_EAC:
89 return Graphics::Format::EAC_R11_UNORM_BLOCK;
90 case Pixel::COMPRESSED_SIGNED_R11_EAC:
91 return Graphics::Format::EAC_R11_SNORM_BLOCK;
92 case Pixel::COMPRESSED_RG11_EAC:
93 return Graphics::Format::EAC_R11G11_UNORM_BLOCK;
94 case Pixel::COMPRESSED_SIGNED_RG11_EAC:
95 return Graphics::Format::EAC_R11G11_SNORM_BLOCK;
98 case Pixel::COMPRESSED_RGB8_ETC2:
99 return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK;
100 case Pixel::COMPRESSED_SRGB8_ETC2:
101 return Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK;
103 case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
104 return Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK; // no 'punchthrough' format
106 case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
107 return Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK; // no 'punchthrough' format
109 case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
110 return Graphics::Format::ETC2_R8G8B8A8_UNORM_BLOCK;
112 case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
113 return Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK;
115 case Pixel::COMPRESSED_RGB8_ETC1:
116 return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to be supported at all
118 case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
119 return Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG; // or SRGB?
122 case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
123 return Graphics::Format::ASTC_4x4_UNORM_BLOCK; // or SRGB?
124 case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
125 return Graphics::Format::ASTC_5x4_UNORM_BLOCK;
126 case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
127 return Graphics::Format::ASTC_5x5_UNORM_BLOCK;
128 case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
129 return Graphics::Format::ASTC_6x5_UNORM_BLOCK;
130 case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
131 return Graphics::Format::ASTC_6x6_UNORM_BLOCK;
132 case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
133 return Graphics::Format::ASTC_8x5_UNORM_BLOCK;
134 case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
135 return Graphics::Format::ASTC_8x6_UNORM_BLOCK;
136 case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
137 return Graphics::Format::ASTC_8x8_UNORM_BLOCK;
138 case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
139 return Graphics::Format::ASTC_10x5_UNORM_BLOCK;
140 case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
141 return Graphics::Format::ASTC_10x6_UNORM_BLOCK;
142 case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
143 return Graphics::Format::ASTC_10x8_UNORM_BLOCK;
144 case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
145 return Graphics::Format::ASTC_10x10_UNORM_BLOCK;
146 case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
147 return Graphics::Format::ASTC_12x10_UNORM_BLOCK;
148 case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
149 return Graphics::Format::ASTC_12x12_UNORM_BLOCK;
150 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
152 return Graphics::Format::ASTC_4x4_SRGB_BLOCK; // not type with alpha, but likely to use SRGB
153 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
154 return Graphics::Format::ASTC_5x4_SRGB_BLOCK;
155 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
156 return Graphics::Format::ASTC_5x5_SRGB_BLOCK;
157 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
158 return Graphics::Format::ASTC_6x5_SRGB_BLOCK;
159 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
160 return Graphics::Format::ASTC_6x6_SRGB_BLOCK;
161 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
162 return Graphics::Format::ASTC_8x5_SRGB_BLOCK;
163 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
164 return Graphics::Format::ASTC_8x6_UNORM_BLOCK;
165 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
166 return Graphics::Format::ASTC_8x8_SRGB_BLOCK;
167 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
168 return Graphics::Format::ASTC_10x5_SRGB_BLOCK;
169 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
170 return Graphics::Format::ASTC_10x6_SRGB_BLOCK;
171 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
172 return Graphics::Format::ASTC_10x8_SRGB_BLOCK;
173 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
174 return Graphics::Format::ASTC_10x10_SRGB_BLOCK;
175 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
176 return Graphics::Format::ASTC_12x10_SRGB_BLOCK;
177 case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
178 return Graphics::Format::ASTC_12x12_SRGB_BLOCK;
180 return Graphics::Format::R16G16B16_SFLOAT;
182 return Graphics::Format::R32G32B32_SFLOAT;
183 case Pixel::R11G11B10F:
184 return Graphics::Format::R11G11B10_UFLOAT_PACK32;
186 return Graphics::Format::UNDEFINED;
189 constexpr Graphics::TextureType ConvertType(Texture::Type type)
193 case TextureType::TEXTURE_2D:
194 return Graphics::TextureType::TEXTURE_2D;
195 case TextureType::TEXTURE_CUBE:
196 return Graphics::TextureType::TEXTURE_CUBEMAP;
198 return Graphics::TextureType::TEXTURE_2D;
201 } //Unnamed namespace
203 Texture::Texture(Type type, Pixel::Format format, ImageDimensions size)
204 : mGraphicsController(nullptr),
205 mGraphicsTexture(nullptr),
208 mPixelFormat(format),
209 mWidth(size.GetWidth()),
210 mHeight(size.GetHeight()),
212 mHasAlpha(HasAlpha(format))
216 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
217 : mGraphicsController(nullptr),
218 mGraphicsTexture(nullptr),
219 mNativeImage(nativeImageInterface),
221 mPixelFormat(Pixel::RGBA8888),
222 mWidth(static_cast<uint16_t>(nativeImageInterface->GetWidth())), // ignoring overflow, not happening in practice
223 mHeight(static_cast<uint16_t>(nativeImageInterface->GetHeight())), // ignoring overflow, not happening in practice
224 mType(TextureType::TEXTURE_2D),
225 mHasAlpha(nativeImageInterface->RequiresBlending())
229 Texture::~Texture() = default;
231 void Texture::Initialize(Graphics::Controller& graphicsController)
233 mGraphicsController = &graphicsController;
236 Create(static_cast<uint32_t>(Graphics::TextureUsageFlagBits::SAMPLE));
240 void Texture::Destroy()
242 mGraphicsTexture.reset();
245 Graphics::Texture* Texture::GetGraphicsObject() const
247 DALI_LOG_INFO(gTextureFilter, Debug::General, "SC::Texture(%p)::GetGraphicsObject() = %p\n", this, mGraphicsTexture.get());
249 return mGraphicsTexture.get();
252 void Texture::Create(Graphics::TextureUsageFlags usage)
254 CreateWithData(usage, nullptr, 0u);
257 void Texture::CreateWithData(Graphics::TextureUsageFlags usage, uint8_t* data, uint32_t size)
259 auto createInfo = Graphics::TextureCreateInfo();
261 .SetTextureType(ConvertType(mType))
262 .SetUsageFlags(usage)
263 .SetFormat(ConvertPixelFormat(mPixelFormat))
264 .SetSize({mWidth, mHeight})
265 .SetLayout(Graphics::TextureLayout::LINEAR)
268 .SetNativeImage(mNativeImage)
269 .SetMipMapFlag(Graphics::TextureMipMapFlag::DISABLED);
271 mGraphicsTexture = mGraphicsController->CreateTexture(createInfo, std::move(mGraphicsTexture));
274 void Texture::Upload(PixelDataPtr pixelData, const Internal::Texture::UploadParams& params)
276 DALI_ASSERT_ALWAYS(mNativeImage == nullptr);
278 if(!mGraphicsTexture)
280 Create(static_cast<Graphics::TextureUsageFlags>(Graphics::TextureUsageFlagBits::SAMPLE));
283 Graphics::TextureUpdateInfo info{};
284 info.dstTexture = mGraphicsTexture.get();
285 info.dstOffset2D = {params.xOffset, params.yOffset};
286 info.layer = params.layer;
287 info.level = params.mipmap;
288 info.srcReference = 0;
289 info.srcExtent2D = {params.width, params.height};
291 info.srcSize = pixelData->GetBufferSize();
292 info.srcFormat = ConvertPixelFormat(pixelData->GetPixelFormat());
294 Graphics::TextureUpdateSourceInfo updateSourceInfo{};
295 updateSourceInfo.sourceType = Graphics::TextureUpdateSourceInfo::Type::MEMORY;
296 updateSourceInfo.memorySource.memory = pixelData->GetBuffer();
298 mGraphicsController->UpdateTextures({info}, {updateSourceInfo});
301 bool Texture::HasAlphaChannel() const
303 bool alpha = mHasAlpha;
306 alpha = mNativeImage->RequiresBlending();
311 void Texture::GenerateMipmaps()
313 if(!mGraphicsTexture)
315 Create(static_cast<Graphics::TextureUsageFlags>(Graphics::TextureUsageFlagBits::SAMPLE));
318 mGraphicsController->GenerateTextureMipmaps(*mGraphicsTexture.get());
321 } // namespace Render
323 } // namespace Internal