[dali_1.1.20] Merge branch 'devel/master' 49/58949/1
authorXiangyin Ma <x1.ma@samsung.com>
Fri, 5 Feb 2016 08:53:30 +0000 (08:53 +0000)
committerXiangyin Ma <x1.ma@samsung.com>
Fri, 5 Feb 2016 08:53:30 +0000 (08:53 +0000)
Change-Id: I7d77e0d851c8af079ce2d3f64f22d85b9d8c4d17

37 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
automated-tests/src/dali/dali-test-suite-utils/test-application.h
automated-tests/src/dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp
automated-tests/src/dali/dali-test-suite-utils/test-gl-sync-abstraction.h
automated-tests/src/dali/dali-test-suite-utils/test-native-image.cpp
automated-tests/src/dali/dali-test-suite-utils/test-native-image.h
automated-tests/src/dali/utc-Dali-Animation.cpp
automated-tests/src/dali/utc-Dali-FrameBufferImage.cpp
automated-tests/src/dali/utc-Dali-NativeImage.cpp
automated-tests/src/dali/utc-Dali-RenderTask.cpp
dali/devel-api/file.list
dali/devel-api/images/native-image-interface-extension.h [new file with mode: 0644]
dali/integration-api/gl-defines.h
dali/internal/event/animation/animation-impl.cpp
dali/internal/event/animation/animation-impl.h
dali/internal/event/animation/animation-playlist.cpp
dali/internal/event/images/frame-buffer-image-impl.cpp
dali/internal/event/images/frame-buffer-image-impl.h
dali/internal/event/images/native-image-impl.cpp
dali/internal/event/images/native-image-impl.h
dali/internal/render/common/render-manager.cpp
dali/internal/update/animation/scene-graph-animation.cpp
dali/internal/update/animation/scene-graph-animation.h
dali/internal/update/manager/process-render-tasks.cpp
dali/internal/update/manager/update-manager.cpp
dali/internal/update/render-tasks/scene-graph-render-task.cpp
dali/internal/update/render-tasks/scene-graph-render-task.h
dali/public-api/actors/image-actor.h
dali/public-api/actors/layer.h
dali/public-api/animation/animation.cpp
dali/public-api/animation/animation.h
dali/public-api/dali-core-version.cpp
dali/public-api/images/frame-buffer-image.cpp
dali/public-api/images/native-image.cpp
dali/public-api/images/native-image.h
dali/public-api/shader-effects/shader-effect.h
packaging/dali.spec

index 995e117..5fb6e11 100644 (file)
@@ -59,6 +59,9 @@ TestApplication::TestApplication( bool   initialize,
 
 void TestApplication::Initialize()
 {
+  // We always need the first update!
+  mStatus.keepUpdating = Integration::KeepUpdating::STAGE_KEEP_RENDERING;
+
   mCore = Dali::Integration::Core::New(
     mRenderController,
     mPlatformAbstraction,
@@ -153,11 +156,20 @@ void TestApplication::SetSurfaceWidth( unsigned int width, unsigned height )
 
 void TestApplication::DoUpdate( unsigned int intervalMilliseconds )
 {
+  if( GetUpdateStatus() == 0 &&
+      mRenderStatus.NeedsUpdate() == false &&
+      ! GetRenderController().WasCalled(TestRenderController::RequestUpdateFunc) )
+  {
+    fprintf(stderr, "WARNING - Update not required\n");
+  }
+
   unsigned int nextVSyncTime = mLastVSyncTime + intervalMilliseconds;
   float elapsedSeconds = intervalMilliseconds / 1e3f;
 
   mCore->Update( elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus );
 
+  GetRenderController().Initialize();
+
   mLastVSyncTime = nextVSyncTime;
 }
 
@@ -182,6 +194,15 @@ bool TestApplication::UpdateOnly( unsigned int intervalMilliseconds  )
   return mStatus.KeepUpdating();
 }
 
+bool TestApplication::GetRenderNeedsUpdate()
+{
+  return mRenderStatus.NeedsUpdate();
+}
+bool TestApplication::GetRenderHasRendered()
+{
+  return mRenderStatus.HasRendered();
+}
+
 bool TestApplication::RenderOnly( )
 {
   // Update Time values
index 3f61b93..cb5a92c 100644 (file)
@@ -78,6 +78,8 @@ public:
   bool UpdateOnly( unsigned int intervalMilliseconds = DEFAULT_RENDER_INTERVAL );
   bool RenderOnly( );
   void ResetContext();
+  bool GetRenderNeedsUpdate();
+  bool GetRenderHasRendered();
 
 private:
   void DoUpdate( unsigned int intervalMilliseconds );
index 533355c..65a884e 100644 (file)
@@ -132,5 +132,10 @@ void TestGlSyncAbstraction::ResetTrace() { mTrace.Reset(); }
  */
 TraceCallStack& TestGlSyncAbstraction::GetTrace() { return mTrace; }
 
+int TestGlSyncAbstraction::GetNumberOfSyncObjects()
+{
+  return mSyncObjects.size();
+}
+
 
 } // Dali
index e233176..278bcd7 100644 (file)
@@ -100,6 +100,13 @@ public: // TEST FUNCTIONS
    */
   TraceCallStack& GetTrace();
 
+  /**
+   * Get the number of sync objects
+   *
+   * @return the number of sync objects
+   */
+  int GetNumberOfSyncObjects();
+
 private:
   typedef std::vector<TestSyncObject*>   SyncContainer;
   typedef SyncContainer::iterator SyncIter;
index d143d35..d8ad2ba 100644 (file)
@@ -31,6 +31,7 @@ TestNativeImagePointer TestNativeImage::New(int width, int height)
 TestNativeImage::TestNativeImage(int width, int height)
 : mWidth(width), mHeight(height), mExtensionCreateCalls(0), mExtensionDestroyCalls(0), mTargetTextureCalls(0)
 {
+  mExtension = new TestNativeImageExtension();
 }
 
 TestNativeImage::~TestNativeImage()
index 4a39cb1..8dc6431 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/public-api/images/native-image-interface.h>
+#include <dali/devel-api/images/native-image-interface-extension.h>
 
 namespace Dali
 {
 class TestNativeImage;
 typedef IntrusivePtr<TestNativeImage> TestNativeImagePointer;
 
+class DALI_IMPORT_API TestNativeImageExtension: public Dali::NativeImageInterface::Extension
+{
+public:
+  inline const char* GetCustomFragmentPreFix(){return "#extension GL_OES_EGL_image_external:require\n";}
+  inline const char* GetCustomSamplerTypename(){return "samplerExternalOES";}
+
+};
+
 class DALI_IMPORT_API TestNativeImage : public Dali::NativeImageInterface
 {
 public:
@@ -38,6 +47,7 @@ public:
   inline virtual unsigned int GetWidth() const {return mWidth;};
   inline virtual unsigned int GetHeight() const {return mHeight;};
   inline virtual bool RequiresBlending() const {return true;};
+  inline virtual Dali::NativeImageInterface::Extension* GetExtension() {return mExtension;}
 
 private:
   TestNativeImage(int width, int height);
@@ -49,6 +59,7 @@ public:
   int mExtensionCreateCalls;
   int mExtensionDestroyCalls;
   int mTargetTextureCalls;
+  TestNativeImageExtension* mExtension;
 };
 
 } // Dali
index 40e6551..fec88e8 100644 (file)
@@ -336,6 +336,422 @@ int UtcDaliAnimationSetLoopingP(void)
   END_TEST;
 }
 
+int UtcDaliAnimationSetLoopCountP(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add(actor);
+
+  // Build the animation
+  float durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+
+  // Start the animation
+  animation.SetLoopCount(3);
+  DALI_TEST_CHECK(animation.IsLooping());
+  animation.Play();
+
+  bool signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+
+  // Loop
+  float intervalSeconds = 3.0f;
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_EQUALS( targetPosition, actor.GetCurrentPosition(), TEST_LOCATION );
+
+  finishCheck.Reset();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  END_TEST;
+}
+
+int UtcDaliAnimationSetLoopCountP2(void)
+{
+  TestApplication application;
+
+  //
+  // switching between forever and loop count
+  //
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add(actor);
+
+  // Build the animation
+  float durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+  animation.SetEndAction(Animation::Discard);
+
+  // Start the animation
+  animation.SetLoopCount(3);
+  DALI_TEST_CHECK(animation.IsLooping());
+  animation.Play();
+
+  bool signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  float intervalSeconds = 3.0f;
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  finishCheck.Reset();
+
+  // Loop forever
+  animation.SetLooping(true);
+  DALI_TEST_CHECK(animation.IsLooping());
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  finishCheck.Reset();
+
+  // Loop N again
+  animation.SetLoopCount(3);
+  DALI_TEST_CHECK(animation.IsLooping());
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  finishCheck.Reset();
+
+  // loop forever
+  animation.SetLooping(true);
+  DALI_TEST_CHECK(animation.IsLooping());
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  finishCheck.Reset();
+
+  // Loop N again
+  animation.SetLoopCount(3);
+  DALI_TEST_CHECK(animation.IsLooping());
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived(); // we never hit play
+
+  finishCheck.Reset();
+
+
+  END_TEST;
+}
+
+int UtcDaliAnimationSetLoopCountP3(void)
+{
+  TestApplication application;
+
+  //
+  // switching between forever and loop count
+  //
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add(actor);
+
+  // Build the animation
+  float durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+  animation.SetEndAction(Animation::Discard);
+
+  float intervalSeconds = 3.0f;
+
+  bool signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  // loop forever
+  animation.SetLooping(true);
+  DALI_TEST_CHECK(animation.IsLooping());
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  finishCheck.Reset();
+
+  // Loop N again
+  animation.SetLoopCount(3);
+  DALI_TEST_CHECK(animation.IsLooping());
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived(); // we never hit play
+
+  finishCheck.Reset();
+
+
+  END_TEST;
+}
+
+int UtcDaliAnimationSetLoopCountP4(void)
+{
+  TestApplication application;
+
+  //
+  // ..and play again
+  //
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add(actor);
+
+  // Build the animation
+  float durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+  animation.SetEndAction(Animation::Bake);
+
+  float intervalSeconds = 3.0f;
+
+  bool signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  animation.SetLoopCount(1);
+  animation.Play();
+  DALI_TEST_CHECK(!animation.IsLooping());
+
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+  actor.SetProperty( Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f) );
+
+  finishCheck.Reset();
+
+  animation.Play(); // again
+  DALI_TEST_CHECK(!animation.IsLooping());
+
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliAnimationGetLoopCountP(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add(actor);
+
+  // Build the animation
+  float durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+
+  DALI_TEST_CHECK(1 == animation.GetLoopCount());
+
+  // Start the animation
+  animation.SetLoopCount(3);
+  DALI_TEST_CHECK(animation.IsLooping());
+  DALI_TEST_CHECK(3 == animation.GetLoopCount());
+
+  animation.Play();
+
+  application.Render(0);
+  application.SendNotification();
+
+  // Loop
+  float intervalSeconds = 3.0f;
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+  application.Render(0);
+  application.SendNotification();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+
+  animation.SetLoopCount(0);
+  DALI_TEST_CHECK(animation.IsLooping());
+  DALI_TEST_CHECK(0 == animation.GetLoopCount());
+
+  animation.SetLoopCount(1);
+  DALI_TEST_CHECK(!animation.IsLooping());
+  DALI_TEST_CHECK(1 == animation.GetLoopCount());
+
+  END_TEST;
+}
+
+
+int UtcDaliAnimationGetCurrentLoopP(void)
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add(actor);
+
+  // Build the animation
+  float durationSeconds(1.0f);
+  Animation animation = Animation::New(durationSeconds);
+  Vector3 targetPosition(10.0f, 10.0f, 10.0f);
+  animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
+
+  // Start the animation
+  animation.SetLoopCount(3);
+  DALI_TEST_CHECK(animation.IsLooping());
+  DALI_TEST_CHECK(0 == animation.GetCurrentLoop());
+  animation.Play();
+
+  bool signalReceived(false);
+  AnimationFinishCheck finishCheck(signalReceived);
+  animation.FinishedSignal().Connect(&application, finishCheck);
+
+  application.SendNotification();
+
+  // Loop
+  float intervalSeconds = 3.0f;
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+  DALI_TEST_CHECK(2 == animation.GetCurrentLoop());
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+  DALI_TEST_CHECK(3 == animation.GetCurrentLoop());
+  DALI_TEST_CHECK(animation.GetLoopCount() == animation.GetCurrentLoop());
+
+  finishCheck.Reset();
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+  DALI_TEST_CHECK(3 == animation.GetCurrentLoop());
+
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.Render(static_cast<unsigned int>(durationSeconds*intervalSeconds*1000.0f));
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+  DALI_TEST_CHECK(3 == animation.GetCurrentLoop());
+
+  END_TEST;
+}
+
 int UtcDaliAnimationIsLoopingP(void)
 {
   TestApplication application;
index b79619a..1f2b880 100644 (file)
@@ -111,8 +111,8 @@ int UtcDaliFrameBufferImageNew03(void)
 
   DALI_TEST_CHECK( image );
 
-  //ReleasePolicy is always never for framebuffer images
-  DALI_TEST_EQUALS( image.GetReleasePolicy(), Image::NEVER, TEST_LOCATION );
+  // ReleasePolicy is deprecated. Only set, but not used internally.
+  DALI_TEST_EQUALS( image.GetReleasePolicy(), Image::UNUSED, TEST_LOCATION );
 
   // initialise handle with NEVER release policy
   image.Reset();
@@ -122,7 +122,7 @@ int UtcDaliFrameBufferImageNew03(void)
 
   DALI_TEST_CHECK( image );
 
-  //ReleasePolicy is always never for framebuffer images
+  // ReleasePolicy is deprecated. Only set, but not used internally.
   DALI_TEST_EQUALS( image.GetReleasePolicy(), Image::NEVER, TEST_LOCATION );
 
   END_TEST;
index 1f080a7..3dc7568 100644 (file)
@@ -208,7 +208,29 @@ int UtcDaliNativeImageExtensionP(void)
   TestNativeImagePointer testNativeImage = TestNativeImage::New( 16, 16 );
   DALI_TEST_CHECK( testNativeImage );
 
-  DALI_TEST_CHECK( NULL == testNativeImage->GetExtension() );
+  DALI_TEST_CHECK( NULL != testNativeImage->GetExtension() );
 
   END_TEST;
 }
