(Images) Reducing thread tennis
authorDavid Steele <david.steele@partner.samsung.com>
Mon, 17 Feb 2014 20:16:48 +0000 (20:16 +0000)
committerPaul Wisbey <p.wisbey@samsung.com>
Mon, 3 Mar 2014 18:34:53 +0000 (18:34 +0000)
[Issue#]       N/A
[Problem]      Non-loaded images do not get size set immediately, and
rely on messages from update thread to update their size.
[Cause]        N/A
[Solution]     Store image size in image base class and in created ticket's image
attributes. Remove message notification of creation of bitmaps, native images and framebuffers
where the size is already known.

This will also prevent LoadingFinished signal from being sent for
bitmaps, native images and framebuffers that are created directly.
LoadingFinished will only be sent for images created from filenames.

On adding images to image-actors, only listens to LoadingFinished signal if the image
has a filename, otherwise it uses the known size.

Change-Id: Ie08a0c9070d903b87447841af8ddc1da0234a51f
Signed-off-by: David Steele <david.steele@partner.samsung.com>
12 files changed:
automated-tests/dali-internal-test-suite/resource-manager/utc-DaliInternal-ResourceClient.cpp
automated-tests/dali-test-suite/actors/utc-Dali-Actor.cpp
dali/internal/event/actors/image-actor-impl.cpp
dali/internal/event/images/bitmap-image-impl.cpp
dali/internal/event/images/frame-buffer-image-impl.cpp
dali/internal/event/images/frame-buffer-image-impl.h
dali/internal/event/images/image-factory.h
dali/internal/event/images/image-impl.cpp
dali/internal/event/images/image-impl.h
dali/internal/event/resources/resource-client.cpp
dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp
dali/internal/update/resources/resource-manager.cpp

index f2a503a..fea9d2b 100644 (file)
@@ -1109,7 +1109,7 @@ static void UtcDaliInternalLoadShaderRequest02()
 static void UtcDaliInternalAllocateBitmapImage01()
 {
   TestApplication application;
-  tet_infoline("Testing AllocateBitmap()");
+  tet_infoline("Testing AllocateBitmapImage()");
   testTicketObserver.Reset();
 
   Internal::ResourceClient& resourceClient  = Internal::ThreadLocalStorage::Get().GetResourceClient();
@@ -1117,20 +1117,20 @@ static void UtcDaliInternalAllocateBitmapImage01()
   imageTicket->AddObserver( testTicketObserver );
 
   DALI_TEST_CHECK( imageTicket );
-  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoading, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetWidth(), 0, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetHeight(), 0, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetWidth(), 80, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGB565, TEST_LOCATION );
 
   application.SendNotification(); // Flush update queue
   application.Render(0); // Process message
   application.SendNotification(); // Send message to tickets
 
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
   DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetWidth(), 80, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGB565, TEST_LOCATION );
-  DALI_TEST_CHECK( testTicketObserver.LoadSucceededCalled() == 1 );
 
   Integration::Bitmap* bitmap = resourceClient.GetBitmap(imageTicket);
   DALI_TEST_CHECK ( bitmap != NULL );
@@ -1154,15 +1154,16 @@ static void UtcDaliInternalAddBitmapImage01()
   DALI_TEST_CHECK( imageTicket );
   imageTicket->AddObserver( testTicketObserver );
 
-  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoading, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetWidth(), 0, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetHeight(), 0, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetWidth(), 80, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGB565, TEST_LOCATION );
 
   application.SendNotification(); // Flush update queue
   application.Render(0); // Process message
   application.SendNotification(); // Send message to tickets
 
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
   DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetWidth(), 80, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
@@ -1190,10 +1191,11 @@ static void UtcDaliInternalAddBitmapImage02()
   DALI_TEST_CHECK( imageTicket );
   imageTicket->AddObserver( testTicketObserver );
 
-  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoading, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetWidth(), 0, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetHeight(), 0, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
 
   application.SendNotification(); // Flush update queue
   application.Render(0); // Process message
