e8cf9b7b5d41d1d2cbebc150e145ee535a98bb41
[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 BitmapImage* BitmapImage::New( unsigned int width, unsigned int height, Pixel::Format pixelformat, LoadPolicy loadPol, ReleasePolicy releasePol )
34 {
35   BitmapImage* internal = new BitmapImage( width, height, pixelformat, loadPol, releasePol );
36   internal->Initialize();
37   return internal;
38 }
39
40 BitmapImage* BitmapImage::New( PixelBuffer* pixBuf, unsigned int width, unsigned int height, Pixel::Format pixelformat, unsigned int stride, ReleasePolicy releasePol )
41 {
42   BitmapImage* 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   Initialize();
52
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   Initialize();
67   mWidth  = width;
68   mHeight = height;
69   Integration::Bitmap* bitmap = new BitmapExternal(pixBuf, width, height, pixelformat, stride);
70   const ImageTicketPtr& t = mResourceClient->AddBitmapImage(bitmap);
71   mTicket = t.Get();
72
73   mTicket->AddObserver(*this);
74 }
75
76 BitmapImage::~BitmapImage()
77 {
78 }
79
80 void BitmapImage::Update( RectArea& updateArea )
81 {
82   if (mTicket)
83   {
84     // TODO:
85     // If updateArea is empty or same as image size, then pass on.
86     // If updateArea is larger than image size, throw exception
87     // Otherwise, copy updateArea window of pixelBuffer into newly
88     // allocated buffer and pass that to resource client. (it will
89     // tramp through to BitmapTexture eventually!)
90     mResourceClient->UpdateBitmapArea( mTicket, updateArea );
91   }
92   else if (mIsDataExternal && mBitmapCached)
93   {
94     // previously freed up resource memory, dali was informed about external BitmapImage put back on screen
95     Integration::Bitmap* bitmap = mBitmapCached.Get();
96     mTicket.Reset((mResourceClient->AddBitmapImage(bitmap)).Get());
97
98     mTicket->AddObserver(*this);
99   }
100 }
101
102 bool BitmapImage::IsDataExternal() const
103 {
104   return mIsDataExternal;
105 }
106
107 PixelBuffer* BitmapImage::GetBuffer()
108 {
109   PixelBuffer* buffer = NULL;
110
111   Integration::Bitmap* const bitmap = GetBitmap();
112
113   if(bitmap)
114   {
115     buffer = bitmap->GetBuffer();
116   }
117   return buffer;
118 }
119
120 unsigned int BitmapImage::GetBufferSize() const
121 {
122   unsigned int bufferSize = 0;
123
124   Integration::Bitmap* const bitmap = GetBitmap();
125
126   if(bitmap)
127   {
128     bufferSize = bitmap->GetBufferSize();
129   }
130   return bufferSize;
131 }
132
133 unsigned int BitmapImage::GetBufferStride() const
134 {
135   unsigned int bufferStride = 0;
136
137   Integration::Bitmap* const bitmap = GetBitmap();
138
139   if(bitmap)
140   {
141     Integration::Bitmap::PackedPixelsProfile* packedBitmap = bitmap->GetPackedPixelsProfile();
142     DALI_ASSERT_DEBUG(packedBitmap);
143     bufferStride = packedBitmap->GetBufferStride();
144   }
145
146   return bufferStride;
147 }
148
149 void BitmapImage::Initialize()
150 {
151   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
152   mResourceClient = &tls.GetResourceClient();
153 }
154
155 void BitmapImage::Connect()
156 {
157   ++mConnectionCount;
158
159   // application owns bitmap buffer, don't do anything. BufferUpdated() has to be called manually.
160   if (mIsDataExternal)
161   {
162     return;
163   }
164
165   if (mConnectionCount == 1)
166   {
167     if (!mTicket && mBitmapCached)
168     {
169       const ImageTicketPtr& t = mResourceClient->AddBitmapImage(mBitmapCached.Get());
170       mTicket = t.Get();
171       mTicket->AddObserver(*this);
172     }
173   }
174 }
175
176 void BitmapImage::Disconnect()
177 {
178   if (!mTicket)
179   {
180     return;
181   }
182
183   --mConnectionCount;
184
185   if (mConnectionCount == 0 && mReleasePolicy == Dali::Image::Unused)
186   {
187     mBitmapCached = mResourceClient->GetBitmap(mTicket);
188     // release image memory when it's not visible anymore (decrease ref. count of texture)
189     mTicket->RemoveObserver(*this);
190     mTicket.Reset();
191   }
192 }
193
194 Integration::Bitmap * BitmapImage::GetBitmap() const
195 {
196   Integration::Bitmap* bitmap = NULL;
197
198   if (mTicket)
199   {
200     bitmap = mResourceClient->GetBitmap(mTicket);
201   }
202   else
203   {
204     // off screen and freeing memory was requested
205     bitmap = mBitmapCached.Get();
206   }
207
208   DALI_ASSERT_DEBUG(bitmap);
209
210   return bitmap;
211 }
212
213 } // namespace Internal
214
215 } // namespace Dali