(Vector) Add NOTIFY_AFTER_RASTERIZATION property for low fps file + Use UpdateOnce... 27/309127/9
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 5 Apr 2024 03:16:25 +0000 (12:16 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Mon, 15 Apr 2024 04:55:25 +0000 (13:55 +0900)
Let we change renderer rendering behavior is IF_REQUIRED.

It will be useful if app try to render lottie file which has less than 60fps.

+

Let we use UpdateOnce() API for force-rendering instead of KeepRendering().

KeepRendering will make ProcessCoreEvents forcely, which might not be need for animated vector cases.

Change-Id: Iaece9a5ff9e135acfdac404f68bdc690e6a7be8c
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h

index 49c344a..6a69f93 100644 (file)
@@ -71,6 +71,8 @@ public:
   void RemoveIdle(CallbackBase* callback);
   void RunIdles();
 
+  void RequestUpdateOnce();
+
   static Integration::Scene GetScene(Dali::Window window);
 
   Dali::RenderSurfaceInterface& GetSurface();
index 4d77310..40c73ae 100644 (file)
@@ -139,6 +139,19 @@ void Adaptor::RunIdles()
   mReturnCallbacks.Swap(reusedCallbacks);
 }
 
+void Adaptor::RequestUpdateOnce()
+{
+  if(mTestApplication)
+  {
+    auto scene = mTestApplication->GetScene();
+    if(scene)
+    {
+      tet_printf("Adaptor::RequestUpdateOnce()\n");
+      scene.KeepRendering(0.0f);
+    }
+  }
+}
+
 Dali::RenderSurfaceInterface& Adaptor::GetSurface()
 {
   DALI_ASSERT_ALWAYS(!mWindows.empty());
index 08921c9..4801874 100644 (file)
@@ -208,13 +208,14 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
     .Add("stopBehavior", DevelImageVisual::StopBehavior::FIRST_FRAME)
     .Add("loopingMode", DevelImageVisual::LoopingMode::AUTO_REVERSE)
     .Add("redrawInScalingDown", false)
+    .Add("enableFrameCache", false)
+    .Add("notifyAfterRasterization", false)
     .Add("cornerRadius", cornerRadius)
     .Add("borderlineWidth", borderlineWidth)
     .Add("borderlineColor", borderlineColor)
     .Add("borderlineOffset", borderlineOffset)
     .Add("desiredWidth", desiredWidth)
-    .Add("desiredHeight", desiredHeight)
-    .Add("useFixedCache", false);
+    .Add("desiredHeight", desiredHeight);
 
   Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
   DALI_TEST_CHECK(visual);
@@ -270,6 +271,14 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == false);
 
+  value = resultMap.Find(DevelImageVisual::Property::ENABLE_FRAME_CACHE, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<bool>() == false);
+
+  value = resultMap.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<bool>() == false);
+
   value = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4);
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<Vector4>(), Vector4(cornerRadius, cornerRadius, cornerRadius, cornerRadius), TEST_LOCATION);
@@ -395,6 +404,10 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == false); // Check default value
 
+  value = resultMap.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<bool>() == false); // Check default value
+
   value = resultMap.Find(DevelImageVisual::Property::REDRAW_IN_SCALING_DOWN, Property::BOOLEAN);
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == true); // Check default value
@@ -1123,7 +1136,7 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - render a frame
+  // Trigger count is 1 - load
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   Vector2 controlSize(200.f, 200.f);
@@ -1132,7 +1145,7 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - load
+  // Trigger count is 1 - render a frame
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   // renderer is added to actor
@@ -1194,6 +1207,91 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed(void)
   END_TEST;
 }
 