@@ -1203,6 +1205,7 @@ static void UtcDaliInternalAddBitmapImage02()
   DALI_TEST_EQUALS ( imageTicket->GetWidth(), 0, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetHeight(), 0, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
 
   Integration::Bitmap* theBitmap = resourceClient.GetBitmap(imageTicket);
   DALI_TEST_CHECK ( theBitmap != NULL );
@@ -1322,15 +1325,15 @@ static void UtcDaliInternalAllocateTexture01()
   resourceTicket->AddObserver( testTicketObserver );
 
   DALI_TEST_CHECK( resourceTicket );
-  DALI_TEST_EQUALS ( resourceTicket->GetLoadingState(), ResourceLoading, TEST_LOCATION );
+  DALI_TEST_EQUALS ( resourceTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
+  DALI_TEST_CHECK( testTicketObserver.LoadSucceededCalled() == 0 );
 
   application.SendNotification(); // Flush update queue
   application.Render(0); // Process message
   application.SendNotification(); // Send message to tickets
 
   DALI_TEST_EQUALS ( resourceTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
-  DALI_TEST_CHECK( testTicketObserver.LoadSucceededCalled() == 1 );
-
+  DALI_TEST_CHECK( testTicketObserver.LoadSucceededCalled() == 0 );
 }
 
 static void UtcDaliInternalAddNativeImage()
@@ -1340,16 +1343,20 @@ static void UtcDaliInternalAddNativeImage()
 
   testTicketObserver.Reset();
   Internal::ResourceClient& resourceClient  = Internal::ThreadLocalStorage::Get().GetResourceClient();
+  Internal::ResourceTicketPtr ticket;
   Internal::ImageTicketPtr imageTicket;
   { // Test image going out of scope after ticket creation (message to Update thread holds a ref)
     TestNativeImagePointer nativeImage = TestNativeImage::New( 80, 80 );
-    Internal::ResourceTicketPtr ticket = resourceClient.AddNativeImage( *nativeImage );
+    ticket = resourceClient.AddNativeImage( *nativeImage );
     imageTicket = dynamic_cast<Internal::ImageTicket*>(ticket.Get());
     DALI_TEST_CHECK( imageTicket );
     imageTicket->AddObserver( testTicketObserver );
   }
 
-  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoading, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetWidth(),  80, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
 
   application.SendNotification(); // Flush update queue
   application.Render(0); // Process message
@@ -1358,6 +1365,7 @@ static void UtcDaliInternalAddNativeImage()
   DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetWidth(),  80, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
 
   Integration::Bitmap* theBitmap = NULL;
   theBitmap = resourceClient.GetBitmap(imageTicket);
@@ -1376,10 +1384,11 @@ static void UtcDaliInternalAddFrameBufferImage()
   DALI_TEST_CHECK( imageTicket );
   imageTicket->AddObserver( testTicketObserver );
 
-  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoading, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetWidth(),  0, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetHeight(), 0, TEST_LOCATION );
-  DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetWidth(),  80, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::A8, TEST_LOCATION );
+  DALI_TEST_EQUALS ( imageTicket->GetLoadingState(), ResourceLoadingSucceeded, TEST_LOCATION );
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
 
   application.SendNotification(); // Flush update queue
   application.Render(0); // Process message
@@ -1389,6 +1398,7 @@ static void UtcDaliInternalAddFrameBufferImage()
   DALI_TEST_EQUALS ( imageTicket->GetWidth(), 80, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetHeight(), 80, TEST_LOCATION );
   DALI_TEST_EQUALS ( imageTicket->GetAttributes().GetPixelFormat(), Pixel::A8, TEST_LOCATION );
+  DALI_TEST_CHECK ( 0 == testTicketObserver.LoadSucceededCalled() ); // Check no message was sent
 
   Integration::Bitmap* theBitmap = NULL;
   theBitmap = resourceClient.GetBitmap(imageTicket);
index 26cfd80..6a5a153 100644 (file)
@@ -2510,6 +2510,9 @@ static void UtcDaliActorSetDrawModeOverlayRender()
   TestApplication app;
   tet_infoline(" UtcDaliActorSetDrawModeOverlayRender");
 
+  app.SendNotification();
+  app.Render(1);
+
   std::vector<GLuint> ids;
   ids.push_back( 8 );   // first rendered actor
   ids.push_back( 9 );   // second rendered actor
@@ -2532,8 +2535,6 @@ static void UtcDaliActorSetDrawModeOverlayRender()
   Stage::GetCurrent().Add(c);
 
   app.SendNotification();
-  app.Render(0);
-  app.SendNotification();
   app.Render(1);
 
   // Should be 3 textures changes.
