X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fimage%2Fimage-visual.cpp;h=098432669ccd940efd4716991c14569c45edb0cc;hp=569646fe18842ff22588f42bdc873c38ad792b4f;hb=0c82f46f03efa9471b47dfd3a73eb8f1a8dae6c3;hpb=4cd15baa1eaa620c0ef5e94e56d82fad17b888d5 diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 569646f..0984326 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -25,15 +25,18 @@ #include #include #include +#include +#include #include // INTERNAL HEADER +#include #include #include #include -#include -#include +#include #include +#include namespace Dali { @@ -54,25 +57,41 @@ const char * const IMAGE_FITTING_MODE( "fittingMode" ); const char * const IMAGE_SAMPLING_MODE( "samplingMode" ); const char * const IMAGE_DESIRED_WIDTH( "desiredWidth" ); const char * const IMAGE_DESIRED_HEIGHT( "desiredHeight" ); +const char * const IMAGE_WRAP_MODE_U("wrapModeU"); +const char * const IMAGE_WRAP_MODE_V("wrapModeV"); const char * const SYNCHRONOUS_LOADING( "synchronousLoading" ); +const char * const BATCHING_ENABLED( "batchingEnabled" ); // fitting modes -const char * const SHRINK_TO_FIT("SHRINK_TO_FIT"); -const char * const SCALE_TO_FILL("SCALE_TO_FILL"); -const char * const FIT_WIDTH("FIT_WIDTH"); -const char * const FIT_HEIGHT("FIT_HEIGHT"); -const char * const DEFAULT("DEFAULT"); +DALI_ENUM_TO_STRING_TABLE_BEGIN( FITTING_MODE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::FittingMode, SHRINK_TO_FIT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::FittingMode, SCALE_TO_FILL ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::FittingMode, FIT_WIDTH ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::FittingMode, FIT_HEIGHT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::FittingMode, DEFAULT ) +DALI_ENUM_TO_STRING_TABLE_END( FITTING_MODE ) // sampling modes -const char * const BOX("BOX"); -const char * const NEAREST("NEAREST"); -const char * const LINEAR("LINEAR"); -const char * const BOX_THEN_NEAREST("BOX_THEN_NEAREST"); -const char * const BOX_THEN_LINEAR("BOX_THEN_LINEAR"); -const char * const NO_FILTER("NO_FILTER"); -const char * const DONT_CARE("DONT_CARE"); +DALI_ENUM_TO_STRING_TABLE_BEGIN( SAMPLING_MODE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, BOX ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, NEAREST ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, LINEAR ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, BOX_THEN_NEAREST ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, BOX_THEN_LINEAR ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, NO_FILTER ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, DONT_CARE ) +DALI_ENUM_TO_STRING_TABLE_END( SAMPLING_MODE ) + +// wrap modes +DALI_ENUM_TO_STRING_TABLE_BEGIN( WRAP_MODE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, DEFAULT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, CLAMP_TO_EDGE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, REPEAT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, MIRRORED_REPEAT ) +DALI_ENUM_TO_STRING_TABLE_END( WRAP_MODE ) const std::string PIXEL_AREA_UNIFORM_NAME = "pixelArea"; +const std::string WRAP_MODE_UNIFORM_NAME = "wrapMode"; const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); @@ -82,7 +101,6 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n uniform mediump mat4 uMvpMatrix;\n uniform mediump vec3 uSize;\n - uniform mediump vec4 uAtlasRect;\n uniform mediump vec4 pixelArea; varying mediump vec2 vTexCoord;\n \n @@ -92,12 +110,12 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( vertexPosition.xyz *= uSize;\n vertexPosition = uMvpMatrix * vertexPosition;\n \n - vTexCoord = mix( uAtlasRect.xy, uAtlasRect.zw, pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) ) );\n + vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n gl_Position = vertexPosition;\n }\n ); -const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( +const char* FRAGMENT_SHADER_NO_ATLAS = DALI_COMPOSE_SHADER( varying mediump vec2 vTexCoord;\n uniform sampler2D sTexture;\n uniform lowp vec4 uColor;\n @@ -108,6 +126,45 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( }\n ); +const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + uniform lowp vec4 uColor;\n + \n + void main()\n + {\n + mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor;\n + }\n +); + +const char* FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + // WrapMode -- 0: CLAMP; 1: REPEAT; 2: REFLECT; + uniform lowp vec2 wrapMode;\n + uniform lowp vec4 uColor;\n + \n + mediump float wrapCoordinate( mediump vec2 range, mediump float coordinate, lowp float wrap )\n + {\n + mediump float coord;\n + if( wrap > 1.5 )\n // REFLECT + coord = 1.0-abs(fract(coordinate*0.5)*2.0 - 1.0);\n + else \n// warp == 0 or 1 + coord = mix(coordinate, fract( coordinate ), wrap);\n + return clamp( mix(range.x, range.y, coord), range.x, range.y ); + }\n + \n + void main()\n + {\n + mediump vec2 texCoord = vec2( wrapCoordinate( uAtlasRect.xz, vTexCoord.x, wrapMode.x ), + wrapCoordinate( uAtlasRect.yw, vTexCoord.y, wrapMode.y ) );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor;\n + }\n +); + Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridSize ) { Geometry geometry; @@ -131,12 +188,14 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS } //unnamed namespace -ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ) -: Visual( factoryCache ), - mAtlasManager( atlasManager ), +ImageVisual::ImageVisual( VisualFactoryCache& factoryCache ) +: Visual::Base( factoryCache ), + mPixelArea( FULL_TEXTURE_RECT ), mDesiredSize(), mFittingMode( FittingMode::DEFAULT ), mSamplingMode( SamplingMode::DEFAULT ), + mWrapModeU( WrapMode::DEFAULT ), + mWrapModeV( WrapMode::DEFAULT ), mNativeFragmentShaderCode( ), mNativeImageFlag( false ) { @@ -150,7 +209,7 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) { std::string oldImageUrl = mImageUrl; - Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME ); + Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME ); if( imageURLValue ) { imageURLValue->Get( mImageUrl ); @@ -159,103 +218,54 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) mImage.Reset(); } - Property::Value* fittingValue = propertyMap.Find( IMAGE_FITTING_MODE ); + Property::Value* fittingValue = propertyMap.Find( Toolkit::ImageVisual::Property::FITTING_MODE, IMAGE_FITTING_MODE ); if( fittingValue ) { - std::string fitting; - fittingValue->Get( fitting ); - - mFittingMode = FittingMode::DEFAULT; - if( fitting == SHRINK_TO_FIT ) - { - mFittingMode = FittingMode::SHRINK_TO_FIT; - } - else if( fitting == SCALE_TO_FILL ) - { - mFittingMode = FittingMode::SCALE_TO_FILL; - } - else if( fitting == FIT_WIDTH ) - { - mFittingMode = FittingMode::FIT_WIDTH; - } - else if( fitting == FIT_HEIGHT ) - { - mFittingMode = FittingMode::FIT_HEIGHT; - } - else if( fitting == DEFAULT ) - { - mFittingMode = FittingMode::DEFAULT; - } - else - { - DALI_ASSERT_ALWAYS("Unknown fitting mode"); - } + Scripting::GetEnumerationProperty( *fittingValue, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, mFittingMode ); } - Property::Value* samplingValue = propertyMap.Find( IMAGE_SAMPLING_MODE ); + Property::Value* samplingValue = propertyMap.Find( Toolkit::ImageVisual::Property::SAMPLING_MODE, IMAGE_SAMPLING_MODE ); if( samplingValue ) { - std::string sampling; - samplingValue->Get( sampling ); - - mSamplingMode = SamplingMode::DEFAULT; - if( sampling == BOX ) - { - mSamplingMode = SamplingMode::BOX; - } - else if( sampling == NEAREST ) - { - mSamplingMode = SamplingMode::NEAREST; - } - else if( sampling == LINEAR ) - { - mSamplingMode = SamplingMode::LINEAR; - } - else if( sampling == BOX_THEN_NEAREST ) - { - mSamplingMode = SamplingMode::BOX_THEN_NEAREST; - } - else if( sampling == BOX_THEN_LINEAR ) - { - mSamplingMode = SamplingMode::BOX_THEN_LINEAR; - } - else if( sampling == NO_FILTER ) - { - mSamplingMode = SamplingMode::NO_FILTER; - } - else if( sampling == DONT_CARE ) - { - mSamplingMode = SamplingMode::DONT_CARE; - } - else if( sampling == DEFAULT ) - { - mSamplingMode = SamplingMode::DEFAULT; - } - else - { - DALI_ASSERT_ALWAYS("Unknown sampling mode"); - } + Scripting::GetEnumerationProperty( *samplingValue, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, mSamplingMode ); } int desiredWidth = 0; - Property::Value* desiredWidthValue = propertyMap.Find( IMAGE_DESIRED_WIDTH ); + Property::Value* desiredWidthValue = propertyMap.Find( Toolkit::ImageVisual::Property::DESIRED_WIDTH, IMAGE_DESIRED_WIDTH ); if( desiredWidthValue ) { desiredWidthValue->Get( desiredWidth ); } int desiredHeight = 0; - Property::Value* desiredHeightValue = propertyMap.Find( IMAGE_DESIRED_HEIGHT ); + Property::Value* desiredHeightValue = propertyMap.Find( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, IMAGE_DESIRED_HEIGHT ); if( desiredHeightValue ) { desiredHeightValue->Get( desiredHeight ); } - mDesiredSize = ImageDimensions( desiredWidth, desiredHeight ); + Property::Value* pixelAreaValue = propertyMap.Find( Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME ); + if( pixelAreaValue ) + { + pixelAreaValue->Get( mPixelArea ); + } + Property::Value* wrapModeValueU = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_U, IMAGE_WRAP_MODE_U ); + if( wrapModeValueU ) + { + Scripting::GetEnumerationProperty( *wrapModeValueU, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeU ); + } + + Property::Value* wrapModeValueV = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_V, IMAGE_WRAP_MODE_V ); + if( wrapModeValueV ) + { + Scripting::GetEnumerationProperty( *wrapModeValueV, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeV ); + } + + mDesiredSize = ImageDimensions( desiredWidth, desiredHeight ); } - Property::Value* syncLoading = propertyMap.Find( SYNCHRONOUS_LOADING ); + Property::Value* syncLoading = propertyMap.Find( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, SYNCHRONOUS_LOADING ); if( syncLoading ) { bool sync; @@ -304,11 +314,6 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) } } -void ImageVisual::SetSize( const Vector2& size ) -{ - Visual::SetSize( size ); -} - void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const { if(mImage) @@ -334,15 +339,6 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const naturalSize = Vector2::ZERO; } -void ImageVisual::SetClipRect( const Rect& clipRect ) -{ - Visual::SetClipRect( clipRect ); -} - -void ImageVisual::SetOffset( const Vector2& offset ) -{ -} - Renderer ImageVisual::CreateRenderer() const { Geometry geometry; @@ -359,23 +355,24 @@ Renderer ImageVisual::CreateRenderer() const { geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - shader = GetImageShader(mFactoryCache); + shader = GetImageShader( mFactoryCache, + mImpl->mFlags & Impl::IS_ATLASING_APPLIED, + mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE ); } else { geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() ) { - shader = GetImageShader(mFactoryCache); + shader = GetImageShader(mFactoryCache, false, true); } else { shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader, - mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER : mImpl->mCustomShader->mFragmentShader, + mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER_NO_ATLAS : mImpl->mCustomShader->mFragmentShader, mImpl->mCustomShader->mHints ); if( mImpl->mCustomShader->mVertexShader.empty() ) { - shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } } @@ -396,7 +393,6 @@ Renderer ImageVisual::CreateNativeImageRenderer() const geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); shader = Shader::New( VERTEX_SHADER, mNativeFragmentShaderCode ); - shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } else @@ -407,7 +403,6 @@ Renderer ImageVisual::CreateNativeImageRenderer() const mImpl->mCustomShader->mHints ); if( mImpl->mCustomShader->mVertexShader.empty() ) { - shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } } @@ -415,7 +410,6 @@ Renderer ImageVisual::CreateNativeImageRenderer() const TextureSet textureSet = TextureSet::New(); Renderer renderer = Renderer::New( geometry, shader ); renderer.SetTextures( textureSet ); - return renderer; } @@ -442,7 +436,7 @@ Image ImageVisual::LoadImage( const std::string& url, bool synchronousLoading ) if( !mPixels ) { // use broken image - return VisualFactory::GetBrokenRendererImage(); + return VisualFactoryCache::GetBrokenVisualImage(); } Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() ); image.Upload( mPixels, 0, 0 ); @@ -466,13 +460,15 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin { // use broken image textureSet = TextureSet::New(); - TextureSetImage( textureSet, 0u, VisualFactory::GetBrokenRendererImage() ); + TextureSetImage( textureSet, 0u, VisualFactoryCache::GetBrokenVisualImage() ); } else { - textureSet = mAtlasManager.Add(textureRect, mPixels ); + textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels ); + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; if( !textureSet ) // big image, no atlasing { + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() ); image.Upload( mPixels, 0, 0 ); textureSet = TextureSet::New(); @@ -482,9 +478,11 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin } else { - textureSet = mAtlasManager.Add(textureRect, url, mDesiredSize, mFittingMode, mSamplingMode ); + textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, mSamplingMode ); + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; if( !textureSet ) // big image, no atlasing { + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode ); resourceImage.LoadingFinishedSignal().Connect( this, &ImageVisual::OnImageLoaded ); textureSet = TextureSet::New(); @@ -492,6 +490,13 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin } } + if( !(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) ) + { + Sampler sampler = Sampler::New(); + sampler.SetWrapMode( mWrapModeU, mWrapModeV ); + textureSet.SetSampler( 0u, sampler ); + } + return textureSet; } @@ -509,28 +514,46 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl ) ( 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 ) + bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; + bool cacheable = defaultWrapMode && mPixelArea == FULL_TEXTURE_RECT; + + mImpl->mFlags &= ~Impl::IS_FROM_CACHE; + if( cacheable ) // fetch the renderer from cache if exist + { + mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl ); + mImpl->mFlags |= Impl::IS_FROM_CACHE; + } + + if( !mImpl->mRenderer ) // new renderer is needed { Vector4 atlasRect; TextureSet textureSet = CreateTextureSet(atlasRect, imageUrl, IsSynchronousResourceLoading() ); Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - Shader shader( GetImageShader(mFactoryCache) ); + Shader shader( GetImageShader(mFactoryCache, mImpl->mFlags & Impl::IS_ATLASING_APPLIED, defaultWrapMode) ); mImpl->mRenderer = Renderer::New( geometry, shader ); mImpl->mRenderer.SetTextures( textureSet ); - if( atlasRect != FULL_TEXTURE_RECT ) + + if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas { mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); + if( !defaultWrapMode ) // custom wrap mode, renderer is not cached. + { + 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 ); + } } - mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer ); - } - mImpl->mFlags |= Impl::IS_FROM_CACHE; + // save the renderer to cache only when default wrap mode and default pixel area is used + if( cacheable ) + { + mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer ); + } + } } 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(); Image image = LoadImage( imageUrl, IsSynchronousResourceLoading() ); @@ -550,7 +573,6 @@ void ImageVisual::InitializeRenderer( const Image& image ) } } - void ImageVisual::DoSetOnStage( Actor& actor ) { if( !mImageUrl.empty() ) @@ -562,6 +584,10 @@ void ImageVisual::DoSetOnStage( Actor& actor ) InitializeRenderer( mImage ); } + if( mPixelArea != FULL_TEXTURE_RECT ) + { + mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea ); + } } void ImageVisual::DoSetOffStage( Actor& actor ) @@ -583,112 +609,70 @@ void ImageVisual::DoSetOffStage( Actor& actor ) void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); - map.Insert( RENDERER_TYPE, IMAGE_RENDERER ); + map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE ); bool sync = IsSynchronousResourceLoading(); map.Insert( SYNCHRONOUS_LOADING, sync ); if( !mImageUrl.empty() ) { - map.Insert( IMAGE_URL_NAME, mImageUrl ); - map.Insert( IMAGE_DESIRED_WIDTH, mDesiredSize.GetWidth() ); - map.Insert( IMAGE_DESIRED_HEIGHT, mDesiredSize.GetHeight() ); + map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl ); + map.Insert( Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth() ); + map.Insert( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight() ); } else if( mImage ) { - map.Insert( IMAGE_DESIRED_WIDTH, static_cast(mImage.GetWidth()) ); - map.Insert( IMAGE_DESIRED_HEIGHT, static_cast(mImage.GetHeight()) ); + map.Insert( Toolkit::ImageVisual::Property::DESIRED_WIDTH, static_cast(mImage.GetWidth()) ); + map.Insert( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, static_cast(mImage.GetHeight()) ); ResourceImage resourceImage = ResourceImage::DownCast(mImage); if( resourceImage ) { - map.Insert( IMAGE_URL_NAME, resourceImage.GetUrl() ); + map.Insert( Toolkit::ImageVisual::Property::URL, resourceImage.GetUrl() ); } } - switch( mFittingMode ) + map.Insert( Toolkit::ImageVisual::Property::FITTING_MODE, mFittingMode ); + map.Insert( Toolkit::ImageVisual::Property::SAMPLING_MODE, mSamplingMode ); + + map.Insert( Toolkit::ImageVisual::Property::PIXEL_AREA, mPixelArea ); + map.Insert( Toolkit::ImageVisual::Property::WRAP_MODE_U, mWrapModeU ); + map.Insert( Toolkit::ImageVisual::Property::WRAP_MODE_V, mWrapModeV ); +} + +Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ) +{ + Shader shader; + if( atlasing ) { - case Dali::FittingMode::FIT_HEIGHT: - { - map.Insert( IMAGE_FITTING_MODE, FIT_HEIGHT ); - break; - } - case Dali::FittingMode::FIT_WIDTH: - { - map.Insert( IMAGE_FITTING_MODE, FIT_WIDTH ); - break; - } - case Dali::FittingMode::SCALE_TO_FILL: + if( defaultTextureWrapping ) { - map.Insert( IMAGE_FITTING_MODE, SCALE_TO_FILL ); - break; - } - case Dali::FittingMode::SHRINK_TO_FIT: - { - map.Insert( IMAGE_FITTING_MODE, SHRINK_TO_FIT ); - break; + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader ); + } } - default: + else { - map.Insert( IMAGE_FITTING_MODE, DEFAULT ); - break; + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP, shader ); + } } } - - switch( mSamplingMode ) + else { - case Dali::SamplingMode::BOX: - { - map.Insert( IMAGE_SAMPLING_MODE, BOX ); - break; - } - case Dali::SamplingMode::NEAREST: - { - map.Insert( IMAGE_SAMPLING_MODE, NEAREST ); - break; - } - case Dali::SamplingMode::LINEAR: - { - map.Insert( IMAGE_SAMPLING_MODE, LINEAR ); - break; - } - case Dali::SamplingMode::BOX_THEN_LINEAR: + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER ); + if( !shader ) { - map.Insert( IMAGE_SAMPLING_MODE, BOX_THEN_LINEAR ); - break; + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader ); } - case Dali::SamplingMode::BOX_THEN_NEAREST: - { - map.Insert( IMAGE_SAMPLING_MODE, BOX_THEN_NEAREST ); - break; - } - case Dali::SamplingMode::NO_FILTER: - { - map.Insert( IMAGE_SAMPLING_MODE, NO_FILTER ); - break; - } - case Dali::SamplingMode::DONT_CARE: - { - map.Insert( IMAGE_SAMPLING_MODE, DONT_CARE ); - break; - } - default: - { - map.Insert( IMAGE_SAMPLING_MODE, DEFAULT ); - break; - } - } -} - -Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache ) -{ - Shader shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER ); - if( !shader ) - { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader ); - shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); return shader; } @@ -828,6 +812,9 @@ void ImageVisual::ApplyImageToSampler( const Image& image ) mImpl->mRenderer.SetTextures( textureSet ); } TextureSetImage( textureSet, 0u, image ); + Sampler sampler = Sampler::New(); + sampler.SetWrapMode( mWrapModeU, mWrapModeV ); + textureSet.SetSampler( 0u, sampler ); } } @@ -835,7 +822,7 @@ void ImageVisual::OnImageLoaded( ResourceImage image ) { if( image.GetLoadingState() == Dali::ResourceLoadingFailed ) { - Image brokenImage = VisualFactory::GetBrokenRendererImage(); + Image brokenImage = VisualFactoryCache::GetBrokenVisualImage(); if( mImpl->mRenderer ) { ApplyImageToSampler( brokenImage ); @@ -858,7 +845,7 @@ void ImageVisual::CleanCache(const std::string& url) mImpl->mRenderer.Reset(); if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX ) { - mAtlasManager.Remove( textureSet, atlasRect ); + mFactoryCache.GetAtlasManager()->Remove( textureSet, atlasRect ); } } @@ -879,7 +866,7 @@ void ImageVisual::SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage ) } else { - mNativeFragmentShaderCode += FRAGMENT_SHADER; + mNativeFragmentShaderCode += FRAGMENT_SHADER_NO_ATLAS; } if( customSamplerTypename )