X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fimage%2Fimage-visual.cpp;h=d5bc01093e7dd613854bcda6cafc92a0aa8ed646;hb=HEAD;hp=02df28f4219f65025fcc326dc4e43038afb1af58;hpb=b9d02ab85a00b0a5a95ed531d590a034f0b6b72d;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 02df28f..4ebb5e4 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) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -34,9 +34,9 @@ // INTERNAL HEADERS #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -62,6 +62,7 @@ DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE) 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, VISUAL_FITTING) DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, DEFAULT) DALI_ENUM_TO_STRING_TABLE_END(FITTING_MODE) @@ -180,7 +181,7 @@ ImageVisual::ImageVisual(VisualFactoryCache& factoryCache, ImageDimensions size, FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode) -: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::IMAGE), +: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::IMAGE), mPixelArea(FULL_TEXTURE_RECT), mPixelAreaIndex(Property::INVALID_INDEX), mPlacementActor(), @@ -475,6 +476,23 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) { if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0) { + if(mImpl->mRenderer) + { + auto textureSet = mImpl->mRenderer.GetTextures(); + if(textureSet && textureSet.GetTextureCount()) + { + auto texture = textureSet.GetTexture(0); + if(texture) + { + if(mTextureSize != Vector2::ZERO) + { + naturalSize = mTextureSize; + return; + } + } + } + } + naturalSize.x = mDesiredSize.GetWidth(); naturalSize.y = mDesiredSize.GetHeight(); return; @@ -534,6 +552,7 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) imageSize = mPlacementActorSize; } + mUseBrokenImageRenderer = true; mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); Texture brokenImage = mImpl->mRenderer.GetTextures().GetTexture(0); naturalSize.x = brokenImage.GetWidth(); @@ -547,27 +566,6 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) void ImageVisual::OnInitialize() { - Geometry geometry; - - // Get the geometry - if(mImpl->mCustomShader) - { - geometry = CreateGeometry(mFactoryCache, mImpl->mCustomShader->mGridSize); - } - else // Get any geometry associated with the texture - { - TextureManager& textureManager = mFactoryCache.GetTextureManager(); - - uint32_t firstElementCount{0u}; - uint32_t secondElementCount{0u}; - geometry = textureManager.GetRenderGeometry(mTextureId, firstElementCount, secondElementCount); - - if(!firstElementCount && !secondElementCount) // Otherwise use quad - { - geometry = CreateGeometry(mFactoryCache, ImageDimensions(1, 1)); - } - } - // Increase reference count of External Resources : // EncodedImageBuffer or ExternalTextures. // Reference count will be decreased at destructor of the visual. @@ -577,7 +575,9 @@ void ImageVisual::OnInitialize() textureManager.UseExternalResource(mImageUrl.GetUrl()); } - Shader shader = GenerateShader(); + // Generate geometry and shader. Note that we should check AddOn when generate geometry, due to LoadPolicy::IMMEDIATE case + Geometry geometry = GenerateGeometry(mTextureId, true); + Shader shader = GenerateShader(); // Create the renderer mImpl->mRenderer = DecoratedVisualRenderer::New(geometry, shader); @@ -650,7 +650,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te else if(mUseFastTrackUploading) { DALI_LOG_DEBUG_INFO("FastTrack : Fail to load fast track. mUrl : [%s]%s%s%s%s%s%s%s%s\n", - mImageUrl.GetUrl().c_str(), + mImageUrl.GetEllipsedUrl().c_str(), (mLoadPolicy != Toolkit::ImageVisual::LoadPolicy::ATTACHED) ? "/ mLoadPolicy != ATTACHED" : "", (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::DETACHED) ? "/ mReleasePolicy != DETACHED" : "", (forceReload != TextureManager::ReloadPolicy::CACHED) ? "/ forceReload != CACHED" : "", @@ -680,9 +680,9 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te else { DALI_ASSERT_ALWAYS(mFastTrackLoadingTask->mTextures.size() >= 3u); - textureSet.SetTexture(0u, mFastTrackLoadingTask->mTextures[0]); - textureSet.SetTexture(1u, mFastTrackLoadingTask->mTextures[1]); textureSet.SetTexture(2u, mFastTrackLoadingTask->mTextures[2]); + textureSet.SetTexture(1u, mFastTrackLoadingTask->mTextures[1]); + textureSet.SetTexture(0u, mFastTrackLoadingTask->mTextures[0]); // We cannot determine what kind of shader will be used. // Just use unified shader, and then change shader after load completed. @@ -712,7 +712,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te } EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD); - if(!atlasing) + if(!atlasing && (mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT)) { Sampler sampler = Sampler::New(); sampler.SetWrapMode(mWrapModeU, mWrapModeV); @@ -762,7 +762,9 @@ void ImageVisual::InitializeRenderer() else { mTextures = mFactoryCache.GetTextureManager().GetTextureSet(mTextureId); - if(!(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) && mTextures) + if(!(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) && + mTextures && + (mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT)) { Sampler sampler = Sampler::New(); sampler.SetWrapMode(mWrapModeU, mWrapModeV); @@ -777,7 +779,7 @@ void ImageVisual::InitializeRenderer() ComputeTextureSize(); CheckMaskTexture(); - bool needToUpdateShader = DevelTexture::IsNative(mTextures.GetTexture(0)); + bool needToUpdateShader = DevelTexture::IsNative(mTextures.GetTexture(0)) || mUseBrokenImageRenderer; if(mTextures.GetTextureCount() == 3) { @@ -793,6 +795,21 @@ void ImageVisual::InitializeRenderer() UpdateShader(); } mTextures.Reset(); // Visual should not keep a handle to the texture after this point. + + if(DALI_UNLIKELY(mUseBrokenImageRenderer)) + { + // We need to re-generate geometry only if it was broken image before, and result changed after Reload. + auto geometry = GenerateGeometry(mTextureId, true); + + // Update geometry only if we need. + if(geometry) + { + mImpl->mRenderer.SetGeometry(geometry); + } + } + + // We don't use broken image anymore. + mUseBrokenImageRenderer = false; } if(attemptAtlasing) // the texture is packed inside atlas @@ -937,6 +954,11 @@ void ImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::P case DevelImageVisual::Action::RELOAD: { auto attemptAtlasing = AttemptAtlasing(); + + // Reset resource ready status when we call reload. + ResourceReady(Toolkit::Visual::ResourceStatus::PREPARING); + mLoadState = TextureManager::LoadState::NOT_STARTED; + LoadTexture(attemptAtlasing, mAtlasRect, mTextures, mOrientationCorrection, TextureManager::ReloadPolicy::FORCED); break; } @@ -1042,6 +1064,7 @@ void ImageVisual::FastLoadComplete(FastTrackLoadingTaskPtr task) void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureInformation) { Toolkit::Visual::ResourceStatus resourceStatus; + if(mImpl->mRenderer) { EnablePreMultipliedAlpha(textureInformation.preMultiplied); @@ -1054,23 +1077,33 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn } else { - Sampler sampler = Sampler::New(); - sampler.SetWrapMode(mWrapModeU, mWrapModeV); - textureInformation.textureSet.SetSampler(0u, sampler); + if(mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT) + { + Sampler sampler = Sampler::New(); + sampler.SetWrapMode(mWrapModeU, mWrapModeV); + textureInformation.textureSet.SetSampler(0u, sampler); + } mImpl->mRenderer.SetTextures(textureInformation.textureSet); ComputeTextureSize(); CheckMaskTexture(); + bool needToUpdateShader = mUseBrokenImageRenderer; + if(textureInformation.textureSet.GetTextureCount() == 3) { if(textureInformation.textureSet.GetTexture(0).GetPixelFormat() == Pixel::L8 && textureInformation.textureSet.GetTexture(1).GetPixelFormat() == Pixel::CHROMINANCE_U && textureInformation.textureSet.GetTexture(2).GetPixelFormat() == Pixel::CHROMINANCE_V) { - mNeedYuvToRgb = true; - UpdateShader(); + mNeedYuvToRgb = true; + needToUpdateShader = true; } } + if(needToUpdateShader) + { + UpdateShader(); + } + if(actor) { actor.AddRenderer(mImpl->mRenderer); @@ -1078,6 +1111,19 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn // reset the weak handle so that the renderer only get added to actor once mPlacementActor.Reset(); } + + auto geometry = GenerateGeometry(textureInformation.textureId, mUseBrokenImageRenderer); + + if(DALI_UNLIKELY(geometry)) + { + // Rare cases. If load successed image don't use quad geometry (i.e. Show some n-patch broken image, and call Reload(), and success) + // or If given texture use AddOn, + // then we need to make to use quad geometry and update shader agian. + mImpl->mRenderer.SetGeometry(geometry); + } + + // We don't use broken image anymore. + mUseBrokenImageRenderer = false; } } @@ -1099,36 +1145,6 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn mLoadState = TextureManager::LoadState::LOAD_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); } @@ -1323,6 +1339,10 @@ void ImageVisual::CheckMaskTexture() { mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, ComputeMaskTextureRatio()); } + else + { + mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, Vector2::ONE); + } maskLoadFailed = false; } @@ -1365,6 +1385,7 @@ void ImageVisual::ShowBrokenImage() } } + mUseBrokenImageRenderer = true; mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); if(actor) { @@ -1397,6 +1418,59 @@ void ImageVisual::ResetFastTrackLoadingTask() } } +Geometry ImageVisual::GenerateGeometry(TextureManager::TextureId textureId, bool createForce) +{ + Geometry geometry; + if(Stage::IsInstalled()) + { + if(mImpl->mCustomShader) + { + if(createForce) + { + geometry = CreateGeometry(mFactoryCache, mImpl->mCustomShader->mGridSize); + } + } + else + { + uint32_t firstElementCount{0u}; + uint32_t secondElementCount{0u}; + + geometry = mFactoryCache.GetTextureManager().GetRenderGeometry(textureId, firstElementCount, secondElementCount); + if(geometry) + { + if(mImpl->mRenderer) + { + 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); + } + } + } + else if(createForce) + { + // Create default quad geometry now + geometry = CreateGeometry(mFactoryCache, ImageDimensions(1, 1)); + } + } + } + + return geometry; +} + } // namespace Internal } // namespace Toolkit