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