+
+int UtcDaliNativeImageGetCustomFragmentPreFixP(void)
+{
+  TestApplication application;
+  TestNativeImagePointer nativeImageInterface = TestNativeImage::New( 16, 16 );
+  NativeImage nativeImage = NativeImage::New( *(nativeImageInterface.Get()) );
+
+  const char* preFix = "#extension GL_OES_EGL_image_external:require\n";
+  DALI_TEST_EQUALS( nativeImage.GetCustomFragmentPreFix(), preFix, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliNativeImageGetCustomSamplerTypenameP(void)
+{
+  TestApplication application;
+  TestNativeImagePointer nativeImageInterface = TestNativeImage::New( 16, 16 );
+  NativeImage nativeImage = NativeImage::New( *(nativeImageInterface.Get()) );
+
+  const char* samplerTypename = "samplerExternalOES";
+  DALI_TEST_EQUALS( nativeImage.GetCustomSamplerTypename(), samplerTypename, TEST_LOCATION );
+  END_TEST;
+}
index 69339c6..a18e05f 100644 (file)
@@ -28,6 +28,7 @@
 
 #define BOOLSTR(x) ((x)?"T":"F")
 
+//& set: DaliRenderTask
 
 using namespace Dali;
 
@@ -261,6 +262,9 @@ bool UpdateRender(TestApplication& application, TraceCallStack& callStack, bool
 {
   finishedSig = false;
   callStack.Reset();
+
+  tet_printf("TestApplication::UpdateRender().\n");
+
   application.Render(16);
   application.SendNotification();
 
@@ -1795,9 +1799,7 @@ int UtcDaliRenderTaskSignalFinished(void)
   DALI_TEST_CHECK( finished );
   finished = false;
 
-  application.Render(); // Double check no more finished signal
-  application.SendNotification();
-  DALI_TEST_CHECK( ! finished );
+  DALI_TEST_EQUALS( application.GetUpdateStatus(), 0, TEST_LOCATION );
   END_TEST;
 }
 
@@ -2475,6 +2477,7 @@ int UtcDaliRenderTaskOnce08(void)
   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
   TestGlSyncAbstraction& sync = application.GetGlSyncAbstraction();
   TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace();
+  sync.GetTrace().Enable(true);
   drawTrace.Enable(true);
 
   Actor rootActor = Actor::New();
@@ -2492,7 +2495,7 @@ int UtcDaliRenderTaskOnce08(void)
 
   Stage::GetCurrent().Add(secondRootActor);
 
-  RenderTask newTask = CreateRenderTask(application, offscreenCameraActor, rootActor, secondRootActor, RenderTask::REFRESH_ALWAYS, true);
+  RenderTask newTask = CreateRenderTask(application, offscreenCameraActor, rootActor, secondRootActor, RenderTask::REFRESH_ALWAYS, /*GL-SYNC*/ true);
   bool finished = false;
 
   ConnectionTracker connectionTracker;
@@ -2504,6 +2507,9 @@ int UtcDaliRenderTaskOnce08(void)
   // START PROCESS/RENDER                    Input,    Expected  Input,    Expected
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, true,    finished, false, false, __LINE__ ) );
   Integration::GlSyncAbstraction::SyncObject* lastSyncObj = sync.GetLastSyncObject();
+  DALI_TEST_CHECK( lastSyncObj == NULL );
+  DALI_TEST_EQUALS( sync.GetTrace().CountMethod( "CreateSyncObject" ), 0, TEST_LOCATION );
+
 
   // CHANGE TO RENDER ONCE,
   newTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
@@ -2511,10 +2517,20 @@ int UtcDaliRenderTaskOnce08(void)
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, true,    finished, false, true, __LINE__ ) );
   lastSyncObj = sync.GetLastSyncObject();
   DALI_TEST_CHECK( lastSyncObj != NULL );
