X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fimage%2Fimage-visual.cpp;h=e971be6e8ce987919bca801b42815d2b9f9dc011;hb=88af55c0bf70653347b6918a83bc9a9ee5972e24;hp=bbbab23d058f6525633168b64ed73ba6b3f72a49;hpb=8cd8392e5982d60111b0a2a5d33457c06e8532f5;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index bbbab23..e971be6 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,9 +31,9 @@ // INTERNAL HEADERS #include +#include #include #include -#include #include #include #include @@ -51,6 +51,8 @@ namespace Internal { namespace { +const int CUSTOM_PROPERTY_COUNT(9); // wrap, pixel area, atlas, pixalign, + border/corner + // fitting modes DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE) DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SHRINK_TO_FIT) @@ -187,6 +189,23 @@ ImageVisual::~ImageVisual() } } + if(mImageUrl.IsValid()) + { + // Decrease reference count of External Resources : + // EncodedImageBuffer or ExternalTextures. + // Ensure the stage is still valid before accessing texture manager. + if(mImageUrl.GetProtocolType() == VisualUrl::TEXTURE) + { + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + textureManager.RemoveExternalTexture(mImageUrl.GetUrl()); + } + else if(mImageUrl.IsBufferResource()) + { + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + textureManager.RemoveExternalEncodedImageBuffer(mImageUrl.GetUrl()); + } + } + // ImageVisual destroyed so remove texture unless ReleasePolicy is set to never release if((mTextureId != TextureManager::INVALID_TEXTURE_ID) && (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER)) { @@ -460,7 +479,7 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } auto textureSet = mImpl->mRenderer.GetTextures(); - if(textureSet) + if(textureSet && textureSet.GetTextureCount()) { auto texture = textureSet.GetTexture(0); if(texture) @@ -496,10 +515,16 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } else { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - - naturalSize.x = brokenImage.GetWidth(); - naturalSize.y = brokenImage.GetWidth(); + Actor actor = mPlacementActor.GetHandle(); + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + Texture brokenImage = mImpl->mRenderer.GetTextures().GetTexture(0); + naturalSize.x = brokenImage.GetWidth(); + naturalSize.y = brokenImage.GetWidth(); } return; } @@ -530,13 +555,23 @@ void ImageVisual::OnInitialize() } } - Shader shader = GetShader(); + // Increase reference count of External Resources : + // EncodedImageBuffer or ExternalTextures. + // Reference count will be decreased at destructor of the visual. + if(mImageUrl.IsValid() && (mImageUrl.IsBufferResource() || mImageUrl.GetProtocolType() == VisualUrl::TEXTURE)) + { + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + textureManager.UseExternalResource(mImageUrl.GetUrl()); + } + + Shader shader = GenerateShader(); // Create the renderer - mImpl->mRenderer = Renderer::New(geometry, shader); + mImpl->mRenderer = VisualRenderer::New(geometry, shader); + mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT); //Register transform properties - mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); + mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); EnablePreMultipliedAlpha(IsPreMultipliedAlphaEnabled()); } @@ -595,7 +630,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te bool ImageVisual::AttemptAtlasing() { - return (!mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL && mAttemptAtlasing); + return (!mImpl->mCustomShader && (mImageUrl.IsLocalResource() || mImageUrl.IsBufferResource()) && mAttemptAtlasing); } void ImageVisual::InitializeRenderer() @@ -684,12 +719,12 @@ void ImageVisual::DoSetOnScene(Actor& actor) } else if(mLoadState == TextureManager::LoadState::LOAD_FAILED) { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - - mTextures = TextureSet::New(); - mTextures.SetTexture(0u, brokenImage); - mImpl->mRenderer.SetTextures(mTextures); - + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); mPlacementActor.Reset(); @@ -723,7 +758,7 @@ void ImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); bool sync = IsSynchronousLoadingRequired(); - map.Insert(SYNCHRONOUS_LOADING, sync); + map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, sync); if(mImageUrl.IsValid()) { map.Insert(Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl()); @@ -763,11 +798,11 @@ void ImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const } } -void ImageVisual::OnDoAction(const Dali::Property::Index actionName, const Dali::Property::Value& attributes) +void ImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) { // Check if action is valid for this visual type and perform action if possible - switch(actionName) + switch(actionId) { case DevelImageVisual::Action::RELOAD: { @@ -782,21 +817,15 @@ void ImageVisual::OnSetTransform() { if(mImpl->mRenderer) { - mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); + mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); } } -bool ImageVisual::IsResourceReady() const -{ - return (mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::READY || - mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED); -} - void ImageVisual::UpdateShader() { if(mImpl->mRenderer) { - Shader shader = GetShader(); + Shader shader = GenerateShader(); mImpl->mRenderer.SetShader(shader); } } @@ -821,45 +850,49 @@ void ImageVisual::UploadCompleted() } // From Texture Manager -void ImageVisual::UploadComplete(bool loadingSuccess, int32_t textureId, TextureSet textureSet, bool usingAtlas, const Vector4& atlasRectangle, bool preMultiplied) +void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureInformation) { Toolkit::Visual::ResourceStatus resourceStatus; if(mImpl->mRenderer) { - if(usingAtlas) + if(textureInformation.useAtlasing) { mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, mAtlasRect); } - EnablePreMultipliedAlpha(preMultiplied); + EnablePreMultipliedAlpha(textureInformation.preMultiplied); Actor actor = mPlacementActor.GetHandle(); + if(!loadingSuccess) + { + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + textureInformation.textureSet = mImpl->mRenderer.GetTextures(); + } + else + { + Sampler sampler = Sampler::New(); + sampler.SetWrapMode(mWrapModeU, mWrapModeV); + textureInformation.textureSet.SetSampler(0u, sampler); + mImpl->mRenderer.SetTextures(textureInformation.textureSet); + } + if(actor) { actor.AddRenderer(mImpl->mRenderer); // reset the weak handle so that the renderer only get added to actor once mPlacementActor.Reset(); } - - if(!loadingSuccess) - { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - - textureSet = TextureSet::New(); - textureSet.SetTexture(0u, brokenImage); - mImpl->mRenderer.SetTextures(textureSet); - } - - Sampler sampler = Sampler::New(); - sampler.SetWrapMode(mWrapModeU, mWrapModeV); - textureSet.SetSampler(0u, sampler); - mImpl->mRenderer.SetTextures(textureSet); } // Storing TextureSet needed when renderer staged. if(!mImpl->mRenderer) { - mTextures = textureSet; + mTextures = textureInformation.textureSet; } // Image loaded, set status regardless of staged status. @@ -934,63 +967,71 @@ void ImageVisual::RemoveTexture() } } -Shader ImageVisual::GetShader() +Shader ImageVisual::GenerateShader() const { Shader shader; - std::string_view vertexShaderView; - bool usesWholeTexture = true; - if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty()) - { - vertexShaderView = mImpl->mCustomShader->mVertexShader; - usesWholeTexture = false; // Impossible to tell. - } - else - { - vertexShaderView = mImageVisualShaderFactory.GetVertexShaderSource(); - } - - std::string_view fragmentShaderView; - if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty()) - { - fragmentShaderView = mImpl->mCustomShader->mFragmentShader; - } - else - { - fragmentShaderView = mImageVisualShaderFactory.GetFragmentShaderSource(); - } - - // If the texture is native, we may need to change prefix and sampler in - // the fragment shader - bool modifiedFragmentShader = false; - std::string fragmentShaderString; - if(mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))) - { - Texture nativeTexture = mTextures.GetTexture(0); - fragmentShaderString = std::string(fragmentShaderView); - modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShaderString); - fragmentShaderView = fragmentShaderString; - } + bool usesWholeTexture = true; + const bool useStandardShader = !mImpl->mCustomShader; + const bool useNativeImage = (mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))); - const bool useStandardShader = !mImpl->mCustomShader && !modifiedFragmentShader; if(useStandardShader) { // Create and cache the standard shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - mImpl->mFlags & Impl::IS_ATLASING_APPLIED ? TextureAtlas::ENABLED : TextureAtlas::DISABLED, - mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE ? DefaultTextureWrapMode::APPLY : DefaultTextureWrapMode::DO_NOT_APPLY, - IsRoundedCornerRequired() ? RoundedCorner::ENABLED : RoundedCorner::DISABLED, - IsBorderlineRequired() ? Borderline::ENABLED : Borderline::DISABLED - ); - } - else if(mImpl->mCustomShader) - { - shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints); + ImageVisualShaderFeature::FeatureBuilder() + .EnableTextureAtlas(mImpl->mFlags & Impl::IS_ATLASING_APPLIED && !useNativeImage) + .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE) + .EnableRoundedCorner(IsRoundedCornerRequired()) + .EnableBorderline(IsBorderlineRequired()) + .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture())); } else { - shader = Shader::New(vertexShaderView, fragmentShaderView); + std::string_view vertexShaderView; + std::string_view fragmentShaderView; + + if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty()) + { + vertexShaderView = mImpl->mCustomShader->mVertexShader; + usesWholeTexture = false; // Impossible to tell. + } + else + { + vertexShaderView = mImageVisualShaderFactory.GetVertexShaderSource(); + } + + if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty()) + { + fragmentShaderView = mImpl->mCustomShader->mFragmentShader; + } + else + { + fragmentShaderView = mImageVisualShaderFactory.GetFragmentShaderSource(); + } + + // If the texture is native, we may need to change prefix and sampler in + // the fragment shader + if(useNativeImage) + { + bool modifiedFragmentShader = false; + Texture nativeTexture = mTextures.GetTexture(0); + std::string fragmentShaderString = std::string(fragmentShaderView); + + modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShaderString); + if(modifiedFragmentShader) + { + fragmentShaderView = fragmentShaderString; + } + + // Create shader here cause fragmentShaderString scope issue + shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints); + } + else + { + shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints); + } } if(usesWholeTexture)