4a8445ebecb29368363071941973878049c78196
[platform/core/uifw/dali-core.git] / dali / internal / event / images / bitmap-image-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/event/images/bitmap-image-impl.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/integration-api/bitmap.h>
22 #include <dali/internal/event/images/bitmap-external.h>
23 #include <dali/internal/event/common/thread-local-storage.h>
24 #include <dali/internal/event/resources/resource-client.h>
25 #include <dali/internal/update/manager/update-manager.h>
26 #include <dali/internal/event/images/image-factory.h>
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32
33 BitmapImagePtr BitmapImage::New( unsigned int width, unsigned int height, Pixel::Format pixelformat, LoadPolicy loadPol, ReleasePolicy releasePol )
34 {
35   BitmapImagePtr internal = new BitmapImage( width, height, pixelformat, loadPol, releasePol );
36   internal->Initialize();
37   return internal;
38 }
39
40 BitmapImagePtr BitmapImage::New( PixelBuffer* pixBuf, unsigned int width, unsigned int height, Pixel::Format pixelformat, unsigned int stride, ReleasePolicy releasePol )
41 {
42   BitmapImagePtr internal = new BitmapImage( pixBuf, width, height, pixelformat, stride, releasePol );
43   internal->Initialize();
44   return internal;
45 }
46
47 BitmapImage::BitmapImage(unsigned int width, unsigned int height, Pixel::Format pixelformat, LoadPolicy loadPol, ReleasePolicy releasePol)
48 : Image(loadPol, releasePol),
49   mIsDataExternal(false)
50 {
51   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
52   mResourceClient = &tls.GetResourceClient();
53   mWidth  = width;
54   mHeight = height;
55
56   const ImageTicketPtr& t = mResourceClient->AllocateBitmapImage(width, height, width, height, pixelformat);
57   mTicket = t.Get();
58
59   mTicket->AddObserver(*this);
60 }
61
62 BitmapImage::BitmapImage(PixelBuffer* pixBuf, unsigned int width, unsigned int height, Pixel::Format pixelformat, unsigned int stride, ReleasePolicy releasePol)
63 : Image(ImageLoadPolicyDefault, releasePol),
64   mIsDataExternal(true)
65 {
66   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
67   mResourceClient = &tls.GetResourceClient();
68   mWidth  = width;
69   mHeight = height;
70   Integration::Bitmap* bitmap = new BitmapExternal(pixBuf, width, height, pixelformat, stride);
71   const ImageTicketPtr& t = mResourceClient->AddBitmapImage(bitmap);
72   mTicket = t.Get();
73
74   mTicket->AddObserver(*this);
75 }
76
77 BitmapImage::~BitmapImage()
78 {
79 }
80
81 void BitmapImage::Update( RectArea& updateArea )
82 {
83   if (mTicket)
84   {
85     // TODO:
86     // If updateArea is empty or same as image size, then pass on.
87     // If updateArea is larger than image size, throw exception
88     // Otherwise, copy updateArea window of pixelBuffer into newly
89     // allocated buffer and pass that to resource client. (it will
90     // tramp through to BitmapTexture eventually!)
91     mResourceClient->UpdateBitmapArea( mTicket, updateArea );
92   }
93   else if (mIsDataExternal && mBitmapCached)
94   {
95     // previously freed up resource memory, dali was informed about external BitmapImage put back on screen
96     Integration::Bitmap* bitmap = mBitmapCached.Get();
97     mTicket.Reset((mResourceClient->AddBitmapImage(bitmap)).Get());
98
99     mTicket->AddObserver(*this);
100   }
101 }
102
103 bool BitmapImage::IsDataExternal() const
104 {
105   return mIsDataExternal;
106 }
107
108 PixelBuffer* BitmapImage::GetBuffer()
109 {
110   PixelBuffer* buffer = NULL;
111
112   Integration::Bitmap* const bitmap = GetBitmap();
113
114   if(bitmap)
115   {
116     buffer = bitmap->GetBuffer();
117   }
118   return buffer;
119 }
120
121 unsigned int BitmapImage::GetBufferSize() const
122 {
123   unsigned int bufferSize = 0;
124
125   Integration::Bitmap* const bitmap = GetBitmap();
126
127   if(bitmap)
128   {
129     bufferSize = bitmap->GetBufferSize();
130   }
131   return bufferSize;
132 }
133
134 unsigned int BitmapImage::GetBufferStride() const
135 {
136   unsigned int bufferStride = 0;
137
138   Integration::Bitmap* const bitmap = GetBitmap();
139
140   if(bitmap)
141   {
142     Integration::Bitmap::PackedPixelsProfile* packedBitmap = bitmap->GetPackedPixelsProfile();
143     DALI_ASSERT_DEBUG(packedBitmap);
144     bufferStride = packedBitmap->GetBufferStride();
145   }
146
147   return bufferStride;
148 }
149
150 void BitmapImage::Connect()
151 {
152   ++mConnectionCount;
153
154   // application owns bitmap buffer, don't do anything. BufferUpdated() has to be called manually.
155   if (mIsDataExternal)
156   {
157     return;
158   }
159
160   if (mConnectionCount == 1)
161   {
162     if (!mTicket && mBitmapCached)
163     {
164       const ImageTicketPtr& t = mResourceClient->AddBitmapImage(mBitmapCached.Get());
165       mTicket = t.Get();
166       mTicket->AddObserver(*this);
167     }
168   }
169 }
170
171 void BitmapImage::Disconnect()
172 {
173   if (!mTicket)
174   {
175     return;
176   }
177
178   --mConnectionCount;
179
180   if (mConnectionCount == 0 && mReleasePolicy == Dali::Image::Unused)
181   {
182     mBitmapCached = mResourceClient->GetBitmap(mTicket);
183     // release image memory when it's not visible anymore (decrease ref. count of texture)
184     mTicket->RemoveObserver(*this);
185     mTicket.Reset();
186   }
187 }
188
189 Integration::Bitmap * BitmapImage::GetBitmap() const
190 {
191   Integration::Bitmap* bitmap = NULL;
192
193   if (mTicket)
194   {
195     bitmap = mResourceClient->GetBitmap(mTicket);
196   }
197   else
198   {
199     // off screen and freeing memory was requested
200     bitmap = mBitmapCached.Get();
201   }
202
203   DALI_ASSERT_DEBUG(bitmap);
204
205   return bitmap;
206 }
207
208 } // namespace Internal
209
210 } // namespace Dali