+  DALI_TEST_EQUALS( sync.GetNumberOfSyncObjects(), 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( sync.GetTrace().CountMethod( "CreateSyncObject" ), 1, TEST_LOCATION );
 
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,   finished, false, true, __LINE__ ) );
+
+
+  DALI_TEST_EQUALS( sync.GetNumberOfSyncObjects(), 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( sync.GetTrace().CountMethod( "CreateSyncObject" ), 1, TEST_LOCATION );
+
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,   finished, false, true, __LINE__ ) );
 
+  DALI_TEST_EQUALS( sync.GetNumberOfSyncObjects(), 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( sync.GetTrace().CountMethod( "CreateSyncObject" ), 1, TEST_LOCATION );
+
   sync.SetObjectSynced( lastSyncObj, true );
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,   finished, false, true, __LINE__ ) );
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,   finished, true, false, __LINE__ ) );
@@ -2834,15 +2850,26 @@ int UtcDaliRenderTaskOnceNoSync04(void)
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,   finished, false, true, __LINE__ ) );
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,   finished, false, true, __LINE__ ) );
 
+  TestGlSyncAbstraction& sync = application.GetGlSyncAbstraction();
+  Integration::GlSyncAbstraction::SyncObject* lastSyncObj = sync.GetLastSyncObject();
+  DALI_TEST_CHECK( lastSyncObj == NULL );
+
   // FINISH RESOURCE LOADING
   CompleteImageLoad(application, imageRequestId, imageType); // Need to run update again for this to complete
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, true,    finished, false, false, __LINE__ ) );
   application.GetPlatform().ClearReadyResources();
 
+  lastSyncObj = sync.GetLastSyncObject();
+  DALI_TEST_CHECK( lastSyncObj == NULL );
+
   newTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
   application.SendNotification(); //         Input,    Expected  Input,    Expected
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, true,    finished, false, true, __LINE__ ) );
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,   finished, true, false, __LINE__ ) );
+
+  lastSyncObj = sync.GetLastSyncObject();
+  DALI_TEST_CHECK( lastSyncObj == NULL );
+
   END_TEST;
 }
 
@@ -2877,6 +2904,10 @@ int UtcDaliRenderTaskOnceNoSync05(void)
   newTask.FinishedSignal().Connect( &application, renderTaskFinished );
   application.SendNotification();
 
+  TestGlSyncAbstraction& sync = application.GetGlSyncAbstraction();
+  Integration::GlSyncAbstraction::SyncObject* lastSyncObj = sync.GetLastSyncObject();
+  DALI_TEST_CHECK( lastSyncObj == NULL );
+
   // START PROCESS/RENDER                    Input,    Expected  Input,    Expected
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,    finished, false, true, __LINE__ ) );
   DALI_TEST_CHECK( UpdateRender(application, drawTrace, false,    finished, false, true, __LINE__ ) );
@@ -3325,7 +3356,7 @@ int UtcDaliRenderTaskFinishInvisibleSourceActor(void)
 {
   TestApplication application;
 
-  tet_infoline("Testing RenderTask::SignalFinished()");
+  tet_infoline("Testing RenderTask::FinishInvisibleSourceActor()");
 
   application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
   TestGlSyncAbstraction& sync = application.GetGlSyncAbstraction();
@@ -3461,7 +3492,6 @@ int UtcDaliRenderTaskWorldToViewport(void)
 
   Stage::GetCurrent().Add(actor);
 
-  application.Render();
   application.SendNotification();
   application.Render();
   application.SendNotification();
@@ -3491,7 +3521,6 @@ int UtcDaliRenderTaskWorldToViewport(void)
   actor2.Add(actor);
   actor.SetParentOrigin( Vector3(0,0,0) );
 
-  application.Render();
   application.SendNotification();
   application.Render();
   application.SendNotification();
@@ -3521,6 +3550,8 @@ int UtcDaliRenderTaskViewportToLocal(void)
   // flush the queue and render once
   application.SendNotification();
   application.Render();
+  application.SendNotification();
+  application.Render();
 
   float localX;
   float localY;
index a277021..9631a2e 100644 (file)
@@ -41,7 +41,8 @@ devel_api_core_events_header_files = \
 devel_api_core_images_header_files = \
   $(devel_api_src_dir)/images/atlas.h \
   $(devel_api_src_dir)/images/distance-field.h \
-  $(devel_api_src_dir)/images/pixel-data.h
+  $(devel_api_src_dir)/images/pixel-data.h \
+  $(devel_api_src_dir)/images/native-image-interface-extension.h
 
 devel_api_core_object_header_files = \
   $(devel_api_src_dir)/object/property-buffer.h \
diff --git a/dali/devel-api/images/native-image-interface-extension.h b/dali/devel-api/images/native-image-interface-extension.h
new file mode 100644 (file)
index 0000000..ca19c14
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __DALI_INTEGRATION_NATIVE_IMAGE_INTERFACE_EXTENSION_H__
+#define __DALI_INTEGRATION_NATIVE_IMAGE_INTERFACE_EXTENSION_H__
+
+/*
+ * Copyright (c) 2015 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 <dali/public-api/images/native-image-interface.h>
+
+namespace Dali
+{
+
+/**
+ * @brief Extension abstract interface to provide platform-specific support for handling image data.
+ *
+ */
+class NativeImageInterface::Extension
+{
+public:
+
+  class Extension2; ///< Forward declare future extension interface
+
+  /**
+   * @brief Get custom fragment prefix for rendering native image.
+   *
+   * @return Custom fragment prefix code as string.
+   */
+  virtual const char* GetCustomFragmentPreFix() = 0;
+
+  /**
+   * @brief Get custom sampler type name for rendering native image.
+   *
+   * @return Custom sampler type name.
+   */
+  virtual const char* GetCustomSamplerTypename() = 0;
+
+  /**
+   * @brief Retrieve the extension for the interface.
+   *
+   * @return Extension2 pointer if available, NULL otherwise
+   */
+  virtual Extension2* GetExtension2()
+  {
+    return NULL;
+  }
+
+protected:
+
+  /**
+   * @brief Destructor.
+   *
+   */
+  virtual ~Extension()
+  {
+  }
+
+};
+
+} // namespace Dali
+
+#endif // __DALI_INTEGRATION_NATIVE_IMAGE_INTERFACE_H__
index 3ad852f..eebb484 100644 (file)
 #endif
 
 
+/* GL_OES_EGL_image_external */
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES                                 0x8D65
+#endif
+
+
 #endif // __DALI_INTERNAL_GL_DEFINES_H__
index 04e9ac9..04ca30b 100644 (file)
@@ -122,7 +122,8 @@ Animation::Animation( EventThreadServices& eventThreadServices, AnimationPlaylis
   mFinishedCallbackObject( NULL ),
   mDurationSeconds( durationSeconds ),
   mSpeedFactor(1.0f),
-  mIsLooping( false ),
+  mLoopCount(1),
+  mCurrentLoop(0),
   mPlayRange( Vector2(0.0f,1.0f)),
   mEndAction( endAction ),
   mDisconnectAction( disconnectAction ),
@@ -159,7 +160,7 @@ void Animation::CreateSceneObject()
   DALI_ASSERT_DEBUG( mAnimation == NULL );
 
   // Create a new animation, temporarily owned
-  SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
+  SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mLoopCount, mEndAction, mDisconnectAction );
 
   // Keep a const pointer to the animation.
   mAnimation = animation;
@@ -199,19 +200,33 @@ float Animation::GetDuration() const
   return mDurationSeconds;
 }
 
-void Animation::SetLooping(bool looping)
+void Animation::SetLooping(bool on)
+{
+  SetLoopCount( on ? 0 : 1 );
+}
+
+void Animation::SetLoopCount(int count)
 {
   // Cache for public getters
-  mIsLooping = looping;
+  mLoopCount = count;
 
   // mAnimation is being used in a separate thread; queue a message to set the value
-  SetLoopingMessage( mEventThreadServices, *mAnimation, looping );
+  SetLoopingMessage( mEventThreadServices, *mAnimation, mLoopCount );
+}
+
+int Animation::GetLoopCount()
+{
+  return mLoopCount;
+}
+
+int Animation::GetCurrentLoop()
+{
+  return mCurrentLoop;
 }
 
 bool Animation::IsLooping() const
 {
-  // This is not animatable; the cached value is up-to-date.
-  return mIsLooping;
+  return mLoopCount != 1;
 }
 
 void Animation::SetEndAction(EndAction action)