+int UtcDaliAnimatedVectorImageVisualNotifyAfterRasterization(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedVectorImageVisualNotifyAfterRasterization");
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+    .Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, true)
+    .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - load
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  Vector2 controlSize(200.f, 200.f);
+  actor.SetProperty(Actor::Property::SIZE, controlSize);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  // Play animation
+  Property::Map attributes;
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes);
+
+  application.SendNotification();
+  application.Render();
+
+  // renderer is added to actor
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  Renderer renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
+
+  // Check renderer behavior
+  DALI_TEST_CHECK(renderer.GetProperty<int>(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::IF_REQUIRED);
+
+  Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  Property::Value* value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION);
+  DALI_TEST_CHECK(value->Get<bool>() == true);
+
+  propertyMap.Clear();
+  propertyMap.Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, false);
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, propertyMap);
+
+  application.SendNotification();
+  application.Render();
+
+  // Check renderer behavior again
+  DALI_TEST_CHECK(renderer.GetProperty<int>(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::CONTINUOUSLY);
+
+  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION);
+  DALI_TEST_CHECK(value->Get<bool>() == false);
+
+  propertyMap.Clear();
+  propertyMap.Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, true);
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, propertyMap);
+
+  application.SendNotification();
+  application.Render();
+
+  // Check renderer behavior again
+  DALI_TEST_CHECK(renderer.GetProperty<int>(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::IF_REQUIRED);
+
+  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION);
+  DALI_TEST_CHECK(value->Get<bool>() == true);
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
 {
   ToolkitTestApplication application;
index a5e135c..90e868e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_PROPERTIES_DEVEL_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -193,13 +193,24 @@ enum Type
 
   /**
    * @brief Whether to AnimatedVectorImageVisual fixed cache or not.
-   * @details Name "EnableFrameCache", type Property::BOOLEAN.
+   * @details Name "enableFrameCache", type Property::BOOLEAN.
    * If this property is true, AnimatedVectorImageVisual enable frame cache for loading and keeps loaded frame
    * until the visual is removed. It reduces CPU cost when the animated image will be looping.
    * But it can spend a lot of memory if the resource has high resolution image or many frame count.
-   * @note It is used in the AnimatedImageVisual. The default is false
+   * @note It is used in the AnimatedVectorImageVisual. The default is false
    */
-  ENABLE_FRAME_CACHE = ORIENTATION_CORRECTION + 16
+  ENABLE_FRAME_CACHE = ORIENTATION_CORRECTION + 16,
+
+  /**
+   * @brief Whether notify AnimatedVectorImageVisual to render thread after every rasterization or not.
+   * @details Name "notifyAfterRasterization", type Property::BOOLEAN.
+   * If this property is true, AnimatedVectorImageVisual send notify to render thread after every rasterization.
+   * If false, AnimatedVectorImageVisual set Renderer's Behaviour as Continouly (mean, always update the render thread.)
+   *
+   * This flag is useful if given resource has low fps, so we don't need to render every frame.
+   * @note It is used in the AnimatedVectorImageVisual. The default is false.
+   */
+  NOTIFY_AFTER_RASTERIZATION = ORIENTATION_CORRECTION + 17
 };
 
 } //namespace Property
index b23f066..6ee22d7 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/math/math-utils.h>
 #include <dali/public-api/rendering/decorated-visual-renderer.h>
@@ -103,7 +104,8 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory
   mCoreShutdown(false),
   mRedrawInScalingDown(true),
   mEnableFrameCache(false),
-  mUseNativeImage(false)
+  mUseNativeImage(false),
+  mNotifyAfterRasterization(false)
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Visual::Base::Impl::IS_PREMULTIPLIED_ALPHA;
@@ -221,6 +223,7 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap(Property::Map& map) const
   map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
   map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
   map.Insert(Toolkit::DevelImageVisual::Property::ENABLE_FRAME_CACHE, mEnableFrameCache);
+  map.Insert(Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, mNotifyAfterRasterization);
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const
@@ -285,6 +288,10 @@ void AnimatedVectorImageVisual::DoSetProperties(const Property::Map& propertyMap
       {
         DoSetProperty(Toolkit::DevelImageVisual::Property::ENABLE_FRAME_CACHE, keyValue.second);
       }
+      else if(keyValue.first == NOTIFY_AFTER_RASTERIZATION)
+      {
+        DoSetProperty(Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, keyValue.second);
+      }
     }
   }
 
@@ -404,6 +411,22 @@ void AnimatedVectorImageVisual::DoSetProperty(Property::Index index, const Prope
       }
       break;
     }
+
+    case Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION:
+    {
+      bool notifyAfterRasterization = false;
+      if(value.Get(notifyAfterRasterization))
+      {
+        if(mNotifyAfterRasterization != notifyAfterRasterization)
+        {
+          mNotifyAfterRasterization = notifyAfterRasterization;
+
+          mAnimationData.notifyAfterRasterization = mNotifyAfterRasterization;
+          mAnimationData.resendFlag |= VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION;
+        }
+      }
+      break;
+    }
   }
 }
 
