2 * Copyright (c) 2023 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 <toolkit-texture-upload-manager.h>
22 #include <dali/devel-api/adaptor-framework/texture-upload-manager.h>
23 #include <dali/graphics-api/graphics-controller.h>
24 #include <dali/integration-api/pixel-data-integ.h>
25 #include <dali/integration-api/texture-integ.h>
28 #include <test-graphics-controller.h>
29 #include <toolkit-application.h>
37 class TextureUploadManager : public Dali::BaseObject
40 using ResourceId = Dali::Devel::TextureUploadManager::ResourceId;
43 static Dali::Devel::TextureUploadManager Get();
44 TextureUploadManager();
45 ~TextureUploadManager() = default;
47 Dali::Texture GenerateTexture2D();
49 public: // Update thread called method
50 bool ResourceUpload();
52 void InitalizeGraphicsController(Dali::Graphics::Controller& graphicsController);
54 private: // Update thread called method
55 using UploadRequestItem = std::pair<ResourceId, Dali::PixelData>; ///< TODO : PixelData? PixelBuffer?
56 using RequestUploadQueue = std::vector<UploadRequestItem>;
58 bool ProcessUploadQueue(RequestUploadQueue&& queue);
60 public: // Worker thread called method
62 * @copydoc Dali::Devel::TextureUploadManager::RequestUpload()
64 void RequestUpload(ResourceId id, Dali::PixelData pixelData);
67 Dali::Graphics::Controller* mGraphicsController;
68 RequestUploadQueue mRequestUploadQueue{};
71 ResourceId gUniqueResourceId{0u};
74 inline Internal::Adaptor::TextureUploadManager& GetImplementation(Dali::Devel::TextureUploadManager& obj)
76 DALI_ASSERT_ALWAYS(obj && "TextureUploadManager is empty");
78 Dali::BaseObject& handle = obj.GetBaseObject();
80 return static_cast<Internal::Adaptor::TextureUploadManager&>(handle);
83 inline const Internal::Adaptor::TextureUploadManager& GetImplementation(const Dali::Devel::TextureUploadManager& obj)
85 DALI_ASSERT_ALWAYS(obj && "TextureUploadManager is empty");
87 const Dali::BaseObject& handle = obj.GetBaseObject();
89 return static_cast<const Internal::Adaptor::TextureUploadManager&>(handle);
92 /********************************************************************************/
93 /********************************* INTERNAL CLASS *****************************/
94 /********************************************************************************/
98 Devel::TextureUploadManager gTextureUploadManager;
101 Devel::TextureUploadManager TextureUploadManager::Get()
103 if(!gTextureUploadManager)
105 gTextureUploadManager = Devel::TextureUploadManager(new TextureUploadManager());
107 return gTextureUploadManager;
110 TextureUploadManager::TextureUploadManager()
111 : mGraphicsController{nullptr}
115 Dali::Texture TextureUploadManager::GenerateTexture2D()
117 ResourceId resourceId = ++gUniqueResourceId;
119 Dali::Texture ret = Dali::Integration::NewTextureWithResourceId(Dali::TextureType::TEXTURE_2D, resourceId);
124 // Called by update thread
126 bool TextureUploadManager::ResourceUpload()
128 DALI_ASSERT_DEBUG(mGraphicsController && "GraphicsController is not prepared!");
131 bool uploaded = ProcessUploadQueue(std::move(mRequestUploadQueue));
132 mRequestUploadQueue.clear();
137 void TextureUploadManager::InitalizeGraphicsController(Dali::Graphics::Controller& graphicsController)
139 mGraphicsController = &graphicsController;
142 bool TextureUploadManager::ProcessUploadQueue(RequestUploadQueue&& queue)
144 bool uploaded = false;
148 for(auto& requests : queue)
150 auto& resourceId = requests.first;
151 auto& pixelData = requests.second;
153 Graphics::Texture* graphicsTexture = nullptr;
155 // TODO : Could we detect TEXTURE_2D or TEXTURE_CUBE case in future?
157 // We always need to create new one
158 auto createInfo = Graphics::TextureCreateInfo();
160 .SetTextureType(Dali::Graphics::ConvertTextureType(Dali::TextureType::TEXTURE_2D))
161 .SetUsageFlags(static_cast<Graphics::TextureUsageFlags>(Graphics::TextureUsageFlagBits::SAMPLE))
162 .SetFormat(Dali::Graphics::ConvertPixelFormat(pixelData.GetPixelFormat()))
163 .SetSize({pixelData.GetWidth(), pixelData.GetHeight()})
164 .SetLayout(Graphics::TextureLayout::LINEAR)
167 .SetNativeImage(nullptr)
168 .SetMipMapFlag(Graphics::TextureMipMapFlag::DISABLED);
170 graphicsTexture = mGraphicsController->CreateTextureByResourceId(resourceId, createInfo);
175 Graphics::TextureUpdateInfo info{};
177 info.dstTexture = graphicsTexture;
178 info.dstOffset2D = {0u, 0u};
181 info.srcReference = 0;
182 info.srcExtent2D = {pixelData.GetWidth(), pixelData.GetHeight()};
184 info.srcSize = Dali::Integration::GetPixelDataBuffer(pixelData).bufferSize;
185 info.srcStride = pixelData.GetStride();
186 info.srcFormat = Dali::Graphics::ConvertPixelFormat(pixelData.GetPixelFormat());
188 Graphics::TextureUpdateSourceInfo updateSourceInfo{};
189 updateSourceInfo.sourceType = Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA;
190 updateSourceInfo.pixelDataSource.pixelData = pixelData;
192 mGraphicsController->UpdateTextures({info}, {updateSourceInfo});
198 // Invalidate resouce id! ignore.
205 Graphics::SubmitInfo submitInfo;
206 submitInfo.cmdBuffer.clear(); // Only flush
207 submitInfo.flags = 0 | Graphics::SubmitFlagBits::FLUSH;
208 mGraphicsController->SubmitCommandBuffers(submitInfo);
215 // Called by worker thread
217 void TextureUploadManager::RequestUpload(Dali::Devel::TextureUploadManager::ResourceId resourceId, Dali::PixelData pixelData)
219 mRequestUploadQueue.push_back(std::move(UploadRequestItem(resourceId, pixelData)));
222 } // namespace Adaptor
224 } // namespace Internal
226 /********************************************************************************/
227 /********************************* PUBLIC CLASS *******************************/
228 /********************************************************************************/
232 // Called by main thread
234 TextureUploadManager::TextureUploadManager() = default;
236 TextureUploadManager::~TextureUploadManager() = default;
238 TextureUploadManager TextureUploadManager::Get()
240 return Internal::Adaptor::TextureUploadManager::Get();
243 Dali::Texture TextureUploadManager::GenerateTexture2D()
245 return Internal::Adaptor::GetImplementation(*this).GenerateTexture2D();
248 TextureUploadManager::TextureUploadManager(Internal::Adaptor::TextureUploadManager* impl)
253 // Called by update thread
255 bool TextureUploadManager::ResourceUpload()
257 return Internal::Adaptor::GetImplementation(*this).ResourceUpload();
260 // Called by worker thread
262 void TextureUploadManager::RequestUpload(ResourceId resourceId, PixelData pixelData)
264 Internal::Adaptor::GetImplementation(*this).RequestUpload(resourceId, pixelData);
273 namespace TextureUploadManager
275 void InitalizeGraphicsController(Dali::Graphics::Controller& graphicsController)
277 auto textureUploadManager = Dali::Devel::TextureUploadManager::Get();
278 Internal::Adaptor::GetImplementation(textureUploadManager).InitalizeGraphicsController(graphicsController);
280 } // namespace TextureUploadManager