@@ -721,13 +736,15 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 bool Animation::HasFinished()
 {
   bool hasFinished(false);
-  const int playCount(mAnimation->GetPlayCount());
+  const int playedCount(mAnimation->GetPlayedCount());
 
   // If the play count has been incremented, then another notification is required
-  if (playCount > mNotificationCount)
+  mCurrentLoop = mAnimation->GetCurrentLoop();
+
+  if (playedCount > mNotificationCount)
   {
     // Note that only one signal is emitted, if the animation has been played repeatedly
-    mNotificationCount = playCount;
+    mNotificationCount = playedCount;
 
     hasFinished = true;
   }
index 6272042..f3ade18 100644 (file)
@@ -85,7 +85,22 @@ public:
   /**
    * @copydoc Dali::Animation::SetLooping()
    */
-  void SetLooping(bool looping);
+  void SetLooping(bool on);
+
+  /**
+   * @copydoc Dali::Animation::SetLoopCount()
+   */
+  void SetLoopCount(int count);
+
+  /**
+   * @copydoc Dali::Animation::GetLoopCount()
+   */
+  int GetLoopCount();
+
+  /**
+   * @copydoc Dali::Animation::GetCurrentLoop()
+   */
+  int GetCurrentLoop();
 
   /**
    * @copydoc Dali::Animation::IsLooping()
@@ -446,7 +461,8 @@ private:
   // Cached for public getters
   float mDurationSeconds;
   float mSpeedFactor;
-  bool mIsLooping;
+  int mLoopCount;
+  int mCurrentLoop;
   Vector2 mPlayRange;
   EndAction mEndAction;
   EndAction mDisconnectAction;
index ef3644b..99a61ca 100644 (file)
@@ -91,6 +91,7 @@ void AnimationPlaylist::NotifyCompleted()
       // The animation may be present in mPlaylist - remove if necessary
       // Note that the animation "Finish" signal is emitted after Stop() has been called
       std::vector< Dali::Animation >::iterator iter = std::find( mPlaylist.begin(), mPlaylist.end(), Dali::Animation(animation) );
+      DALI_ASSERT_DEBUG(iter != mPlaylist.end());
       mPlaylist.erase( iter );
     }
   }
index b7fda19..734aee0 100644 (file)
@@ -122,6 +122,12 @@ bool FrameBufferImage::IsNativeFbo() const
 {
   return mIsNativeFbo;
 }
+
+void FrameBufferImage::SetReleasePolicy( Dali::Image::ReleasePolicy releasePolicy )
+{
+  mReleasePolicy = releasePolicy;
+}
+
 FrameBufferImage::~FrameBufferImage()
 {
 }
index 42d5872..ffb778d 100644 (file)
@@ -63,6 +63,12 @@ public:
    */
   bool IsNativeFbo() const;
 
+  /**
+   * @brief Required for backwards compatibility. Value is just stored but not used internally.
+   * @param[in] releasePolicy The release policy (ignored as not supported).
+   */
+  void SetReleasePolicy( Dali::Image::ReleasePolicy releasePolicy );
+
 public: // From Image
   /**
    * @copydoc Dali::Internal::Image::Connect()
index 4043f91..6f965cb 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/resources/resource-client.h>
 #include <dali/internal/event/common/stage-impl.h>
+#include <dali/devel-api/images/native-image-interface-extension.h>
 
 using namespace Dali::Integration;
 
@@ -40,14 +41,20 @@ namespace
 TypeRegistration mType( typeid(Dali::NativeImage), typeid(Dali::Image), NULL );
 }
 
-NativeImage::NativeImage()
+NativeImage::NativeImage( NativeImageInterface& resourceData )
 : Image()
 {
+  NativeImageInterface::Extension* extension = resourceData.GetExtension();
+  if( extension != NULL )
+  {
+    mCustomFragmentPreFix = extension->GetCustomFragmentPreFix();
+    mCustomSamplerTypename = extension->GetCustomSamplerTypename();
+  }
 }
 
 NativeImagePtr NativeImage::New( NativeImageInterface& resourceData )
 {
-  NativeImagePtr image = new NativeImage;
+  NativeImagePtr image = new NativeImage( resourceData );
   image->Initialize();
 
   ResourceClient &resourceClient = ThreadLocalStorage::Get().GetResourceClient();
@@ -73,6 +80,26 @@ void NativeImage::CreateGlTexture()
   resourceClient.CreateGlTexture( GetResourceId() );
 }
 
+const char* NativeImage::GetCustomFragmentPreFix()
+{
+  if( mCustomFragmentPreFix.empty() )
+  {
+    return NULL;
+  }
+
+  return mCustomFragmentPreFix.c_str();
+}
+
+const char* NativeImage::GetCustomSamplerTypename()
+{
+  if( mCustomSamplerTypename.empty() )
+  {
+    return NULL;
+  }
+
+  return mCustomSamplerTypename.c_str();
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 0f1dfe4..ef580fb 100644 (file)
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <string>
+
 // INTERNAL INCLUDES
 #include <dali/public-api/images/native-image.h>
 #include <dali/internal/event/images/image-impl.h>
@@ -56,12 +59,28 @@ protected:
   /**
    * Constructor
    */
-  NativeImage();
+  NativeImage( NativeImageInterface& nativeImageInterface );
 
   /**
    * A reference counted object may only be deleted by calling Unreference()
    */
   virtual ~NativeImage();
+
+public:
+
+  /**
+   * @copydoc Dali::NativeImageInterface::Extension::GetCustomFragmentPreFix()
+   */
+  const char* GetCustomFragmentPreFix();
+
+  /**
+   * @copydoc Dali::NativeImageInterface::Extension::GetCustomSamplerTypename()
+   */
+  const char* GetCustomSamplerTypename();
+
+private:
+  std::string mCustomFragmentPreFix;
+  std::string mCustomSamplerTypename;
 };
 
 } // namespace Internal
index 082d601..ce16412 100644 (file)
@@ -612,6 +612,9 @@ void RenderManager::DoRender( RenderInstruction& instruction, Shader& defaultSha
 
   if( instruction.mRenderTracker && offscreen != NULL )
   {
+    // This will create a sync object every frame this render tracker
+    // is alive (though it should be now be created only for
+    // render-once render tasks)
     instruction.mRenderTracker->CreateSyncObject( mImpl->glSyncAbstraction );
     instruction.mRenderTracker = NULL; // Only create once.
   }
index 207d5b4..877010c 100644 (file)
@@ -29,6 +29,19 @@ namespace //Unnamed namespace
 {
 //Memory pool used to allocate new animations. Memory used by this pool will be released when shutting down DALi
 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Animation> gAnimationMemoryPool;
+
+inline void WrapInPlayRange( float& elapsed, const Dali::Vector2& playRangeSeconds)
+{
+  if (elapsed > playRangeSeconds.y )
+  {
+    elapsed = playRangeSeconds.x + fmod(elapsed, playRangeSeconds.y);
+  }
+  else if( elapsed < playRangeSeconds.x )
+  {
+    elapsed = playRangeSeconds.y - fmod(elapsed, playRangeSeconds.y);
+  }
+}
+
 }
 
 namespace Dali
@@ -40,20 +53,21 @@ namespace Internal
 namespace SceneGraph
 {
 
-Animation* Animation::New( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction )
+Animation* Animation::New( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, EndAction endAction, EndAction disconnectAction )
 {
-  return new ( gAnimationMemoryPool.AllocateRawThreadSafe() ) Animation( durationSeconds, speedFactor, playRange, isLooping, endAction, disconnectAction );
+  return new ( gAnimationMemoryPool.AllocateRawThreadSafe() ) Animation( durationSeconds, speedFactor, playRange, loopCount, endAction, disconnectAction );
 }
 
-Animation::Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, Dali::Animation::EndAction endAction, Dali::Animation::EndAction disconnectAction )
+Animation::Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, Dali::Animation::EndAction endAction, Dali::Animation::EndAction disconnectAction )
 : mDurationSeconds(durationSeconds),
   mSpeedFactor( speedFactor ),
-  mLooping(isLooping),
   mEndAction(endAction),
   mDisconnectAction(disconnectAction),
   mState(Stopped),
   mElapsedSeconds(playRange.x*mDurationSeconds),
-  mPlayCount(0),
+  mPlayedCount(0),
+  mLoopCount(loopCount),
+  mCurrentLoop(0),
   mPlayRange( playRange )
 {
 }
@@ -72,9 +86,10 @@ void Animation::SetDuration(float durationSeconds)
   mDurationSeconds = durationSeconds;
 }
 
-void Animation::SetLooping(bool looping)
+void Animation::SetLoopCount(int loopCount)
 {
-  mLooping = looping;
+  mLoopCount = loopCount;
+  mCurrentLoop = 0;
 }
 
 void Animation::SetEndAction(Dali::Animation::EndAction action)