@@ -719,7 +742,7 @@ void AnimatedVectorImageVisual::OnAnimationFinished(uint32_t playStateId)
     }
   }
 
-  if(mImpl->mRenderer)
+  if(!mNotifyAfterRasterization && mImpl->mRenderer)
   {
     mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
   }
@@ -727,9 +750,9 @@ void AnimatedVectorImageVisual::OnAnimationFinished(uint32_t playStateId)
 
 void AnimatedVectorImageVisual::OnForceRendering(uint32_t playStateId)
 {
-  if(!mCoreShutdown)
+  if(!mCoreShutdown && Dali::Adaptor::IsAvailable())
   {
-    Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing
+    Dali::Adaptor::Get().UpdateOnce();
   }
 }
 
@@ -746,14 +769,18 @@ void AnimatedVectorImageVisual::SendAnimationData()
     }
     mVectorAnimationTask->SetAnimationData(mAnimationData);
 
-    if(mImpl->mRenderer)
+    if(mImpl->mRenderer &&
+       ((mAnimationData.resendFlag & VectorAnimationTask::RESEND_PLAY_STATE) ||
+        (mAnimationData.resendFlag & VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION)))
     {
-      if(mAnimationData.playState == DevelImageVisual::PlayState::PLAYING)
+      if(!mNotifyAfterRasterization && mPlayState == DevelImageVisual::PlayState::PLAYING)
       {
+        // Make rendering behaviour if we don't notify after rasterization, but animation playing.
         mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY);
       }
       else
       {
+        // Otherwise, notify will be sended after rasterization. Make behaviour as required.
         mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
       }
     }
index 7e7b04d..a24a76a 100644 (file)
@@ -267,6 +267,7 @@ private:
   bool mRedrawInScalingDown : 1;
   bool mEnableFrameCache : 1;
   bool mUseNativeImage : 1;
+  bool mNotifyAfterRasterization : 1;
 };
 
 } // namespace Internal
index 423d3fc..d74b22d 100644 (file)
@@ -108,6 +108,7 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
   mLayerInfoCached(false),
   mMarkerInfoCached(false),
   mEnableFrameCache(false),
+  mNotifyAfterRasterization(false),
   mSizeUpdated(false)
 {
   mVectorRenderer.UploadCompletedSignal().Connect(this, &VectorAnimationTask::OnUploadCompleted);
@@ -747,7 +748,7 @@ bool VectorAnimationTask::Rasterize()
   }
 
   // Forcely trigger render once if need.
