Delete ImageFactory and ImageFactoryCache as they are unused
[platform/core/uifw/dali-core.git] / dali / internal / event / images / atlas-impl.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 <dali/internal/event/images/atlas-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for memset()
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/internal/event/common/thread-local-storage.h>
27 #include <dali/internal/event/images/bitmap-packed-pixel.h>
28 #include <dali/internal/event/resources/resource-client.h>
29 #include <dali/integration-api/bitmap.h>
30 #include <dali/integration-api/platform-abstraction.h>
31
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38
39 namespace
40 {
41 TypeRegistration mType( typeid( Dali::Atlas ), typeid( Dali::Image ), NULL );
42 }
43
44 Atlas* Atlas::New( SizeType width,
45                    SizeType height,
46                    Pixel::Format pixelFormat,
47                    bool recoverContext)
48 {
49   return new Atlas( width, height, pixelFormat, recoverContext );
50 }
51
52 void Atlas::Clear(const Vector4& color)
53 {
54   ClearCache();
55   ClearBackground( color );
56 }
57
58 bool Atlas::Upload( BufferImage& bufferImage,
59                     SizeType xOffset,
60                     SizeType yOffset )
61 {
62   bool uploadSuccess( false );
63
64   if( IsInside( xOffset + bufferImage.GetWidth(),  yOffset + bufferImage.GetHeight() ) )
65   {
66     AllocateAtlas();
67     ResourceId destId = GetResourceId();
68
69     if( destId )
70     {
71       bufferImage.UploadBitmap( destId, xOffset, yOffset );
72       uploadSuccess = true;
73     }
74   }
75
76   return uploadSuccess;
77 }
78
79 bool Atlas::Upload( const std::string& url,
80                     SizeType xOffset,
81                     SizeType yOffset)
82 {
83   bool uploadSuccess( false );
84
85   Integration::BitmapPtr bitmap = LoadBitmap( url );
86
87   if( bitmap && IsInside( xOffset + bitmap->GetImageWidth(), yOffset + bitmap->GetImageHeight()) )
88   {
89     AllocateAtlas();
90     ResourceId destId = GetResourceId();
91     if( destId )
92     {
93       mResourceClient.UploadBitmap( destId, bitmap, xOffset, yOffset  );
94       uploadSuccess = true;
95
96       if( mRecoverContext )
97       {
98         mTiles.PushBack( new Tile(xOffset, yOffset, url) );
99       }
100     }
101   }
102   return uploadSuccess;
103 }
104
105 bool Atlas::Upload( PixelDataPtr pixelData,
106                     SizeType xOffset,
107                     SizeType yOffset )
108 {
109   bool uploadSuccess( false );
110   if( IsInside( xOffset + pixelData->GetWidth(),  yOffset + pixelData->GetHeight() ) )
111   {
112     AllocateAtlas();
113     ResourceId destId = GetResourceId();
114
115     if( destId )
116     {
117       mResourceClient.UploadBitmap( destId, pixelData, xOffset, yOffset  );
118       uploadSuccess = true;
119     }
120   }
121
122   return uploadSuccess;
123 }
124
125 void Atlas::RecoverFromContextLoss()
126 {
127   ResourceId destId = GetResourceId();
128   if( destId )
129   {
130     if( mClear )
131     {
132       ClearBackground( mClearColor );
133     }
134
135     if( mRecoverContext )
136     {
137       // Restore the atlas by re-uploading the url resources
138       Vector< Tile* >::ConstIterator end = mTiles.End();
139       for( Vector<Tile*>::Iterator iter = mTiles.Begin(); iter != end; iter++ )
140       {
141         Integration::BitmapPtr bitmap = LoadBitmap( (*iter)->url );
142         mResourceClient.UploadBitmap( destId, bitmap, (*iter)->xOffset, (*iter)->yOffset  );
143       }
144     }
145   }
146 }
147
148 Atlas::~Atlas()
149 {
150   ReleaseAtlas();
151 }
152
153 Atlas::Atlas( SizeType width,
154               SizeType height,
155               Pixel::Format pixelFormat,
156               bool recoverContext )
157 : mResourceClient( ThreadLocalStorage::Get().GetResourceClient() ),
158   mClearColor( Vector4::ZERO ),
159   mPixelFormat( pixelFormat ),
160   mClear( false ),
161   mRecoverContext( recoverContext )
162 {
163   mWidth  = width;
164   mHeight = height;
165 }
166
167 void Atlas::Connect()
168 {
169   ++mConnectionCount;
170
171   if( mConnectionCount == 1 )
172   {
173     AllocateAtlas();
174   }
175 }
176
177 void Atlas::Disconnect()
178 {
179   if( mConnectionCount )
180   {
181     --mConnectionCount;
182
183     // Only release the atlas upon destruction
184   }
185 }
186
187 bool Atlas::IsInside( SizeType x, SizeType y )
188 {
189   bool fit(false);
190
191   if( x <= mWidth  && y <= mHeight )
192   {
193     fit = true;
194   }
195   else
196   {
197     DALI_LOG_ERROR( "image does not fit within the atlas \n" );
198   }
199
200   return fit;
201 }
202
203 void Atlas::AllocateAtlas()
204 {
205   if( !mTicket )
206   {
207     mTicket = mResourceClient.AllocateTexture( mWidth, mHeight, mPixelFormat );
208     mTicket->AddObserver( *this );
209   }
210 }
211
212 void Atlas::ReleaseAtlas()
213 {
214   mTicket.Reset();
215   ClearCache();
216 }
217
218 void Atlas::ClearBackground(const Vector4& color )
219 {
220   AllocateAtlas();
221   ResourceId destId = GetResourceId();
222   if( destId )
223   {
224     const unsigned int numPixels = mWidth * mHeight;
225     unsigned int bytesPerPixel = Pixel::GetBytesPerPixel(mPixelFormat);
226     BufferImagePtr imageData = BufferImage::New( mWidth, mHeight, mPixelFormat );
227     PixelBuffer* pixbuf = imageData->GetBuffer();
228
229     if( pixbuf )
230     {
231       // converting color value from float 0.f~1.f to byte 0~255
232       unsigned char r =  static_cast<unsigned char>( 255.f * Clamp( color.r, 0.f, 1.f ) );
233       unsigned char g =  static_cast<unsigned char>( 255.f * Clamp( color.g, 0.f, 1.f ) );
234       unsigned char b =  static_cast<unsigned char>( 255.f * Clamp( color.b, 0.f, 1.f ) );
235       unsigned char a =  static_cast<unsigned char>( 255.f * Clamp( color.a, 0.f, 1.f ) );
236       if( mPixelFormat == Pixel::RGBA8888 )
237       {
238         // For little-endian byte order, the RGBA channels needs to be reversed for bit shifting.
239         uint32_t clearColor = ( (uint32_t) a<<24 | (uint32_t)b << 16 | (uint32_t)g << 8 | (uint32_t)r );
240         uint32_t* buf = (uint32_t *) pixbuf;
241         for( unsigned int i = 0; i < numPixels; ++i )
242         {
243           buf[i] = clearColor;
244         }
245       }
246       else if( mPixelFormat == Pixel::RGB888 )
247       {
248         for( unsigned int i = 0; i < numPixels; ++i )
249         {
250           pixbuf[i*bytesPerPixel] = r;
251           pixbuf[i*bytesPerPixel+1] = g;
252           pixbuf[i*bytesPerPixel+2] = b;
253         }
254       }
255       else if( mPixelFormat == Pixel::A8 )
256       {
257         memset( pixbuf, a, numPixels );
258       }
259     }
260
261     mClearColor = color;
262     mClear = true;
263
264     imageData->UploadBitmap( destId, 0, 0 );
265   }
266 }
267
268 void Atlas::ClearCache()
269 {
270   Vector< Tile* >::ConstIterator end = mTiles.End();
271   for( Vector<Tile*>::Iterator iter = mTiles.Begin(); iter != end; iter++ )
272   {
273     delete *iter;
274   }
275   mTiles.Clear();
276 }
277
278 Integration::BitmapPtr Atlas::LoadBitmap( const std::string& url )
279 {
280   Integration::BitmapResourceType resourceType;
281   Integration::PlatformAbstraction& platformAbstraction = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction();
282
283   Integration::ResourcePointer resource = platformAbstraction.LoadResourceSynchronously(resourceType, url);
284   Integration::BitmapPtr bitmap = static_cast<Integration::Bitmap*>( resource.Get());
285
286   return bitmap;
287 }
288
289 } // namespace Internal
290
291 } // namespace Dali