@@ -113,6 +128,8 @@ void Animation::Play()
   }
 
   SetAnimatorsActive( true );
+
+  mCurrentLoop = 0;
 }
 
 void Animation::PlayFrom( float progress )
@@ -180,7 +197,8 @@ bool Animation::Stop(BufferIndex bufferIndex)
     }
 
     // The animation has now been played to completion
-    ++mPlayCount;
+    ++mPlayedCount;
+    mCurrentLoop = 0;
   }
 
   mElapsedSeconds = mPlayRange.x*mDurationSeconds;
@@ -216,12 +234,15 @@ void Animation::AddAnimator( AnimatorBase* animator )
   mAnimators.PushBack( animator );
 }
 
-bool Animation::Update(BufferIndex bufferIndex, float elapsedSeconds)
+void Animation::Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished )
 {
+  looped = false;
+  finished = false;
+
   if (mState == Stopped || mState == Destroyed)
   {
     // Short circuit when animation isn't running
-    return false;
+    return;
   }
 
   // The animation must still be applied when Paused/Stopping
@@ -231,35 +252,60 @@ bool Animation::Update(BufferIndex bufferIndex, float elapsedSeconds)
   }
 
   Vector2 playRangeSeconds = mPlayRange * mDurationSeconds;
-  if (mLooping)
+
+  if( 0 == mLoopCount )
   {
-    if (mElapsedSeconds > playRangeSeconds.y )
-    {
-      mElapsedSeconds = playRangeSeconds.x + fmod(mElapsedSeconds, playRangeSeconds.y);
-    }
-    else if( mElapsedSeconds < playRangeSeconds.x )
+    // loop forever
+    WrapInPlayRange(mElapsedSeconds, playRangeSeconds);
+
+    UpdateAnimators(bufferIndex, false, false);
+
+    // don't increment mPlayedCount as event loop tracks this to indicate animation finished (end of all loops)
+  }
+  else if( mCurrentLoop < mLoopCount - 1) // '-1' here so last loop iteration uses play once below
+  {
+    // looping
+    looped =  (mState == Playing                                                 &&
+               (( mSpeedFactor > 0.0f && mElapsedSeconds > playRangeSeconds.y )  ||
+                ( mSpeedFactor < 0.0f && mElapsedSeconds < playRangeSeconds.x )) );
+
+    WrapInPlayRange(mElapsedSeconds, playRangeSeconds);
+
+    UpdateAnimators(bufferIndex, false, false);
+
+    if(looped)
     {
-      mElapsedSeconds = playRangeSeconds.y - fmod(mElapsedSeconds, playRangeSeconds.y);
+      ++mCurrentLoop;
+      // don't increment mPlayedCount until the finished final loop
     }
   }
+  else
+  {
+    // playing once (and last mCurrentLoop)
+    finished = (mState == Playing                                                 &&
+                (( mSpeedFactor > 0.0f && mElapsedSeconds > playRangeSeconds.y )  ||
+                 ( mSpeedFactor < 0.0f && mElapsedSeconds < playRangeSeconds.x )) );
 
-  const bool animationFinished(mState == Playing                                                &&
-                              (( mSpeedFactor > 0.0f && mElapsedSeconds > playRangeSeconds.y )  ||
-                               ( mSpeedFactor < 0.0f && mElapsedSeconds < playRangeSeconds.x ))
-                              );
+    // update with bake if finished
+    UpdateAnimators(bufferIndex, finished && (mEndAction != Dali::Animation::Discard), finished);
 
-  UpdateAnimators(bufferIndex, animationFinished && (mEndAction != Dali::Animation::Discard), animationFinished);
+    if(finished)
+    {
+      // The animation has now been played to completion
+      ++mPlayedCount;
 
-  if (animationFinished)
-  {
-    // The animation has now been played to completion
-    ++mPlayCount;
+      // loop iterations come to this else branch for their final iterations
+      if( mCurrentLoop < mLoopCount)
+      {
+        ++mCurrentLoop;
+        DALI_ASSERT_DEBUG(mCurrentLoop == mLoopCount);
+      }
 
-    mElapsedSeconds = playRangeSeconds.x;
-    mState = Stopped;
+      mElapsedSeconds = playRangeSeconds.x;
+      mState = Stopped;
+    }
   }
 
-  return animationFinished;
 }
 
 void Animation::UpdateAnimators( BufferIndex bufferIndex, bool bake, bool animationFinished )
index 94d42f0..1885560 100644 (file)
@@ -66,12 +66,12 @@ public:
    * @param[in] durationSeconds The duration of the animation in seconds.
    * @param[in] speedFactor Multiplier to the animation velocity.
    * @param[in] playRange Minimum and maximum progress between which the animation will play.
-   * @param[in] isLooping Whether the animation will loop.
+   * @param[in] loopCount The number of times the animation will loop. ( See SetLoopCount() )
    * @param[in] endAction The action to perform when the animation ends.
    * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
    * @return A new Animation
    */
-  static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction );
+  static Animation* New( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, EndAction endAction, EndAction disconnectAction );
 
   /**
    * Virtual destructor
@@ -129,10 +129,11 @@ public:
   }
 
   /**
-   * Set whether the animation will loop.
-   * @param[in] looping True if the animation will loop.
+   * Set the animation loop count.
+   * 0 is loop forever, N loop play N times
+   * @param[in] loopCount The loop count
    */
-  void SetLooping(bool looping);
+  void SetLoopCount(int loopCount);
 
   /**
    * Query whether the animation will loop.
@@ -140,7 +141,16 @@ public:
    */
   bool IsLooping() const
   {
-    return mLooping;
+    return mLoopCount != 1;
+  }
+
+  /*
+   * Get the loop count
+   * @return the loop count
+   */
+  int GetLoopCount() const
+  {
+    return mLoopCount;
   }
 
   /**
@@ -226,9 +236,17 @@ public:
    * Retrive a count of the number of times the animation has been played to completion.
    * This can be used to emit "Finised" signals from the public-api
    */
-  int GetPlayCount() const
+  int GetPlayedCount() const
+  {
+    return mPlayedCount;
+  }
+
+  /**
+   * Get the current loop count from zero to GetLoopCount().
+   */
+  int GetCurrentLoop() const
   {
-    return mPlayCount;
+    return mCurrentLoop;
   }
 
   /**
@@ -254,9 +272,10 @@ public:
    * @pre The animation is playing or paused.
    * @param[in] bufferIndex The buffer to update.
    * @param[in] elapsedSeconds The time elapsed since the previous frame.
-   * @return True if the animation has finished.
+   * @param[out] looped True if the animation looped
+   * @param[out] finished True if the animation has finished.
    */
-  bool Update(BufferIndex bufferIndex, float elapsedSeconds);
+  void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished );
 
 
 protected:
@@ -264,7 +283,7 @@ protected:
   /**
    * Protected constructor. See New()
    */
-  Animation( float durationSeconds, float speedFactor, const Vector2& playRange, bool isLooping, EndAction endAction, EndAction disconnectAction );
+  Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, EndAction endAction, EndAction disconnectAction );
 
 
 private:
@@ -301,13 +320,15 @@ protected:
 
   float mDurationSeconds;
   float mSpeedFactor;
-  bool mLooping;
   EndAction mEndAction;
   EndAction mDisconnectAction;
 
   State mState;
   float mElapsedSeconds;
-  int mPlayCount;
+  int mPlayedCount;              // Incremented at end of animation or completion of all loops
+                                 // Never incremented when looping forever. Event thread tracks to signal end.
+  int mLoopCount;                // N loop setting
+  int mCurrentLoop;              // Current loop number
 
   Vector2 mPlayRange;
   AnimatorContainer mAnimators;
@@ -334,15 +355,15 @@ inline void SetDurationMessage( EventThreadServices& eventThreadServices, const
   new (slot) LocalType( &animation, &Animation::SetDuration, durationSeconds );
 }
 
-inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, bool looping )
+inline void SetLoopingMessage( EventThreadServices& eventThreadServices, const Animation& animation, int loopCount )
 {
-  typedef MessageValue1< Animation, bool > LocalType;
+  typedef MessageValue1< Animation, int > LocalType;
 
   // Reserve some memory inside the message queue
   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &animation, &Animation::SetLooping, looping );
+  new (slot) LocalType( &animation, &Animation::SetLoopCount, loopCount );
 }
 
 inline void SetEndActionMessage( EventThreadServices& eventThreadServices, const Animation& animation, Dali::Animation::EndAction action )
index 4c27d15..bcaf5fa 100644 (file)
@@ -96,7 +96,7 @@ Layer* FindLayer( Node& node )
 /**
  * Rebuild the Layer::colorRenderables, stencilRenderables and overlayRenderables members,
  * including only renderers which are included in the current render-task.
- * Returns true if all renderers have finshed acquiring resources.
+ * Returns true if all renderers have finished acquiring resources.
  */
 bool AddRenderablesForTask( BufferIndex updateBufferIndex,
                             Node& node,
@@ -252,6 +252,7 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
                                                  renderTask,
                                                  sourceNode->GetDrawMode() );
 