-  if(mNeedForceRenderOnceTrigger)
+  if(mNotifyAfterRasterization || mNeedForceRenderOnceTrigger)
   {
     Mutex::ScopedLock lock(mMutex);
     if(mForceRenderOnceCallback)
@@ -891,6 +892,11 @@ void VectorAnimationTask::ApplyAnimationData()
       SetCurrentFrameNumber(animationData.currentFrame);
     }
 
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION)
+    {
+      mNotifyAfterRasterization = animationData.notifyAfterRasterization;
+    }
+
     if(animationData.resendFlag & VectorAnimationTask::RESEND_NEED_RESOURCE_READY)
     {
       mVectorRenderer.InvalidateBuffer();
index 46976a5..92eff23 100644 (file)
@@ -67,15 +67,16 @@ public:
    */
   enum ResendFlags
   {
-    RESEND_PLAY_RANGE          = 1 << 0,
-    RESEND_LOOP_COUNT          = 1 << 1,
-    RESEND_STOP_BEHAVIOR       = 1 << 2,
-    RESEND_LOOPING_MODE        = 1 << 3,
-    RESEND_CURRENT_FRAME       = 1 << 4,
-    RESEND_SIZE                = 1 << 5,
-    RESEND_PLAY_STATE          = 1 << 6,
-    RESEND_NEED_RESOURCE_READY = 1 << 7,
-    RESEND_DYNAMIC_PROPERTY    = 1 << 8
+    RESEND_PLAY_RANGE                 = 1 << 0,
+    RESEND_LOOP_COUNT                 = 1 << 1,
+    RESEND_STOP_BEHAVIOR              = 1 << 2,
+    RESEND_LOOPING_MODE               = 1 << 3,
+    RESEND_CURRENT_FRAME              = 1 << 4,
+    RESEND_SIZE                       = 1 << 5,
+    RESEND_PLAY_STATE                 = 1 << 6,
+    RESEND_NEED_RESOURCE_READY        = 1 << 7,
+    RESEND_DYNAMIC_PROPERTY           = 1 << 8,
+    RESEND_NOTIFY_AFTER_RASTERIZATION = 1 << 9,
   };
 
   /**
@@ -94,22 +95,24 @@ public:
       width(0),
       height(0),
       loopCount(-1),
-      playStateId(0)
+      playStateId(0),
+      notifyAfterRasterization(false)
     {
     }
 
     AnimationData& operator=(const AnimationData& rhs)
     {
       resendFlag |= rhs.resendFlag; // OR resend flag
-      playRange    = rhs.playRange;
-      playState    = rhs.playState;
-      stopBehavior = rhs.stopBehavior;
-      loopingMode  = rhs.loopingMode;
-      currentFrame = rhs.currentFrame;
-      width        = rhs.width;
-      height       = rhs.height;
-      loopCount    = rhs.loopCount;
-      playStateId  = rhs.playStateId;
+      playRange                = rhs.playRange;
+      playState                = rhs.playState;
+      stopBehavior             = rhs.stopBehavior;
+      loopingMode              = rhs.loopingMode;
+      currentFrame             = rhs.currentFrame;
+      width                    = rhs.width;
+      height                   = rhs.height;
+      loopCount                = rhs.loopCount;
+      playStateId              = rhs.playStateId;
+      notifyAfterRasterization = rhs.notifyAfterRasterization;
       dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end());
       return *this;
     }
@@ -125,6 +128,7 @@ public:
     uint32_t                             height;
     int32_t                              loopCount;
     uint32_t                             playStateId;
+    bool                                 notifyAfterRasterization;
   };
 
   /**
@@ -263,6 +267,16 @@ public:
    */
   bool IsAnimating();
 
+  void KeepRasterizedBuffer(bool enableFrameCache)
+  {
+    mEnableFrameCache = enableFrameCache;
+  }
+
+  bool IsKeptRasterizedBuffer() const
+  {
+    return mEnableFrameCache;
+  }
+
 public: // Implementation of AsyncTask
   /**
    * @copydoc Dali::AsyncTask::Process()
@@ -282,16 +296,6 @@ public: // Implementation of AsyncTask
     return "VectorAnimationTask";
   }
 
-  void KeepRasterizedBuffer(bool enableFrameCache)
-  {
-    mEnableFrameCache = enableFrameCache;
-  }
-
-  bool IsKeptRasterizedBuffer()
-  {
-    return mEnableFrameCache;
-  }
-
 private:
   /**
    * @brief Loads the animation file.
@@ -433,6 +437,7 @@ private:
   mutable bool                         mLayerInfoCached : 1;
   mutable bool                         mMarkerInfoCached : 1;
   bool                                 mEnableFrameCache : 1;
+  bool                                 mNotifyAfterRasterization : 1;
   bool                                 mSizeUpdated : 1;
 };
 
index 6d89342..ae39540 100644 (file)
@@ -212,6 +212,7 @@ const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio");
 const char* const FAST_TRACK_UPLOADING_NAME("fastTrackUploading");
 const char* const ENABLE_BROKEN_IMAGE("enableBrokenImage");
 const char* const ENABLE_FRAME_CACHE("enableFrameCache");
+const char* const NOTIFY_AFTER_RASTERIZATION("notifyAfterRasterization");
 
 // Text visual
 const char* const TEXT_PROPERTY("text");
index cc97413..9835299 100644 (file)
@@ -114,6 +114,7 @@ extern const char* const MASK_TEXTURE_RATIO_NAME;
 extern const char* const FAST_TRACK_UPLOADING_NAME;
 extern const char* const ENABLE_BROKEN_IMAGE;
 extern const char* const ENABLE_FRAME_CACHE;
+extern const char* const NOTIFY_AFTER_RASTERIZATION;
 
 // Text visual
 extern const char* const TEXT_PROPERTY;