SET(TC_SOURCES
utc-Dali-Internal-Core.cpp
utc-Dali-Internal-Handles.cpp
- utc-Dali-Internal-ImageFactory.cpp
utc-Dali-Internal-ResourceClient.cpp
utc-Dali-Internal-FixedSizeMemoryPool.cpp
utc-Dali-Internal-MemoryPoolObjectAllocator.cpp
+++ /dev/null
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <iostream>
-
-#include <stdlib.h>
-#include <dali/public-api/dali-core.h>
-#include <dali-test-suite-utils.h>
-
-// Internal headers are allowed here
-#include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/images/image-factory.h>
-#include <dali/internal/event/resources/resource-ticket.h>
-#include <dali/internal/common/image-attributes.h>
-
-using namespace Dali;
-
-using Internal::ResourceTicketPtr;
-using Internal::ImageFactory;
-using Internal::ImageFactoryCache::RequestPtr;
-using Internal::ImageAttributes;
-
-namespace
-{
-
-static const char* gTestImageFilename = "icon_wrt.png";
-
-static void EmulateImageLoaded( TestApplication& application, unsigned int width, unsigned int height )
-{
- // emulate load success
- Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
- Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD );
- Integration::ResourcePointer resource( bitmap );
- bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, width, height, width, height );
- if( request )
- {
- application.GetPlatform().SetResourceLoaded( request->GetId(), request->GetType()->id, resource );
- }
-
- application.SendNotification();
- application.Render();
-
- application.SendNotification();
- application.Render();
-}
-
-} //anonymous namespace
-
-
-// High-level test for image factory request cache
-int UtcDaliImageFactoryUseCachedRequest01(void)
-{
- TestApplication application;
-
- tet_infoline( "UtcDaliImageFactoryCachedRequest01 - Request same image more than once" );
-
- Image image = ResourceImage::New( gTestImageFilename );
-
- application.SendNotification();
- application.Render();
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceSynchronouslyFunc ) );
- application.GetPlatform().ResetTrace();
-
- Image image2 = ResourceImage::New( gTestImageFilename );
-
- application.SendNotification();
- application.Render();
-
- // Resource is loaded twice
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceSynchronouslyFunc ) );
- application.GetPlatform().ResetTrace();
-
- Image image3 = ResourceImage::New( gTestImageFilename );
-
- application.SendNotification();
- application.Render();
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceSynchronouslyFunc ) );
- END_TEST;
-}
-
-// High-level test for image factory request cache
-int UtcDaliImageFactoryUseCachedRequest02(void)
-{
- TestApplication application;
-
- // testing resource deletion when taken off stage
- tet_infoline( "UtcDaliImageFactoryCachedRequest02 - Discard previously requested resource" );
-
- Image image = ResourceImage::New( gTestImageFilename );
- Actor actor = CreateRenderableActor( image );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceSynchronouslyFunc ) );
- application.GetPlatform().ResetTrace();
-
- // Add actor to stage
- Stage::GetCurrent().Add( actor );
-
- application.Render();
- application.SendNotification();
- application.Render();
- application.SendNotification();
-
- // Release the resource, request is still cached
- Stage::GetCurrent().Remove( actor );
- application.Render();
- application.SendNotification();
- application.Render();
- application.SendNotification();
-
- // Should find stale request in cache, so load image from filesystem
- Image image2 = ResourceImage::New( gTestImageFilename );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceSynchronouslyFunc ) );
- application.GetPlatform().ResetTrace();
-
- // Resource is reloaded
- Image image3 = ResourceImage::New( gTestImageFilename );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- END_TEST;
-}
-
-// Low-level test for image factory request cache
-int UtcDaliImageFactoryUseCachedRequest03(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryCachedRequest03 - Request same image more than once - Request Ids" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
- DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
- DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
-
- req2 = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket3 = imageFactory.Load( *req2.Get() );
- DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
- DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
-
- // request differs in scaled size - not default size
- ImageAttributes attr = ImageAttributes::New( 80, 160);
- req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
- ResourceTicketPtr ticket4 = imageFactory.Load( *req2.Get() );
- DALI_TEST_CHECK( req != req2 );
- END_TEST;
-}
-
-// Low-level test for image factory request cache
-int UtcDaliImageFactoryUseCachedRequest04(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryCachedRequest04 - Request same image with different Image objects - Request Ids" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- ImageAttributes attr = ImageAttributes::New( 80, 160 );
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
-
- ImageAttributes attr2 = ImageAttributes::New( 80, 160 );
- RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
- DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
- END_TEST;
-}
-
-// Different requests, compatible resource
-int UtcDaliImageFactoryCompatibleResource01(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryCompatibleResource01 - Two requests mapping to same resource" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize(80.0f, 80.0f);
- application.GetPlatform().SetClosestImageSize(testSize);
-
- // request with default attributes ( size is 0,0 )
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- // emulate load success
- EmulateImageLoaded( application, 80, 80 );
-
- // Request a second load using exact-match image size:
- ImageAttributes attr = ImageAttributes::New();
- attr.SetSize( 80, 80 );
- RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
- ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
-
- DALI_TEST_CHECK( req != req2 ); // different requests
- DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
- END_TEST;
-}
-
-// Different requests, compatible resource
-int UtcDaliImageFactoryCompatibleResource02(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize( 2048.0f, 2048.0f );
- application.GetPlatform().SetClosestImageSize( testSize );
-
- // request with default attributes ( size is 0,0 )
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- // emulate load success
- EmulateImageLoaded( application, testSize.x, testSize.y );
-
- // Request slightly bigger size than actual image.
- // This will load the same resource as the ImageFactory cache uses a small fudge factor in matching.
- // See UtcDaliImageFactoryReload06
- ImageAttributes attr = ImageAttributes::New();
- attr.SetSize( testSize.x + 1, testSize.y + 1 );
- RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
- ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
-
- DALI_TEST_CHECK( req != req2 ); // different requests
- DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
- END_TEST;
-}
-
-// Different requests, incompatible resource, so two loads result:
-int UtcDaliImageFactoryInCompatibleResource(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize(2048.0f, 2048.0f);
- application.GetPlatform().SetClosestImageSize(testSize);
-
- // request with default attributes ( size is 0,0 )
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- // emulate load success
- EmulateImageLoaded( application, testSize.x, testSize.y );
-
- // Request substantially different size than actual image.
- // This will issue a second resource load as difference in sizes is greater than
- // the small fudge factor used in the ImageFactory cache.
- ImageAttributes attr = ImageAttributes::New();
- attr.SetSize( testSize.x - 16, testSize.y - 16 );
- RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
- ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
-
- DALI_TEST_CHECK( req != req2 ); // different requests
- DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // differnet resources
- END_TEST;
-}
-
-// Different requests, compatible resource
-int UtcDaliImageFactoryCompatibleResource03(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryCompatibleResource03 - Two requests mapping to same resource" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize(80.0f, 80.0f);
- application.GetPlatform().SetClosestImageSize(testSize);
-
- // this time use defined attributes, nut just NULL
- ImageAttributes attr = ImageAttributes::New();
- attr.SetSize( 120, 120 );
-
- // request with default attributes ( size is 0,0 )
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- // emulate load success
- EmulateImageLoaded( application, 80, 80 );
-
- ImageAttributes attr2 = ImageAttributes::New();
- attr2.SetSize( 80, 80 );
- RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
- ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
-
- DALI_TEST_CHECK( req != req2 ); // different requests
- DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
- END_TEST;
-}
-
-// Test for reloading image
-int UtcDaliImageFactoryReload01(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryReload01 - Reload unchanged image" );
-
- Vector2 testSize(80.0f, 80.0f);
- application.GetPlatform().SetClosestImageSize(testSize);
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
- DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
-
- ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
- DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
- END_TEST;
-}
-
-// Testing file system access when reloading image
-int UtcDaliImageFactoryReload02(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryReload02 - Reload unchanged image" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize(80.0f, 80.0f);
- application.GetPlatform().SetClosestImageSize(testSize);
-
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- application.GetPlatform().ResetTrace();
-
- ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
- // resource is still loading, do not issue another request
- DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
-
- // emulate load success
- EmulateImageLoaded( application, 80, 80 );
-
- ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- application.GetPlatform().ResetTrace();
-
- ticket3 = imageFactory.Reload( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- END_TEST;
-}
-
-// Test for reloading changed image
-int UtcDaliImageFactoryReload03(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryReload03 - Reload changed image" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize( 80.0f, 80.0f );
- application.GetPlatform().SetClosestImageSize( testSize );
-
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
-
- // emulate load success
- EmulateImageLoaded( application, 80, 80 );
-
- Vector2 newSize( 192.0f, 192.0f );
- application.GetPlatform().SetClosestImageSize( newSize );
-
- // Image file changed size, new resource request should be issued
- ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
- DALI_TEST_CHECK( ticket != ticket2 );
-
- ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
- DALI_TEST_EQUALS( ticket2, ticket3, TEST_LOCATION );
- END_TEST;
-}
-
-// Testing file system access when reloading image
-int UtcDaliImageFactoryReload04(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryReload04 - Reload unchanged image" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize(80.0f, 80.0f);
- application.GetPlatform().SetClosestImageSize(testSize);
-
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- application.GetPlatform().ResetTrace();
-
- ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
- // resource is still loading, do not issue another request
- DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
-
- // emulate load success
- EmulateImageLoaded( application, 80, 80 );
-
- ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- // size didn't change, using same ticket
- DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- application.GetPlatform().ResetTrace();
-
- // still loading
- ticket3 = imageFactory.Reload( *req.Get() );
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- END_TEST;
-}
-
-// Testing OnDemand + Reload
-// Reload should have no effect if OnDemand Image is not loaded yet, as stated in the API documentation
-int UtcDaliImageFactoryReload05(void)
-{
- TestApplication application;
-
- tet_infoline( "UtcDaliImageFactoryReload05 - Reload OnDemand image" );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize(80.0f, 80.0f);
- application.GetPlatform().SetClosestImageSize(testSize);
-
- RequestPtr req;
- ImageAttributes attr = ImageAttributes::New();
- attr.SetSize( 80, 80 );
-
- // this happens first when loading Image OnDemand
- req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
-
- application.SendNotification();
- application.Render();
-
- ResourceTicketPtr ticket = imageFactory.Reload( *req.Get() );
-
- DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- DALI_TEST_CHECK( !ticket );
-
- // this happens when Image is put on stage
- ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
-
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- DALI_TEST_CHECK( ticket );
- application.GetPlatform().ResetTrace();
-
- ticket = imageFactory.Reload( *req.Get() );
- DALI_TEST_CHECK( ticket );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- // still loading, no new request
- DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
-
- // emulate load success
- EmulateImageLoaded( application, 80, 80 );
-
- ticket = imageFactory.Reload( *req.Get() );
- DALI_TEST_CHECK( ticket );
-
- application.SendNotification();
- application.Render();
-
- application.SendNotification();
- application.Render();
-
-
- DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
- END_TEST;
-}
-
-// Initally two different requests map to same resource.
-// After overwriting the file, they load different image resources.
-int UtcDaliImageFactoryReload06(void)
-{
- TestApplication application;
- tet_infoline( "UtcDaliImageFactoryReload06 - Two requests first mapping to same resource, then different resources." );
-
- ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
-
- Vector2 testSize(2048.0f, 2048.0f);
- application.GetPlatform().SetClosestImageSize( testSize );
-
- // request with default attributes ( size is 0,0 )
- RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
- ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
-
- application.SendNotification();
- application.Render();
- application.SendNotification();
- application.Render();
-
- // emulate load success
- EmulateImageLoaded( application, testSize.x, testSize.y );
-
- // Request bigger size than actual image.
- // This will load the same resource.
- // However if image size changes later on to eg. 512*512 (file is overwritten),
- // reissuing these two requests will load different resources.
- ImageAttributes attr = ImageAttributes::New();
- attr.SetSize( testSize.x + 1, testSize.y + 1 );
- RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
- ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
-
- DALI_TEST_CHECK( req != req2 ); // different requests
- DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
-
- Vector2 newSize(512.0f, 512.0f);
- application.GetPlatform().SetClosestImageSize(newSize);
-
- // reload fixed size (192,192) request
- ticket2 = imageFactory.Reload( *req2.Get() );
-
- // emulate load success
- // note: this is the only way to emulate what size is loaded by platform abstraction
- EmulateImageLoaded( application, testSize.x + 1, testSize.y + 1 );
-
- // reload default size request
- ticket = imageFactory.Reload( *req.Get() );
-
- DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // different resources
- END_TEST;
-}
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
#include <dali/internal/event/images/image-impl.h>
-#include <dali/internal/event/images/image-factory-cache.h>
#include <dali/internal/event/resources/resource-ticket.h>
#include <dali/internal/event/resources/image-ticket.h>
sizeof( Internal::SceneGraph::Layer ) );
const int IMAGE_MEMORY_SIZE(
sizeof( Internal::Image ) +
- sizeof( Internal::ImageFactoryCache::Request ) +
sizeof( Integration::Bitmap ) +
sizeof( Internal::TextureMetadata ) +
sizeof( Internal::BitmapTexture ) +
* @sa Dali::Integration::PlatformAbstraction::LoadResource
* Dali::Integration::PlatformAbstraction::GetResources
* Dali::Integration::ResourceCache
- * Dali::Internal::ImageFactoryCache::RequestId
*/
typedef unsigned int ResourceId;
const ResourceId InvalidResourceId = (ResourceId)-1;
#include <dali/internal/event/effects/shader-factory.h>
#include <dali/internal/event/events/event-processor.h>
#include <dali/internal/event/events/gesture-event-processor.h>
-#include <dali/internal/event/images/image-factory.h>
#include <dali/internal/event/render-tasks/render-task-list-impl.h>
#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
mDiscardQueue(NULL),
mTextureUploadedQueue(),
mNotificationManager(NULL),
- mImageFactory(NULL),
mShaderFactory(NULL),
mGeometryBatcher( NULL ),
mIsActive(true),
mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
- mImageFactory = new ImageFactory( *mResourceClient );
mShaderFactory = new ShaderFactory();
mUpdateManager->SetShaderSaver( *mShaderFactory );
delete mEventProcessor;
delete mGestureEventProcessor;
delete mNotificationManager;
- delete mImageFactory;
delete mShaderFactory;
delete mResourceClient;
delete mResourceManager;
{
DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n");
- mImageFactory->RecoverFromContextLoss(); // Reload images from files
mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks
}
// Run the size negotiation after event processing finished signal
mRelayoutController->Relayout();
- // Flush discard queue for image factory
- mImageFactory->FlushReleaseQueue();
-
// Flush any queued messages for the update-thread
const bool messagesToProcess = mUpdateManager->FlushQueue();
return *(mResourceClient);
}
-ImageFactory& Core::GetImageFactory()
-{
- return *(mImageFactory);
-}
-
ShaderFactory& Core::GetShaderFactory()
{
return *(mShaderFactory);
class GestureEventProcessor;
class ResourceClient;
class ResourceManager;
-class ImageFactory;
class ShaderFactory;
class TouchResampler;
class RelayoutController;
ResourceClient& GetResourceClient();
/**
- * Returns the Image factory
- * @return A reference to the Image factory.
- */
- ImageFactory& GetImageFactory();
-
- /**
* Returns the Shader factory
* @return A reference to the Shader binary factory.
*/
NotificationManager* mNotificationManager; ///< Notification manager
AnimationPlaylistOwner mAnimationPlaylist; ///< For 'Fire and forget' animation support
OwnerPointer<PropertyNotificationManager> mPropertyNotificationManager; ///< For safe signal emmision of property changed notifications
- ImageFactory* mImageFactory; ///< Image resource factory
ShaderFactory* mShaderFactory; ///< Shader resource factory
ResourceClient* mResourceClient; ///< Asynchronous Resource Loading
ResourceManager* mResourceManager; ///< Asynchronous Resource Loading
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
return mCore->GetResourceClient();
}
-ImageFactory& ThreadLocalStorage::GetImageFactory()
-{
- return mCore->GetImageFactory();
-}
-
ShaderFactory& ThreadLocalStorage::GetShaderFactory()
{
return mCore->GetShaderFactory();
#define __DALI_INTERNAL_THREAD_LOCAL_STORAGE_H__
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
class NotificationManager;
class ResourceClient;
class ResourceManager;
-class ImageFactory;
class ShaderFactory;
class GestureEventProcessor;
class RelayoutController;
ResourceClient& GetResourceClient();
/**
- * Returns the Image Factory
- * @return reference to the Image Factory
- */
- ImageFactory& GetImageFactory();
-
- /**
* Returns the Shader Factory
* @return reference to the Shader Factory
*/
// INTERNAL INCLUDES
#include <dali/public-api/object/type-registry.h>
#include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/images/image-factory.h>
#include <dali/internal/event/images/bitmap-packed-pixel.h>
#include <dali/internal/event/resources/resource-client.h>
#include <dali/integration-api/bitmap.h>
Pixel::Format pixelFormat,
bool recoverContext )
: mResourceClient( ThreadLocalStorage::Get().GetResourceClient() ),
- mImageFactory( ThreadLocalStorage::Get().GetImageFactory() ),
mClearColor( Vector4::ZERO ),
mPixelFormat( pixelFormat ),
mClear( false ),
{
mTicket = mResourceClient.AllocateTexture( mWidth, mHeight, mPixelFormat );
mTicket->AddObserver( *this );
- mImageFactory.RegisterForContextRecovery( this );
}
}
{
mTicket.Reset();
ClearCache();
- mImageFactory.UnregisterFromContextRecovery( this );
}
void Atlas::ClearBackground(const Vector4& color )
private:
ResourceClient& mResourceClient;
- ImageFactory& mImageFactory;
Vector4 mClearColor; ///< The background clear color
Vector<Tile*> mTiles; ///< The url resources, which would recover automatically when regaining context
Pixel::Format mPixelFormat; ///< The pixel format (rgba 32 bit by default)
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/event/resources/resource-client.h>
#include <dali/internal/update/manager/update-manager.h>
-#include <dali/internal/event/images/image-factory.h>
using namespace Dali::Integration;
EncodedBufferImagePtr image( new EncodedBufferImage() );
image->Initialize(); // Second stage initialization
- // Replicate the functionality of ImageFactory::load() without the filesystem caching:
Dali::Integration::BitmapResourceType resourceType( size, fittingMode, samplingMode, orientationCorrection );
RequestBufferPtr buffer( new RequestBuffer );
buffer->GetVector().Resize( encodedImageByteCount );
+++ /dev/null
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/event/images/image-connector.h>
-
-// INTERNAL INCLUDES
-#include <dali/public-api/common/dali-common.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-ImageConnector::ImageConnector()
-: mImage(NULL)
-{
-}
-
-ImageConnector::~ImageConnector()
-{
-}
-
-ImagePtr ImageConnector::Get() const
-{
- return mImage;
-}
-
-void ImageConnector::Set( ImagePtr image, bool onStage )
-{
- if ( mImage != image )
- {
- // Disconnect from old image
- if ( mImage && onStage )
- {
- mImage->Disconnect();
- }
-
- mImage = image;
-
- // Connect to new image
- if ( mImage && onStage )
- {
- mImage->Connect();
- }
- }
-}
-
-void ImageConnector::OnStageConnect()
-{
- if ( mImage )
- {
- mImage->Connect();
- }
-}
-
-void ImageConnector::OnStageDisconnect()
-{
- if ( mImage )
- {
- mImage->Disconnect();
- }
-}
-
-} // namespace Internal
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_INTERNAL_IMAGE_CONNECTOR_H__
-#define __DALI_INTERNAL_IMAGE_CONNECTOR_H__
-
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// EXTERNAL INCLUDES
-#include <string>
-
-// INTERNAL INCLUDES
-#include <dali/internal/event/images/image-impl.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-/**
- * Wrapper class which helps managing intrusive pointer assignments and Connect / Disconnect.
- */
-class ImageConnector
-{
-
-public:
- /**
- * Constructor. Takes no parameters.
- */
- ImageConnector();
-
- /**
- * Destructor.
- */
- ~ImageConnector();
-
- /**
- * Returns a smart pointer to the image
- * @return a smart pointer to the image
- */
- ImagePtr Get() const;
-
- /**
- * Assigns image, calling Connect and Disconnect methods accordingly, taking onStage into account.
- * @param [in] image smart pointer to new Image
- * @param [in] onStage whether Image is used on stage or not
- */
- void Set( ImagePtr image, bool onStage );
-
- /**
- * Manages connection reference count.
- * Must be called from owner when connected to stage.
- */
- void OnStageConnect();
-
- /**
- * Manages connection reference count.
- * Must be called from owner when disconnecting from stage.
- */
- void OnStageDisconnect();
-
-private:
-
- ImageConnector( const ImageConnector& ptr ); ///< copy constructor, not defined
- const ImageConnector& operator=( const ImageConnector& ptr ); ///< copy assignment operator, not defined
-
- ImagePtr mImage; ///< intrusive pointer to the Image. ImageConnector owns this.
-
-};
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_IMAGE_CONNECTOR_H__
+++ /dev/null
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/event/images/image-factory-cache.h>
-
-// INTERNAL INCLUDES
-#include <dali/public-api/common/dali-common.h>
-#include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/common/stage-impl.h>
-#include <dali/internal/event/images/image-factory.h>
-
-// EXTERNAL INCLUDES
-
-
-using namespace Dali::Internal::ImageFactoryCache;
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace ImageFactoryCache
-{
- Request::Request( RequestLifetimeObserver& observer,
- RequestId reqId,
- ResourceId resId,
- const std::string& path,
- const ImageAttributes* attr )
- : resourceId( resId ),
- url( path ),
- mId( reqId ),
- mLifetimeObserver( &observer )
- {
- if( attr )
- {
- attributes = new ImageAttributes( *attr );
- }
- else
- {
- attributes = NULL;
- }
- }
-
- Request::~Request()
- {
- if( Stage::IsInstalled() && mLifetimeObserver )
- {
- mLifetimeObserver->RequestDiscarded( *this );
- }
- delete attributes;
- }
-
- RequestId Request::GetId() const
- {
- return mId;
- }
-
- void Request::StopLifetimeObservation()
- {
- mLifetimeObserver = NULL;
- }
-
-} // namespace ImageFactoryCache
-
-} // namespace Internal
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_INTERNAL_IMAGE_FACTORY_CACHE_H__
-#define __DALI_INTERNAL_IMAGE_FACTORY_CACHE_H__
-
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/public-api/common/dali-common.h>
-#include <dali/internal/event/resources/resource-client.h>
-#include <dali/internal/common/image-attributes.h>
-
-// EXTERNAL INCLUDES
-
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-namespace ImageFactoryCache
-{
-
-/**
- * Request contains information about requests made when loading image resources.
- */
-struct Request;
-
-/**
- * @brief Unique ID for image resource requests.
- *
- * Images are loaded from a string locator (typically a file path) using a set
- * of ImageAttributes. Each unique pair of string and attributes is mapped to a
- * unique RequestId value. This ensures multiple Image objects loading the same
- * image file with the same attributes only generate one resource request and
- * Core only issues one IO operation to Adaptor to do the load.
- *
- * @sa Dali::Integration::ResourceId
- */
-typedef unsigned int RequestId;
-
-typedef std::multimap<size_t, RequestId> RequestPathHashMap;
-typedef std::pair<size_t, RequestId> RequestPathHashPair;
-typedef std::map<RequestId, Request*> RequestIdMap;
-typedef std::pair<RequestId, Request*> RequestIdPair;
-
-typedef IntrusivePtr<Request> RequestPtr;
-
-/**
- * The RequestLifetimeObserver observes the lifetime of image requests.
- */
-class RequestLifetimeObserver
-{
-public:
-
- /**
- * Called when an image request is discarded.
- * This occurs during the ImageFactoryCache::Request destructor.
- * @param[in] request The discarded request.
- */
- virtual void RequestDiscarded( const Request& request ) = 0;
-};
-
-/**
-* Request is a reference counted object to control the lifetime of elements in ImageFactory's cache.
-* When no more Image objects reference a request, it gets removed from ImageFactory cache.
-*/
-struct Request : public RefObject
-{
- /**
- * Image request.
- * These requests are stored in ImageFactory's cache.
- * @param [in] observer The object which observes request lifetime.
- * @param [in] reqId A unique ID for this request.
- * @param [ib] resId A unique ticket ID.
- * @param [in] path Url of request.
- * @param [in] attr Requested ImageAttributes.
- */
- Request( RequestLifetimeObserver& observer, RequestId reqId, ResourceId resId, const std::string& path, const ImageAttributes *attr );
-
- ResourceId resourceId; ///< The Ticket ID. This can be used to acquire details of the loaded resource from ResourceClient.
- const std::string url; ///< Path to the image resource
- ImageAttributes* attributes; ///< ImageAttributes that were used
-
-public:
- /**
- * Retrieve the unique ID of this request.
- * @return The unique ID for this request.
- */
- RequestId GetId() const;
-
- /**
- * Called when the RequestLifetimeObserver is being destroyed.
- * This method should only be called during destruction of the Dali core.
- */
- void StopLifetimeObservation();
-
-protected:
- virtual ~Request();
-
-private:
- Request(); ///< not defined
- Request(const Request& rhs); ///< not defined
- Request& operator=(const Request& rhs); ///< not defined
-
-private:
- RequestId mId; ///< Request id assigned by ImageFactory
- RequestLifetimeObserver* mLifetimeObserver; ///< reference to the lifetime-observer; not owned
-};
-
-typedef std::pair<RequestPathHashMap::iterator, RequestPathHashMap::iterator> RequestPathHashRange;
-
-} // namespace ImageFactoryCache
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_IMAGE_FACTORY_CACHE_H__
-
+++ /dev/null
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali/internal/event/images/image-factory.h>
-
-// INTERNAL INCLUDES
-#include <dali/integration-api/debug.h>
-#include <dali/integration-api/platform-abstraction.h>
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/common/constants.h>
-#include <dali/devel-api/common/hash.h>
-#include <dali/public-api/images/resource-image.h>
-#include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/common/notification-manager.h>
-#include <dali/internal/event/resources/resource-client.h>
-#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/common/image-attributes.h>
-
-// EXTERNAL INCLUDES
-#include <float.h>
-
-using namespace Dali::Integration;
-using namespace Dali::Internal::ImageFactoryCache;
-
-namespace Dali
-{
-
-namespace Internal
-{
-
-ImageFactory::ImageFactory( ResourceClient& resourceClient )
-: mResourceClient(resourceClient),
- mMaxScale( 4 / 1024.0f ), ///< Only allow a very tiny fudge factor in matching new requests to existing resource transactions: 4 pixels at a dimension of 1024, 2 at 512, ...
- mReqIdCurrent(0)
-{
-}
-
-ImageFactory::~ImageFactory()
-{
- // Request memory is freed up by intrusive_ptr
-
- mRequestCache.clear();
-}
-
-Request* ImageFactory::RegisterRequest( const std::string &filename, const ImageAttributes *attr )
-{
- // check url cache
- // check if same request exists
- std::size_t urlHash = CalculateHash( filename );
-
- Request* foundReq( NULL );
- foundReq = FindRequest( filename, urlHash, attr );
-
- if( !foundReq )
- {
- // the same request hasn't been made before
- foundReq = InsertNewRequest( 0, filename, urlHash, attr );
- }
-
- return foundReq;
-}
-
-ResourceTicketPtr ImageFactory::Load( Request& request )
-{
- ResourceTicketPtr ticket;
-
- // See if any resource transaction has already been associated with this request:
- const ResourceId resId = request.resourceId;
- if( resId != 0 )
- {
- // An IO operation has been started at some time for the request so recover the
- // ticket that was created for that:
- ticket = mResourceClient.RequestResourceTicket( resId ); ///@note Always succeeds in normal use.
- }
- else
- {
- // Request not yet associated with a ticketed async resource transaction, so
- // attempt to find a compatible cached one:
- const std::size_t urlHash = GetHashForCachedRequest( request );
- ticket = FindCompatibleResource( request.url, urlHash, request.attributes );
- }
-
- // Start a new resource IO transaction for the request if none is already happening:
- if( !ticket )
- {
- ticket = IssueLoadRequest( request.url, request.attributes );
- }
- request.resourceId = ticket->GetId();
-
- DALI_ASSERT_DEBUG( ticket->GetTypePath().type->id == ResourceBitmap ||
- ticket->GetTypePath().type->id == ResourceNativeImage ||
- ticket->GetTypePath().type->id == ResourceTargetImage );
- return ticket;
-}
-
-// File can change on fs, but still requesting same attributes.
-// Returning the ticket is important, because if two different requests mapped to the same resource
-// before, it is not guaranteed that they will still map to the same resource after reloading.
-// Example:
-// Image size (40, 40), Req1(img, 40, 40), Req2(img, 256, 256)
-// In this case both requests will be associated with the resource of size (40, 40)
-// If image changes on filesystem to size (96, 96) -> now after reloading Req2 would load a
-// new resource of size (96, 96), but reloading Req1 would load a scaled down version
-ResourceTicketPtr ImageFactory::Reload( Request& request )
-{
- // go through requests, check real size and attributes again. If different, update related ticket.
- ResourceTicketPtr ticket;
-
- if( !request.resourceId )
- {
- // in case of OnDemand loading, just return
- return NULL;
- }
-
- ticket = mResourceClient.RequestResourceTicket( request.resourceId );
-
- // ticket might have been deleted, eg. Image::Disconnect
- if( !ticket )
- {
- ticket = IssueLoadRequest( request.url, request.attributes );
- request.resourceId = ticket->GetId();
- }
- else // ticket still alive
- {
- DALI_ASSERT_DEBUG( ticket->GetTypePath().type->id == ResourceBitmap ||
- ticket->GetTypePath().type->id == ResourceNativeImage ||
- ticket->GetTypePath().type->id == ResourceTargetImage );
-
- // do not reload if still loading
- if ( ticket->GetLoadingState() == ResourceLoading )
- {
- return ticket;
- }
-
- ImageDimensions closestSize;
- if( request.attributes )
- {
- closestSize = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().
- GetClosestImageSize( request.url, ImageDimensions( request.attributes->GetSize().width, request.attributes->GetSize().width ),
- request.attributes->GetScalingMode(), request.attributes->GetFilterMode(), request.attributes->GetOrientationCorrection() );
- }
- else
- {
- closestSize = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction().GetClosestImageSize( request.url );
- }
- Vector2 size( closestSize.GetX(), closestSize.GetY() );
-
- const ImageAttributes& attrib = static_cast<ImageTicket*>(ticket.Get())->GetAttributes();
-
- if( size == attrib.GetSize() )
- {
- mResourceClient.ReloadResource( ticket->GetId(), false );
- }
- else
- {
- // if not, return a different ticket
- ticket = IssueLoadRequest( request.url, request.attributes );
- request.resourceId = ticket->GetId();
- }
- }
- return ticket;
-}
-
-void ImageFactory::RecoverFromContextLoss()
-{
- for( RequestIdMap::iterator it = mRequestCache.begin(); it != mRequestCache.end(); ++it )
- {
- // go through requests, reload with resource ticket's attributes.
- Request* request = (*it).second;
- if( request->resourceId )
- {
- ResourceTicketPtr ticket = mResourceClient.RequestResourceTicket( request->resourceId );
-
- // do not reload if still loading
- // check ticket is not NULL as the resource could have already been destroyed
- if ( ticket && ticket->GetLoadingState() != ResourceLoading )
- {
- // Ensure the finished status is reset
- mResourceClient.ReloadResource( ticket->GetId(), true );
- }
- }
- }
-
- Vector< ContextRecoveryInterface* >::ConstIterator end = mContextRecoveryList.End();
- for( Vector< ContextRecoveryInterface* >::Iterator iter = mContextRecoveryList.Begin();
- iter != end; iter++)
- {
- (*iter)->RecoverFromContextLoss();
- }
-}
-
-
-void ImageFactory::RegisterForContextRecovery( ContextRecoveryInterface* object )
-{
- bool exist( false );
- // To avoid registering the same object again
- Vector< ContextRecoveryInterface* >::ConstIterator end = mContextRecoveryList.End();
- for( Vector< ContextRecoveryInterface* >::Iterator iter = mContextRecoveryList.Begin();
- iter != end; iter++)
- {
- if( object == *(iter) )
- {
- exist = true;
- break;
- }
- }
- if( !exist )
- {
- mContextRecoveryList.PushBack( object );
- }
-}
-void ImageFactory::UnregisterFromContextRecovery( ContextRecoveryInterface* object )
-{
- Vector< ContextRecoveryInterface* >::ConstIterator end = mContextRecoveryList.End();
- for( Vector< ContextRecoveryInterface* >::Iterator iter = mContextRecoveryList.Begin();
- iter != end; iter++ )
- {
- if( object == *(iter) )
- {
- iter = mContextRecoveryList.Erase( iter );
- break;
- }
- }
-}
-
-const std::string& ImageFactory::GetRequestPath( const ImageFactoryCache::RequestPtr& request ) const
-{
- if( request )
- {
- return request->url;
- }
-
- // Only create empty string if required
- static std::string empty;
- return empty;
-}
-
-const ImageAttributes& ImageFactory::GetActualAttributes( const ResourceTicketPtr& ticket ) const
-{
- if( ticket )
- {
- DALI_ASSERT_DEBUG( ticket->GetTypePath().type->id == ResourceBitmap ||
- ticket->GetTypePath().type->id == ResourceNativeImage ||
- ticket->GetTypePath().type->id == ResourceTargetImage );
- const ImageAttributes& attrib = static_cast<ImageTicket*>(ticket.Get())->GetAttributes();
- return attrib;
- }
- return ImageAttributes::DEFAULT_ATTRIBUTES;
-}
-
-const ImageAttributes& ImageFactory::GetRequestAttributes( const ImageFactoryCache::RequestPtr& request ) const
-{
- if( request && request->attributes )
- {
- return *(request->attributes);
- }
-
- return ImageAttributes::DEFAULT_ATTRIBUTES;
-}
-
-void ImageFactory::GetImageSize( const ImageFactoryCache::RequestPtr& request, const ResourceTicketPtr& ticket, Size& size )
-{
- if( ticket && ticket->GetLoadingState() != ResourceLoading )
- {
- // it is loaded so get the size from actual attributes
- size = GetActualAttributes( ticket ).GetSize();
- }
- else
- {
- // not loaded so either loading or not yet loaded, ask platform abstraction
- Integration::PlatformAbstraction& platformAbstraction = Internal::ThreadLocalStorage::Get().GetPlatformAbstraction();
-
- const ImageAttributes& attributes = GetRequestAttributes( request );
- const ImageDimensions closestSize = platformAbstraction.GetClosestImageSize( GetRequestPath( request ),
- ImageDimensions( attributes.GetSize().width, attributes.GetSize().width ),
- attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() );
- size[0] = closestSize.GetX();
- size[1] = closestSize.GetY();
- }
-}
-
-void ImageFactory::ReleaseTicket( ResourceTicket* ticket )
-{
- ResourceTicketPtr ticketPtr(ticket);
- mTicketsToRelease.push_back(ticketPtr);
-}
-
-void ImageFactory::FlushReleaseQueue()
-{
- mTicketsToRelease.clear();
-}
-
-bool ImageFactory::CompareAttributes( const ImageAttributes& requested,
- const ImageAttributes& actual ) const
-{
- // do not load image resource again if there is a similar resource loaded:
- // see explanation in image.h of what is deemed compatible
- return (requested.GetScalingMode() == actual.GetScalingMode()) &&
- (
- (requested.GetFilterMode() == actual.GetFilterMode()) ||
- (requested.GetFilterMode() == SamplingMode::DONT_CARE)
- ) &&
- (fabsf(static_cast<float>(requested.GetWidth()) - static_cast<float>(actual.GetWidth())) <= actual.GetWidth() * mMaxScale) &&
- (fabsf(static_cast<float>(requested.GetHeight()) - static_cast<float>(actual.GetHeight())) <= actual.GetHeight() * mMaxScale);
-}
-
-Request* ImageFactory::InsertNewRequest( ResourceId resourceId, const std::string& filename, std::size_t urlHash, const ImageAttributes* attr )
-{
- ++mReqIdCurrent;
- Request* request = new Request( *this, mReqIdCurrent, resourceId, filename, attr );
- mRequestCache.insert( RequestIdPair( mReqIdCurrent, request ) );
- mUrlCache.insert( RequestPathHashPair( urlHash, mReqIdCurrent ) );
- return request;
-}
-
-Request* ImageFactory::FindRequest( const std::string& filename, size_t hash, const ImageAttributes* attributes )
-{
- // Search for a matching resource
-
- // check whether the url has been used before
- RequestPathHashRange foundRequests = mUrlCache.equal_range( hash );
-
- // look for exact matches first
- for( RequestPathHashMap::iterator it = foundRequests.first; it != foundRequests.second; ++it )
- {
- RequestId cachedReqId = it->second;
-
- // get cached request
- RequestIdMap::iterator foundRequestIter = mRequestCache.find( cachedReqId );
- DALI_ASSERT_DEBUG( foundRequestIter != mRequestCache.end() && "Only requests that are live in mRequestCache should appear in mUrlCache which is an index to speed-up lookups into it.");
- if( foundRequestIter != mRequestCache.end() )
- {
- const Request& cachedRequest = *(foundRequestIter->second);
- const ImageAttributes* storedAttributes = cachedRequest.attributes;
-
- // compare attributes: NULL means default attributes
- if( !attributes )
- {
- attributes = &ImageAttributes::DEFAULT_ATTRIBUTES;
- }
- if( !storedAttributes )
- {
- storedAttributes = &ImageAttributes::DEFAULT_ATTRIBUTES;
- }
-
- if( *attributes != *storedAttributes )
- {
- continue;
- }
-
- if( filename.compare( cachedRequest.url ) )
- {
- // hash collision, filenames don't match
- continue;
- }
-
- // we've found an exact match
- return foundRequestIter->second;
- }
- }
-
- return NULL;
-}
-
-ResourceTicketPtr ImageFactory::FindCompatibleResource( const std::string& filename, size_t hash, const ImageAttributes* attr )
-{
- ResourceTicketPtr ticket;
- // check whether the url has been used before
- RequestPathHashRange foundRequests = mUrlCache.equal_range( hash );
-
- bool foundCompatible = false;
- if( foundRequests.first != mUrlCache.end() )
- {
- // check if we have a compatible resource already loaded
- for( RequestPathHashMap::iterator it = foundRequests.first; it != foundRequests.second; ++it )
- {
- RequestId cachedReqId = it->second;
-
- // get cached request
- RequestIdMap::iterator foundRequestIter = mRequestCache.find( cachedReqId );
- DALI_ASSERT_DEBUG( foundRequestIter != mRequestCache.end() );
- if( foundRequestIter != mRequestCache.end() )
- {
- Request& cachedRequest = *(foundRequestIter->second);
- if( filename.compare( cachedRequest.url ) )
- {
- // hash collision, filenames don't match
- continue;
- }
-
- if( !cachedRequest.resourceId )
- {
- continue;
- }
-
- ticket = mResourceClient.RequestResourceTicket( cachedRequest.resourceId );
- if( !ticket )
- {
- cachedRequest.resourceId = 0;
- continue;
- }
-
- DALI_ASSERT_DEBUG( ticket->GetTypePath().type->id == ResourceBitmap ||
- ticket->GetTypePath().type->id == ResourceNativeImage ||
- ticket->GetTypePath().type->id == ResourceTargetImage );
-
- // check for compatible ImageAttributes
- const ImageAttributes& storedAttributes = static_cast<ImageTicket*>(ticket.Get())->GetAttributes();
- if( !attr )
- {
- attr = &ImageAttributes::DEFAULT_ATTRIBUTES;
- }
-
- // in case both attributes are default or they are matching custom ones
- if( CompareAttributes( *attr, storedAttributes ) )
- {
- // found compatible resource
- foundCompatible = true;
- break;
- }
- }
- } // for( it ...
- } // foundRequests.first
-
- if( !foundCompatible )
- {
- ticket.Reset();
- }
-
- return ticket;
-}
-
-ResourceTicketPtr ImageFactory::IssueLoadRequest( const std::string& filename, const ImageAttributes* attr )
-{
- ImageDimensions dimensions;
- FittingMode::Type fittingMode = FittingMode::DEFAULT;
- SamplingMode::Type samplingMode = SamplingMode::DEFAULT;
- bool orientation = true;
-
- if( attr )
- {
- dimensions = ImageDimensions::FromFloatVec2( attr->GetSize() );
- fittingMode = attr->GetScalingMode();
- samplingMode = attr->GetFilterMode();
- orientation = attr->GetOrientationCorrection();
- }
- else
- {
- // query image size from file if NULL was provided
- dimensions = Dali::ResourceImage::GetImageSize( filename );
- ///@ToDo: This is weird and pointless: we introduce a synchronous load of the image header on the event thread here to learn the image's on-disk dimensions to pass on to the resource system,
- /// but the default behaviour of the resource system when no dimensions are provided is to use exactly these on-disk dimensions when it eventually does the full load and decode.
- }
-
- BitmapResourceType resourceType( dimensions, fittingMode, samplingMode, orientation );
- ResourceTicketPtr ticket = mResourceClient.RequestResource( resourceType, filename );
- return ticket;
-}
-
-void ImageFactory::RequestDiscarded( const Request& req )
-{
- RequestId id( req.GetId() );
- // find in mRequestCache
- RequestIdMap::iterator foundRequestIter = mRequestCache.find( id );
- DALI_ASSERT_DEBUG( foundRequestIter != mRequestCache.end() );
-
- // memory is freed up by intrusive_ptr
-
- mRequestCache.erase( foundRequestIter );
-
- // find in mUrlCache
- for( RequestPathHashMap::iterator it = mUrlCache.begin(); it != mUrlCache.end(); ++it )
- {
- if( id == it->second )
- {
- mUrlCache.erase( it );
- break;
- }
- }
-}
-
-std::size_t ImageFactory::GetHashForCachedRequest( const Request& request )
-{
- const RequestId requestId = request.GetId();
- std::size_t locatorHash(0);
- RequestPathHashMap::const_iterator it;
-
- for( it = mUrlCache.begin(); it != mUrlCache.end(); ++it )
- {
- if( it->second == requestId )
- {
- locatorHash = it->first;
- break;
- }
- }
- DALI_ASSERT_DEBUG( it!=mUrlCache.end() && "Only already-cached requests can have their locator hashes looked-up." );
- return locatorHash;
-}
-
-} // namespace Internal
-
-} // namespace Dali
+++ /dev/null
-#ifndef __DALI_INTERNAL_IMAGE_FACTORY_H__
-#define __DALI_INTERNAL_IMAGE_FACTORY_H__
-
-/*
- * Copyright (c) 2014 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include <dali/public-api/common/dali-vector.h>
-#include <dali/internal/event/resources/resource-ticket.h>
-#include <dali/internal/event/images/context-recovery-interface.h>
-#include <dali/internal/event/images/image-factory-cache.h>
-
-namespace Dali
-{
-
-namespace Internal
-{
-class ResourceType;
-
-namespace ImageFactoryCache
-{
-struct 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 necessary.
- */
-class ImageFactory : public ImageFactoryCache::RequestLifetimeObserver
-{
-public:
-
- /**
- * default constructor
- */
- ImageFactory( ResourceClient& resourceClient );
-
- /**
- * Default destructor
- */
- virtual ~ImageFactory();
-
- /**
- * Registers a request for an image resource if not yet available, but does not start loading yet.
- * Use Load( req ) to issue load request.
- * If image was already requested, an existing request is returned.
- * @param [in] filename path of requested image resource
- * @param [in] attributes pointer to the ImageAttributes of the request. If NULL, default attributes are used.
- * @return request pointer
- */
- ImageFactoryCache::Request* RegisterRequest( const std::string& filename, const ImageAttributes *attributes );
-
- /**
- * Issue a request which has already been registered with ImageFactory.
- * If the associated Ticket is no longer alive ImageFactory issues a resource load request.
- * @param [in] request Request to be loaded.
- * @return intrusive pointer to image ticket. If Load fails, returned pointer is invalid. (!ret)
- */
- ResourceTicketPtr Load( ImageFactoryCache::Request& request );
-
- /**
- * Tells ResourceManager to reload image from filesystem.
- * Also sends message to render thread.
- * This operation uses the originally requested attributes when reloading the image.
- * @pre req must be registered with ImageFactory
- * @note if image is still loading, no new load request will be issued
- * @param[in] request Request to be reloaded.
- * @return the ResourceTicket mapped to the request
- */
- ResourceTicketPtr Reload( ImageFactoryCache::Request& request );
-
- /**
- * Ensures all filesystem images are reloaded into textures.
- * This operation uses the originally requested attributes when reloading the image.
- *
- * Recovering from context loss does not change the number of tickets if the
- * image size has changed on the file system since the last load/reload.
- *
- * If two different requests mapped to the same resource before, they will still
- * map to the same resource after context regain even if there would be a better
- * fitting texture.
- * @pre requests must be registered with ImageFactory
- * @note If an image is still loading, no new load request will be issued.
- */
- void RecoverFromContextLoss();
-
- /**
- * Register an object into the context recovery list of the image factory.
- * Thus its RecoverFromContextLoss() function would be called when the Stage regaining context.
- * @param[in] object The object whose RecoverFromContextLoss() function needs to be called to regain the context.
- */
- void RegisterForContextRecovery( ContextRecoveryInterface* object );
-
- /**
- * Unregister an object from the context recovery list of the image factory
- * @param[in] object The object whose RecoverFromContextLoss() function needs to be called to regain the context.
- */
- void UnregisterFromContextRecovery( ContextRecoveryInterface* object );
-
- /**
- * Get resource path used in request.
- * @param [in] request of the image
- * @return resource path
- */
- const std::string& GetRequestPath( const ImageFactoryCache::RequestPtr& request ) const;
-
- /**
- * Get ImageAttributes for an already requested image resource.
- * @pre id should mark an existing Resource (Ticket is alive)
- * @param [in] ticket of the image
- * @return ImageAttributes used for request.
- * @throws Throws exception if id is not valid.
- */
- const ImageAttributes& GetActualAttributes( const ResourceTicketPtr& ticket ) const;
-
- /**
- * Get ImageAttributes used for request.
- * @pre req must point to a Request registered with ImageFactory
- * @param [in] request of the image
- * @return ImageAttributes used for request.
- */
- const ImageAttributes& GetRequestAttributes( const ImageFactoryCache::RequestPtr& request ) const;
-
- /**
- * Retrieve the size of an image. This is either the application requested size or
- * the actual (full size) that is or will be loaded.
- * @param[in] request of the image
- * @param[in] ticket of the image
- * @param[out] size of the image
- */
- void GetImageSize( const ImageFactoryCache::RequestPtr& request, const ResourceTicketPtr& ticket, Size& size );
-
- /**
- * Prevents releasing and reloading image resources in the same frame
- * @param [in] ticket the resource ticket to queue for releasing
- */
- void ReleaseTicket( ResourceTicket* ticket );
-
- /**
- * Flush the queue of resource tickets that were about to be relased.
- * This discards the kept ticket handles at the end of each frame, and this way prevents
- * releasing and reloading image resources in the same frame.
- */
- void FlushReleaseQueue();
-
-public: // From RequestLifetimeObserver
-
- /**
- * Finds request by id in mRequestCache and mUrlCache and removes relevant entries.
- * @param [in] id request id
- */
- virtual void RequestDiscarded( const ImageFactoryCache::Request& request );
-
-private:
-
- // Undefined
- ImageFactory( const ImageFactory& );
-
- // Undefined
- ImageFactory& operator=( const ImageFactory& rhs );
-
- /**
- * Checks if the previously loaded image's attributes are compatible with a new request
- * @param [in] requested The requested attributes
- * @param [in] actual The actual attributes
- * @return True if the attributes are compatible
- */
- bool CompareAttributes( const ImageAttributes& requested,
- const ImageAttributes& actual ) const;
-
- /**
- * Inserts a new request to the request cache and url cache.
- * @note this method increases the current request Id counter (mReqIdCurrent)
- * @param [in] resourceId Ticket id to insert.
- * @param [in] url The requested url to insert.
- * @param [in] urlHash Calculated hash value for the url.
- * @param [in] attr Pointer to the requested attributes, NULL if default values are used.
- * @return pointer to Request
- */
- ImageFactoryCache::Request* InsertNewRequest( ResourceId resourceId, const std::string& url, std::size_t urlHash, const ImageAttributes* attr );
-
- /**
- * Searches request cache for exact match.
- * @param [in] filename The url of the image resource.
- * @param [in] hash Hash value for the filename.
- * @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.
- */
- ImageFactoryCache::Request* FindRequest( const std::string& filename, size_t hash, const ImageAttributes *attributes );
-
- /**
- * Searches through tickets to find a compatible resource.
- * @param [in] filename The url of the image resource.
- * @param [in] hash Hash value for the filename.
- * @param [in] attributes Pointer to ImageAttributes used for the request or NULL if default attributes were used.
- * @return A ticket pointer to the found resource or an unitialized pointer if no compatible one is found.
- */
- ResourceTicketPtr FindCompatibleResource( const std::string& filename, size_t hash, const ImageAttributes* attributes );
-
- /**
- * Helper function that requests the image resource from platform abstraction.
- * @param [in] filename The url of the image resource.
- * @param [in] attributes Pointer to ImageAttributes to be used for the request or NULL if default attributes are used.
- * @return intrusive pointer to Ticket
- */
- ResourceTicketPtr IssueLoadRequest( const std::string& filename, const ImageAttributes* attributes );
-
- /**
- * Looks-up the hash of the string locator of the already-registered Request
- * passed in.
- * @param[in] request The image load request to return a locator string hash for.
- * @return The hash of the locator string used in the request.
- */
- std::size_t GetHashForCachedRequest( const ImageFactoryCache::Request& request );
-
-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
- Vector<ContextRecoveryInterface*> mContextRecoveryList; ///< List of the objects who needs context recovery
- float mMaxScale; ///< Defines maximum size difference between compatible resources
- ImageFactoryCache::RequestId mReqIdCurrent; ///< Internal counter for Request IDs
-};
-
-} // namespace Internal
-
-} // namespace Dali
-
-#endif // __DALI_INTERNAL_IMAGE_FACTORY_H__
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/event/resources/resource-client.h>
#include <dali/internal/update/manager/update-manager.h>
-#include <dali/internal/event/images/image-factory.h>
#include <dali/integration-api/platform-abstraction.h>
#include <dali/integration-api/resource-types.h>
#include <dali/integration-api/resource-cache.h>
// INTERNAL INCLUDES
#include <dali/public-api/images/resource-image.h>
#include <dali/internal/event/images/image-impl.h>
-#include <dali/internal/event/images/image-factory-cache.h>
#include <dali/integration-api/debug.h> // For DALI_LOG_OBJECT_STRING_DECLARATION
namespace Dali
#include <dali/internal/event/common/connectable.h> // Dali::Internal::Connectable
#include <dali/internal/event/common/object-connector.h> // Dali::Internal::ObjectConnector
#include <dali/internal/event/common/object-impl.h> // Dali::Internal::Object
-#include <dali/internal/event/images/image-connector.h> // Dali::Internal::ImageConnector
namespace Dali
{
#include <dali/internal/event/common/object-connector.h> // Dali::Internal::ObjectConnector
#include <dali/internal/event/common/object-impl.h> // Dali::Internal::Object
#include <dali/internal/event/common/property-buffer-impl.h> // Dali::Internal::PropertyBuffer
+#include <dali/internal/event/images/image-impl.h> // Dali::Internal::Image
#include <dali/internal/event/rendering/sampler-impl.h> // Dali::Internal::Sampler
#include <dali/internal/event/rendering/texture-impl.h> // Dali::Internal::Texture
#include <dali/internal/event/rendering/shader-impl.h> // Dali::Internal::Shader
$(internal_src_dir)/event/images/buffer-image-impl.cpp \
$(internal_src_dir)/event/images/frame-buffer-image-impl.cpp \
$(internal_src_dir)/event/images/encoded-buffer-image-impl.cpp \
- $(internal_src_dir)/event/images/image-connector.cpp \
- $(internal_src_dir)/event/images/image-factory.cpp \
- $(internal_src_dir)/event/images/image-factory-cache.cpp \
$(internal_src_dir)/event/images/nine-patch-image-impl.cpp \
$(internal_src_dir)/event/images/resource-image-impl.cpp \
$(internal_src_dir)/event/images/native-image-impl.cpp \