+      renderTask.SetResourcesFinished( resourcesFinished );
       PrepareRenderInstruction( updateBufferIndex,
                                 sortedLayers,
                                 renderTask,
@@ -259,8 +260,10 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex,
                                 renderTask.GetCullMode(),
                                 instructions );
     }
-
-    renderTask.SetResourcesFinished( resourcesFinished );
+    else
+    {
+      renderTask.SetResourcesFinished( resourcesFinished );
+    }
   }
 
   DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "ProcessRenderTasks() Onscreen\n");
index 7a37ec4..8a36580 100644 (file)
@@ -715,12 +715,16 @@ void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
 {
   AnimationContainer &animations = mImpl->animations;
   AnimationIter iter = animations.Begin();
+  bool animationLooped = false;
   while ( iter != animations.End() )
   {
     Animation* animation = *iter;
-    bool finished = animation->Update( bufferIndex, elapsedSeconds );
+    bool finished = false;
+    bool looped = false;
+    animation->Update( bufferIndex, elapsedSeconds, looped, finished );
 
     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
+    animationLooped = animationLooped || looped;
 
     // Remove animations that had been destroyed but were still waiting for an update
     if (animation->GetState() == Animation::Destroyed)
@@ -733,7 +737,8 @@ void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
     }
   }
 
