Delete ImageFactory and ImageFactoryCache as they are unused
[platform/core/uifw/dali-core.git] / dali / internal / event / images / buffer-image-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/buffer-image-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <string.h>
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/resources/resource-client.h>
28 #include <dali/internal/update/manager/update-manager.h>
29
30 using namespace Dali::Integration;
31
32 namespace Dali
33 {
34 namespace Internal
35 {
36
37 namespace
38 {
39 TypeRegistration mType( typeid( Dali::BufferImage ), typeid( Dali::Image ), NULL );
40 } // unnamed namespace
41
42 BufferImagePtr BufferImage::New( unsigned int width,
43                                  unsigned int height,
44                                  Pixel::Format pixelformat )
45 {
46   BufferImagePtr internal = new BufferImage( width, height, pixelformat );
47   internal->Initialize();
48   return internal;
49 }
50
51 BufferImagePtr BufferImage::New( PixelBuffer* pixBuf,
52                                  unsigned int width,
53                                  unsigned int height,
54                                  Pixel::Format pixelformat,
55                                  unsigned int stride )
56 {
57   BufferImagePtr internal = new BufferImage( pixBuf, width, height, pixelformat, stride );
58   internal->Initialize();
59   return internal;
60 }
61
62 BufferImage::BufferImage(unsigned int width, unsigned int height, Pixel::Format pixelformat)
63 : Image(),
64   mInternalBuffer( NULL ),
65   mExternalBuffer( NULL ),
66   mResourceClient( NULL ),
67   mBufferSize( 0 ),
68   mByteStride( 0 ),
69   mBytesPerPixel( 0 ),
70   mBufferWidth( 0 ),
71   mPixelFormat( pixelformat ),
72   mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
73 {
74   SetupBuffer( width, height, pixelformat, width );
75
76   // Allocate a persistent internal buffer
77   mInternalBuffer = new PixelBuffer[ mBufferSize ];
78 }
79
80 BufferImage::BufferImage(PixelBuffer* pixBuf,
81                          unsigned int width,
82                          unsigned int height,
83                          Pixel::Format pixelformat,
84                          unsigned int stride)
85 : Image(),
86   mInternalBuffer( NULL ),
87   mExternalBuffer( pixBuf ),
88   mResourceClient( NULL ),
89   mBufferSize( 0 ),
90   mByteStride( 0 ),
91   mBytesPerPixel( 0 ),
92   mBufferWidth( 0 ),
93   mPixelFormat( pixelformat ),
94   mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
95 {
96   SetupBuffer( width, height, pixelformat, stride ? stride: width );
97 }
98
99 BufferImage::~BufferImage()
100 {
101   if( mTicket )
102   {
103     mTicket->RemoveObserver(*this);
104     mTicket.Reset();
105   }
106
107   delete[] mInternalBuffer;
108 }
109
110 void BufferImage::SetupBuffer( unsigned int width,
111                                unsigned int height,
112                                Pixel::Format pixelformat,
113                                unsigned int byteStride )
114 {
115   ThreadLocalStorage& tls = ThreadLocalStorage::Get();
116   mResourceClient = &tls.GetResourceClient();
117   mWidth  = width;
118   mHeight = height;
119   mPixelFormat = pixelformat;
120   mBytesPerPixel = Pixel::GetBytesPerPixel( pixelformat );
121
122   mByteStride = byteStride * mBytesPerPixel;
123   mBufferSize = height * mByteStride;
124
125   // Respect the desired release policy
126   mResourcePolicy = ResourcePolicy::OWNED_RETAIN;
127 }
128
129 bool BufferImage::IsDataExternal() const
130 {
131   return ( mExternalBuffer ? true : false );
132 }
133
134 void BufferImage::Update( RectArea& updateArea )
135 {
136   if ( !mTicket )
137   {
138     CreateHostBitmap();
139   }
140   DALI_ASSERT_DEBUG( updateArea.x + updateArea.width <= mWidth && updateArea.y + updateArea.height <= mHeight );
141   UploadArea( mTicket->GetId(), updateArea );
142 }
143
144 void BufferImage::CreateHostBitmap()
145 {
146   Integration::Bitmap* bitmap = Bitmap::New( Bitmap::BITMAP_2D_PACKED_PIXELS, mResourcePolicy );
147   Bitmap::PackedPixelsProfile* const packedBitmap = bitmap->GetPackedPixelsProfile();
148   DALI_ASSERT_DEBUG(packedBitmap);
149
150   packedBitmap->ReserveBuffer( mPixelFormat, mWidth, mHeight );
151   DALI_ASSERT_DEBUG(bitmap->GetBuffer() != 0);
152   DALI_ASSERT_DEBUG(bitmap->GetBufferSize() >= mHeight * mWidth * mBytesPerPixel );
153
154   mTicket = mResourceClient->AddBitmapImage( bitmap );
155   mTicket->AddObserver(*this);
156 }
157
158 void BufferImage::UploadArea( ResourceId destId, const RectArea& area )
159 {
160   Integration::Bitmap* bitmap = Bitmap::New( Bitmap::BITMAP_2D_PACKED_PIXELS, mResourcePolicy );
161   Bitmap::PackedPixelsProfile* const packedBitmap = bitmap->GetPackedPixelsProfile();
162   DALI_ASSERT_DEBUG(packedBitmap);
163   DALI_ASSERT_DEBUG( area.width <= mWidth && area.height <= mHeight );
164
165   mBufferWidth = area.width ? area.width : mWidth;
166   packedBitmap->ReserveBuffer( mPixelFormat, mBufferWidth, area.height ? area.height : mHeight );
167   DALI_ASSERT_DEBUG(bitmap->GetBuffer() != 0);
168   DALI_ASSERT_DEBUG(bitmap->GetBufferSize() >= mBufferWidth * ( area.height ? area.height : mHeight ) * mBytesPerPixel );
169
170   // Are we uploading from an external or internal buffer ?
171   if ( mExternalBuffer )
172   {
173     // Check if we're doing the entire area without stride mismatch between source and dest ?
174     if( ( mByteStride == mWidth * mBytesPerPixel ) && area.IsEmpty() )
175     {
176       memcpy( bitmap->GetBuffer(), mExternalBuffer, mBufferSize );
177     }
178     else
179     {
180       UpdateBufferArea( mExternalBuffer, bitmap->GetBuffer(), area );
181     }
182   }
183   else
184   {
185     // Check if we're doing the entire internal buffer ?
186     if( area.IsEmpty() )
187     {
188       memcpy( bitmap->GetBuffer(), mInternalBuffer, bitmap->GetBufferSize() );
189     }
190     else
191     {
192       UpdateBufferArea( mInternalBuffer, bitmap->GetBuffer(), area );
193     }
194   }
195   mResourceClient->UploadBitmap( destId, bitmap, area.x, area.y );
196
197 }
198
199 void BufferImage::UploadBitmap( ResourceId destId, std::size_t xOffset, std::size_t yOffset )
200 {
201   RectArea area( xOffset, yOffset, 0, 0 );
202   if ( !mTicket )
203   {
204     CreateHostBitmap();
205   }
206
207   UploadArea( destId, area );
208 }
209
210 void BufferImage::UpdateBufferArea( PixelBuffer* src, PixelBuffer* dest, const RectArea& area )
211 {
212   DALI_ASSERT_DEBUG( area.x + area.width <= mWidth && area.y + area.height <= mHeight );
213
214   uint32_t width = mBufferWidth * mBytesPerPixel;
215
216   src += ( area.y * mByteStride ) + ( area.x * mBytesPerPixel );
217   for ( uint32_t i = 0; i < area.height; ++i )
218   {
219     memcpy( dest, src, width );
220     src += mByteStride;
221     dest += width;
222   }
223 }
224
225 void BufferImage::Connect()
226 {
227   if ( !mConnectionCount++ && !mTicket )
228   {
229     RectArea area;
230     Update( area );
231   }
232 }
233
234 void BufferImage::Disconnect()
235 {
236   --mConnectionCount;
237 }
238
239 } // namespace Internal
240
241 } // namespace Dali