+ mImpl->mRenderer = Renderer::New(geometry, shader);
+
+ // Register transform properties
+ mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+
+ if(!defaultWrapMode) // custom wrap mode
+ {
+ Vector2 wrapMode(mWrapModeU - WrapMode::CLAMP_TO_EDGE, mWrapModeV - WrapMode::CLAMP_TO_EDGE);
+ wrapMode.Clamp(Vector2::ZERO, Vector2(2.f, 2.f));
+ mImpl->mRenderer.RegisterProperty(WRAP_MODE_UNIFORM_NAME, wrapMode);
+ }
+
+ if(mPixelArea != FULL_TEXTURE_RECT)
+ {
+ mImpl->mRenderer.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, mPixelArea);
+ }
+}
+
+void AnimatedImageVisual::LoadFirstBatch()
+{
+ // Ensure the batch size and cache size are no bigger than the number of URLs,
+ // and that the cache is at least as big as the batch size.
+ uint16_t numUrls = 0;
+ uint16_t batchSize = 1;
+ uint16_t cacheSize = 1;
+
+ if(mImageUrls)
+ {
+ numUrls = mImageUrls->size();
+ }
+ else
+ {
+ numUrls = mFrameCount;
+ }
+
+ batchSize = std::min(mBatchSize, numUrls);
+ cacheSize = std::min(std::max(batchSize, mCacheSize), numUrls);
+
+ DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::LoadFirstBatch() batchSize:%d cacheSize:%d\n", batchSize, cacheSize);
+
+ mUrlIndex = 0;
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+
+ if(mAnimatedImageLoading)
+ {
+ mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, mFrameCount, *this, cacheSize, batchSize, IsSynchronousLoadingRequired());
+ }
+ else if(mImageUrls)
+ {
+ if(batchSize > 0 && cacheSize > 0)
+ {
+ if(cacheSize < numUrls)
+ {
+ mImageCache = new RollingImageCache(textureManager, *mImageUrls, *this, cacheSize, batchSize);
+ }
+ else
+ {
+ mImageCache = new FixedImageCache(textureManager, *mImageUrls, *this, batchSize);
+ }
+ }
+ else
+ {
+ mImageCache = new RollingImageCache(textureManager, *mImageUrls, *this, 1, 1);
+ }
+ }
+
+ if(!mImageCache)
+ {
+ DALI_LOG_ERROR("mImageCache is null\n");
+ }
+}
+
+void AnimatedImageVisual::StartFirstFrame(TextureSet& textureSet)
+{
+ DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::StartFirstFrame()\n");
+
+ mStartFirstFrame = false;
+ if(mImpl->mRenderer)
+ {
+ mImpl->mRenderer.SetTextures(textureSet);
+
+ Actor actor = mPlacementActor.GetHandle();
+ if(actor)
+ {
+ actor.AddRenderer(mImpl->mRenderer);
+ mPlacementActor.Reset();
+ }
+ }
+
+ if(mFrameCount > 1)
+ {
+ int frameDelay = mImageCache->GetFrameInterval(0);
+ if(frameDelay == 0u)
+ {
+ frameDelay = mFrameDelay; // from URL array
+ }
+ mFrameDelayTimer = Timer::New(frameDelay);
+ mFrameDelayTimer.TickSignal().Connect(this, &AnimatedImageVisual::DisplayNextFrame);
+ mFrameDelayTimer.Start();
+ }
+
+ if(mImpl->mResourceStatus != Toolkit::Visual::ResourceStatus::FAILED)
+ {
+ DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::READY)\n");
+ ResourceReady(Toolkit::Visual::ResourceStatus::READY);
+ }
+}
+
+TextureSet AnimatedImageVisual::PrepareTextureSet()
+{
+ TextureSet textureSet;
+ if(mImageCache)
+ {
+ textureSet = mImageCache->FirstFrame();