-  if ( mImpl->animationFinishedDuringUpdate )
+  // queue the notification on finished or looped (to update loop count)
+  if ( mImpl->animationFinishedDuringUpdate || animationLooped )
   {
     // The application should be notified by NotificationManager, in another thread
     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
index 95b9015..5c06a12 100644 (file)
@@ -417,10 +417,11 @@ void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, Buffe
                      viewportSet ? &viewport : NULL,
                      mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
 
-  // if using native framebuffer, add a tracker
-  if( mTargetIsNativeFramebuffer )
+  if( mTargetIsNativeFramebuffer &&
+      mRefreshRate == Dali::RenderTask::REFRESH_ONCE &&
+      mResourcesFinished )
   {
-    // create tracker if not yet exists. if we switch to on-screen fbo, we still keep the tracker in case we need it again
+    // create tracker if one doesn't yet exist.
     if( !mRenderSyncTracker )
     {
       mRenderSyncTracker = new Render::RenderTracker();
index 3ccbbc2..698abe6 100644 (file)
@@ -313,6 +313,11 @@ public:
 
   /**
    * Prepares the render-instruction buffer to be populated with instructions.
+   *
+   * If the render task is a render-once framebuffer backed by a native image,
+   * then this method will ensure that a GL sync object is created to track
+   * when the rendering has finished.
+   *
    * @param[out] instruction to prepare
    * @param[in] updateBufferIndex The current update buffer index.
    */
index 072f3cc..3717007 100644 (file)
@@ -70,6 +70,7 @@ class DALI_IMPORT_API ImageActor : public Actor
 public:
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief An enumeration of properties belonging to the ImageActor class.
    * Properties additional to RenderableActor.
    * @SINCE_1_0.0
@@ -79,6 +80,7 @@ public:
     enum
     {
       /**
+       * @DEPRECATED_1_1.11
        * @brief name "pixelArea",   type Rect<int>
        * @SINCE_1_0.0
        */
@@ -96,6 +98,7 @@ public:
        */
       BORDER,
       /**
+       * @DEPRECATED_1_1.11
        * @brief name "image",       type Map {"filename":"", "loadPolicy":...}
        * @SINCE_1_0.0
        */
@@ -129,7 +132,12 @@ public:
    */
   enum Style
   {
-    STYLE_QUAD,                 ///< As a simple quad. @SINCE_1_0.0
+    /**
+     * @DEPRECATED_1_1.11
+     * @brief As a simple quad.
+     * @SINCE_1_0.0
+     */
+    STYLE_QUAD,
     /**
      * @DEPRECATED_1_1.11
      * @brief As a nine-patch.
@@ -145,6 +153,7 @@ public:
   };
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Pixel area is relative to the top-left (0,0) of the image.
    * @SINCE_1_0.0
    */
@@ -153,6 +162,7 @@ public:
   static const BlendingMode::Type DEFAULT_BLENDING_MODE; ///< default value is BlendingMode::AUTO
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Create an uninitialized ImageActor handle.
    *
    * This can be initialized with ImageActor::New(...)
@@ -162,6 +172,7 @@ public:
   ImageActor();
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Create an empty image actor object.
    *
    * @SINCE_1_0.0
@@ -170,6 +181,7 @@ public:
   static ImageActor New();
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Create a image actor object.
    *
    * The actor will take the image's natural size unless a custom size
@@ -183,6 +195,7 @@ public:
   static ImageActor New(Image image);
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Create a image actor object.
    *
    * The actor will take the image's natural size unless a custom size
@@ -198,6 +211,7 @@ public:
   static ImageActor New(Image image, PixelArea pixelArea);
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Downcast an Object handle to ImageActor.
    *
    *
@@ -211,6 +225,7 @@ public:
   static ImageActor DownCast( BaseHandle handle );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Destructor
    *
    * This is non-virtual since derived Handle types must not contain data or virtual methods.
@@ -219,6 +234,7 @@ public:
   ~ImageActor();
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Copy constructor
    *
    * @SINCE_1_0.0
@@ -227,6 +243,7 @@ public:
   ImageActor(const ImageActor& copy);
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Assignment operator
    *
    * @SINCE_1_0.0
@@ -235,7 +252,9 @@ public:
   ImageActor& operator=(const ImageActor& rhs);
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Set the image rendered by the actor.
+   *
    * Set the image rendered by the actor.
    * If actor was already displaying a different image, the old image is dropped and actor may
    * temporarily display nothing. Setting an empty image (handle) causes the current image to be
@@ -250,6 +269,7 @@ public:
   void SetImage(Image image);
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Retrieve the image rendered by the actor.
    *
    * If no image is assigned, an empty handle is returned
@@ -259,6 +279,7 @@ public:
   Image GetImage();
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Set a region of the image to display, in pixels.
    *
    * When the image is loaded the actor's size will be reset to the pixelArea,
@@ -272,6 +293,7 @@ public:
   void SetPixelArea(const PixelArea& pixelArea);
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Retrieve the region of the image to display, in pixels.
    *
    * @SINCE_1_0.0
@@ -330,6 +352,7 @@ public:
 
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Allows modification of an actors position in the depth sort algorithm.
    *
    * The offset can be altered for each coplanar actor hence allowing an order of painting.
@@ -340,6 +363,7 @@ public:
   void SetSortModifier(float depthOffset);
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Retrieves the offset used to modify an actors position in the depth sort algorithm.
    *
    * The offset can be altered for each coplanar actor hence allowing an order of painting.
@@ -350,6 +374,7 @@ public:
   float GetSortModifier() const;
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Sets the blending mode.
    *
    * Possible values are: BlendingMode::OFF, BlendingMode::AUTO and BlendingMode::ON. Default is BlendingMode::AUTO.
@@ -368,6 +393,7 @@ public:
   void SetBlendMode( BlendingMode::Type mode );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Retrieves the blending mode.
    *
    * @SINCE_1_0.0
@@ -376,6 +402,7 @@ public:
   BlendingMode::Type GetBlendMode() const;
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Specify the pixel arithmetic used when the actor is blended.
    *
    * @SINCE_1_0.0
@@ -392,6 +419,7 @@ public:
   void SetBlendFunc( BlendingFactor::Type srcFactorRgba, BlendingFactor::Type destFactorRgba );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Specify the pixel arithmetic used when the actor is blended.
    *
    * @SINCE_1_0.0
@@ -415,6 +443,7 @@ public:
                      BlendingFactor::Type srcFactorAlpha, BlendingFactor::Type destFactorAlpha );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Query the pixel arithmetic used when the actor is blended.
    *
    * @SINCE_1_0.0
@@ -427,6 +456,7 @@ public:
                      BlendingFactor::Type& srcFactorAlpha, BlendingFactor::Type& destFactorAlpha ) const;
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Specify the equation used when the actor is blended.
    *
    * The options are BlendingEquation::ADD, SUBTRACT, or REVERSE_SUBTRACT.
@@ -436,6 +466,7 @@ public:
   void SetBlendEquation( BlendingEquation::Type equationRgba );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Specify the equation used when the actor is blended.
    *
    * @SINCE_1_0.0
@@ -446,6 +477,7 @@ public:
   void SetBlendEquation( BlendingEquation::Type equationRgb, BlendingEquation::Type equationAlpha );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Query the equation used when the actor is blended.
    *
    * @SINCE_1_0.0
@@ -455,6 +487,7 @@ public:
   void GetBlendEquation( BlendingEquation::Type& equationRgb, BlendingEquation::Type& equationAlpha ) const;
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Specify the color used when the actor is blended; the default is Vector4::ZERO.
    *
    * @SINCE_1_0.0
@@ -463,6 +496,7 @@ public:
   void SetBlendColor( const Vector4& color );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Query the color used when the actor is blended.
    *
    * @SINCE_1_0.0
@@ -471,6 +505,7 @@ public:
   const Vector4& GetBlendColor() const;
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Sets the filtering mode.
    *
    * Possible values are: FilterMode::NEAREST and FilterMode::LINEAR. Default is FilterMode::LINEAR.
@@ -487,6 +522,7 @@ public:
   void SetFilterMode( FilterMode::Type minFilter, FilterMode::Type magFilter );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Retrieves the filtering mode.
    *
    * @SINCE_1_0.0
@@ -496,6 +532,7 @@ public:
   void GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter) const;
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Sets the shader effect for the RenderableActor.
    *
    * Shader effects provide special effects like ripple and bend.
@@ -508,6 +545,7 @@ public:
   void SetShaderEffect( ShaderEffect effect );
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Retrieve the custom shader effect for the RenderableActor.
    * If default shader is used an empty handle is returned.
    *
@@ -518,6 +556,7 @@ public:
   ShaderEffect GetShaderEffect() const;
 
   /**
+   * @DEPRECATED_1_1.11
    * @brief Removes the current shader effect.
    *
    * @SINCE_1_0.0
@@ -533,6 +572,7 @@ public: // Not intended for application developers
 
 
 /**
+ * @DEPRECATED_1_1.11
  * @brief Sets the shader effect for all ImageActors in a tree of Actors.
  *
  * @SINCE_1_0.0
@@ -544,6 +584,7 @@ public: // Not intended for application developers
 DALI_IMPORT_API void SetShaderEffectRecursively( Actor actor, ShaderEffect effect );
 
 /**
+ * @DEPRECATED_1_1.11
  * @brief Removes the shader effect from all ImageActors in a tree of Actors.
  *
  * @SINCE_1_0.0
index d02c830..559b26e 100644 (file)
@@ -104,11 +104,16 @@ public:
     LAYER_2D,
 
     /**
-     * @brief Layer will use depth test and do several clears.
+     * @brief Layer will use depth test.
+     *
+     * When using this mode depth depth test will be used. Opaque renderers are drawn first
+     * and write to the depth buffer. Then transparent renderers are drawn with depth test
+     * enabled but depth write switched off.
+     * Transparent renderers are drawn based on their distance from the camera (painter's algorithm).
+     * A renderers DEPTH_INDEX property is used to offset the distance to the camera when ordering transparent renderers.
+     * This is useful if you want to define the draw order of two or more transparent renderers that are
+     * equal distance from the camera.
      *
-     * When using this mode depth depth test will be used. A depth clear will happen for each distinct
-     * depth-index value in the layer, opaque renderers are drawn first and write to the depth buffer.
-     * Then transparent renderers are drawn with depth test enabled but depth write switched off.
      * @SINCE_1_0.0
      */
     LAYER_3D,
index 32c8ebe..686d81b 100644 (file)
@@ -79,6 +79,21 @@ void Animation::SetLooping(bool looping)
   GetImplementation(*this).SetLooping(looping);
 }
 
+void Animation::SetLoopCount(int count)
+{
+  GetImplementation(*this).SetLoopCount(count);
+}
+
+int Animation::GetLoopCount()
+{
+  return GetImplementation(*this).GetLoopCount();
+}
+
+int Animation::GetCurrentLoop()
+{
+  return GetImplementation(*this).GetCurrentLoop();
+}
+
 bool Animation::IsLooping() const
 {
   return GetImplementation(*this).IsLooping();
index 61a5007..d562c63 100644 (file)
@@ -215,14 +215,50 @@ public:
   float GetDuration() const;
 
   /**
-   * @brief Set whether the animation will loop.
+   * @brief Set whether the animation will loop forever.
+   *
+   * This function resets the loop count and should not be used with SetLoopCount(int).
+   * Setting this parameter does not cause the animation to Play()
    *
    * @SINCE_1_0.0
-   * @param[in] looping True if the animation will loop.
+   * @param[in] looping If true then the animation will loop forever, if false it will never loop.
    */
   void SetLooping(bool looping);
 
   /**
+   * @brief Enable looping for 'count' repeats.
+   *
+   * A zero is the same as SetLooping(true) ie repeat forever.
+   * If Play() Stop() or 'count' loops is reached, the loop counter will reset.
+   * Setting this parameter does not cause the animation to Play()
+   *
+   * @SINCE_1_1.20
+   * @param[in] count The number of times to loop.
+   */
+  void SetLoopCount(int count);
+
+  /**
+   * @brief Get the loop count.
+   *
+   * A zero is the same as SetLooping(true) ie repeat forever.
+   * The loop count is initially 1 for play once.
+   *
+   * @SINCE_1_1.20
+   * @return The number of times to loop.
+   */
+  int GetLoopCount();
+
+  /**
+   * @brief Get the current loop count.
+   *
+   * A value 0 to GetLoopCount() indicating the current loop count when looping.
+   *
+   * @SINCE_1_1.20
+   * @return The current number of loops that have occured.
+   */
+  int GetCurrentLoop();
+
+  /**
    * @brief Query whether the animation will loop.
    *
    * @SINCE_1_0.0
index 5fa2fde..7d86e14 100644 (file)
@@ -28,7 +28,7 @@ namespace Dali
 
 const unsigned int CORE_MAJOR_VERSION = 1;
 const unsigned int CORE_MINOR_VERSION = 1;
-const unsigned int CORE_MICRO_VERSION = 19;
+const unsigned int CORE_MICRO_VERSION = 20;
 const char * const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifndef EMSCRIPTEN
index e63aeda..028217d 100644 (file)
@@ -63,7 +63,7 @@ FrameBufferImage FrameBufferImage::New( unsigned int width, unsigned int height,
   return FrameBufferImage(internal.Get());
 }
 
-FrameBufferImage FrameBufferImage::New( unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy /*releasePolicy*/, RenderBuffer::Format bufferformat )
+FrameBufferImage FrameBufferImage::New( unsigned int width, unsigned int height, Pixel::Format pixelformat, ReleasePolicy releasePolicy, RenderBuffer::Format bufferformat )
 {
   Dali::Vector2 stageSize = Stage::GetCurrent().GetSize();
   Internal::FrameBufferImagePtr internal = Internal::FrameBufferImage::New(
@@ -72,12 +72,14 @@ FrameBufferImage FrameBufferImage::New( unsigned int width, unsigned int height,
     pixelformat,
     bufferformat);
 
+  internal->SetReleasePolicy( releasePolicy );
   return FrameBufferImage(internal.Get());
 }
 
-FrameBufferImage FrameBufferImage::New( NativeImageInterface& image, ReleasePolicy /*releasePolicy*/ )
+FrameBufferImage FrameBufferImage::New( NativeImageInterface& image, ReleasePolicy releasePolicy )
 {
   Internal::FrameBufferImagePtr internal = Internal::FrameBufferImage::New( image );
+  internal->SetReleasePolicy( releasePolicy );
   return FrameBufferImage(internal.Get());
 }
 
index fd40713..81fae36 100644 (file)
@@ -64,4 +64,14 @@ NativeImage NativeImage::DownCast( BaseHandle handle )
   return NativeImage( dynamic_cast<Internal::NativeImage*>( handle.GetObjectPtr()) );
 }
 
+const char* NativeImage::GetCustomSamplerTypename()
+{
+  return GetImplementation(*this).GetCustomSamplerTypename();
+}
+
+const char* NativeImage::GetCustomFragmentPreFix()
+{
+  return GetImplementation(*this).GetCustomFragmentPreFix();
+}
+
 } // namespace Dali
index 43ccbe6..b666b15 100644 (file)
@@ -107,10 +107,24 @@ public:
    * If not, the returned handle is left unintialized.
    * @SINCE_1_0.0
    * @param[in] handle Handle to an object.
-   * @return handle to a NativeImage or an uninitialized handle.
+   * @return Handle to a NativeImage or an uninitialized handle.
    */
   static NativeImage DownCast( BaseHandle handle );
 
+  /**
+   * @brief Get custom fragment prefix for rendering a native image.
+   *
+   * @return String for custom fragment prefix
+   */
+  const char* GetCustomFragmentPreFix();
+
+  /**
+   * @brief Get custom sampler type name for rendering a native image.
+   *
+   * @return String for custom sampler type name
+   */
+  const char* GetCustomSamplerTypename();
+
 public: // Not intended for application developers
 
   explicit DALI_INTERNAL NativeImage( Internal::NativeImage* );
