Reduce the number of conversion between std::string <-> VisaulUrl at interal
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / image-atlas-manager.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
18 // CLASS HEADER
19 #include "image-atlas-manager.h"
20
21 // EXTERNAL HEADER
22 #include <dali/devel-api/adaptor-framework/image-loading.h>
23
24 // INTERNAL HEADERS
25 #include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
26
27 namespace Dali
28 {
29 namespace Toolkit
30 {
31 namespace Internal
32 {
33 namespace
34 {
35 const uint32_t DEFAULT_ATLAS_SIZE(1024u); // this size can fit 8 by 8 images of average size 128*128
36 const uint32_t MAX_ITEM_SIZE(512u);
37 const uint32_t MAX_ITEM_AREA(MAX_ITEM_SIZE* MAX_ITEM_SIZE);
38 } // namespace
39
40 ImageAtlasManager::ImageAtlasManager()
41 : mBrokenImageUrl("")
42 {
43 }
44
45 ImageAtlasManager::~ImageAtlasManager()
46 {
47 }
48
49 TextureSet ImageAtlasManager::Add(Vector4&             textureRect,
50                                   const VisualUrl&     url,
51                                   ImageDimensions&     size,
52                                   FittingMode::Type    fittingMode,
53                                   bool                 orientationCorrection,
54                                   AtlasUploadObserver* atlasUploadObserver)
55 {
56   ImageDimensions dimensions = size;
57   ImageDimensions zero;
58   if(size == zero)
59   {
60     dimensions = Dali::GetClosestImageSize(url.GetUrl());
61   }
62
63   // big image, atlasing is not applied
64   if(static_cast<uint32_t>(dimensions.GetWidth()) * static_cast<uint32_t>(dimensions.GetHeight()) > MAX_ITEM_AREA || dimensions.GetWidth() > DEFAULT_ATLAS_SIZE || dimensions.GetHeight() > DEFAULT_ATLAS_SIZE)
65   {
66     return TextureSet();
67   }
68   size = dimensions;
69
70   unsigned int i = 0;
71   for(AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
72   {
73     if(GetImplementation(*iter).Upload(textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver))
74     {
75       return mTextureSetList[i];
76     }
77     i++;
78   }
79
80   CreateNewAtlas();
81   GetImplementation(mAtlasList.back()).Upload(textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver);
82   return mTextureSetList.back();
83 }
84
85 TextureSet ImageAtlasManager::Add(Vector4&  textureRect,
86                                   PixelData pixelData)
87 {
88   // big buffer, atlasing is not applied
89   if(static_cast<uint32_t>(pixelData.GetWidth()) * static_cast<uint32_t>(pixelData.GetHeight()) > MAX_ITEM_AREA || pixelData.GetWidth() > DEFAULT_ATLAS_SIZE || pixelData.GetHeight() > DEFAULT_ATLAS_SIZE)
90   {
91     return TextureSet();
92   }
93
94   unsigned int i = 0;
95   for(AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
96   {
97     if((*iter).Upload(textureRect, pixelData))
98     {
99       return mTextureSetList[i];
100     }
101     i++;
102   }
103
104   CreateNewAtlas();
105   mAtlasList.back().Upload(textureRect, pixelData);
106   return mTextureSetList.back();
107 }
108
109 void ImageAtlasManager::Remove(TextureSet textureSet, const Vector4& textureRect)
110 {
111   unsigned int i = 0;
112   for(TextureSetContainer::iterator iter = mTextureSetList.begin(); iter != mTextureSetList.end(); ++iter)
113   {
114     if((*iter) == textureSet)
115     {
116       mAtlasList[i].Remove(textureRect);
117       return;
118     }
119     i++;
120   }
121 }
122
123 void ImageAtlasManager::SetBrokenImage(const std::string& brokenImageUrl)
124 {
125   if(!brokenImageUrl.empty())
126   {
127     mBrokenImageUrl = brokenImageUrl;
128   }
129 }
130
131 void ImageAtlasManager::CreateNewAtlas()
132 {
133   Toolkit::ImageAtlas newAtlas = Toolkit::ImageAtlas::New(DEFAULT_ATLAS_SIZE, DEFAULT_ATLAS_SIZE);
134   if(!mBrokenImageUrl.empty())
135   {
136     newAtlas.SetBrokenImage(mBrokenImageUrl);
137   }
138   mAtlasList.push_back(newAtlas);
139   TextureSet textureSet = TextureSet::New();
140   textureSet.SetTexture(0u, newAtlas.GetAtlas());
141   mTextureSetList.push_back(textureSet);
142 }
143
144 } // namespace Internal
145
146 } // namespace Toolkit
147
148 } // namespace Dali