#include "image-renderer.h"
// EXTERNAL HEADER
+#include <cstring> // for strncasecmp
#include <dali/public-api/images/resource-image.h>
#include <dali/integration-api/debug.h>
namespace
{
+const char HTTP_URL[] = "http://";
+const char HTTPS_URL[] = "https://";
+
const char * const RENDERER_TYPE("rendererType");
const char * const RENDERER_TYPE_VALUE("imageRenderer");
mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
}
+ // remove old renderer if exit
if( mImpl->mRenderer )
{
- //remove old renderer
- if( actor )
+ if( actor ) //remove old renderer from actor
{
actor.RemoveRenderer( mImpl->mRenderer );
}
-
- //clean the cache
- if( !oldImageUrl.empty() )
+ if( !oldImageUrl.empty() ) //clean old renderer from cache
{
CleanCache( oldImageUrl );
}
+ }
- //Initialize the renderer
- if( !mImageUrl.empty() )
- {
- InitializeRenderer( mImageUrl );
- }
- else if( mImage )
- {
- InitializeRenderer( mImage );
- }
-
- //add the new renderer to the actor
- if( actor && mImpl->mRenderer )
- {
- actor.AddRenderer( mImpl->mRenderer );
- }
+ // if actor is on stage, create new renderer and apply to actor
+ if( actor && actor.OnStage() )
+ {
+ SetOnStage( actor );
}
}
void ImageRenderer::InitializeRenderer( const std::string& imageUrl )
{
- if( mImageUrl.empty() )
+ if( imageUrl.empty() )
{
- mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
return;
}
+ mImageUrl = imageUrl;
mImpl->mRenderer.Reset();
- if( !mImpl->mCustomShader )
+
+ if( !mImpl->mCustomShader &&
+ ( strncasecmp( imageUrl.c_str(), HTTP_URL, sizeof(HTTP_URL) -1 ) != 0 ) && // ignore remote images
+ ( strncasecmp( imageUrl.c_str(), HTTPS_URL, sizeof(HTTPS_URL) -1 ) != 0 ) )
{
mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl );
if( !mImpl->mRenderer )
{
- Material material = mAtlasManager.Add(mTextureRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
- if( material )
- {
- Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
- mImpl->mRenderer = Renderer::New( geometry, material );
- SetTextureRectUniform(mTextureRect);
- }
- else // big image, atlasing is not applied
- {
- mImpl->mRenderer = CreateRenderer();
+ Material material = mAtlasManager.Add(mTextureRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+ if( material )
+ {
+ Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
+ mImpl->mRenderer = Renderer::New( geometry, material );
+ SetTextureRectUniform(mTextureRect);
+ }
+ else // big image, atlasing is not applied
+ {
+ mImpl->mRenderer = CreateRenderer();
+ mTextureRect = FULL_TEXTURE_RECT;
+ SetTextureRectUniform(mTextureRect);
- ResourceImage image = Dali::ResourceImage::New( imageUrl );
- image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
- Material material = mImpl->mRenderer.GetMaterial();
- material.AddTexture( image, TEXTURE_UNIFORM_NAME );
- }
+ ResourceImage image = Dali::ResourceImage::New( imageUrl );
+ image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
+ Material material = mImpl->mRenderer.GetMaterial();
+ material.AddTexture( image, TEXTURE_UNIFORM_NAME );
+ }
- mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer );
+ mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer );
}
else
{
}
else
{
+ // for custom shader or remote image, renderer is not cached and atlas is not applied
+
mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
mImpl->mRenderer = CreateRenderer();
- ResourceImage image = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
- image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
- ApplyImageToSampler( image );
+ ResourceImage resourceImage = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+ resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
+ ApplyImageToSampler( resourceImage );
+
+ // custom vertex shader does not need texture rect uniform
+ if( mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty() )
+ {
+ return;
+ }
+
+ mTextureRect = FULL_TEXTURE_RECT;
+ SetTextureRectUniform( mTextureRect );
}
}
mImpl->mRenderer = CreateRenderer();
ApplyImageToSampler( image );
- SetTextureRectUniform( FULL_TEXTURE_RECT );
+
+ // default shader or custom shader with the default image vertex shader
+ if( !mImpl->mCustomShader || mImpl->mCustomShader->mVertexShader.empty() )
+ {
+ mTextureRect = FULL_TEXTURE_RECT;
+ SetTextureRectUniform( mTextureRect );
+ }
}
{
InitializeRenderer( mImage );
}
-
- if( !GetIsFromCache() )
- {
- Image image = mImage;
- if( !mImageUrl.empty() )
- {
- ResourceImage resourceImage = Dali::ResourceImage::New( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode );
- resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
- image = resourceImage;
-
- // Set value to the uTextureRect uniform
- SetTextureRectUniform( FULL_TEXTURE_RECT );
- }
-
- ApplyImageToSampler( image );
- }
}
void ImageRenderer::DoSetOffStage( Actor& actor )
void ImageRenderer::SetImage( Actor& actor, const std::string& imageUrl, ImageDimensions size, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
{
- mDesiredSize = size;
- mFittingMode = fittingMode;
- mSamplingMode = samplingMode;
-
if( mImageUrl != imageUrl )
{
+ std::string oldImageUrl = mImageUrl;
+ mImageUrl = imageUrl;
+ mDesiredSize = size;
+ mFittingMode = fittingMode;
+ mSamplingMode = samplingMode;
+ mImage.Reset();
+
if( mImpl->mRenderer )
{
- if( GetIsFromCache() )
+ if( GetIsFromCache() ) // if renderer is from cache, remove the old one
{
//remove old renderer
if( actor )
}
//clean the cache
- if( !mImageUrl.empty() )
+ if( !oldImageUrl.empty() )
{
- CleanCache(mImageUrl);
+ CleanCache(oldImageUrl);
}
- //Initialize the renderer
- InitializeRenderer( imageUrl );
-
- //add the new renderer to the actor
- if( actor && mImpl->mRenderer )
+ if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
{
- actor.AddRenderer( mImpl->mRenderer );
+ SetOnStage(actor);
}
}
- else
+ else // if renderer is not from cache, reuse the same renderer and only change the texture
{
ResourceImage image = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
ApplyImageToSampler( image );
}
}
-
- mImageUrl = imageUrl;
-
- mImage.Reset();
}
}
{
if( mImage != image )
{
+ mImage = image;
+
if( mImpl->mRenderer )
{
- if( GetIsFromCache() )
+ if( GetIsFromCache() ) // if renderer is from cache, remove the old one
{
//remove old renderer
if( actor )
{
CleanCache(mImageUrl);
}
+ mImageUrl.clear();
- //Initialize the renderer
- InitializeRenderer( image );
-
- //add the new renderer to the actor
- if( actor && mImpl->mRenderer )
+ if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
{
- actor.AddRenderer( mImpl->mRenderer );
+ SetOnStage(actor);
}
}
- else
+ else // if renderer is not from cache, reuse the same renderer and only change the texture
{
ApplyImageToSampler( image );
}
}
- SetTextureRectUniform( FULL_TEXTURE_RECT );
- mImage = image;
mImageUrl.clear();
mDesiredSize = ImageDimensions();
mFittingMode = FittingMode::DEFAULT;
{
if( image.GetLoadingState() == Dali::ResourceLoadingFailed )
{
- Image image = RendererFactory::GetBrokenRendererImage();
+ Image brokenImage = RendererFactory::GetBrokenRendererImage();
if( mImpl->mRenderer )
{
- ApplyImageToSampler( image );
+ ApplyImageToSampler( brokenImage );
}
}
}
{
if( mImpl->mRenderer )
{
- Property::Index index = mImpl->mRenderer.GetPropertyIndex( TEXTURE_RECT_UNIFORM_NAME );
- if( index == Property::INVALID_INDEX )
- {
- index = mImpl->mRenderer.RegisterProperty( TEXTURE_RECT_UNIFORM_NAME, textureRect );
- }
- else
- {
- mImpl->mRenderer.SetProperty( index, textureRect );
- }
+ // Register/Set property.
+ mImpl->mRenderer.RegisterProperty( TEXTURE_RECT_UNIFORM_NAME, textureRect );
}
}