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