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=b0324ed4530369f2922d9f412c982a300134189a;hp=ceb366928377f5a2e282752f50b0937cb39df158;hb=1885ccc169669850fcdb3f817fb283dee9cfb0e8;hpb=4b11a25bb26aeb1eaef96ac024de6009a790387f diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index ceb3669..b0324ed 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -21,11 +21,10 @@ // EXTERNAL HEADERS #include // for strlen() #include -#include -#include -#include -#include +#include #include +#include +#include #include #include #include @@ -56,15 +55,6 @@ namespace Internal namespace { -// property names -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 SYNCHRONOUS_LOADING( "synchronousLoading" ); -const char * const IMAGE_ATLASING("atlasing"); -const char * const ALPHA_MASK_URL("alphaMaskUrl"); - // fitting modes DALI_ENUM_TO_STRING_TABLE_BEGIN( FITTING_MODE ) DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::FittingMode, SHRINK_TO_FIT ) @@ -108,8 +98,6 @@ DALI_ENUM_TO_STRING_TABLE_END( RELEASE_POLICY ) const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); -const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D"; - const float PIXEL_ALIGN_ON = 1.0f; const float PIXEL_ALIGN_OFF = 0.0f; @@ -131,6 +119,7 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS } // unnamed namespace + ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, @@ -154,19 +143,13 @@ ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, return new ImageVisual( factoryCache, shaderFactory, imageUrl, size, fittingMode, samplingMode ); } -ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image ) -{ - return new ImageVisual( factoryCache, shaderFactory, image ); -} - ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size, FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode ) -: Visual::Base( factoryCache, Visual::FittingMode::FILL ), - mImage(), +: Visual::Base( factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::IMAGE ), mPixelArea( FULL_TEXTURE_RECT ), mPlacementActor(), mImageUrl( imageUrl ), @@ -190,31 +173,6 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() ); } -ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image ) -: Visual::Base( factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO ), - mImage( image ), - mPixelArea( FULL_TEXTURE_RECT ), - mPlacementActor(), - mImageUrl(), - mMaskingData( ), - mDesiredSize(), - mTextureId( TextureManager::INVALID_TEXTURE_ID ), - mTextures(), - mImageVisualShaderFactory( shaderFactory ), - mFittingMode( FittingMode::DEFAULT ), - mSamplingMode( SamplingMode::DEFAULT ), - mWrapModeU( WrapMode::DEFAULT ), - mWrapModeV( WrapMode::DEFAULT ), - mLoadPolicy( Toolkit::ImageVisual::LoadPolicy::ATTACHED ), - mReleasePolicy( Toolkit::ImageVisual::ReleasePolicy::DESTROYED ), - mAtlasRect( 0.0f, 0.0f, 0.0f, 0.0f ), - mAttemptAtlasing( false ), - mLoading( false ), - mOrientationCorrection( true ) -{ - EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() ); -} - ImageVisual::~ImageVisual() { if( Stage::IsInstalled() ) @@ -489,13 +447,7 @@ void ImageVisual::AllocateMaskData() void ImageVisual::GetNaturalSize( Vector2& naturalSize ) { - if(mImage) - { - naturalSize.x = mImage.GetWidth(); - naturalSize.y = mImage.GetHeight(); - return; - } - else if( mDesiredSize.GetWidth()>0 && mDesiredSize.GetHeight()>0) + if( mDesiredSize.GetWidth()>0 && mDesiredSize.GetHeight()>0) { naturalSize.x = mDesiredSize.GetWidth(); naturalSize.y = mDesiredSize.GetHeight(); @@ -514,9 +466,12 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) if( textureSet ) { auto texture = textureSet.GetTexture(0); - naturalSize.x = texture.GetWidth(); - naturalSize.y = texture.GetHeight(); - return; + if( texture ) + { + naturalSize.x = texture.GetWidth(); + naturalSize.y = texture.GetHeight(); + return; + } } } @@ -544,7 +499,7 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) } else { - Image brokenImage = mFactoryCache.GetBrokenVisualImage(); + Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); naturalSize.x = brokenImage.GetWidth(); naturalSize.y = brokenImage.GetWidth(); @@ -552,7 +507,6 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) return; } } - naturalSize = Vector2::ZERO; } @@ -561,112 +515,101 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet ) Geometry geometry; Shader shader; - if( !mImpl->mCustomShader ) + // Get the geometry + if( mImpl->mCustomShader ) { - geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - - shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - mImpl->mFlags & Impl::IS_ATLASING_APPLIED, - mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE ); + geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); } - else + else // Get any geometry associated with the texture { - geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); - if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() ) - { - // Use custom hints - shader = Shader::New( mImageVisualShaderFactory.GetVertexShaderSource(), mImageVisualShaderFactory.GetFragmentShaderSource(), mImpl->mCustomShader->mHints ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - } - else + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + + uint32_t firstElementCount {0u}; + uint32_t secondElementCount {0u}; + geometry = textureManager.GetRenderGeometry(mTextureId, firstElementCount, secondElementCount); + + if(!firstElementCount && !secondElementCount) // Otherwise use quad { - shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader, - mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader, - mImpl->mCustomShader->mHints ); - if( mImpl->mCustomShader->mVertexShader.empty() ) - { - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - } + geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); } } - // Set pixel align off as default. - // ToDo: Pixel align causes issues such as rattling image animation. - // We should trun it off until issues are resolved - shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF ); - - mImpl->mRenderer = Renderer::New( geometry, shader ); - if( textureSet ) + std::string vertexShader; + bool usesWholeTexture = true; + if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty()) { - mImpl->mRenderer.SetTextures( textureSet ); + vertexShader = mImpl->mCustomShader->mVertexShader; + usesWholeTexture = false; // Impossible to tell. } - // else still waiting for texture load to finish. - - //Register transform properties - mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); - - EnablePreMultipliedAlpha( IsPreMultipliedAlphaEnabled() ); -} - -void ImageVisual::CreateNativeImageRenderer( NativeImage& nativeImage ) -{ - Geometry geometry; - Shader shader; - - std::string fragmentShader; - const char* fragmentPreFix = nativeImage.GetCustomFragmentPreFix(); - const char* customSamplerTypename = nativeImage.GetCustomSamplerTypename(); - - if( fragmentPreFix ) + else { - fragmentShader = fragmentPreFix; - fragmentShader += "\n"; + vertexShader = mImageVisualShaderFactory.GetVertexShaderSource(); } - if( mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty() ) + std::string fragmentShader; + if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty()) { - fragmentShader += mImpl->mCustomShader->mFragmentShader; + fragmentShader = mImpl->mCustomShader->mFragmentShader; } else { - fragmentShader += mImageVisualShaderFactory.GetFragmentShaderSource(); + fragmentShader = mImageVisualShaderFactory.GetFragmentShaderSource(); } - if( customSamplerTypename ) + // If the texture is native, we may need to change prefix and sampler in + // the fragment shader + bool modifiedFragmentShader = false; + if(mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))) { - fragmentShader.replace( fragmentShader.find( DEFAULT_SAMPLER_TYPENAME ), strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename ); + Texture nativeTexture = mTextures.GetTexture(0); + modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShader); } - if( !mImpl->mCustomShader ) + const bool useStandardShader = !mImpl->mCustomShader && !modifiedFragmentShader; + if(useStandardShader) { - geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - - shader = Shader::New( mImageVisualShaderFactory.GetVertexShaderSource(), fragmentShader ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + // Create and cache the standard shader + shader = mImageVisualShaderFactory.GetShader( + mFactoryCache, + mImpl->mFlags & Impl::IS_ATLASING_APPLIED, + mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE, + IsRoundedCornerRequired() ); + } + else if(mImpl->mCustomShader) + { + shader = Shader::New(vertexShader, fragmentShader, mImpl->mCustomShader->mHints); } else { - geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); - shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader, - fragmentShader, - mImpl->mCustomShader->mHints ); - if( mImpl->mCustomShader->mVertexShader.empty() ) - { - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - } + shader = Shader::New(vertexShader, fragmentShader); + } + + if(usesWholeTexture) + { + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } + // Set pixel align off as default. + // ToDo: Pixel align causes issues such as rattling image animation. + // We should trun it off until issues are resolved + shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF ); + + // Create the renderer mImpl->mRenderer = Renderer::New( geometry, shader ); + if( textureSet ) + { + mImpl->mRenderer.SetTextures( textureSet ); + } + // else still waiting for texture load to finish. + //Register transform properties mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); -} -bool ImageVisual::IsSynchronousResourceLoading() const -{ - return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; + EnablePreMultipliedAlpha( IsPreMultipliedAlphaEnabled() ); } + void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, TextureManager::ReloadPolicy forceReload ) { @@ -687,7 +630,7 @@ void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& t : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; textures = textureManager.LoadTexture( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, - mMaskingData, IsSynchronousResourceLoading(), mTextureId, + mMaskingData, IsSynchronousLoadingRequired(), mTextureId, atlasRect, mAtlasRectSize, atlasing, mLoading, mWrapModeU, mWrapModeV, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad); @@ -715,13 +658,27 @@ bool ImageVisual::AttemptAtlasing() void ImageVisual::InitializeRenderer() { auto attemptAtlasing = AttemptAtlasing(); - // texture set has to be created first as we need to know if atlasing succeeded or not - // when selecting the shader - if( mTextureId == TextureManager::INVALID_TEXTURE_ID && ! mTextures ) // Only load the texture once + // Load Texture if mTextures is empty. + // mTextures is already set, the mTexture can be used to create Renderer. + // There are two cases mTextures is empty. + // 1. mTextureId == TextureManager::INVALID_TEXTURE_ID + // - Visual is on stage with LoadPolicy::ATTACHED + // 2. mTextureId != TextureManager::INVALID_TEXTURE_ID + // - If ReleasePolicy is DESTROYED, InitializeRenderer called every on stage called. + // - Then every resources those contained in Visual are Reset but mTextureId is remained when the Off stage time, + // - So, mTextures needed to be get from texture manager to created resources like mImpl->mRenderer. + if( ! mTextures ) { - LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, - TextureManager::ReloadPolicy::CACHED ); + if( mTextureId == TextureManager::INVALID_TEXTURE_ID ) + { + LoadTexture( attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, + TextureManager::ReloadPolicy::CACHED ); + } + else + { + mTextures = mFactoryCache.GetTextureManager().GetTextureSet( mTextureId ); + } } CreateRenderer( mTextures ); @@ -742,35 +699,12 @@ void ImageVisual::InitializeRenderer() } } -void ImageVisual::InitializeRenderer( const Image& image ) -{ - TextureSet textures = TextureSet::New(); - - NativeImage nativeImage = NativeImage::DownCast( image ); - if( nativeImage ) - { - CreateNativeImageRenderer( nativeImage ); - DALI_ASSERT_DEBUG( textures ); - mImpl->mRenderer.SetTextures( textures ); - } - else - { - // reuse existing code for regular images - CreateRenderer( textures ); // Textures will be retreived from Image - } - ApplyImageToSampler( image ); -} - -void ImageVisual::DoSetOnStage( Actor& actor ) +void ImageVisual::DoSetOnScene( Actor& actor ) { if( mImageUrl.IsValid() ) { InitializeRenderer(); } - else if( mImage ) - { - InitializeRenderer( mImage ); - } if( !mImpl->mRenderer ) { @@ -780,7 +714,7 @@ void ImageVisual::DoSetOnStage( Actor& actor ) mPlacementActor = actor; // Search the Actor tree to find if Layer UI behaviour set. Layer layer = actor.GetLayer(); - if( layer && layer.GetBehavior() == Layer::LAYER_3D ) + if( layer && layer.GetProperty( Layer::Property::BEHAVIOR ) == Layer::LAYER_3D ) { // Layer 3D set, do not align pixels mImpl->mRenderer.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF ); @@ -801,9 +735,9 @@ void ImageVisual::DoSetOnStage( Actor& actor ) } } -void ImageVisual::DoSetOffStage( Actor& actor ) +void ImageVisual::DoSetOffScene( Actor& actor ) { - // Visual::Base::SetOffStage only calls DoSetOffStage if mRenderer exists (is on onstage) + // Visual::Base::SetOffScene only calls DoSetOffScene if mRenderer exists (is on onstage) // Image release is dependent on the ReleasePolicy, renderer is destroyed. actor.RemoveRenderer( mImpl->mRenderer); @@ -813,11 +747,6 @@ void ImageVisual::DoSetOffStage( Actor& actor ) mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING; } - if( mImageUrl.IsValid() ) - { - // Legacy support for deprecated Dali::Image - mImage.Reset(); - } mLoading = false; mImpl->mRenderer.Reset(); mPlacementActor.Reset(); @@ -828,7 +757,7 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const map.Clear(); map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE ); - bool sync = IsSynchronousResourceLoading(); + bool sync = IsSynchronousLoadingRequired(); map.Insert( SYNCHRONOUS_LOADING, sync ); if( mImageUrl.IsValid() ) { @@ -836,17 +765,6 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth() ); map.Insert( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight() ); } - else if( mImage ) - { - 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( Toolkit::ImageVisual::Property::URL, resourceImage.GetUrl() ); - } - } map.Insert( Toolkit::ImageVisual::Property::FITTING_MODE, mFittingMode ); map.Insert( Toolkit::ImageVisual::Property::SAMPLING_MODE, mSamplingMode ); @@ -878,11 +796,6 @@ void ImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const map.Insert( Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth() ); map.Insert( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight() ); } - else if( mImage ) - { - map.Insert( Toolkit::ImageVisual::Property::DESIRED_WIDTH, static_cast(mImage.GetWidth()) ); - map.Insert( Toolkit::ImageVisual::Property::DESIRED_HEIGHT, static_cast(mImage.GetHeight()) ); - } } void ImageVisual::OnDoAction( const Dali::Property::Index actionName, const Dali::Property::Value& attributes ) @@ -915,20 +828,6 @@ bool ImageVisual::IsResourceReady() const mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED ); } -void ImageVisual::ApplyImageToSampler( const Image& image ) -{ - if( image ) - { - TextureSet textureSet = mImpl->mRenderer.GetTextures(); - DALI_ASSERT_DEBUG( textureSet ); // texture set should always exist by this time - - TextureSetImage( textureSet, 0u, image ); - Sampler sampler = Sampler::New(); - sampler.SetWrapMode( mWrapModeU, mWrapModeV ); - textureSet.SetSampler( 0u, sampler ); - } -} - // From existing atlas manager void ImageVisual::UploadCompleted() { @@ -969,22 +868,20 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur mPlacementActor.Reset(); } - if( loadingSuccess ) + if( !loadingSuccess ) { - Sampler sampler = Sampler::New(); - sampler.SetWrapMode( mWrapModeU, mWrapModeV ); - textureSet.SetSampler( 0u, sampler ); - mImpl->mRenderer.SetTextures(textureSet); - } - else - { - Image brokenImage = mFactoryCache.GetBrokenVisualImage(); + Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); textureSet = TextureSet::New(); + textureSet.SetTexture(0u, brokenImage); mImpl->mRenderer.SetTextures( textureSet ); - - ApplyImageToSampler( brokenImage ); } + + Sampler sampler = Sampler::New(); + sampler.SetWrapMode( mWrapModeU, mWrapModeV ); + textureSet.SetSampler( 0u, sampler ); + mImpl->mRenderer.SetTextures(textureSet); + } // Storing TextureSet needed when renderer staged. @@ -1002,6 +899,37 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur { resourceStatus = Toolkit::Visual::ResourceStatus::FAILED; } + + // use geometry if needed + if( loadingSuccess ) + { + uint32_t firstElementCount{0u}; + uint32_t secondElementCount{0u}; + auto geometry = mFactoryCache.GetTextureManager().GetRenderGeometry(mTextureId, firstElementCount, secondElementCount); + if (mImpl->mRenderer && geometry) + { + mImpl->mRenderer.SetGeometry(geometry); + Dali::DevelRenderer::DrawCommand drawCommand{}; + drawCommand.drawType = DevelRenderer::DrawType::INDEXED; + + if (firstElementCount) + { + drawCommand.firstIndex = 0; + drawCommand.elementCount = firstElementCount; + drawCommand.queue = DevelRenderer::RENDER_QUEUE_OPAQUE; + DevelRenderer::AddDrawCommand(mImpl->mRenderer, drawCommand); + } + + if (secondElementCount) + { + drawCommand.firstIndex = firstElementCount; + drawCommand.elementCount = secondElementCount; + drawCommand.queue = DevelRenderer::RENDER_QUEUE_TRANSPARENT; + DevelRenderer::AddDrawCommand(mImpl->mRenderer, drawCommand); + } + } + } + // Signal to observers ( control ) that resources are ready. Must be all resources. ResourceReady( resourceStatus ); mLoading = false;