03eb4a725041ffed260f9a80141d3b572911d225
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / renderers / image-atlas-manager.cpp
1  /*
2  * Copyright (c) 2015 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/public-api/images/resource-image.h>
23
24 namespace Dali
25 {
26
27 namespace Toolkit
28 {
29
30 namespace Internal
31 {
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 }
39
40 ImageAtlasManager::ImageAtlasManager()
41 : mBrokenImageUrl( "" )
42 {
43 }
44
45 ImageAtlasManager::~ImageAtlasManager()
46 {
47 }
48
49 TextureSet ImageAtlasManager::Add( Vector4& textureRect,
50                                  const std::string& url,
51                                  ImageDimensions size,
52                                  FittingMode::Type fittingMode,
53                                  bool orientationCorrection )
54 {
55   ImageDimensions dimensions = size;
56   ImageDimensions zero;
57   if( size == zero )
58   {
59     dimensions = ResourceImage::GetImageSize( url );
60   }
61
62   // big image, atlasing is not applied
63   if( static_cast<uint32_t>(dimensions.GetWidth()) * static_cast<uint32_t>(dimensions.GetHeight()) > MAX_ITEM_AREA
64       || dimensions.GetWidth()>DEFAULT_ATLAS_SIZE
65       || dimensions.GetHeight()>DEFAULT_ATLAS_SIZE)
66   {
67     return TextureSet();
68   }
69
70   unsigned int i = 0;
71   for( AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
72   {
73     if( (*iter).Upload( textureRect, url, size, fittingMode, orientationCorrection ) )
74     {
75       return mTextureSetList[i];
76     }
77     i++;
78   }
79
80   CreateNewAtlas();
81   mAtlasList.back().Upload( textureRect, url, size, fittingMode, orientationCorrection );
82   return mTextureSetList.back();
83 }
84
85 TextureSet ImageAtlasManager::Add( Vector4& textureRect,
86                                  PixelDataPtr pixelData )
87 {
88
89   // big buffer, atlasing is not applied
90   if( static_cast<uint32_t>(pixelData->GetWidth()) * static_cast<uint32_t>(pixelData->GetHeight()) > MAX_ITEM_AREA
91       || pixelData->GetWidth()>DEFAULT_ATLAS_SIZE
92       || pixelData->GetHeight()>DEFAULT_ATLAS_SIZE )
93   {
94     return TextureSet();
95   }
96
97   unsigned int i = 0;
98   for( AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
99   {
100     if( (*iter).Upload( textureRect, pixelData ) )
101     {
102       return mTextureSetList[i];
103     }
104     i++;
105   }
106
107   CreateNewAtlas();
108   mAtlasList.back().Upload( textureRect, pixelData );
109   return mTextureSetList.back();
110
111 }
112
113 void ImageAtlasManager::Remove( TextureSet textureSet, const Vector4& textureRect )
114 {
115   unsigned int i = 0;
116   for( TextureSetContainer::iterator iter = mTextureSetList.begin(); iter != mTextureSetList.end(); ++iter)
117   {
118     if( (*iter) == textureSet )
119     {
120       mAtlasList[i].Remove(textureRect);
121       return;
122     }
123     i++;
124   }
125 }
126
127 void ImageAtlasManager::SetBrokenImage( const std::string& brokenImageUrl )
128 {
129   if( !brokenImageUrl.empty() )
130   {
131     mBrokenImageUrl = brokenImageUrl;
132   }
133 }
134
135 void ImageAtlasManager::CreateNewAtlas()
136 {
137   Toolkit::ImageAtlas newAtlas = Toolkit::ImageAtlas::New( DEFAULT_ATLAS_SIZE, DEFAULT_ATLAS_SIZE  );
138   if( !mBrokenImageUrl.empty() )
139   {
140     newAtlas.SetBrokenImage( mBrokenImageUrl );
141   }
142   mAtlasList.push_back( newAtlas );
143   TextureSet textureSet = TextureSet::New();
144   textureSet.SetImage( 0u, newAtlas.GetAtlas() );
145   mTextureSetList.push_back( textureSet );
146 }
147
148 } // namespace Internal
149
150 } // namespace Toolkit
151
152 } // namespace Dali