index ed0d44f..f810db4 100644 (file)
@@ -30,6 +30,7 @@ namespace Dali
  */
 
 /**
+ * @DEPRECATED_1_0.47
  * @brief DALI_COMPOSE_SHADER macro provides a convenient way to write shader source code.
  *
  * We normally use double quotation marks to write a string such as "Hello World".
@@ -116,6 +117,7 @@ public:
 
   // Default Properties
   /**
+   * @DEPRECATED_1_0.47
    * @brief An enumeration of properties belonging to the ShaderEffect class.
    * Grid Density defines the spacing of vertex coordinates in world units.
    * ie a larger actor will have more grids at the same spacing.
@@ -133,31 +135,33 @@ public:
   {
     enum
     {
-      GRID_DENSITY = DEFAULT_ACTOR_PROPERTY_START_INDEX, ///< name "gridDensity",    type float @SINCE_1_0.0
-      IMAGE,                                             ///< name "image",          type Map {"filename":"", "loadPolicy":...} @SINCE_1_0.0
-      PROGRAM,                                           ///< name "program",        type Map {"vertexPrefix":"","fragmentPrefix":"","vertex":"","fragment":""} @SINCE_1_0.0
-      GEOMETRY_HINTS                                     ///< name "geometryHints",  type int (bitfield) values from enum GeometryHints @SINCE_1_0.0
+      GRID_DENSITY = DEFAULT_ACTOR_PROPERTY_START_INDEX, ///< @DEPRECATED_1_0.47 @brief name "gridDensity",    type float @SINCE_1_0.0
+      IMAGE,                                             ///< @DEPRECATED_1_0.47 @brief name "image",          type Map {"filename":"", "loadPolicy":...} @SINCE_1_0.0
+      PROGRAM,                                           ///< @DEPRECATED_1_0.47 @brief name "program",        type Map {"vertexPrefix":"","fragmentPrefix":"","vertex":"","fragment":""} @SINCE_1_0.0
+      GEOMETRY_HINTS                                     ///< @DEPRECATED_1_0.47 @brief name "geometryHints",  type int (bitfield) values from enum GeometryHints @SINCE_1_0.0
     };
   };
 
   static const float DEFAULT_GRID_DENSITY;              ///< The default density is 40 pixels
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Hints for rendering/subdividing geometry.
    * @SINCE_1_0.0
    */
   enum GeometryHints
   {
-    HINT_NONE           = 0x00,   ///< no hints @SINCE_1_0.0
-    HINT_GRID_X         = 0x01,   ///< Geometry must be subdivided in X @SINCE_1_0.0
-    HINT_GRID_Y         = 0x02,   ///< Geometry must be subdivided in Y @SINCE_1_0.0
-    HINT_GRID           = (HINT_GRID_X | HINT_GRID_Y),
-    HINT_DEPTH_BUFFER   = 0x04,   ///< Needs depth buffering turned on @SINCE_1_0.0
-    HINT_BLENDING       = 0x08,   ///< Notifies the actor to use blending even if it's fully opaque. Needs actor's blending set to BlendingMode::AUTO @SINCE_1_0.0
-    HINT_DOESNT_MODIFY_GEOMETRY = 0x10 ///< Notifies that the vertex shader will not change geometry (enables bounding box culling) @SINCE_1_0.0
+    HINT_NONE           = 0x00,   ///< @DEPRECATED_1_0.47 @brief no hints @SINCE_1_0.0
+    HINT_GRID_X         = 0x01,   ///< @DEPRECATED_1_0.47 @brief Geometry must be subdivided in X @SINCE_1_0.0
+    HINT_GRID_Y         = 0x02,   ///< @DEPRECATED_1_0.47 @brief Geometry must be subdivided in Y @SINCE_1_0.0
+    HINT_GRID           = (HINT_GRID_X | HINT_GRID_Y),  ///< @DEPRECATED_1_0.47 @brief HINT_GRID_X | HINT_GRID_Y @SINCE_1_0.0
+    HINT_DEPTH_BUFFER   = 0x04,   ///< @DEPRECATED_1_0.47 @brief Needs depth buffering turned on @SINCE_1_0.0
+    HINT_BLENDING       = 0x08,   ///< @DEPRECATED_1_0.47 @brief Notifies the actor to use blending even if it's fully opaque. Needs actor's blending set to BlendingMode::AUTO @SINCE_1_0.0
+    HINT_DOESNT_MODIFY_GEOMETRY = 0x10 ///< @DEPRECATED_1_0.47 @brief Notifies that the vertex shader will not change geometry (enables bounding box culling) @SINCE_1_0.0
   };
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Coordinate type of the shader uniform.
    *
    * Viewport coordinate types will convert from viewport to view space.
@@ -168,12 +172,13 @@ public:
    */
   enum UniformCoordinateType
   {
-    COORDINATE_TYPE_DEFAULT,           ///< @brief Default, No transformation to be applied @SINCE_1_0.0
-    COORDINATE_TYPE_VIEWPORT_POSITION, ///< @DEPRECATED_1_1.11 @brief The uniform is a position vector in viewport coordinates that needs to be converted to GL view space coordinates. @SINCE_1_0.0
-    COORDINATE_TYPE_VIEWPORT_DIRECTION ///< @DEPRECATED_1_1.11 @brief The uniform is a directional vector in viewport coordinates that needs to be converted to GL view space coordinates. @SINCE_1_0.0
+    COORDINATE_TYPE_DEFAULT,           ///< @DEPRECATED_1_0.47 @brief Default, No transformation to be applied @SINCE_1_0.0
+    COORDINATE_TYPE_VIEWPORT_POSITION, ///< @DEPRECATED_1_0.47 @brief The uniform is a position vector in viewport coordinates that needs to be converted to GL view space coordinates. @SINCE_1_0.0
+    COORDINATE_TYPE_VIEWPORT_DIRECTION ///< @DEPRECATED_1_0.47 @brief The uniform is a directional vector in viewport coordinates that needs to be converted to GL view space coordinates. @SINCE_1_0.0
   };
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Create an empty ShaderEffect.
    *
    * This can be initialised with ShaderEffect::New(...)
@@ -182,6 +187,7 @@ public:
   ShaderEffect();
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Create ShaderEffect.
    *
    * @SINCE_1_0.0
@@ -195,6 +201,7 @@ public:
                            GeometryHints hints = GeometryHints(HINT_NONE) );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Create ShaderEffect.
    * @SINCE_1_0.0
    * @param vertexShaderPrefix code for the effect. It will be inserted before the default uniforms (ideal for \#defines)
@@ -211,6 +218,7 @@ public:
                                     GeometryHints hints = GeometryHints(HINT_NONE) );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Downcast an Object handle to ShaderEffect.
    *
    * If handle points to a ShaderEffect the downcast produces valid
@@ -223,6 +231,7 @@ public:
   static ShaderEffect DownCast( BaseHandle handle );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Destructor
    *
    * This is non-virtual since derived Handle types must not contain data or virtual methods.
@@ -231,6 +240,7 @@ public:
   ~ShaderEffect();
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Copy constructor
    *
    * @SINCE_1_0.0
@@ -239,6 +249,7 @@ public:
   ShaderEffect(const ShaderEffect& object);
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief This assignment operator is required for (smart) pointer semantics.
    *
    * @SINCE_1_0.0
@@ -248,6 +259,7 @@ public:
   ShaderEffect& operator=(const ShaderEffect& rhs);
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Sets image for using as effect texture.
    *
    * This image texture will be bound to the "sEffect" sampler
@@ -259,7 +271,9 @@ public:
   void SetEffectImage( Image image );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Set a uniform value.
+   *
    * This will register a property of type Property::FLOAT; see Object::RegisterProperty() for more details.
    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
    * @SINCE_1_0.0
@@ -273,6 +287,7 @@ public:
                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Set a uniform value.
    *
    * This will register a property of type Property::VECTOR2; see Object::RegisterProperty() for more details.
@@ -288,6 +303,7 @@ public:
                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Set a uniform value.
    *
    * This will register a property of type Property::VECTOR3; see Object::RegisterProperty() for more details.
@@ -303,6 +319,7 @@ public:
                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Set a uniform value.
    *
    * This will register a property of type Property::VECTOR4; see Object::RegisterProperty() for more details.
@@ -318,6 +335,7 @@ public:
                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Set a uniform value.
    *
    * This will register a property of type Property::MATRIX; see Object::RegisterProperty() for more details.
@@ -333,6 +351,7 @@ public:
                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief Set a uniform value.
    *
    * This will register a property of type Property::MATRIX3; see Object::RegisterProperty() for more details.
@@ -350,6 +369,7 @@ public:
 public: // Not intended for application developers
 
   /**
+   * @DEPRECATED_1_0.47
    * @brief This constructor is used by Dali New() methods.
    * @SINCE_1_0.0
    * @param [in] effect A pointer to a newly allocated Dali resource.
index ad8571a..01d8294 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali
 Summary:    The OpenGLES Canvas Core Library
-Version:    1.1.19
+Version:    1.1.20
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT