Merge branch 'devel/graphics' into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-texture.cpp
1 /*
2  * Copyright (c) 2021 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 // CLASS HEADER
18 #include <dali/internal/render/renderers/render-texture.h>
19
20 // EXTERNAL INCLUDES
21 #include <math.h> //floor, log2
22
23 // INTERNAL INCLUDES
24
25 namespace Dali
26 {
27 namespace Internal
28 {
29 namespace Render
30 {
31 namespace
32 {
33 #if defined(DEBUG_ENABLED)
34 Debug::Filter* gTextureFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TEXTURE");
35 #endif
36
37 /**
38  * Converts DALi pixel format to Graphics::Format
39  * @param format
40  * @return
41  */
42 constexpr Graphics::Format ConvertPixelFormat(Pixel::Format format)
43 {
44   switch(format)
45   {
46     case Pixel::INVALID:
47       return Graphics::Format::UNDEFINED;
48     case Pixel::A8:
49       return Graphics::Format::R8_UNORM;
50
51     case Pixel::L8:
52       return Graphics::Format::L8;
53     case Pixel::LA88:
54       return Graphics::Format::L8A8;
55     case Pixel::RGB565:
56       return Graphics::Format::R5G6B5_UNORM_PACK16;
57     case Pixel::BGR565:
58       return Graphics::Format::B5G6R5_UNORM_PACK16;
59     case Pixel::RGBA4444:
60       return Graphics::Format::R4G4B4A4_UNORM_PACK16;
61
62     case Pixel::BGRA4444:
63       return Graphics::Format::B4G4R4A4_UNORM_PACK16;
64     case Pixel::RGBA5551:
65       return Graphics::Format::R5G5B5A1_UNORM_PACK16;
66     case Pixel::BGRA5551:
67       return Graphics::Format::B5G5R5A1_UNORM_PACK16;
68     case Pixel::RGB888:
69       return Graphics::Format::R8G8B8_UNORM;
70     case Pixel::RGB8888:
71       return Graphics::Format::R8G8B8A8_UNORM;
72     case Pixel::BGR8888:
73       return Graphics::Format::B8G8R8A8_UNORM;
74     case Pixel::RGBA8888:
75       return Graphics::Format::R8G8B8A8_UNORM;
76     case Pixel::BGRA8888:
77       return Graphics::Format::B8G8R8A8_UNORM;
78
79     case Pixel::DEPTH_UNSIGNED_INT:
80       return Graphics::Format::D16_UNORM;
81     case Pixel::DEPTH_FLOAT:
82       return Graphics::Format::D32_SFLOAT;
83     case Pixel::DEPTH_STENCIL:
84       return Graphics::Format::D24_UNORM_S8_UINT;
85
86     // EAC
87     case Pixel::COMPRESSED_R11_EAC:
88       return Graphics::Format::EAC_R11_UNORM_BLOCK;
89     case Pixel::COMPRESSED_SIGNED_R11_EAC:
90       return Graphics::Format::EAC_R11_SNORM_BLOCK;
91     case Pixel::COMPRESSED_RG11_EAC:
92       return Graphics::Format::EAC_R11G11_UNORM_BLOCK;
93     case Pixel::COMPRESSED_SIGNED_RG11_EAC:
94       return Graphics::Format::EAC_R11G11_SNORM_BLOCK;
95
96     // ETC
97     case Pixel::COMPRESSED_RGB8_ETC2:
98       return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK;
99     case Pixel::COMPRESSED_SRGB8_ETC2:
100       return Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK;
101
102     case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
103       return Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK; // no 'punchthrough' format
104
105     case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
106       return Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK; // no 'punchthrough' format
107
108     case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
109       return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to map onto any format
110
111     case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
112       return Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK; // doesn't seem to map onto any format
113
114     case Pixel::COMPRESSED_RGB8_ETC1:
115       return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to be supported at all
116
117     case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
118       return Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG; // or SRGB?
119
120     // ASTC
121     case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
122       return Graphics::Format::ASTC_4x4_UNORM_BLOCK; // or SRGB?
123     case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
124       return Graphics::Format::ASTC_5x4_UNORM_BLOCK;
125     case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
126       return Graphics::Format::ASTC_5x5_UNORM_BLOCK;
127     case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
128       return Graphics::Format::ASTC_6x5_UNORM_BLOCK;
129     case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
130       return Graphics::Format::ASTC_6x6_UNORM_BLOCK;
131     case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
132       return Graphics::Format::ASTC_8x5_UNORM_BLOCK;
133     case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
134       return Graphics::Format::ASTC_8x6_UNORM_BLOCK;
135     case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
136       return Graphics::Format::ASTC_8x8_UNORM_BLOCK;
137     case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
138       return Graphics::Format::ASTC_10x5_UNORM_BLOCK;
139     case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
140       return Graphics::Format::ASTC_10x6_UNORM_BLOCK;
141     case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
142       return Graphics::Format::ASTC_10x8_UNORM_BLOCK;
143     case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
144       return Graphics::Format::ASTC_10x10_UNORM_BLOCK;
145     case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
146       return Graphics::Format::ASTC_12x10_UNORM_BLOCK;
147     case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
148       return Graphics::Format::ASTC_12x12_UNORM_BLOCK;
149     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
150
151       return Graphics::Format::ASTC_4x4_SRGB_BLOCK; // not type with alpha, but likely to use SRGB
152     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
153       return Graphics::Format::ASTC_5x4_SRGB_BLOCK;
154     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
155       return Graphics::Format::ASTC_5x5_SRGB_BLOCK;
156     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
157       return Graphics::Format::ASTC_6x5_SRGB_BLOCK;
158     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
159       return Graphics::Format::ASTC_6x6_SRGB_BLOCK;
160     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
161       return Graphics::Format::ASTC_8x5_SRGB_BLOCK;
162     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
163       return Graphics::Format::ASTC_8x6_UNORM_BLOCK;
164     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
165       return Graphics::Format::ASTC_8x8_SRGB_BLOCK;
166     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
167       return Graphics::Format::ASTC_10x5_SRGB_BLOCK;
168     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
169       return Graphics::Format::ASTC_10x6_SRGB_BLOCK;
170     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
171       return Graphics::Format::ASTC_10x8_SRGB_BLOCK;
172     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
173       return Graphics::Format::ASTC_10x10_SRGB_BLOCK;
174     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
175       return Graphics::Format::ASTC_12x10_SRGB_BLOCK;
176     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
177       return Graphics::Format::ASTC_12x12_SRGB_BLOCK;
178     case Pixel::RGB16F:
179       return Graphics::Format::R16G16B16_SFLOAT;
180     case Pixel::RGB32F:
181       return Graphics::Format::R32G32B32_SFLOAT;
182   }
183   return Graphics::Format::UNDEFINED;
184 }
185
186 constexpr Graphics::TextureType ConvertType(Texture::Type type)
187 {
188   switch(type)
189   {
190     case TextureType::TEXTURE_2D:
191       return Graphics::TextureType::TEXTURE_2D;
192     case TextureType::TEXTURE_CUBE:
193       return Graphics::TextureType::TEXTURE_CUBEMAP;
194   }
195   return Graphics::TextureType::TEXTURE_2D;
196 }
197
198 } //Unnamed namespace
199
200 Texture::Texture(Type type, Pixel::Format format, ImageDimensions size)
201 : mGraphicsController(nullptr),
202   mGraphicsTexture(nullptr),
203   mNativeImage(),
204   mSampler(),
205   mPixelFormat(format),
206   mWidth(size.GetWidth()),
207   mHeight(size.GetHeight()),
208   mMaxMipMapLevel(0),
209   mType(type),
210   mHasAlpha(HasAlpha(format))
211 {
212 }
213
214 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
215 : mGraphicsController(nullptr),
216   mGraphicsTexture(nullptr),
217   mNativeImage(nativeImageInterface),
218   mSampler(),
219   mPixelFormat(Pixel::RGBA8888),
220   mWidth(static_cast<uint16_t>(nativeImageInterface->GetWidth())),   // ignoring overflow, not happening in practice
221   mHeight(static_cast<uint16_t>(nativeImageInterface->GetHeight())), // ignoring overflow, not happening in practice
222   mMaxMipMapLevel(0),
223   mType(TextureType::TEXTURE_2D),
224   mHasAlpha(nativeImageInterface->RequiresBlending())
225 {
226 }
227
228 Texture::~Texture() = default;
229
230 void Texture::Initialize(Graphics::Controller& graphicsController)
231 {
232   mGraphicsController = &graphicsController;
233   if(mNativeImage)
234   {
235     Create(static_cast<uint32_t>(Graphics::TextureUsageFlagBits::SAMPLE));
236   }
237 }
238
239 void Texture::Destroy()
240 {
241   mGraphicsTexture.reset();
242 }
243
244 Graphics::Texture* Texture::GetGraphicsObject() const
245 {
246   DALI_LOG_INFO(gTextureFilter, Debug::General, "SC::Texture(%p)::GetGraphicsObject() = %p\n", this, mGraphicsTexture.get());
247
248   return mGraphicsTexture.get();
249 }
250
251 void Texture::Create(Graphics::TextureUsageFlags usage)
252 {
253   CreateWithData(usage, nullptr, 0u);
254 }
255
256 void Texture::CreateWithData(Graphics::TextureUsageFlags usage, uint8_t* data, uint32_t size)
257 {
258   auto createInfo = Graphics::TextureCreateInfo();
259   createInfo
260     .SetTextureType(ConvertType(mType))
261     .SetUsageFlags(usage)
262     .SetFormat(ConvertPixelFormat(mPixelFormat))
263     .SetSize({mWidth, mHeight})
264     .SetLayout(Graphics::TextureLayout::LINEAR)
265     .SetData(data)
266     .SetDataSize(size)
267     .SetNativeImage(mNativeImage)
268     .SetMipMapFlag(Graphics::TextureMipMapFlag::DISABLED);
269
270   mGraphicsTexture = mGraphicsController->CreateTexture(createInfo, std::move(mGraphicsTexture));
271 }
272
273 void Texture::Upload(PixelDataPtr pixelData, const Internal::Texture::UploadParams& params)
274 {
275   DALI_ASSERT_ALWAYS(mNativeImage == nullptr);
276
277   if(!mGraphicsTexture)
278   {
279     Create(static_cast<Graphics::TextureUsageFlags>(Graphics::TextureUsageFlagBits::SAMPLE));
280   }
281
282   Graphics::TextureUpdateInfo info{};
283   info.dstTexture   = mGraphicsTexture.get();
284   info.dstOffset2D  = {params.xOffset, params.yOffset};
285   info.layer        = params.layer;
286   info.level        = params.mipmap;
287   info.srcReference = 0;
288   info.srcExtent2D  = {params.width, params.height};
289   info.srcOffset    = 0;
290   info.srcSize      = pixelData->GetBufferSize();
291
292   Graphics::TextureUpdateSourceInfo updateSourceInfo{};
293   updateSourceInfo.sourceType          = Graphics::TextureUpdateSourceInfo::Type::MEMORY;
294   updateSourceInfo.memorySource.memory = pixelData->GetBuffer();
295
296   mGraphicsController->UpdateTextures({info}, {updateSourceInfo});
297 }
298
299 bool Texture::HasAlphaChannel() const
300 {
301   bool alpha = mHasAlpha;
302   if(mNativeImage)
303   {
304     alpha = mNativeImage->RequiresBlending();
305   }
306   return alpha;
307 }
308
309 void Texture::GenerateMipmaps()
310 {
311   mMaxMipMapLevel = 0;
312   DALI_LOG_ERROR("FIXME: GRAPHICS");
313   //@todo Implement with Graphics API
314 }
315
316 } // namespace Render
317
318 } // namespace Internal
319
320 } // namespace Dali