X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fimages%2Fbuffer-image-impl.cpp;h=c34dede406a3343b26c1e6152d8bf4da432fbb93;hb=d2d43506df25b63d0385270b2cbd6ccc2ca16ccb;hp=e9459305e8b556038d140a07c66c6adfcca1aed5;hpb=e840e65577af79cdd96b216dd738ff6b874bfa0b;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/images/buffer-image-impl.cpp b/dali/internal/event/images/buffer-image-impl.cpp index e945930..c34dede 100644 --- a/dali/internal/event/images/buffer-image-impl.cpp +++ b/dali/internal/event/images/buffer-image-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,9 @@ // INTERNAL INCLUDES #include +#include #include -#include #include -#include using namespace Dali::Integration; @@ -40,71 +39,83 @@ namespace TypeRegistration mType( typeid( Dali::BufferImage ), typeid( Dali::Image ), NULL ); } // unnamed namespace -BufferImagePtr BufferImage::New( unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy releasePol ) +BufferImagePtr BufferImage::New( unsigned int width, + unsigned int height, + Pixel::Format pixelformat ) { - BufferImagePtr internal = new BufferImage( width, height, pixelformat, releasePol ); + BufferImagePtr internal = new BufferImage( width, height, pixelformat ); internal->Initialize(); + internal->Update( RectArea() ); return internal; } -BufferImagePtr BufferImage::New( PixelBuffer* pixBuf, unsigned int width, unsigned int height, Pixel::Format pixelformat, unsigned int stride, ReleasePolicy releasePol ) +BufferImagePtr BufferImage::New( PixelBuffer* pixBuf, + unsigned int width, + unsigned int height, + Pixel::Format pixelformat, + unsigned int stride ) { - BufferImagePtr internal = new BufferImage( pixBuf, width, height, pixelformat, stride, releasePol ); + BufferImagePtr internal = new BufferImage( pixBuf, width, height, pixelformat, stride ); internal->Initialize(); + internal->Update( RectArea() ); return internal; } -BufferImage::BufferImage(unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy releasePol) -: Image(releasePol), - mInternalBuffer(NULL), - mExternalBuffer(NULL), - mBitmap(NULL) +BufferImage::BufferImage(unsigned int width, unsigned int height, Pixel::Format pixelformat) +: Image(), + mInternalBuffer( NULL ), + mExternalBuffer( NULL ), + mBufferSize( 0 ), + mByteStride( 0 ), + mBytesPerPixel( 0 ), + mBufferWidth( 0 ), + mPixelFormat( pixelformat ), + mResourcePolicy( ResourcePolicy::OWNED_DISCARD ) { - ThreadLocalStorage& tls = ThreadLocalStorage::Get(); - mResourceClient = &tls.GetResourceClient(); - mWidth = width; - mHeight = height; - mPixelFormat = pixelformat; - mBytesPerPixel = Pixel::GetBytesPerPixel( pixelformat ); - mByteStride = width * mBytesPerPixel; - mBufferSize = height * mByteStride; + SetupBuffer( width, height, pixelformat, width ); // Allocate a persistent internal buffer mInternalBuffer = new PixelBuffer[ mBufferSize ]; +} - // Respect the desired release policy - mResourcePolicy = releasePol == Dali::Image::UNUSED ? ResourcePolicy::OWNED_DISCARD : ResourcePolicy::OWNED_RETAIN; +BufferImage::BufferImage(PixelBuffer* pixBuf, + unsigned int width, + unsigned int height, + Pixel::Format pixelformat, + unsigned int stride) +: Image(), + mInternalBuffer( NULL ), + mExternalBuffer( pixBuf ), + mBufferSize( 0 ), + mByteStride( 0 ), + mBytesPerPixel( 0 ), + mBufferWidth( 0 ), + mPixelFormat( pixelformat ), + mResourcePolicy( ResourcePolicy::OWNED_DISCARD ) +{ + SetupBuffer( width, height, pixelformat, stride ? stride: width ); +} + +BufferImage::~BufferImage() +{ + delete[] mInternalBuffer; } -BufferImage::BufferImage(PixelBuffer* pixBuf, unsigned int width, unsigned int height, Pixel::Format pixelformat, unsigned int stride, ReleasePolicy releasePol ) -: Image(releasePol), - mInternalBuffer(NULL), - mExternalBuffer(pixBuf), - mBitmap(NULL) +void BufferImage::SetupBuffer( unsigned int width, + unsigned int height, + Pixel::Format pixelformat, + unsigned int byteStride ) { - ThreadLocalStorage& tls = ThreadLocalStorage::Get(); - mResourceClient = &tls.GetResourceClient(); mWidth = width; mHeight = height; mPixelFormat = pixelformat; mBytesPerPixel = Pixel::GetBytesPerPixel( pixelformat ); - mByteStride = ( stride ? stride : mWidth ) * mBytesPerPixel; + + mByteStride = byteStride * mBytesPerPixel; mBufferSize = height * mByteStride; // Respect the desired release policy - mResourcePolicy = releasePol == Dali::Image::UNUSED ? ResourcePolicy::OWNED_DISCARD : ResourcePolicy::OWNED_RETAIN; - - // Create a bitmap to hold copy of external buffer - ReserveBitmap(); - - // Take a copy of the external buffer immediately, so it can be released if desired - RectArea area; - MirrorExternal( area ); -} - -BufferImage::~BufferImage() -{ - delete[] mInternalBuffer; + mResourcePolicy = ResourcePolicy::OWNED_RETAIN; } bool BufferImage::IsDataExternal() const @@ -112,124 +123,69 @@ bool BufferImage::IsDataExternal() const return ( mExternalBuffer ? true : false ); } -void BufferImage::Update( RectArea& updateArea ) +void BufferImage::Update( const RectArea& updateArea ) { - ValidateBitmap(); - UpdateBitmap( updateArea ); - - if (mTicket) + if ( !mTexture ) { - DALI_ASSERT_DEBUG( updateArea.x + updateArea.width <= mWidth && updateArea.y + updateArea.height <= mHeight ); - mResourceClient->UpdateBitmapArea( mTicket, updateArea ); - - // Bitmap ownership has been passed on, so any subsequent update will need another bitmap - mBitmap = NULL; + mTexture = Texture::New( Dali::TextureType::TEXTURE_2D, mPixelFormat, mWidth, mHeight ); } + DALI_ASSERT_DEBUG( updateArea.x + updateArea.width <= mWidth && updateArea.y + updateArea.height <= mHeight ); + UploadArea( updateArea ); } -void BufferImage::UpdateBitmap( RectArea& updateArea ) +void BufferImage::UploadArea( const RectArea& area ) { - if ( mExternalBuffer ) - { - MirrorExternal( updateArea ); - } - else - { - // Copy the internal buffer to the bitmap area - memcpy( mBitmap->GetBuffer(), mInternalBuffer, mBufferSize ); - } -} + DALI_ASSERT_DEBUG( area.width <= mWidth && area.height <= mHeight ); -void BufferImage::ValidateBitmap() -{ - ReserveBitmap(); - if ( !mTicket ) - { - mTicket = mResourceClient->AddBitmapImage( mBitmap ); - mTicket->AddObserver(*this); - } -} + mBufferWidth = area.width ? area.width : mWidth; + uint32_t bufferHeight = area.height ? area.height : mHeight; + size_t bufferSize = mBytesPerPixel * mBufferWidth * bufferHeight; + unsigned char* buffer = reinterpret_cast< Dali::Integration::PixelBuffer* >( malloc( bufferSize ) ); + DALI_ASSERT_DEBUG(buffer != 0); -void BufferImage::ReserveBitmap() -{ - // Does a bitmap currently exist ? - if ( !mBitmap ) + // Are we uploading from an external or internal buffer ? + if ( mExternalBuffer ) { - mBitmap = Bitmap::New( Bitmap::BITMAP_2D_PACKED_PIXELS, mResourcePolicy ); + // Check if we're doing the entire area without stride mismatch between source and dest ? + if( ( mByteStride == mWidth * mBytesPerPixel ) && area.IsEmpty() ) + { + memcpy( buffer, mExternalBuffer, mBufferSize ); + } + else + { + UpdateBufferArea( mExternalBuffer, buffer, area ); + } } - - if ( !mBitmap->GetBuffer() ) + else { - Bitmap::PackedPixelsProfile* const packedBitmap = mBitmap->GetPackedPixelsProfile(); - DALI_ASSERT_DEBUG(packedBitmap); - - packedBitmap->ReserveBuffer( mPixelFormat, mWidth, mHeight, mByteStride / mBytesPerPixel, mHeight ); - DALI_ASSERT_DEBUG(mBitmap->GetBuffer() != 0); - DALI_ASSERT_DEBUG(mBitmap->GetBufferSize() >= mWidth * mHeight * Pixel::GetBytesPerPixel( mBitmap->GetPixelFormat() ) ); + // Check if we're doing the entire internal buffer ? + if( area.IsEmpty() ) + { + memcpy( buffer, mInternalBuffer, bufferSize ); + } + else + { + UpdateBufferArea( mInternalBuffer, buffer, area ); + } } -} - -void BufferImage::UploadBitmap( ResourceId destId, std::size_t xOffset, std::size_t yOffset ) -{ - // Make sure we have a bitmap for transport - ReserveBitmap(); + PixelDataPtr pixelData = PixelData::New( buffer, bufferSize, mBufferWidth, bufferHeight, mPixelFormat, Dali::PixelData::FREE ); + mTexture->Upload( pixelData, 0u, 0u, area.x, area.y, mBufferWidth, bufferHeight ); - // Copy source pixel data into bitmap - RectArea area; - UpdateBitmap( area ); - - mResourceClient->UploadBitmap( destId, mBitmap, xOffset, yOffset); - mBitmap = NULL; + UploadedSignal().Emit( Dali::Image( this ) ); } -void BufferImage::UpdateBufferArea( PixelBuffer* src, const RectArea& area ) +void BufferImage::UpdateBufferArea( PixelBuffer* src, PixelBuffer* dest, const RectArea& area ) { DALI_ASSERT_DEBUG( area.x + area.width <= mWidth && area.y + area.height <= mHeight ); - PixelBuffer* dest = mBitmap->GetBuffer(); - uint32_t width = area.width * mBytesPerPixel; - uint32_t stride = mWidth * mBytesPerPixel; + uint32_t width = mBufferWidth * mBytesPerPixel; src += ( area.y * mByteStride ) + ( area.x * mBytesPerPixel ); - dest +=( ( area.y * mWidth ) + area.x ) * mBytesPerPixel; for ( uint32_t i = 0; i < area.height; ++i ) { memcpy( dest, src, width ); src += mByteStride; - dest += stride; - } -} - -void BufferImage::MirrorExternal( const RectArea& area ) -{ - if( ( mByteStride == mWidth * mBytesPerPixel ) && area.IsEmpty() ) - { - memcpy( mBitmap->GetBuffer(), mExternalBuffer, mBufferSize ); - } - else - { - UpdateBufferArea( mExternalBuffer, area ); - } -} - -void BufferImage::Connect() -{ - if ( !mConnectionCount++ ) - { - RectArea area; - Update( area ); - } -} - -void BufferImage::Disconnect() -{ - if ( mTicket ) - { - if ( !( --mConnectionCount ) && mReleasePolicy == Dali::Image::UNUSED ) - { - mTicket->RemoveObserver(*this); - mTicket.Reset(); - } + dest += width; } }