2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/images/buffer-image-impl.h>
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 #include <dali/internal/event/images/image-factory.h>
31 using namespace Dali::Integration;
40 TypeRegistration mType( typeid( Dali::BufferImage ), typeid( Dali::Image ), NULL );
41 } // unnamed namespace
43 BufferImagePtr BufferImage::New( unsigned int width,
45 Pixel::Format pixelformat,
46 ReleasePolicy releasePol )
48 BufferImagePtr internal = new BufferImage( width, height, pixelformat, releasePol );
49 internal->Initialize();
53 BufferImagePtr BufferImage::New( PixelBuffer* pixBuf,
56 Pixel::Format pixelformat,
58 ReleasePolicy releasePol )
60 BufferImagePtr internal = new BufferImage( pixBuf, width, height, pixelformat, stride, releasePol );
61 internal->Initialize();
65 BufferImage::BufferImage(unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy releasePol)
66 : Image( releasePol ),
67 mInternalBuffer( NULL ),
68 mExternalBuffer( NULL ),
69 mResourceClient( NULL ),
74 mPixelFormat( pixelformat ),
75 mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
77 SetupBuffer( width, height, pixelformat, width, releasePol );
79 // Allocate a persistent internal buffer
80 mInternalBuffer = new PixelBuffer[ mBufferSize ];
83 BufferImage::BufferImage(PixelBuffer* pixBuf,
86 Pixel::Format pixelformat,
88 ReleasePolicy releasePol )
89 : Image( releasePol ),
90 mInternalBuffer( NULL ),
91 mExternalBuffer( pixBuf ),
92 mResourceClient( NULL ),
97 mPixelFormat( pixelformat ),
98 mResourcePolicy( ResourcePolicy::OWNED_DISCARD )
100 SetupBuffer( width, height, pixelformat, stride ? stride: width, releasePol );
103 BufferImage::~BufferImage()
105 delete[] mInternalBuffer;
108 void BufferImage::SetupBuffer( unsigned int width,
110 Pixel::Format pixelformat,
111 unsigned int byteStride,
112 ReleasePolicy releasePol )
114 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
115 mResourceClient = &tls.GetResourceClient();
118 mPixelFormat = pixelformat;
119 mBytesPerPixel = Pixel::GetBytesPerPixel( pixelformat );
121 mByteStride = byteStride * mBytesPerPixel;
122 mBufferSize = height * mByteStride;
124 // Respect the desired release policy
125 mResourcePolicy = releasePol == Dali::Image::UNUSED ? ResourcePolicy::OWNED_DISCARD : ResourcePolicy::OWNED_RETAIN;
128 bool BufferImage::IsDataExternal() const
130 return ( mExternalBuffer ? true : false );
133 void BufferImage::Update( RectArea& updateArea )
139 DALI_ASSERT_DEBUG( updateArea.x + updateArea.width <= mWidth && updateArea.y + updateArea.height <= mHeight );
140 UploadArea( mTicket->GetId(), updateArea );
143 void BufferImage::CreateHostBitmap()
145 Integration::Bitmap* bitmap = Bitmap::New( Bitmap::BITMAP_2D_PACKED_PIXELS, mResourcePolicy );
146 Bitmap::PackedPixelsProfile* const packedBitmap = bitmap->GetPackedPixelsProfile();
147 DALI_ASSERT_DEBUG(packedBitmap);
149 packedBitmap->ReserveBuffer( mPixelFormat, mWidth, mHeight );
150 DALI_ASSERT_DEBUG(bitmap->GetBuffer() != 0);
151 DALI_ASSERT_DEBUG(bitmap->GetBufferSize() >= mHeight * mWidth * mBytesPerPixel );
153 mTicket = mResourceClient->AddBitmapImage( bitmap );
154 mTicket->AddObserver(*this);
157 void BufferImage::UploadArea( ResourceId destId, const RectArea& area )
159 Integration::Bitmap* bitmap = Bitmap::New( Bitmap::BITMAP_2D_PACKED_PIXELS, mResourcePolicy );
160 Bitmap::PackedPixelsProfile* const packedBitmap = bitmap->GetPackedPixelsProfile();
161 DALI_ASSERT_DEBUG(packedBitmap);
162 DALI_ASSERT_DEBUG( area.width <= mWidth && area.height <= mHeight );
164 mBufferWidth = area.width ? area.width : mWidth;
165 packedBitmap->ReserveBuffer( mPixelFormat, mBufferWidth, area.height ? area.height : mHeight );
166 DALI_ASSERT_DEBUG(bitmap->GetBuffer() != 0);
167 DALI_ASSERT_DEBUG(bitmap->GetBufferSize() >= mBufferWidth * ( area.height ? area.height : mHeight ) * mBytesPerPixel );
169 // Are we uploading from an external or internal buffer ?
170 if ( mExternalBuffer )
172 // Check if we're doing the entire area without stride mismatch between source and dest ?
173 if( ( mByteStride == mWidth * mBytesPerPixel ) && area.IsEmpty() )
175 memcpy( bitmap->GetBuffer(), mExternalBuffer, mBufferSize );
179 UpdateBufferArea( mExternalBuffer, bitmap->GetBuffer(), area );
184 // Check if we're doing the entire internal buffer ?
187 memcpy( bitmap->GetBuffer(), mInternalBuffer, bitmap->GetBufferSize() );
191 UpdateBufferArea( mInternalBuffer, bitmap->GetBuffer(), area );
194 mResourceClient->UploadBitmap( destId, bitmap, area.x, area.y );
198 void BufferImage::UploadBitmap( ResourceId destId, std::size_t xOffset, std::size_t yOffset )
200 RectArea area( xOffset, yOffset, 0, 0 );
206 UploadArea( destId, area );
209 void BufferImage::UpdateBufferArea( PixelBuffer* src, PixelBuffer* dest, const RectArea& area )
211 DALI_ASSERT_DEBUG( area.x + area.width <= mWidth && area.y + area.height <= mHeight );
213 uint32_t width = mBufferWidth * mBytesPerPixel;
215 src += ( area.y * mByteStride ) + ( area.x * mBytesPerPixel );
216 for ( uint32_t i = 0; i < area.height; ++i )
218 memcpy( dest, src, width );
224 void BufferImage::Connect()
226 if ( !mConnectionCount++ )
233 void BufferImage::Disconnect()
237 if ( !( --mConnectionCount ) && mReleasePolicy == Dali::Image::UNUSED )
239 mTicket->RemoveObserver(*this);
245 } // namespace Internal