From 199e382cf82c98b5d9ad2f6b8544e54007a1591b Mon Sep 17 00:00:00 2001 From: David Steele Date: Mon, 7 Jul 2014 20:35:36 +0100 Subject: [PATCH] Removed synchronous image size getter [problem] Image::New() takes 1-4ms under load [cause] Each Image::New() calls GetClosestImageSize(), which performs synchronous file i/o to load the image header. [solution] Removed this call and backed off to use the requested size or the loaded size. Application code that relies on image size being immediately set on creation will break. (Image actors will no longer get their size set automatically ). Change-Id: Ide116312cf841a61e13993ff42b7c8399bb86ca7 Signed-off-by: David Steele --- dali/internal/event/images/bitmap-image-impl.cpp | 2 + .../event/images/encoded-buffer-image-impl.cpp | 1 + .../event/images/frame-buffer-image-impl.cpp | 1 + dali/internal/event/images/image-impl.cpp | 70 +++++++++++++++++----- dali/internal/event/images/image-impl.h | 1 + .../event/images/nine-patch-image-impl.cpp | 2 + 6 files changed, 63 insertions(+), 14 deletions(-) diff --git a/dali/internal/event/images/bitmap-image-impl.cpp b/dali/internal/event/images/bitmap-image-impl.cpp index 20773b7..96e1eff 100644 --- a/dali/internal/event/images/bitmap-image-impl.cpp +++ b/dali/internal/event/images/bitmap-image-impl.cpp @@ -59,6 +59,7 @@ BitmapImage::BitmapImage(unsigned int width, unsigned int height, Pixel::Format mResourceClient = &tls.GetResourceClient(); mWidth = width; mHeight = height; + mNaturalSizeSet = true; const ImageTicketPtr& t = mResourceClient->AllocateBitmapImage(width, height, width, height, pixelformat); mTicket = t.Get(); @@ -74,6 +75,7 @@ BitmapImage::BitmapImage(PixelBuffer* pixBuf, unsigned int width, unsigned int h mResourceClient = &tls.GetResourceClient(); mWidth = width; mHeight = height; + mNaturalSizeSet = true; Integration::Bitmap* bitmap = new BitmapExternal(pixBuf, width, height, pixelformat, stride); const ImageTicketPtr& t = mResourceClient->AddBitmapImage(bitmap); mTicket = t.Get(); diff --git a/dali/internal/event/images/encoded-buffer-image-impl.cpp b/dali/internal/event/images/encoded-buffer-image-impl.cpp index 0d3faf8..015165c 100644 --- a/dali/internal/event/images/encoded-buffer-image-impl.cpp +++ b/dali/internal/event/images/encoded-buffer-image-impl.cpp @@ -63,6 +63,7 @@ EncodedBufferImagePtr EncodedBufferImage::New( const uint8_t * const encodedImag Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( buffer, attributes, size ); image->mWidth = (unsigned int) size.width; image->mHeight = (unsigned int) size.height; + image->mNaturalSizeSet = true; ResourceClient &resourceClient = ThreadLocalStorage::Get().GetResourceClient(); ResourceTicketPtr ticket = resourceClient.DecodeResource( resourceType, buffer ); diff --git a/dali/internal/event/images/frame-buffer-image-impl.cpp b/dali/internal/event/images/frame-buffer-image-impl.cpp index 8735abb..08ecf50 100644 --- a/dali/internal/event/images/frame-buffer-image-impl.cpp +++ b/dali/internal/event/images/frame-buffer-image-impl.cpp @@ -65,6 +65,7 @@ FrameBufferImage::FrameBufferImage(unsigned int width, unsigned int height, Pixe { mWidth = width; mHeight = height; + mNaturalSizeSet = true; } diff --git a/dali/internal/event/images/image-impl.cpp b/dali/internal/event/images/image-impl.cpp index cdb355e..e52ead8 100644 --- a/dali/internal/event/images/image-impl.cpp +++ b/dali/internal/event/images/image-impl.cpp @@ -57,6 +57,7 @@ Dali::SignalConnectorType signalConnector2(mType, Dali::Image::SIGNAL_IMAGE_UPLO Image::Image( LoadPolicy loadPol, ReleasePolicy releasePol ) : mWidth(0), mHeight(0), + mNaturalSizeSet(false), mLoadPolicy(loadPol), mReleasePolicy(releasePol), mConnectionCount(0), @@ -83,15 +84,6 @@ ImagePtr Image::New( const std::string& filename, const Dali::ImageAttributes& a ImagePtr image = new Image( loadPol, releasePol ); image->Initialize(); - if( ! filename.empty() ) - { - Vector2 closestSize; - - Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( filename, attributes, closestSize ); - image->mWidth = closestSize.width; - image->mHeight = closestSize.height; - } - image->mRequest = image->mImageFactory.RegisterRequest( filename, &attributes ); if( Dali::Image::Immediate == loadPol ) @@ -119,6 +111,7 @@ ImagePtr Image::New( NativeImage& nativeImg, LoadPolicy loadPol, ReleasePolicy r image->mWidth = nativeImg.GetWidth(); image->mHeight = nativeImg.GetHeight(); + image->mNaturalSizeSet = true; const ResourceTicketPtr& ticket = resourceClient.AddNativeImage( nativeImg ); DALI_ASSERT_DEBUG( dynamic_cast( ticket.Get() ) && "Resource ticket not ImageTicket subclass for image resource.\n" ); @@ -212,6 +205,7 @@ void Image::ResourceLoadingSucceeded(const ResourceTicket& ticket) const ImageTicket* imageTicket = static_cast(&ticket); mWidth = imageTicket->GetWidth(); mHeight = imageTicket->GetHeight(); + mNaturalSizeSet = true; mLoadingFinishedV2.Emit( Dali::Image( this ) ); } @@ -232,19 +226,67 @@ void Image::ResourceSavingFailed( const ResourceTicket& ticket ) unsigned int Image::GetWidth() const { - // Width has already been calculated - just return that - return mWidth; + unsigned int width = 0; + if( mNaturalSizeSet ) + { + // Width has already been calculated - just return that + width = mWidth; + } + else if( mTicket ) + { + const ImageAttributes& attr = mImageFactory.GetActualAttributes( mTicket->GetId() ); + width = attr.GetWidth(); + } + else if( mRequest ) + { + const ImageAttributes& attr = mImageFactory.GetRequestAttributes( mRequest.Get() ); + width = attr.GetWidth(); + } + + return width; } unsigned int Image::GetHeight() const { - // Height has already been calculated - just return that - return mHeight; + unsigned int height = 0; + if( mNaturalSizeSet ) + { + // Height has already been calculated - just return that + height = mHeight; + } + else if( mTicket ) + { + const ImageAttributes& attr = mImageFactory.GetActualAttributes( mTicket->GetId() ); + height = attr.GetHeight(); + } + else if( mRequest ) + { + const ImageAttributes& attr = mImageFactory.GetRequestAttributes( mRequest.Get() ); + height = attr.GetHeight(); + } + + return height; } Vector2 Image::GetNaturalSize() const { - return Vector2( mWidth, mHeight ); + Vector2 naturalSize(mWidth, mHeight); + if( ! mNaturalSizeSet ) + { + if( mTicket ) + { + const ImageAttributes& attr = mImageFactory.GetActualAttributes( mTicket->GetId() ); + naturalSize.width = attr.GetWidth(); + naturalSize.height = attr.GetHeight(); + } + else if( mRequest ) + { + const ImageAttributes& attr = mImageFactory.GetRequestAttributes( mRequest.Get() ); + naturalSize.width = attr.GetWidth(); + naturalSize.height = attr.GetHeight(); + } + } + return naturalSize; } void Image::Connect() diff --git a/dali/internal/event/images/image-impl.h b/dali/internal/event/images/image-impl.h index 41d575a..d05918e 100644 --- a/dali/internal/event/images/image-impl.h +++ b/dali/internal/event/images/image-impl.h @@ -257,6 +257,7 @@ private: protected: unsigned int mWidth; unsigned int mHeight; + bool mNaturalSizeSet; ResourceTicketPtr mTicket; ImageFactoryCache::RequestPtr mRequest; ///< contains the initially requested attributes for image. Request is reissued when memory was released. diff --git a/dali/internal/event/images/nine-patch-image-impl.cpp b/dali/internal/event/images/nine-patch-image-impl.cpp index 65cbb72..32e584a 100644 --- a/dali/internal/event/images/nine-patch-image-impl.cpp +++ b/dali/internal/event/images/nine-patch-image-impl.cpp @@ -157,6 +157,8 @@ NinePatchImage::NinePatchImage( const std::string& filename, const Dali::ImageAt loadedAttrs.SetSize( closestSize ); mWidth = closestSize.width; mHeight = closestSize.height; + mNaturalSizeSet = true; + Integration::BitmapResourceType resourceType( loadedAttrs ); // Note, bitmap is only destroyed when the image is destroyed. -- 2.7.4