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=d6cda4fb53180f35874e8a066bacf5310d2df9ca;hp=d9cb845d8092fb63486fade336b70d3ea4c5425b;hb=338e77da9020278bb4e8874e9791da96bd2717eb;hpb=63f9b5207c2794cdc460d587723be89585872a51 diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index d9cb845..d6cda4f 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -16,7 +16,7 @@ */ // CLASS HEADER -#include "image-visual.h" +#include // EXTERNAL HEADER #include // for strncasecmp @@ -31,6 +31,7 @@ // INTERNAL HEADER #include +#include #include #include #include @@ -104,12 +105,24 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( uniform mediump vec4 pixelArea; varying mediump vec2 vTexCoord;\n \n + + //Visual size and offset + uniform mediump vec2 offset;\n + uniform mediump vec2 size;\n + uniform mediump vec4 offsetSizeMode;\n + uniform mediump vec2 origin;\n + uniform mediump vec2 anchorPoint;\n + + vec4 ComputeVertexPosition()\n + {\n + vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n + vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n + return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n + }\n + void main()\n {\n - mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n - vertexPosition.xyz *= uSize;\n - vertexPosition = uMvpMatrix * vertexPosition;\n - \n + mediump vec4 vertexPosition = uMvpMatrix *ComputeVertexPosition();\n vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n gl_Position = vertexPosition;\n }\n @@ -186,7 +199,26 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS return geometry; } -} //unnamed namespace +} // unnamed namespace + +ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache ) +{ + return new ImageVisual( factoryCache ); +} + +ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, + const std::string& imageUrl, + ImageDimensions size, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode ) +{ + return new ImageVisual( factoryCache, imageUrl, size, fittingMode, samplingMode ); +} + +ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, const Image& image ) +{ + return new ImageVisual( factoryCache, image ); +} ImageVisual::ImageVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ), @@ -199,9 +231,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache ) mFittingMode( FittingMode::DEFAULT ), mSamplingMode( SamplingMode::DEFAULT ), mWrapModeU( WrapMode::DEFAULT ), - mWrapModeV( WrapMode::DEFAULT ), - mNativeFragmentShaderCode(), - mNativeImageFlag( false ) + mWrapModeV( WrapMode::DEFAULT ) { } @@ -220,9 +250,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, mFittingMode( fittingMode ), mSamplingMode( samplingMode ), mWrapModeU( WrapMode::DEFAULT ), - mWrapModeV( WrapMode::DEFAULT ), - mNativeFragmentShaderCode(), - mNativeImageFlag( false ) + mWrapModeV( WrapMode::DEFAULT ) { } @@ -237,30 +265,16 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image ) mFittingMode( FittingMode::DEFAULT ), mSamplingMode( SamplingMode::DEFAULT ), mWrapModeU( WrapMode::DEFAULT ), - mWrapModeV( WrapMode::DEFAULT ), - mNativeFragmentShaderCode(), - mNativeImageFlag( false ) + mWrapModeV( WrapMode::DEFAULT ) { - NativeImage newNativeImage = NativeImage::DownCast( image ); - if( newNativeImage ) - { - SetNativeFragmentShaderCode( newNativeImage ); - mNativeImageFlag = true; - } - else - { - mNativeImageFlag = false; - } } ImageVisual::~ImageVisual() { } -void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) +void ImageVisual::DoSetProperties( const Property::Map& propertyMap ) { - std::string oldImageUrl = mImageUrl; - Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME ); if( imageURLValue ) { @@ -273,13 +287,17 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) Property::Value* fittingValue = propertyMap.Find( Toolkit::ImageVisual::Property::FITTING_MODE, IMAGE_FITTING_MODE ); if( fittingValue ) { - Scripting::GetEnumerationProperty( *fittingValue, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, mFittingMode ); + int value; + Scripting::GetEnumerationProperty( *fittingValue, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, value ); + mFittingMode = Dali::FittingMode::Type( value ); } Property::Value* samplingValue = propertyMap.Find( Toolkit::ImageVisual::Property::SAMPLING_MODE, IMAGE_SAMPLING_MODE ); if( samplingValue ) { - Scripting::GetEnumerationProperty( *samplingValue, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, mSamplingMode ); + int value; + Scripting::GetEnumerationProperty( *samplingValue, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, value ); + mSamplingMode = Dali::SamplingMode::Type( value ); } int desiredWidth = 0; @@ -305,13 +323,17 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) 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 ); + int value; + Scripting::GetEnumerationProperty( *wrapModeValueU, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, value ); + mWrapModeU = Dali::WrapMode::Type( value ); } 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 ); + int value; + Scripting::GetEnumerationProperty( *wrapModeValueV, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, value ); + mWrapModeV = Dali::WrapMode::Type( value ); } mDesiredSize = ImageDimensions( desiredWidth, desiredHeight ); @@ -325,32 +347,18 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) if( sync ) { mImpl->mFlags |= Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; + // if sync loading is required, the loading should start immediately when new image url is set or the actor is off stage + // ( for on-stage actor with image url unchanged, resource loading is already finished) + if( imageURLValue ) + { + LoadResourceSynchronously(); + } } else { mImpl->mFlags &= ~Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; } } - - // if sync loading is required, the loading should start immediately when new image url is set or the actor is off stage - // ( for on-stage actor with image url unchanged, resource loading is already finished) - if( imageURLValue && IsSynchronousResourceLoading() ) - { - LoadResourceSynchronously(); - } - - NativeImage nativeImage = NativeImage::DownCast( mImage ); - - if( nativeImage ) - { - SetNativeFragmentShaderCode( nativeImage ); - } - - // if actor is on stage, create new renderer and apply to actor - if( actor && actor.OnStage() ) - { - SetOnStage( actor ); - } } void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const @@ -378,18 +386,11 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const naturalSize = Vector2::ZERO; } -Renderer ImageVisual::CreateRenderer() const +void ImageVisual::CreateRenderer( TextureSet& textures ) { Geometry geometry; Shader shader; - // If mImage is nativeImage with custom sampler or prefix, mNativeFragmentShaderCode will be applied. - // Renderer can't be shared between NativeImage and other image types. - if( !mNativeFragmentShaderCode.empty() ) - { - return CreateNativeImageRenderer(); - } - if( !mImpl->mCustomShader ) { geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); @@ -403,7 +404,7 @@ Renderer ImageVisual::CreateRenderer() const geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() ) { - shader = GetImageShader(mFactoryCache, false, true); + shader = GetImageShader( mFactoryCache, false, true ); } else { @@ -417,28 +418,52 @@ Renderer ImageVisual::CreateRenderer() const } } - Renderer renderer = Renderer::New( geometry, shader ); + mImpl->mRenderer = Renderer::New( geometry, shader ); + DALI_ASSERT_DEBUG( textures ); + mImpl->mRenderer.SetTextures( textures ); - return renderer; + //Register transform properties + mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); } -Renderer ImageVisual::CreateNativeImageRenderer() const +void ImageVisual::CreateNativeImageRenderer( NativeImage& nativeImage ) { Geometry geometry; Shader shader; + std::string fragmentShader; + const char* fragmentPreFix = nativeImage.GetCustomFragmentPreFix(); + const char* customSamplerTypename = nativeImage.GetCustomSamplerTypename(); + if( fragmentPreFix ) + { + fragmentShader = fragmentPreFix; + fragmentShader += "\n"; + } + if( mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty() ) + { + fragmentShader += mImpl->mCustomShader->mFragmentShader; + } + else + { + fragmentShader += FRAGMENT_SHADER_NO_ATLAS; + } + if( customSamplerTypename ) + { + fragmentShader.replace( fragmentShader.find( DEFAULT_SAMPLER_TYPENAME ), strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename ); + } + if( !mImpl->mCustomShader ) { geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - shader = Shader::New( VERTEX_SHADER, mNativeFragmentShaderCode ); + shader = Shader::New( VERTEX_SHADER, fragmentShader ); shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } else { geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader, - mNativeFragmentShaderCode, + fragmentShader, mImpl->mCustomShader->mHints ); if( mImpl->mCustomShader->mVertexShader.empty() ) { @@ -446,10 +471,10 @@ Renderer ImageVisual::CreateNativeImageRenderer() const } } - TextureSet textureSet = TextureSet::New(); - Renderer renderer = Renderer::New( geometry, shader ); - renderer.SetTextures( textureSet ); - return renderer; + mImpl->mRenderer = Renderer::New( geometry, shader ); + + //Register transform properties + mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); } @@ -468,28 +493,7 @@ void ImageVisual::LoadResourceSynchronously() } } -Image ImageVisual::LoadImage( const std::string& url, bool synchronousLoading ) -{ - if( synchronousLoading ) - { - if( !mPixels ) - { - // use broken image - return VisualFactoryCache::GetBrokenVisualImage(); - } - Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() ); - image.Upload( mPixels, 0, 0 ); - return image; - } - else - { - ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode ); - resourceImage.LoadingFinishedSignal().Connect( this, &ImageVisual::OnImageLoaded ); - return resourceImage; - } -} - -TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading ) +TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading, bool attemptAtlasing ) { TextureSet textureSet; textureRect = FULL_TEXTURE_RECT; @@ -503,23 +507,30 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin } else { - textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels ); - mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; - if( !textureSet ) // big image, no atlasing + if( attemptAtlasing ) + { + textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels ); + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + } + if( !textureSet ) // big image, no atlasing or atlasing failed { mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; - Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() ); - image.Upload( mPixels, 0, 0 ); + Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, mPixels.GetPixelFormat(), + mPixels.GetWidth(), mPixels.GetHeight() ); + texture.Upload( mPixels ); textureSet = TextureSet::New(); - TextureSetImage( textureSet, 0u, image ); + textureSet.SetTexture( 0u, texture ); } } } else { - textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, true, this ); - mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; - if( !textureSet ) // big image, no atlasing + if( attemptAtlasing ) + { + textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, true, this ); + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + } + if( !textureSet ) // big image, no atlasing or atlasing failed { mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode ); @@ -535,19 +546,14 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin sampler.SetWrapMode( mWrapModeU, mWrapModeV ); textureSet.SetSampler( 0u, sampler ); } - return textureSet; } void ImageVisual::InitializeRenderer( const std::string& imageUrl ) { - if( imageUrl.empty() ) - { - return; - } + mImpl->mRenderer.Reset(); mImageUrl = imageUrl; - mImpl->mRenderer.Reset(); mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; if( !mImpl->mCustomShader && @@ -555,7 +561,14 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl ) ( strncasecmp( imageUrl.c_str(), HTTPS_URL, sizeof(HTTPS_URL) -1 ) != 0 ) ) { bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; - bool cacheable = defaultWrapMode && mPixelArea == FULL_TEXTURE_RECT; + bool defaultTransform = mImpl->mTransform.mSize == Vector2::ONE && + mImpl->mTransform.mOffset == Vector2::ZERO && + mImpl->mTransform.mOffsetSizeMode == Vector4::ZERO && + mImpl->mTransform.mOrigin == Toolkit::Align::CENTER && + mImpl->mTransform.mAnchorPoint == Toolkit::Align::CENTER; + + bool cacheable = defaultWrapMode && defaultTransform && mPixelArea == FULL_TEXTURE_RECT; + mImpl->mFlags &= ~Impl::IS_FROM_CACHE; if( cacheable ) // fetch the renderer from cache if exist @@ -567,11 +580,10 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl ) 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, mImpl->mFlags & Impl::IS_ATLASING_APPLIED, defaultWrapMode) ); - mImpl->mRenderer = Renderer::New( geometry, shader ); - mImpl->mRenderer.SetTextures( textureSet ); + // texture set has to be created first as we need to know if atlasing succeeded or not + // when selecting the shader + TextureSet textures = CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), true ); + CreateRenderer( textures ); if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas { @@ -595,22 +607,33 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl ) { // 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() ); - ApplyImageToSampler( image ); + Vector4 atlasRect; // ignored in this case + TextureSet textures = CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), false ); + CreateRenderer( textures ); } } void ImageVisual::InitializeRenderer( const Image& image ) { mImpl->mFlags &= ~Impl::IS_FROM_CACHE; + mImpl->mRenderer.Reset(); - mImpl->mRenderer = CreateRenderer(); - - if( image ) + // don't reuse CreateTextureSet + TextureSet textures = TextureSet::New(); + // Renderer can't be shared if mImage is NativeImage + NativeImage nativeImage = NativeImage::DownCast( image ); + if( nativeImage ) + { + CreateNativeImageRenderer( nativeImage ); + DALI_ASSERT_DEBUG( textures ); + mImpl->mRenderer.SetTextures( textures ); + } + else { - ApplyImageToSampler( image ); + // reuse existing code for regular images + CreateRenderer( textures ); } + ApplyImageToSampler( image ); } void ImageVisual::UploadCompleted() @@ -627,17 +650,22 @@ void ImageVisual::UploadCompleted() void ImageVisual::DoSetOnStage( Actor& actor ) { - mPlacementActor = actor; - if( !mImageUrl.empty() ) { InitializeRenderer( mImageUrl ); } - else + else if ( mImage ) { InitializeRenderer( mImage ); } + if ( !mImpl->mRenderer) + { + return; + } + + mPlacementActor = actor; + if( mPixelArea != FULL_TEXTURE_RECT ) { mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea ); @@ -652,25 +680,24 @@ void ImageVisual::DoSetOnStage( Actor& actor ) void ImageVisual::DoSetOffStage( Actor& actor ) { + // Visual::Base::SetOffStage only calls DoSetOffStage if mRenderer exists (is on onstage) + //If we own the image then make sure we release it when we go off stage + actor.RemoveRenderer( mImpl->mRenderer); if( !mImageUrl.empty() ) { - actor.RemoveRenderer( mImpl->mRenderer ); CleanCache(mImageUrl); mImage.Reset(); } - else - { - actor.RemoveRenderer( mImpl->mRenderer ); - mImpl->mRenderer.Reset(); - } + + mImpl->mRenderer.Reset(); mPlacementActor.Reset(); } void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); - map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE ); + map.Insert( Toolkit::VisualProperty::TYPE, Toolkit::Visual::IMAGE ); bool sync = IsSynchronousResourceLoading(); map.Insert( SYNCHRONOUS_LOADING, sync ); @@ -711,6 +738,14 @@ Dali::Property::Value ImageVisual::DoGetProperty( Dali::Property::Index index ) return Dali::Property::Value(); } +void ImageVisual::OnSetTransform() +{ + if( mImpl->mRenderer ) + { + mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); + } +} + Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ) { Shader shader; @@ -753,11 +788,8 @@ void ImageVisual::ApplyImageToSampler( const Image& image ) if( image ) { TextureSet textureSet = mImpl->mRenderer.GetTextures(); - if( !textureSet ) - { - textureSet = TextureSet::New(); - mImpl->mRenderer.SetTextures( textureSet ); - } + DALI_ASSERT_DEBUG( textureSet ); // texture set should always exist by this time + TextureSetImage( textureSet, 0u, image ); Sampler sampler = Sampler::New(); sampler.SetWrapMode( mWrapModeU, mWrapModeV ); @@ -781,8 +813,6 @@ void ImageVisual::CleanCache(const std::string& url) { if( IsFromCache() ) { - TextureSet textureSet = mImpl->mRenderer.GetTextures(); - Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f ); Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME ); if( index != Property::INVALID_INDEX ) @@ -791,6 +821,7 @@ void ImageVisual::CleanCache(const std::string& url) atlasRectValue.Get( atlasRect ); } + TextureSet textureSet = mImpl->mRenderer.GetTextures(); mImpl->mRenderer.Reset(); if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX ) { @@ -799,32 +830,6 @@ void ImageVisual::CleanCache(const std::string& url) } } -void ImageVisual::SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage ) -{ - const char* fragmentPreFix = nativeImage.GetCustomFragmentPreFix(); - const char* customSamplerTypename = nativeImage.GetCustomSamplerTypename(); - - if( fragmentPreFix ) - { - mNativeFragmentShaderCode = fragmentPreFix; - mNativeFragmentShaderCode += "\n"; - } - - if( mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty() ) - { - mNativeFragmentShaderCode += mImpl->mCustomShader->mFragmentShader; - } - else - { - mNativeFragmentShaderCode += FRAGMENT_SHADER_NO_ATLAS; - } - - if( customSamplerTypename ) - { - mNativeFragmentShaderCode.replace( mNativeFragmentShaderCode.find( DEFAULT_SAMPLER_TYPENAME ), strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename ); - } -} - } // namespace Internal } // namespace Toolkit