index cf35969..da67e4c 100644 (file)
@@ -92,7 +92,6 @@ std::string StyleString(const ImageActor::Style style)
     return "STYLE_QUAD";
   }
 }
-
 }
 
 ImageActorPtr ImageActor::New( Image* image )
@@ -274,14 +273,14 @@ ImageActor::~ImageActor()
 void ImageActor::OnImageSet( Image& image )
 {
   // observe image loaded
-  if( Dali::ResourceLoadingSucceeded == image.GetLoadingState() )
+  if( Dali::ResourceLoading == image.GetLoadingState() && ! image.GetFilename().empty() )
   {
-    //image already loaded
-    ImageLoaded( Dali::Image(&image) );
+    image.LoadingFinishedSignal().Connect( mLoadedConnection, &ImageActor::ImageLoaded );
   }
   else
   {
-    image.LoadingFinishedSignal().Connect( mLoadedConnection, &ImageActor::ImageLoaded );
+    // image already loaded, or generated
+    ImageLoaded( Dali::Image(&image) );
   }
 }
 
index b88a75e..eab6083 100644 (file)
@@ -52,6 +52,9 @@ BitmapImage::BitmapImage(unsigned int width, unsigned int height, Pixel::Format
 {
   Initialize();
 
+  mWidth  = width;
+  mHeight = height;
+
   const ImageTicketPtr& t = mResourceClient->AllocateBitmapImage(width, height, width, height, pixelformat);
   mTicket = t.Get();
 
@@ -63,7 +66,8 @@ BitmapImage::BitmapImage(PixelBuffer* pixBuf, unsigned int width, unsigned int h
   mIsDataExternal(true)
 {
   Initialize();
-
+  mWidth  = width;
+  mHeight = height;
   Integration::Bitmap* bitmap = new BitmapExternal(pixBuf, width, height, pixelformat, stride);
   const ImageTicketPtr& t = mResourceClient->AddBitmapImage(bitmap);
   mTicket = t.Get();
@@ -212,4 +216,3 @@ Integration::Bitmap * BitmapImage::GetBitmap() const
 } // namespace Internal
 
 } // namespace Dali
-
index dfd1cc9..90cfda1 100644 (file)
@@ -32,31 +32,29 @@ FrameBufferImage::~FrameBufferImage()
 }
 
 FrameBufferImage::FrameBufferImage(unsigned int width, unsigned int height, Pixel::Format pixelFormat, ReleasePolicy releasePolicy)
-  : Image(Dali::Image::Immediate, releasePolicy)
-  , mWidth(width)
-  , mHeight(height)
-  , mPixelFormat(pixelFormat)
-{}
+: Image(Dali::Image::Immediate, releasePolicy),
+  mPixelFormat(pixelFormat)
+{
+  mWidth  = width;
+  mHeight = height;
+}
 
 FrameBufferImage::FrameBufferImage( NativeImage& nativeImage )
-  : Image(Dali::Image::Immediate)
-  , mNativeImage(&nativeImage)
-  , mWidth(nativeImage.GetWidth())
-  , mHeight(nativeImage.GetHeight())
-  , mPixelFormat(nativeImage.GetPixelFormat())
+: Image(Dali::Image::Immediate),
+  mNativeImage(&nativeImage),
+  mPixelFormat(nativeImage.GetPixelFormat())
 {
-
+  mWidth = nativeImage.GetWidth();
+  mHeight = nativeImage.GetHeight();
 }
 
 FrameBufferImage::FrameBufferImage( NativeImage& nativeImage, ReleasePolicy releasePolicy )
-  : Image(Dali::Image::Immediate, releasePolicy)
-  , mNativeImage(&nativeImage)
-  , mWidth(nativeImage.GetWidth())
-  , mHeight(nativeImage.GetHeight())
-  , mPixelFormat(nativeImage.GetPixelFormat())
+: Image(Dali::Image::Immediate, releasePolicy),
+  mNativeImage(&nativeImage),
+  mPixelFormat(nativeImage.GetPixelFormat())
 {
-
-
+  mWidth = nativeImage.GetWidth();
+  mHeight = nativeImage.GetHeight();
 }
 
 void FrameBufferImage::Connect()
@@ -103,4 +101,3 @@ void FrameBufferImage::Disconnect()
 } // namespace Internal
 
 } // namespace Dali
