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=e6e07e8afdd08deee1114e9dc04c437874dd66a1;hpb=d770f13ba1f88060fdb7dcd2997cd6d8aa4524cb;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 e6e07e8..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,8 +34,9 @@ // INTERNAL HEADERS #include #include -#include -#include +#include +#include +#include #include #include #include @@ -61,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) @@ -100,6 +102,35 @@ const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u; +struct NameIndexMatch +{ + const char* const name; + Property::Index index; +}; + +const NameIndexMatch NAME_INDEX_MATCH_TABLE[] = + { + {IMAGE_FITTING_MODE, Toolkit::ImageVisual::Property::FITTING_MODE}, + {IMAGE_SAMPLING_MODE, Toolkit::ImageVisual::Property::SAMPLING_MODE}, + {IMAGE_DESIRED_WIDTH, Toolkit::ImageVisual::Property::DESIRED_WIDTH}, + {IMAGE_DESIRED_HEIGHT, Toolkit::ImageVisual::Property::DESIRED_HEIGHT}, + {PIXEL_AREA_UNIFORM_NAME, Toolkit::ImageVisual::Property::PIXEL_AREA}, + {IMAGE_WRAP_MODE_U, Toolkit::ImageVisual::Property::WRAP_MODE_U}, + {IMAGE_WRAP_MODE_V, Toolkit::ImageVisual::Property::WRAP_MODE_V}, + {SYNCHRONOUS_LOADING, Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING}, + {IMAGE_ATLASING, Toolkit::ImageVisual::Property::ATLASING}, + {ALPHA_MASK_URL, Toolkit::ImageVisual::Property::ALPHA_MASK_URL}, + {MASK_CONTENT_SCALE_NAME, Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE}, + {CROP_TO_MASK_NAME, Toolkit::ImageVisual::Property::CROP_TO_MASK}, + {MASKING_TYPE_NAME, Toolkit::DevelImageVisual::Property::MASKING_TYPE}, + {ENABLE_BROKEN_IMAGE, Toolkit::DevelImageVisual::Property::ENABLE_BROKEN_IMAGE}, + {LOAD_POLICY_NAME, Toolkit::ImageVisual::Property::LOAD_POLICY}, + {RELEASE_POLICY_NAME, Toolkit::ImageVisual::Property::RELEASE_POLICY}, + {ORIENTATION_CORRECTION_NAME, Toolkit::ImageVisual::Property::ORIENTATION_CORRECTION}, + {FAST_TRACK_UPLOADING_NAME, Toolkit::DevelImageVisual::Property::FAST_TRACK_UPLOADING}, +}; +const int NAME_INDEX_MATCH_TABLE_SIZE = sizeof(NAME_INDEX_MATCH_TABLE) / sizeof(NAME_INDEX_MATCH_TABLE[0]); + Geometry CreateGeometry(VisualFactoryCache& factoryCache, ImageDimensions gridSize) { Geometry geometry; @@ -150,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(), @@ -219,77 +250,13 @@ void ImageVisual::DoSetProperties(const Property::Map& propertyMap) } else { - if(keyValue.first == IMAGE_FITTING_MODE) - { - DoSetProperty(Toolkit::ImageVisual::Property::FITTING_MODE, keyValue.second); - } - else if(keyValue.first == IMAGE_SAMPLING_MODE) - { - DoSetProperty(Toolkit::ImageVisual::Property::SAMPLING_MODE, keyValue.second); - } - else if(keyValue.first == IMAGE_DESIRED_WIDTH) - { - DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_WIDTH, keyValue.second); - } - else if(keyValue.first == IMAGE_DESIRED_HEIGHT) - { - DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second); - } - else if(keyValue.first == PIXEL_AREA_UNIFORM_NAME) - { - DoSetProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, keyValue.second); - } - else if(keyValue.first == IMAGE_WRAP_MODE_U) - { - DoSetProperty(Toolkit::ImageVisual::Property::WRAP_MODE_U, keyValue.second); - } - else if(keyValue.first == IMAGE_WRAP_MODE_V) - { - DoSetProperty(Toolkit::ImageVisual::Property::WRAP_MODE_V, keyValue.second); - } - else if(keyValue.first == SYNCHRONOUS_LOADING) + for(int i = 0; i < NAME_INDEX_MATCH_TABLE_SIZE; ++i) { - DoSetProperty(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second); - } - else if(keyValue.first == IMAGE_ATLASING) - { - DoSetProperty(Toolkit::ImageVisual::Property::ATLASING, keyValue.second); - } - else if(keyValue.first == ALPHA_MASK_URL) - { - DoSetProperty(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, keyValue.second); - } - else if(keyValue.first == MASK_CONTENT_SCALE_NAME) - { - DoSetProperty(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, keyValue.second); - } - else if(keyValue.first == CROP_TO_MASK_NAME) - { - DoSetProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, keyValue.second); - } - else if(keyValue.first == MASKING_TYPE_NAME) - { - DoSetProperty(Toolkit::DevelImageVisual::Property::MASKING_TYPE, keyValue.second); - } - else if(keyValue.first == ENABLE_BROKEN_IMAGE) - { - DoSetProperty(Toolkit::DevelImageVisual::Property::ENABLE_BROKEN_IMAGE, keyValue.second); - } - else if(keyValue.first == LOAD_POLICY_NAME) - { - DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second); - } - else if(keyValue.first == RELEASE_POLICY_NAME) - { - DoSetProperty(Toolkit::ImageVisual::Property::RELEASE_POLICY, keyValue.second); - } - else if(keyValue.first == ORIENTATION_CORRECTION_NAME) - { - DoSetProperty(Toolkit::ImageVisual::Property::ORIENTATION_CORRECTION, keyValue.second); - } - else if(keyValue.first == FAST_TRACK_UPLOADING_NAME) - { - DoSetProperty(Toolkit::DevelImageVisual::Property::FAST_TRACK_UPLOADING, keyValue.second); + if(keyValue.first == NAME_INDEX_MATCH_TABLE[i].name) + { + DoSetProperty(NAME_INDEX_MATCH_TABLE[i].index, keyValue.second); + break; + } } } } @@ -452,7 +419,7 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va } else { - mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false; + mMaskingData->mPreappliedMasking = (Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING); } } break; @@ -460,11 +427,7 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va case Toolkit::DevelImageVisual::Property::ENABLE_BROKEN_IMAGE: { - bool enableBrokenImage(mEnableBrokenImage); - if(value.Get(enableBrokenImage)) - { - mEnableBrokenImage = enableBrokenImage; - } + value.Get(mEnableBrokenImage); break; } @@ -485,21 +448,13 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va } case Toolkit::ImageVisual::Property::ORIENTATION_CORRECTION: { - bool orientationCorrection(mOrientationCorrection); - if(value.Get(orientationCorrection)) - { - mOrientationCorrection = orientationCorrection; - } + value.Get(mOrientationCorrection); break; } case Toolkit::DevelImageVisual::Property::FAST_TRACK_UPLOADING: { - bool fastTrackUploading = false; - if(value.Get(fastTrackUploading)) - { - mUseFastTrackUploading = fastTrackUploading; - } + value.Get(mUseFastTrackUploading); break; } } @@ -521,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; @@ -580,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(); @@ -593,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. @@ -623,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); @@ -696,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" : "", @@ -726,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. @@ -758,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); @@ -808,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); @@ -823,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) { @@ -839,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 @@ -983,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; } @@ -1088,13 +1064,9 @@ void ImageVisual::FastLoadComplete(FastTrackLoadingTaskPtr task) void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureInformation) { Toolkit::Visual::ResourceStatus resourceStatus; + if(mImpl->mRenderer) { - if(textureInformation.useAtlasing) - { - mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, mAtlasRect); - } - EnablePreMultipliedAlpha(textureInformation.preMultiplied); Actor actor = mPlacementActor.GetHandle(); @@ -1105,7 +1077,7 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn } else { - if(!textureInformation.useAtlasing) + if(mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT) { Sampler sampler = Sampler::New(); sampler.SetWrapMode(mWrapModeU, mWrapModeV); @@ -1116,15 +1088,22 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn 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); @@ -1132,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; } } @@ -1153,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); } @@ -1282,7 +1244,7 @@ Shader ImageVisual::GenerateShader() const // Create and cache the standard shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - ImageVisualShaderFeature::FeatureBuilder() + ImageVisualShaderFeatureBuilder() .EnableTextureAtlas(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED && !useNativeImage) .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE) .EnableRoundedCorner(IsRoundedCornerRequired()) @@ -1377,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; } @@ -1419,6 +1385,7 @@ void ImageVisual::ShowBrokenImage() } } + mUseBrokenImageRenderer = true; mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); if(actor) { @@ -1451,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