From 8dab3d03d9b87a89a608b36a3427119a46a74a50 Mon Sep 17 00:00:00 2001 From: David Steele Date: Thu, 3 Apr 2014 18:42:01 +0100 Subject: [PATCH] Added support for loading image files synchronously [Issue#] N/A [Problem] Need to load and parse 9 patch images synchronously. [Cause] N/A [Solution] Added new integration API to load directly. [Verification] Build Repo Change-Id: I17c7457ea49591f9b2e681f2bd612a2a75088c1e Signed-off-by: David Steele --- .../resource-loader/resource-bitmap-requester.cpp | 8 +++ .../resource-loader/resource-bitmap-requester.h | 5 ++ .../slp/resource-loader/resource-loader.cpp | 16 +++++ .../slp/resource-loader/resource-loader.h | 5 ++ .../resource-loader/resource-model-requester.cpp | 6 ++ .../slp/resource-loader/resource-model-requester.h | 5 ++ .../slp/resource-loader/resource-requester-base.h | 9 +++ .../resource-loader/resource-shader-requester.cpp | 6 ++ .../resource-loader/resource-shader-requester.h | 5 ++ .../resource-loader/resource-text-requester.cpp | 6 ++ .../slp/resource-loader/resource-text-requester.h | 5 ++ .../slp/resource-loader/resource-thread-image.cpp | 75 +++++++++++++++------- .../slp/resource-loader/resource-thread-image.h | 23 +++++-- .../slp/slp-platform-abstraction.cpp | 13 ++++ .../slp/slp-platform-abstraction.h | 6 ++ 15 files changed, 164 insertions(+), 29 deletions(-) diff --git a/platform-abstractions/slp/resource-loader/resource-bitmap-requester.cpp b/platform-abstractions/slp/resource-loader/resource-bitmap-requester.cpp index 8aeba48..689fdd3 100644 --- a/platform-abstractions/slp/resource-loader/resource-bitmap-requester.cpp +++ b/platform-abstractions/slp/resource-loader/resource-bitmap-requester.cpp @@ -85,10 +85,17 @@ void ResourceBitmapRequester::CancelLoad(Integration::ResourceId id, Integration mThreadDistanceField->CancelRequest(id); } +Integration::ResourcePointer ResourceBitmapRequester::LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath ) +{ + // TODO - Refactor common code out of thread + return mThreadImage->LoadResourceSynchronously( resourceType, resourcePath ); +} + void ResourceBitmapRequester::GetClosestImageSize( const std::string& filename, const ImageAttributes& attributes, Vector2 &closestSize ) { + // TODO - Refactor common code out of thread mThreadImage->GetClosestImageSize(filename, attributes, closestSize ); } @@ -96,6 +103,7 @@ void ResourceBitmapRequester::GetClosestImageSize( Integration::ResourcePointer const ImageAttributes& attributes, Vector2 &closestSize ) { + // TODO - Refactor common code out of thread mThreadImage->GetClosestImageSize(resourceBuffer, attributes, closestSize ); } diff --git a/platform-abstractions/slp/resource-loader/resource-bitmap-requester.h b/platform-abstractions/slp/resource-loader/resource-bitmap-requester.h index f5b829f..2db5e3f 100644 --- a/platform-abstractions/slp/resource-loader/resource-bitmap-requester.h +++ b/platform-abstractions/slp/resource-loader/resource-bitmap-requester.h @@ -74,6 +74,11 @@ public: virtual void CancelLoad(Integration::ResourceId id, Integration::ResourceTypeId typeId); /** + * @copydoc ResourceLoader::LoadResourceSynchronously() + */ + Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath ); + + /** * @copydoc PlatformAbstraction::GetClosestImageSize() */ void GetClosestImageSize( const std::string& filename, diff --git a/platform-abstractions/slp/resource-loader/resource-loader.cpp b/platform-abstractions/slp/resource-loader/resource-loader.cpp index 0265fcc..0abdded 100755 --- a/platform-abstractions/slp/resource-loader/resource-loader.cpp +++ b/platform-abstractions/slp/resource-loader/resource-loader.cpp @@ -194,6 +194,17 @@ struct ResourceLoader::ResourceLoaderImpl } } + ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath ) + { + ResourcePointer ptr; + ResourceRequesterBase* requester = GetRequester(resourceType.id); + if( requester ) + { + ptr = requester->LoadResourceSynchronously( resourceType, resourcePath ); + } + return ptr; + } + void SaveResource(const ResourceRequest& request) { ResourceRequesterBase* requester = GetRequester( request.GetType()->id ); @@ -462,6 +473,11 @@ void ResourceLoader::LoadResource(const ResourceRequest& request) mImpl->LoadResource(request); } +ResourcePointer ResourceLoader::LoadResourceSynchronously(const Integration::ResourceType& resourceType, const std::string& resourcePath) +{ + return mImpl->LoadResourceSynchronously( resourceType, resourcePath ); +} + void ResourceLoader::SaveResource(const ResourceRequest& request) { mImpl->SaveResource(request); diff --git a/platform-abstractions/slp/resource-loader/resource-loader.h b/platform-abstractions/slp/resource-loader/resource-loader.h index 0621c6f..d4b1f56 100644 --- a/platform-abstractions/slp/resource-loader/resource-loader.h +++ b/platform-abstractions/slp/resource-loader/resource-loader.h @@ -240,6 +240,11 @@ public: void LoadResource(const Integration::ResourceRequest& request); /** + * @copydoc PlatformAbstraction::LoadResourceSynchronously() + */ + Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath); + + /** * @copydoc PlatformAbstraction::SaveResource() */ void SaveResource(const Integration::ResourceRequest& request); diff --git a/platform-abstractions/slp/resource-loader/resource-model-requester.cpp b/platform-abstractions/slp/resource-loader/resource-model-requester.cpp index 7af7b6e..07ed413 100644 --- a/platform-abstractions/slp/resource-loader/resource-model-requester.cpp +++ b/platform-abstractions/slp/resource-loader/resource-model-requester.cpp @@ -60,6 +60,12 @@ void ResourceModelRequester::LoadResource( Integration::ResourceRequest& request mThreadModel->AddRequest(request, ResourceThreadBase::RequestLoad); } +ResourcePointer ResourceModelRequester::LoadResourceSynchronously( const Integration::ResourceType& type, const std::string& path ) +{ + DALI_ASSERT_ALWAYS( 0 && "Cannot load models synchronously" ); + return NULL; +} + LoadStatus ResourceModelRequester::LoadFurtherResources( ResourceRequest& request, LoadedResource partialResource ) { // Nothing to do diff --git a/platform-abstractions/slp/resource-loader/resource-model-requester.h b/platform-abstractions/slp/resource-loader/resource-model-requester.h index 82e24f6..a60806a 100644 --- a/platform-abstractions/slp/resource-loader/resource-model-requester.h +++ b/platform-abstractions/slp/resource-loader/resource-model-requester.h @@ -58,6 +58,11 @@ public: virtual void LoadResource( Integration::ResourceRequest& request ); /** + * @copydoc ResourceRequester::LoadResourceSynchronously() + */ + virtual Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& type, const std::string& path ); + + /** * @copydoc ResourceRequester::LoadFurtherResources() */ virtual Integration::LoadStatus LoadFurtherResources( Integration::ResourceRequest& request, LoadedResource partialResource ); diff --git a/platform-abstractions/slp/resource-loader/resource-requester-base.h b/platform-abstractions/slp/resource-loader/resource-requester-base.h index 9a0fc2e..e9fd6e9 100644 --- a/platform-abstractions/slp/resource-loader/resource-requester-base.h +++ b/platform-abstractions/slp/resource-loader/resource-requester-base.h @@ -19,6 +19,7 @@ #include #include +#include namespace Dali { @@ -64,6 +65,14 @@ public: virtual void LoadResource( Integration::ResourceRequest& request ) = 0; /** + * Load a resource synchronously. + * @param[in] type The type of resource + * @param[in] path The path to the resource + * @return A pointer to the resource + */ + virtual Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& type, const std::string& path ) = 0; + + /** * Load more resources (for partial loading) * @param[in] request The initial load request * @param[in] partialResource The resources loaded by the last request diff --git a/platform-abstractions/slp/resource-loader/resource-shader-requester.cpp b/platform-abstractions/slp/resource-loader/resource-shader-requester.cpp index 5002079..8b894ef 100644 --- a/platform-abstractions/slp/resource-loader/resource-shader-requester.cpp +++ b/platform-abstractions/slp/resource-loader/resource-shader-requester.cpp @@ -49,6 +49,12 @@ void ResourceShaderRequester::LoadResource( Integration::ResourceRequest& reques mThreadShader->AddRequest(request, ResourceThreadBase::RequestLoad); } +ResourcePointer ResourceShaderRequester::LoadResourceSynchronously( const Integration::ResourceType& type, const std::string& path ) +{ + DALI_ASSERT_ALWAYS( 0 && "Cannot load shaders synchronously" ); + return NULL; +} + Integration::LoadStatus ResourceShaderRequester::LoadFurtherResources( Integration::ResourceRequest& request, LoadedResource partialResource ) { // Nothing to do diff --git a/platform-abstractions/slp/resource-loader/resource-shader-requester.h b/platform-abstractions/slp/resource-loader/resource-shader-requester.h index bf5b430..fec1691 100644 --- a/platform-abstractions/slp/resource-loader/resource-shader-requester.h +++ b/platform-abstractions/slp/resource-loader/resource-shader-requester.h @@ -58,6 +58,11 @@ public: virtual void LoadResource( Integration::ResourceRequest& request ); /** + * @copydoc ResourceRequester::LoadResourceSynchronously() + */ + virtual Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& type, const std::string& path ); + + /** * @copydoc ResourceRequester::LoadFurtherResources() */ virtual Integration::LoadStatus LoadFurtherResources( Integration::ResourceRequest& request, LoadedResource partialResource ); diff --git a/platform-abstractions/slp/resource-loader/resource-text-requester.cpp b/platform-abstractions/slp/resource-loader/resource-text-requester.cpp index a96997e..9140c29 100644 --- a/platform-abstractions/slp/resource-loader/resource-text-requester.cpp +++ b/platform-abstractions/slp/resource-loader/resource-text-requester.cpp @@ -116,6 +116,12 @@ void ResourceTextRequester::LoadResource( Integration::ResourceRequest& request } } +ResourcePointer ResourceTextRequester::LoadResourceSynchronously( const Integration::ResourceType& type, const std::string& path ) +{ + DALI_ASSERT_ALWAYS( 0 && "Cannot load text synchronously" ); + return NULL; +} + LoadStatus ResourceTextRequester::LoadFurtherResources( ResourceRequest& request, LoadedResource partialResource ) { // nothing to do diff --git a/platform-abstractions/slp/resource-loader/resource-text-requester.h b/platform-abstractions/slp/resource-loader/resource-text-requester.h index ce3b0b8..978d766 100644 --- a/platform-abstractions/slp/resource-loader/resource-text-requester.h +++ b/platform-abstractions/slp/resource-loader/resource-text-requester.h @@ -60,6 +60,11 @@ public: virtual void LoadResource( Integration::ResourceRequest& request ); /** + * @copydoc ResourceRequester::LoadResourceSynchronously() + */ + virtual Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& type, const std::string& path ); + + /** * @copydoc ResourceRequester::LoadFurtherResources() */ virtual Integration::LoadStatus LoadFurtherResources( Integration::ResourceRequest& request, LoadedResource partialResource ); diff --git a/platform-abstractions/slp/resource-loader/resource-thread-image.cpp b/platform-abstractions/slp/resource-loader/resource-thread-image.cpp index 1820ca8..f031a4d 100755 --- a/platform-abstractions/slp/resource-loader/resource-thread-image.cpp +++ b/platform-abstractions/slp/resource-loader/resource-thread-image.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "loader-bmp.h" #include "loader-gif.h" @@ -251,6 +252,24 @@ ResourceThreadImage::~ResourceThreadImage() { } +ResourcePointer ResourceThreadImage::LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath ) +{ + ResourcePointer resource; + BitmapPtr bitmap = 0; + + FILE * const fp = fopen( resourcePath.c_str(), "rb" ); + if( fp != NULL ) + { + bool result = ConvertStreamToBitmap( resourceType, resourcePath, fp, bitmap ); + if( result && bitmap ) + { + resource.Reset(bitmap.Get()); + } + } + return resource; +} + + void ResourceThreadImage::GetClosestImageSize( const std::string& filename, const ImageAttributes& attributes, Vector2 &closestSize ) @@ -349,12 +368,20 @@ void ResourceThreadImage::Load(const ResourceRequest& request) bool file_not_found = false; BitmapPtr bitmap = 0; + bool result = false; FILE * const fp = fopen( request.GetPath().c_str(), "rb" ); if( fp != NULL ) { - bitmap = ConvertStreamToBitmap( request, fp ); - if( !bitmap ) + result = ConvertStreamToBitmap( *request.GetType(), request.GetPath(), fp, bitmap ); + if( result && bitmap ) + { + // Construct LoadedResource and ResourcePointer for image data + LoadedResource resource( request.GetId(), request.GetType()->id, ResourcePointer( bitmap.Get() ) ); + // Queue the loaded resource + mResourceLoader.AddLoadedResource( resource ); + } + else { DALI_LOG_WARNING( "Unable to decode %s\n", request.GetPath().c_str() ); } @@ -406,11 +433,19 @@ void ResourceThreadImage::Decode(const ResourceRequest& request) FILE * const fp = fmemopen(blobBytes, blobSize, "rb"); if ( fp != NULL ) { - bitmap = ConvertStreamToBitmap(request, fp); - } - if ( !bitmap ) - { - DALI_LOG_WARNING( "Unable to decode bitmap supplied as in-memory blob.\n" ); + bool result = ConvertStreamToBitmap( *request.GetType(), request.GetPath(), fp, bitmap ); + + if ( result && bitmap ) + { + // Construct LoadedResource and ResourcePointer for image data + LoadedResource resource( request.GetId(), request.GetType()->id, ResourcePointer( bitmap.Get() ) ); + // Queue the loaded resource + mResourceLoader.AddLoadedResource( resource ); + } + else + { + DALI_LOG_WARNING( "Unable to decode bitmap supplied as in-memory blob.\n" ); + } } } } @@ -430,39 +465,37 @@ void ResourceThreadImage::Save(const Integration::ResourceRequest& request) } -BitmapPtr ResourceThreadImage::ConvertStreamToBitmap(const ResourceRequest& request, FILE * const fp) +bool ResourceThreadImage::ConvertStreamToBitmap(const ResourceType& resourceType, std::string path, FILE * const fp, BitmapPtr& ptr) { DALI_LOG_TRACE_METHOD(mLogFilter); - DALI_ASSERT_DEBUG( request.GetType() && ResourceBitmap == request.GetType()->id ); + DALI_ASSERT_DEBUG( ResourceBitmap == resourceType.id ); bool result = false; BitmapPtr bitmap = 0; - std::string path = request.GetPath(); if (fp != NULL) { - // Only png, jpg, bmp, gif, and compressed-data-containing ktx files are supported. LoadBitmapFunction function; LoadBitmapHeaderFunction header; Bitmap::Profile profile; if ( GetBitmapLoaderFunctions( fp, - GetFormatHint( request.GetPath() ), + GetFormatHint( path ), function, header, profile ) ) { bitmap = Bitmap::New(profile, true); - DALI_LOG_SET_OBJECT_STRING(bitmap, request.GetPath()); - BitmapResourceType& resType = static_cast(*(request.GetType())); - ImageAttributes& attributes = resType.imageAttributes; + DALI_LOG_SET_OBJECT_STRING(bitmap, path); + const BitmapResourceType& resType = static_cast(resourceType); + ImageAttributes attributes = resType.imageAttributes; result = function(fp, *bitmap, attributes); if (!result) { - DALI_LOG_WARNING("Unable to decode %s\n", path.c_str()); + DALI_LOG_WARNING("Unable to convert %s\n", path.c_str()); bitmap = 0; } } @@ -473,14 +506,8 @@ BitmapPtr ResourceThreadImage::ConvertStreamToBitmap(const ResourceRequest& requ fclose(fp); ///! Not exception safe, but an exception on a resource thread will bring the process down anyway. } - if ( result ) - { - // Construct LoadedResource and ResourcePointer for image data - LoadedResource resource( request.GetId(), request.GetType()->id, ResourcePointer( bitmap.Get() ) ); - // Queue the loaded resource - mResourceLoader.AddLoadedResource( resource ); - } - return bitmap; + ptr.Reset( bitmap.Get() ); + return result; } diff --git a/platform-abstractions/slp/resource-loader/resource-thread-image.h b/platform-abstractions/slp/resource-loader/resource-thread-image.h index 9622189..332d1df 100644 --- a/platform-abstractions/slp/resource-loader/resource-thread-image.h +++ b/platform-abstractions/slp/resource-loader/resource-thread-image.h @@ -18,7 +18,8 @@ // #include - +#include +#include #include "resource-thread-base.h" namespace Dali @@ -50,6 +51,12 @@ public: virtual ~ResourceThreadImage(); /** + * @copydoc ResourceLoader::LoadResourceSynchronously() + * Note, this is not threaded, but is called synchronously. + */ + Integration::ResourcePointer LoadResourceSynchronously( const Integration::ResourceType& resourceType, const std::string& resourcePath ); + + /** * @copydoc ResourceLoader::GetClosestImageSize() * Note, this is not threaded, but is called synchronously. */ @@ -84,11 +91,17 @@ private: private: /** * Convert the file stream into a bitmap. - * @param[in] request + * @param[in] resourceType The type of resource to convert. + * @param[in] path The path to the resource. * @param[in] fp File Pointer. Closed on exit. - * @return Null on failure or a valid BitmapPtr on success. */ - Integration::BitmapPtr ConvertStreamToBitmap( const Integration::ResourceRequest& request, - FILE * const fp ); + * @param[out] bitmap Pointer to write bitmap to + * @return true on success, false on failure + */ + bool ConvertStreamToBitmap( const Integration::ResourceType& resourceType, + std::string path, + FILE * const fp, + Integration::BitmapPtr& ptr ); + }; // class ResourceThreadImage diff --git a/platform-abstractions/slp/slp-platform-abstraction.cpp b/platform-abstractions/slp/slp-platform-abstraction.cpp index 7aac0cc..6b39365 100644 --- a/platform-abstractions/slp/slp-platform-abstraction.cpp +++ b/platform-abstractions/slp/slp-platform-abstraction.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "resource-loader/resource-loader.h" #include "resource-loader/loader-jpeg.h" @@ -196,6 +197,18 @@ void SlpPlatformAbstraction::LoadResource(const Integration::ResourceRequest& re } } +Integration::ResourcePointer SlpPlatformAbstraction::LoadResourceSynchronously(const Integration::ResourceType& resourceType, const std::string& resourcePath) +{ + Integration::ResourcePointer resource; + + if (mResourceLoader) + { + resource = mResourceLoader->LoadResourceSynchronously( resourceType, resourcePath ); + } + return resource; +} + + void SlpPlatformAbstraction::SaveResource(const Integration::ResourceRequest& request) { if (mResourceLoader) diff --git a/platform-abstractions/slp/slp-platform-abstraction.h b/platform-abstractions/slp/slp-platform-abstraction.h index 2dc120f..a445ecb 100644 --- a/platform-abstractions/slp/slp-platform-abstraction.h +++ b/platform-abstractions/slp/slp-platform-abstraction.h @@ -18,6 +18,7 @@ // #include +#include #include #include @@ -93,6 +94,11 @@ public: // PlatformAbstraction overrides virtual void LoadResource(const Integration::ResourceRequest& request); /** + * @copydoc PlatformAbstraction::LoadResourceSynchronously() + */ + virtual Integration::ResourcePointer LoadResourceSynchronously(const Integration::ResourceType& resourceType, const std::string& resourcePath); + + /** * @copydoc PlatformAbstraction::SaveResource() */ virtual void SaveResource(const Integration::ResourceRequest& request); -- 2.7.4