-
index 76d5849..37be53b 100644 (file)
@@ -49,7 +49,6 @@ public:
   FrameBufferImage(NativeImage& image, ReleasePolicy releasePolicy);
 
 public: // From Image
-
   /**
    * @copydoc Dali::Internal::Image::Connect()
    */
@@ -69,8 +68,6 @@ protected:
 private:
   // cached values for the size / pixel format we were created with. Needed to recreate us when we Connect() to stage and mTicket was reset from a previous call to Disconnect().
   NativeImagePtr mNativeImage;
-  unsigned int mWidth;
-  unsigned int mHeight;
   Pixel::Format mPixelFormat;
 }; // class FrameBufferImage
 
index ffbd349..f40cc1e 100644 (file)
@@ -27,17 +27,19 @@ namespace Dali
 
 namespace Internal
 {
-
 class ResourceType;
 
-using namespace Dali::Internal::ImageFactoryCache;
+namespace ImageFactoryCache
+{
+class Request;
+}
 
 /**
  * ImageFactory is an object that manages Image resource load requests.
  * It utilises an internal caching system where previous requests and associated
  * resources are stored to avoid accessing the file system when not neccessary.
  */
-class ImageFactory : public RequestLifetimeObserver
+class ImageFactory : public ImageFactoryCache::RequestLifetimeObserver
 {
 public:
 
@@ -59,7 +61,7 @@ public:
    * @param [in] attributes pointer to the ImageAttributes of the request. If NULL, default attributes are used.
    * @return     request pointer
    */
-  Dali::Internal::ImageFactoryCache::Request* RegisterRequest( const std::string& filename, const ImageAttributes *attributes );
+  ImageFactoryCache::Request* RegisterRequest( const std::string& filename, const ImageAttributes *attributes );
 
   /**
    * Issue a request which has already been registered with ImageFactory.
@@ -67,7 +69,7 @@ public:
    * @param [in] req pointer to request
    * @return     intrusive pointer to image ticket. If Load fails, returned pointer is invalid. (!ret)
    */
-  ResourceTicketPtr Load( Request* req );
+  ResourceTicketPtr Load( ImageFactoryCache::Request* req );
 
   /**
    * Tells ResourceManager to reload image from filesystem.
@@ -78,14 +80,14 @@ public:
    * @param [in]  req Request pointer
    * @return[out] the ResourceTicket mapped to the request
    */
-  ResourceTicketPtr Reload( Request* req );
+  ResourceTicketPtr Reload( ImageFactoryCache::Request* req );
 
   /**
    * Get resource path used in request.
    * @param [in] req request pointer
    * @return     resource path
    */
-  const std::string& GetRequestPath( const Request* req ) const;
+  const std::string& GetRequestPath( const ImageFactoryCache::Request* req ) const;
 
   /**
    * Get ImageAttributes for an already requested image resource.
@@ -102,7 +104,7 @@ public:
    * @param [in] req request pointer
    * @return     ImageAttributes used for request.
    */
-  const ImageAttributes& GetRequestAttributes( const Request* req ) const;
+  const ImageAttributes& GetRequestAttributes( const ImageFactoryCache::Request* req ) const;
 
   /**
    * Prevents releasing and reloading image resources in the same frame
@@ -123,7 +125,7 @@ public: // From RequestLifetimeObserver
    * Finds request by id in mRequestCache and mUrlCache and removes relevant entries.
    * @param [in] id request id
    */
-  virtual void RequestDiscarded( const Request& request );
+  virtual void RequestDiscarded( const ImageFactoryCache::Request& request );
 
 private:
 
@@ -151,7 +153,7 @@ private:
    * @param [in] attr       Pointer to the requested attributes, NULL if default values are used.
    * @return pointer to Request
    */
-  Request* InsertNewRequest( ResourceId resourceId, const std::string& url, std::size_t urlHash, const ImageAttributes* attr );
+  ImageFactoryCache::Request* InsertNewRequest( ResourceId resourceId, const std::string& url, std::size_t urlHash, const ImageAttributes* attr );
 
   /**
    * Searches request cache for exact match.
@@ -160,7 +162,7 @@ private:
    * @param [in] attributes  Pointer to ImageAttributes used for the request or NULL if default attributes were used.
    * @return pointer to the found request or NULL if no exact match is found.
    */
-  Request* FindRequest( const std::string& filename, size_t hash, const ImageAttributes *attributes );
+  ImageFactoryCache::Request* FindRequest( const std::string& filename, size_t hash, const ImageAttributes *attributes );
 
   /**
    * Searches through tickets to find a compatible resource.
@@ -180,14 +182,12 @@ private:
   ResourceTicketPtr IssueLoadRequest( const std::string& filename, const ImageAttributes* attributes );
 
 private:
-  ResourceClient&         mResourceClient;
-
-  ImageFactoryCache::RequestPathHashMap      mUrlCache;     ///< A multimap of url hashes and request IDs
-  ImageFactoryCache::RequestIdMap            mRequestCache; ///< A map of request IDs and request information.
-
-  ResourceTicketContainer mTicketsToRelease; ///< List of ticket handles
-  float                   mMaxScale;         ///< Defines maximum size difference between compatible resources
-  RequestId               mReqIdCurrent;     ///< Internal counter for Request IDs
+  ResourceClient&                        mResourceClient;
+  ImageFactoryCache::RequestPathHashMap  mUrlCache;         ///< A multimap of url hashes and request IDs
+  ImageFactoryCache::RequestIdMap        mRequestCache;     ///< A map of request IDs and request information.
+  ResourceTicketContainer                mTicketsToRelease; ///< List of ticket handles
+  float                                  mMaxScale;         ///< Defines maximum size difference between compatible resources
+  ImageFactoryCache::RequestId           mReqIdCurrent;     ///< Internal counter for Request IDs
 };
 
 } // namespace Internal
index ad4cd8d..71405e6 100644 (file)
@@ -20,6 +20,7 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
 
+#include <dali/integration-api/platform-abstraction.h>
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/resources/resource-ticket.h>
 #include <dali/internal/event/common/thread-local-storage.h>
@@ -36,7 +37,9 @@ namespace Internal
 {
 
 Image::Image( LoadPolicy loadPol, ReleasePolicy releasePol )
-: mLoadPolicy(loadPol),
+: mWidth(0),
+  mHeight(0),
+  mLoadPolicy(loadPol),
   mReleasePolicy(releasePol),
   mConnectionCount(0),
   mImageFactory(ThreadLocalStorage::Get().GetImageFactory())
@@ -50,7 +53,32 @@ Image* Image::New()
 
 Image* Image::New( const std::string& filename, LoadPolicy loadPol, ReleasePolicy releasePol )
 {
-  Image* image = Image::New( filename, *static_cast<ImageAttributes*>(NULL), loadPol, releasePol );
+  Image* image = new Image( loadPol, releasePol );
+
+  image->mRequest = image->mImageFactory.RegisterRequest( filename, NULL );
+
+  if( ! filename.empty() )
+  {
+    Vector2 size;
+    Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().LoadImageMetadata( filename, size );
+    image->mWidth = (int)size.width;
+    image->mHeight = (int)size.height;
+  }
+
+  if( Dali::Image::OnDemand == loadPol )
+  {
+    // load image on demand,
+    // ask for ticket on connect
+  }
+  else
+  {
+    // load image immediately
+    image->mTicket = image->mImageFactory.Load( image->mRequest.Get() );
+    image->mTicket->AddObserver( *image );
+  }
+
+  DALI_LOG_SET_OBJECT_STRING( image, filename );
+
   return image;
 }
 
@@ -58,6 +86,19 @@ Image* Image::New( const std::string& filename, const Dali::ImageAttributes& att
 {
   Image* image = new Image( loadPol, releasePol );
 
+  if( ! filename.empty() )
+  {
+    if( attributes.GetWidth() == 0 && attributes.GetHeight() == 0 )
+    {
+      // Only get actual file size if a requested size is not present.
+      Vector2 size;
+      Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().LoadImageMetadata( filename, size );
+      image->mWidth = (int)size.width;
+      image->mHeight = (int)size.height;
+    }
+    // @TODO: else, determine closest size to requested size
+  }
+
   image->mRequest = image->mImageFactory.RegisterRequest( filename, &attributes );
 
   // Lazily load image data later, only when it is needed to draw something:
@@ -83,7 +124,9 @@ Image* Image::New( NativeImage& nativeImg, LoadPolicy loadPol, ReleasePolicy rel
   Image* image = new Image;
   ResourceClient &resourceClient = ThreadLocalStorage::Get().GetResourceClient();
 
-  /// @todo check policy and ref with intrusive pointer if needed
+
+  image->mWidth  = nativeImg.GetWidth();
+  image->mHeight = nativeImg.GetHeight();
 
   const ResourceTicketPtr& ticket = resourceClient.AddNativeImage( nativeImg );
   DALI_ASSERT_DEBUG( dynamic_cast<ImageTicket*>( ticket.Get() ) && "Resource ticket not ImageTicket subclass for image resource.\n" );
@@ -168,6 +211,10 @@ void Image::ResourceLoadingFailed(const ResourceTicket& ticket)
 
 void Image::ResourceLoadingSucceeded(const ResourceTicket& ticket)
 {
+  // Update size with actual loaded size
+  const ImageTicket* imageTicket = static_cast<const ImageTicket*>(&ticket);
+  mWidth = imageTicket->GetWidth();
+  mHeight = imageTicket->GetHeight();
   mLoadingFinishedV2.Emit( Dali::Image( this ) );
 }
 
@@ -193,11 +240,15 @@ unsigned int Image::GetWidth() const
     const ImageAttributes& attr = mImageFactory.GetActualAttributes( mTicket->GetId() );
     return attr.GetWidth();
   }
-  else
+  else if( mRequest )
   {
     const ImageAttributes& attr = mImageFactory.GetRequestAttributes( mRequest.Get() );
     return attr.GetWidth();
   }
+  else
+  {
+    return mWidth;
+  }
 }
 
 unsigned int Image::GetHeight() const
@@ -207,11 +258,15 @@ unsigned int Image::GetHeight() const
     const ImageAttributes& attr = mImageFactory.GetActualAttributes( mTicket->GetId() );
     return attr.GetHeight();
   }
-  else
+  else if( mRequest )
   {
     const ImageAttributes& attr = mImageFactory.GetRequestAttributes( mRequest.Get() );
     return attr.GetHeight();
   }
+  else
+  {
+    return mHeight;
+  }
 }
 
 void Image::Connect()
index b9b000d..7665f79 100644 (file)
@@ -158,7 +158,7 @@ public:
   ResourceId GetResourceId() const;
 
   /**
-   * Get the attributes of an image.
+   * Get the attributes of the image.
    * Only to be used after the image has finished loading.
    * (Ticket's LoadingSucceeded callback was called)
    * Reflects the last cached values after a LoadComplete.
@@ -168,7 +168,7 @@ public:
   const Dali::ImageAttributes& GetAttributes() const;
 
   /**
-   * Get the width of an image.
+   * Get the width of the image.
    * Only to be used after the image has finished loading.
    * (Ticket's LoadingSucceeded callback was called)
    * The returned value will reflect the true image dimensions once the asynchronous loading has finished.
@@ -178,7 +178,7 @@ public:
   unsigned int GetWidth() const;
 
   /**
-   * Get the height of an image.
+   * Get the height of the image.
    * Only to be used after the image has finished loading.
    * (Ticket's LoadingSucceeded callback was called)
    * The returned value will reflect the true image dimensions once the asynchronous loading has finished.
@@ -246,6 +246,8 @@ private:
   void SetTicket( ResourceTicket* ticket );
 
 protected:
+  unsigned int mWidth;
+  unsigned int mHeight;
 
   ResourceTicketPtr mTicket;
   ImageFactoryCache::RequestPtr mRequest;         ///< contains the initially requested attributes for image. Request is reissued when memory was released.
@@ -288,4 +290,3 @@ inline const Internal::Image& GetImplementation(const Dali::Image& image)
 
 } // namespace Dali
 #endif // __DALI_INTERNAL_IMAGE_H__
-
index 9fdda4d..25c5d99 100644 (file)
@@ -295,7 +295,10 @@ ImageTicketPtr ResourceClient::AddBitmapImage(Bitmap* bitmap)
 
   Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New(bitmap->GetImageWidth(), bitmap->GetImageHeight(), bitmap->GetPixelFormat());
   ResourceTypePath typePath(BitmapResourceType(imageAttributes), "");
+
   newTicket = new ImageTicket(*this, newId, typePath);
+  newTicket->mAttributes = imageAttributes;
+  newTicket->LoadingSucceeded();
 
   mImpl->mTickets.insert(TicketPair(newId, newTicket.Get()));
 
@@ -305,7 +308,6 @@ ImageTicketPtr ResourceClient::AddBitmapImage(Bitmap* bitmap)
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceClient: AddBitmapImage() New id = %u\n", newId);
   RequestAddBitmapImageMessage( mUpdateManager.GetEventToUpdate(), mResourceManager, newId, bitmap );
 
-  // Ticket attributes will be updated via message
   return newTicket;
 }
 
@@ -317,6 +319,10 @@ ResourceTicketPtr ResourceClient::AddNativeImage ( NativeImage& resourceData )
 
   ResourceTypePath typePath(NativeImageResourceType(), "");
   newTicket = new ImageTicket(*this, newId, typePath);
+  newTicket->mAttributes = ImageAttributes::New(resourceData.GetWidth(),
+                                                resourceData.GetHeight(),
+                                                resourceData.GetPixelFormat());
+  newTicket->LoadingSucceeded();
 
   mImpl->mTickets.insert(TicketPair(newId, newTicket.Get()));
 
@@ -324,7 +330,6 @@ ResourceTicketPtr ResourceClient::AddNativeImage ( NativeImage& resourceData )
 
   RequestAddNativeImageMessage( mUpdateManager.GetEventToUpdate(), mResourceManager, newId, &resourceData );
 
-  // Ticket attributes will be updated via message
   return newTicket;
 }
 
@@ -337,13 +342,14 @@ ImageTicketPtr ResourceClient::AddFrameBufferImage ( unsigned int width, unsigne
   Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New(width, height, pixelFormat );
   ResourceTypePath typePath(RenderTargetResourceType(imageAttributes), "");
   newTicket = new ImageTicket(*this, newId, typePath);
+  newTicket->mAttributes = imageAttributes;
+  newTicket->LoadingSucceeded();
 
   mImpl->mTickets.insert(TicketPair(newId, newTicket.Get()));
 
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceClient: AddFrameBufferImage() New id = %u\n", newId);
   RequestAddFrameBufferImageMessage( mUpdateManager.GetEventToUpdate(), mResourceManager, newId, width, height, pixelFormat );
 
-  // Ticket attributes will be updated via message
   return newTicket;
 }
 
@@ -356,13 +362,14 @@ ImageTicketPtr ResourceClient::AddFrameBufferImage ( NativeImage& nativeImage )
   Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New(nativeImage.GetWidth(), nativeImage.GetHeight(), nativeImage.GetPixelFormat() );
   ResourceTypePath typePath(RenderTargetResourceType(imageAttributes), "");
   newTicket = new ImageTicket(*this, newId, typePath);
+  newTicket->mAttributes = imageAttributes;
+  newTicket->LoadingSucceeded();
 
   mImpl->mTickets.insert(TicketPair(newId, newTicket.Get()));
 
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceClient: AddFrameBufferImage() New id = %u\n", newId);
   RequestAddFrameBufferImageMessage( mUpdateManager.GetEventToUpdate(), mResourceManager, newId, &nativeImage );
 
-  // Ticket attributes will be updated via message
   return newTicket;
 }
 
@@ -371,7 +378,7 @@ ResourceTicketPtr ResourceClient::AllocateTexture( unsigned int width,
                                                    unsigned int height,
                                                    Pixel::Format pixelformat )
 {
-  ResourceTicketPtr newTicket;
+  ImageTicketPtr newTicket;
   const ResourceId newId = ++(mImpl->mNextId);
 
   Dali::ImageAttributes imageAttributes = Dali::ImageAttributes::New( width, height, pixelformat);
@@ -379,13 +386,13 @@ ResourceTicketPtr ResourceClient::AllocateTexture( unsigned int width,
   newTicket = new ImageTicket(*this, newId, typePath);
 
   mImpl->mTickets.insert(TicketPair(newId, newTicket.Get()));
-
+  newTicket->mAttributes = imageAttributes;
+  newTicket->LoadingSucceeded();
 
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceClient: AllocateTexture() New id = %u\n", newId);
 
   RequestAllocateTextureMessage( mUpdateManager.GetEventToUpdate(), mResourceManager, newId, width, height, pixelformat );
 
-  // Ticket attributes will be updated via message
   return newTicket;
 }
 
index 1e68b02..0409a29 100644 (file)
@@ -188,7 +188,7 @@ void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3&
 void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
 {
   ready = false;
-  complete = true; // If attachment doesn't have size or color, this should be marked as complete.
+  complete = false;
 
   CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
 
index 15d948e..c51a233 100644 (file)
@@ -309,16 +309,9 @@ void ResourceManager::HandleAddBitmapImageRequest( ResourceId id, Bitmap* bitmap
   DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddBitmapImageRequest(id:%u)\n", id);
 
-  mImpl->newCompleteRequests.insert(id);
-
-  ImageAttributes imageAttributes = ImageAttributes::New();
-  ImageAttributes attrs = ImageAttributes::New(bitmap->GetImageWidth(), bitmap->GetImageHeight(), bitmap->GetPixelFormat());
-
+  mImpl->oldCompleteRequests.insert(id);
   mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, BitmapMetadata::New(bitmap)));
   mImpl->mTextureCacheDispatcher.DispatchCreateTextureForBitmap( id, bitmap );
-
-  UpdateImageTicket( id, attrs );
-  NotifyTickets();
 }
 
 void ResourceManager::HandleAddNativeImageRequest(ResourceId id, NativeImagePtr nativeImage)
@@ -326,13 +319,10 @@ void ResourceManager::HandleAddNativeImageRequest(ResourceId id, NativeImagePtr
   DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddNativeImageRequest(id:%u)\n", id);
 
-  ImageAttributes attrs = ImageAttributes::New(nativeImage->GetWidth(), nativeImage->GetHeight(), nativeImage->GetPixelFormat());
-  mImpl->newCompleteRequests.insert(id);
+  mImpl->oldCompleteRequests.insert(id);
 
   mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, BitmapMetadata::New(nativeImage)));
   mImpl->mTextureCacheDispatcher.DispatchCreateTextureForNativeImage( id, nativeImage );
-  UpdateImageTicket( id, attrs );
-  NotifyTickets();
 }
 
 void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat )
@@ -340,16 +330,13 @@ void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, unsigned
   DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddFrameBufferImageRequest(id:%u)\n", id);
 
-  // get values for dimensions and pixelformat
-  ImageAttributes attrs = ImageAttributes::New(width, height, pixelFormat);
-  mImpl->newCompleteRequests.insert(id);
+  mImpl->oldCompleteRequests.insert(id);
+
   BitmapMetadata bitmapMetadata = BitmapMetadata::New(width, height, pixelFormat);
   bitmapMetadata.SetIsFramebuffer(true);
-
   mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, bitmapMetadata));
+
   mImpl->mTextureCacheDispatcher.DispatchCreateTextureForFrameBuffer( id, width, height, pixelFormat );
-  UpdateImageTicket( id, attrs );
-  NotifyTickets();
 }
 
 void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, NativeImagePtr nativeImage )
@@ -357,28 +344,22 @@ void ResourceManager::HandleAddFrameBufferImageRequest( ResourceId id, NativeIma
   DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAddFrameBufferImageRequest(id:%u)\n", id);
 
-  // get values for dimensions and pixelformat
-  ImageAttributes attrs = ImageAttributes::New(nativeImage->GetWidth(), nativeImage->GetHeight(), nativeImage->GetPixelFormat());
-  mImpl->newCompleteRequests.insert(id);
+  mImpl->oldCompleteRequests.insert(id);
 
   BitmapMetadata bitmapMetadata = BitmapMetadata::New(nativeImage->GetWidth(), nativeImage->GetHeight(), nativeImage->GetPixelFormat());
   bitmapMetadata.SetIsNativeImage(true);
   bitmapMetadata.SetIsFramebuffer(true);
   mImpl->mBitmapMetadata.insert(BitmapMetadataPair(id, bitmapMetadata));
+
   mImpl->mTextureCacheDispatcher.DispatchCreateTextureForFrameBuffer( id, nativeImage );
-  UpdateImageTicket( id, attrs );
-  NotifyTickets();
 }
 
 void ResourceManager::HandleAllocateTextureRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat )
 {
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceManager: HandleAllocateTextureRequest(id:%u)\n", id);
 
-  mImpl->newCompleteRequests.insert(id);
-
+  mImpl->oldCompleteRequests.insert(id);
   mImpl->mTextureCacheDispatcher.DispatchCreateTexture( id, width, height, pixelFormat, true /* true = clear the texture */ );
-
-  NotifyTickets();
 }
 
 void ResourceManager::HandleUpdateTextureRequest( ResourceId id,  const BitmapUploadArray& uploadArray )