From: Agnelo Vaz Date: Tue, 7 Nov 2017 14:38:55 +0000 (+0000) Subject: ImageVisual ResourceReady signalled regardless of parent X-Git-Tag: dali_1.3.0~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=refs%2Fchanges%2F38%2F159238%2F9 ImageVisual ResourceReady signalled regardless of parent Regardless of whether the ImageVisual is staged on not it will signal when resource has loaded Reusing the resource over multiple visuals should still return a ResourceReady signal once the control registers the visual. Change-Id: Ib4af7dc79b11fa2a96a96ed1b53a387e4001debc --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index c8cf88f..a770a77 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -1507,3 +1508,108 @@ int UtcDaliImageViewReplaceImageAndGetNaturalSize(void) END_TEST; } + +int UtcDaliImageViewResourceReadySignalWithImmediateLoad(void) +{ + tet_infoline("Test Setting Image with IMMEDIATE load and receving ResourceReadySignal before staged."); + + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + Property::Map imageMap; + + imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageMap[ DevelImageVisual::Property::LOAD_POLICY ] = DevelImageVisual::LoadPolicy::IMMEDIATE; + + tet_infoline("Creating ImageView without URL so image does not start loading"); + ImageView imageView = ImageView::New(); + tet_infoline("Connect to image loaded signal before setting image"); + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + tet_infoline("Setting Image with IMMEDIATE load, signal already connected so will be triggered."); + imageView.SetProperty( ImageView::Property::IMAGE, imageMap ); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewResourceReadySignalWithReusedImage(void) +{ + tet_infoline("Test Setting Image that was already loaded by another ImageView and still getting ResourceReadySignal."); + + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + Property::Map imageMap; + + imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageMap[ DevelImageVisual::Property::LOAD_POLICY ] = DevelImageVisual::LoadPolicy::IMMEDIATE; + + ImageView imageView = ImageView::New(); + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + imageView.SetProperty( ImageView::Property::IMAGE, imageMap ); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + gResourceReadySignalFired = false; + + ImageView imageViewWithExistingImage = ImageView::New(); + imageViewWithExistingImage.ResourceReadySignal().Connect( &ResourceReadySignal); + imageViewWithExistingImage.SetProperty( ImageView::Property::IMAGE, imageMap ); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewResourceReadySignalWithReusedImage02(void) +{ + tet_infoline("Test Setting Image that was already loaded by another ImageView and still getting ResourceReadySignal when staged."); + + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + Property::Map imageImmediateLoadingMap; + imageImmediateLoadingMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageImmediateLoadingMap[ DevelImageVisual::Property::LOAD_POLICY ] = DevelImageVisual::LoadPolicy::IMMEDIATE; + + tet_infoline("Immediate load an image"); + ImageView imageView = ImageView::New(); + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + imageView.SetProperty( ImageView::Property::IMAGE, imageImmediateLoadingMap ); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + tet_infoline("Check image loaded"); + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + gResourceReadySignalFired = false; + + tet_infoline("Create another ImageView with the same URL"); + ImageView imageViewWithExistingImage = ImageView::New( gImage_34_RGBA ); + tet_infoline("Connect to ResourceReady signal for second ImageView, it should still fire as resource is ready"); + imageViewWithExistingImage.ResourceReadySignal().Connect( &ResourceReadySignal); + + Stage::GetCurrent().Add( imageViewWithExistingImage ); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp index 3de6688..679721c 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp @@ -59,7 +59,6 @@ void ResourceReadySignal( Control control ) gResourceReadySignalFired = true; } - Actor CreateActorWithImageVisual(const Property::Map& map) { VisualFactory factory = VisualFactory::Get(); @@ -1684,44 +1683,145 @@ int UtcDaliImageVisualLoadPolicy02(void) int UtcDaliImageVisualLoadPolicy03(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliImageVisualLoadPolicy03 Load a visual image before attaching to stage and receive ResourceReady signal" ); + tet_infoline( "UtcDaliImageVisualLoadPolicy03 Load a visual image and receive ResourceReady Signal when loaded" ); + + const bool VISUAL_NOT_ENABLED( false ); // Instead of just passing 'false' into an API. // Set up trace debug TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); + tet_infoline( "Create a control and connect to resource ready signal without adding to stage" ); + DummyControl actor = DummyControl::New(true); + actor.ResourceReadySignal().Connect( &ResourceReadySignal); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + actor.SetSize(200.f, 200.f); + tet_infoline( "Create visual with IMMEDIATE load policy" ); Visual::Base imageVisual = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::IMMEDIATE ); - // Wait for image to load, ResourceReady signal will not be emitted until Visual is registered with a control and on stage. + tet_infoline( "Registering visual allows control to get a signal once loaded even if visual not enabled( not staged )" ); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED ); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + + tet_infoline( "Allow image time to load resource" ); DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + application.SendNotification(); + application.Render(); // Ensure texture has been uploaded + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageVisualLoadPolicy04(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliImageVisualLoadPolicy04 First part Load a visual image before attaching to stage"); + tet_infoline( "Second part, Reuse the same image in aonther control and check resource ready signal fired" ); + + const bool VISUAL_NOT_ENABLED( false ); // Instead of just passing false into an API. + + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline( "Create a control and connect to resource ready signal" ); + DummyControl actor = DummyControl::New(true); + actor.ResourceReadySignal().Connect( &ResourceReadySignal); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + actor.SetSize(200.f, 200.f); + + tet_infoline( "Create visual with IMMEDIATE load policy" ); + Visual::Base imageVisual = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::IMMEDIATE ); + + tet_infoline( "Registering visual allows control to get a signal once loaded even if visual not enabled( staged )" ); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED ); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + + tet_infoline( "Allow image time to load" ); + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); application.SendNotification(); application.Render(); - tet_infoline( "Ensure texture loading starts after visual created" ); + tet_infoline( "Testing texture is loaded and resource ready signal fired" ); DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); - textureTrace.Reset(); + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); - tet_infoline( "Register visuals with control and ensure it has the only handles" ); + tet_infoline( "Original control correctly signalled, now testing for signal with new Control reusing the image" ); + + gResourceReadySignalFired = false; // Reset signal check ready for testing next Control + Visual::Base imageVisual2 = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::IMMEDIATE ); + DummyControl actor2 = DummyControl::New(true); + Impl::DummyControl& dummyImpl2 = static_cast(actor.GetImplementation()); + actor2.ResourceReadySignal().Connect( &ResourceReadySignal); + + tet_infoline( "Registering visual this should trigger the loading signal as is already image loaded for previous control" ); + dummyImpl2.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual2 ); + imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive. + actor2.SetSize(200.f, 200.f); + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 0 ), true, TEST_LOCATION ); // Not expecting any further loading as texture is being reused. + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageVisualLoadPolicy05(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliImageVisualLoadPolicy05 LoadPolicy::ATTACHED (default) First part Load a visual image before attaching to stage"); + tet_infoline( "Second part, Reuse the same image in aonther control and check resource ready signal fired" ); + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline( "Create a control and connect to resource ready signal" ); DummyControl actor = DummyControl::New(true); actor.ResourceReadySignal().Connect( &ResourceReadySignal); Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + actor.SetSize(200.f, 200.f); + Stage::GetCurrent().Add( actor ); - tet_infoline( "Registering visual attaches it to stage and trigger the loading signal if Image loaded" ); + tet_infoline( "Create visual with ATTACHED load policy" ); + Visual::Base imageVisual = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::ATTACHED ); + + tet_infoline( "Registering visual allows control to get a signal once loaded" ); dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual ); imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. - actor.SetSize(200.f, 200.f); - // Adding the Control hence Visual to stage will cause the Visual to trigger ResourceReadySignal if the image is already loaded. - Stage::GetCurrent().Add( actor ); // If LoadPolicy was not IMMEDIATE then as this point (after attached to stage) the test would need to wait for Loading + tet_infoline( "Allow image time to load" ); + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + application.SendNotification(); + application.Render(); + + tet_infoline( "Testing texture is loaded and resource ready signal fired" ); + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + tet_infoline( "Original control correctly signalled, now testing for signal with new Control reusing the image" ); + + gResourceReadySignalFired = false; // Reset signal check ready for testing next Control + Visual::Base imageVisual2 = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::ATTACHED ); + DummyControl actor2 = DummyControl::New(true); + Impl::DummyControl& dummyImpl2 = static_cast(actor.GetImplementation()); + actor2.ResourceReadySignal().Connect( &ResourceReadySignal); + + tet_infoline( "Registering visual this should trigger the loading signal as is already image loaded for previous control" ); + dummyImpl2.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual2 ); + imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive. + actor2.SetSize(200.f, 200.f); + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 0 ), true, TEST_LOCATION ); // Not expecting any further loading as texture is being reused. DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); END_TEST; } + int UtcDaliImageVisualOrientationCorrection(void) { ToolkitTestApplication application; diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index 6ff1efb..1630b92 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -525,12 +525,17 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base ( visualReplaced && enabled ) ) ; mVisuals.PushBack( newRegisteredVisual ); + Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual ); // Put on stage if enabled and the control is already on the stage - // Visual must be set on stage for the renderer to be created and the ResourceReady triggered. if( ( enabled == VisualState::ENABLED ) && self.OnStage() ) { - Toolkit::GetImplementation(visual).SetOnStage( self ); + visualImpl.SetOnStage( self ); } + else if( visualImpl.IsResourceReady() ) // When not being staged, check if visual already 'ResourceReady' before it was Registered. ( Resource may have been loaded already ) + { + ResourceReady( visualImpl ); + } + } DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n", visual.GetName().c_str(), index, enabled?"true":"false" ); @@ -657,8 +662,11 @@ void Control::Impl::ResourceReady( Visual::Base& object) } } - // A visual is ready so control may need relayouting - mControlImpl.RelayoutRequest(); + // A visual is ready so control may need relayouting if staged + if ( self.OnStage() ) + { + mControlImpl.RelayoutRequest(); + } // Emit signal if all enabled visuals registered by the control are ready. if( IsResourceReady() ) diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 7ef4669..57445ea 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -1035,6 +1035,8 @@ void ImageVisual::UploadCompleted() // reset the weak handle so that the renderer only get added to actor once mPlacementActor.Reset(); } + // Image loaded + ResourceReady( Toolkit::Visual::ResourceStatus::READY ); mLoading = false; } @@ -1061,8 +1063,6 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur sampler.SetWrapMode( mWrapModeU, mWrapModeV ); textureSet.SetSampler( 0u, sampler ); mImpl->mRenderer.SetTextures(textureSet); - - resourceStatus = Toolkit::Visual::ResourceStatus::READY; } else { @@ -1072,20 +1072,26 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur mImpl->mRenderer.SetTextures( textureSet ); ApplyImageToSampler( brokenImage ); - - resourceStatus = Toolkit::Visual::ResourceStatus::FAILED; } - // Image loaded and ready to display - ResourceReady( resourceStatus ); } } - // Storing TextureSet needed when renderer staged. if( ! mImpl->mRenderer ) { mTextures = textureSet; } + // Image loaded, set status regardless of staged status. + if( loadingSuccess ) + { + resourceStatus = Toolkit::Visual::ResourceStatus::READY; + } + else + { + resourceStatus = Toolkit::Visual::ResourceStatus::FAILED; + } + // Signal to observers ( control ) that resources are ready. Must be all resources. + ResourceReady( resourceStatus ); mLoading = false; }