From: Richard Huang Date: Fri, 30 Sep 2022 10:29:18 +0000 (+0100) Subject: [dali_2.1.42] Merge branch 'devel/master' X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85a1dde40d638ac5f39e2d839f77ca6a9596761d;hp=ad8d1ae9c54e99dbe5d9fb1a4b61e7c4d1a33983;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git [dali_2.1.42] Merge branch 'devel/master' Change-Id: I3f0b3575115588e6985702abc30290026792869d --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp index 5f82a5c..c80d1b5 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp @@ -54,8 +54,9 @@ void utc_dali_toolkit_texture_manager_cleanup(void) namespace { -const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1.jpg"; -const char* TEST_MASK_FILE_NAME = TEST_RESOURCE_DIR "/mask.png"; +const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1.jpg"; +const char* TEST_IMAGE_2_FILE_NAME = TEST_RESOURCE_DIR "/icon-delete.png"; +const char* TEST_MASK_FILE_NAME = TEST_RESOURCE_DIR "/mask.png"; class TestObserver : public Dali::Toolkit::TextureUploadObserver { @@ -1034,7 +1035,7 @@ int UtcTextureManagerAsyncSyncAsync(void) Texture asyncTexture2 = asyncTextureSet2.GetTexture(0u); DALI_TEST_CHECK(syncTexture); DALI_TEST_CHECK(asyncTexture2); - DALI_TEST_CHECK(asyncTexture2 == syncTexture); // check loaded two texture is same. + DALI_TEST_CHECK(asyncTexture2 == syncTexture); // check loaded two texture is same. // observer is called synchronously because the texture is cached. DALI_TEST_EQUALS(asyncObserver2.mLoaded, true, TEST_LOCATION); @@ -1216,3 +1217,162 @@ int UtcTextureManagerRemoveDuringApplyMasking(void) END_TEST; } + +int UtcTextureManagerMaskCacheTest(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcTextureManagerMaskCacheTest"); + + TextureManager textureManager; // Create new texture manager + + TestObserver observer1; + TestObserver observer2; + + std::string filename(TEST_IMAGE_FILE_NAME); + std::string filename2(TEST_IMAGE_2_FILE_NAME); + std::string maskname(TEST_MASK_FILE_NAME); + TextureManager::MaskingDataPointer maskInfo = nullptr; + maskInfo.reset(new TextureManager::MaskingData()); + maskInfo->mAlphaMaskUrl = maskname; + maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + maskInfo->mCropToMask = true; + maskInfo->mContentScaleFactor = 1.0f; + + TextureManager::MaskingDataPointer maskInfo2 = nullptr; + maskInfo2.reset(new TextureManager::MaskingData()); + maskInfo2->mAlphaMaskUrl = maskname; + maskInfo2->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + maskInfo2->mCropToMask = true; + maskInfo2->mContentScaleFactor = 1.0f; + + auto textureId1(TextureManager::INVALID_TEXTURE_ID); + auto textureId2(TextureManager::INVALID_TEXTURE_ID); + Vector4 atlasRect(0.f, 0.f, 1.f, 1.f); + Dali::ImageDimensions atlasRectSize(0, 0); + bool synchronousLoading(false); + bool atlasingStatus(false); + bool loadingStatus(false); + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + ImageAtlasManagerPtr atlasManager = nullptr; + Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr; + + textureManager.LoadTexture( + filename, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId1, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer1, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + // Load image and mask image. + // Now, LoadState become MASK_APPLYING + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + tet_printf("Current textureId1:%d's state become MASK_APPLYING\n", static_cast(textureId1)); + + textureManager.LoadTexture( + filename2, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo2, + synchronousLoading, + textureId2, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer2, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + application.SendNotification(); + application.Render(); + + // Load image2 + image1 apply mask + image2 apply mask = total 3 event trigger required. + // Note that we use cached mask image. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + + DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION); + + try + { + // Remove textureId1 first, and then remove textureId2. Check whether segfault occured. + textureManager.Remove(textureId1, &observer1); + textureManager.Remove(textureId2, &observer2); + + TestObserver observer3; + maskInfo.reset(new TextureManager::MaskingData()); + maskInfo->mAlphaMaskUrl = maskname; + maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + maskInfo->mCropToMask = true; + maskInfo->mContentScaleFactor = 1.0f; + + textureManager.LoadTexture( + filename, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + maskInfo, + synchronousLoading, + textureId1, + atlasRect, + atlasRectSize, + atlasingStatus, + loadingStatus, + &observer3, + atlasUploadObserver, + atlasManager, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply); + + DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + // Load image and mask image. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION); + + // Apply mask. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION); + DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION); + } + catch(...) + { + DALI_TEST_CHECK(false); + } + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 1559ae7..34aa8a3 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -3474,7 +3474,7 @@ void OnResourceReadySignal06(Control control) // We hope this request result is return later than gImageView2. Property::Map map1; - map1[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_1; + map1[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_1; map1[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT; gImageView3 = ImageView::New(); @@ -3482,9 +3482,9 @@ void OnResourceReadySignal06(Control control) gImageView3.ResourceReadySignal().Connect(&OnResourceReadySignal06); Property::Map map2; - map2[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_2; + map2[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_2; map2[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_S; - gImageView4 = ImageView::New(); + gImageView4 = ImageView::New(); gImageView4.SetProperty(Toolkit::ImageView::Property::IMAGE, map2); gImageView4.ResourceReadySignal().Connect(&OnResourceReadySignal06); @@ -3529,6 +3529,28 @@ void OnResourceReadySignal06(Control control) } } +void OnResourceReadySignal07(Control control) +{ + gResourceReadySignalCounter++; + // Load masked image + tet_printf("rc %d %d\n", gResourceReadySignalCounter, static_cast(gImageView2)); + + if(!gImageView2) + { + auto scene = gImageView1.GetParent(); + + Property::Map map1; + map1[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_1; + map1[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT; + + gImageView2 = ImageView::New(); + gImageView2.SetProperty(Toolkit::ImageView::Property::IMAGE, map1); + gImageView2.ResourceReadySignal().Connect(&OnResourceReadySignal07); + + scene.Add(gImageView2); + } +} + } // namespace int UtcDaliImageViewSetImageOnResourceReadySignal01(void) @@ -3966,7 +3988,7 @@ int UtcDaliImageViewSetImageOnResourceReadySignal06(void) gResourceReadySignal06ComesOrder = 0; Property::Map map; - map[Toolkit::ImageVisual::Property::URL] = "invalid.jpg"; + map[Toolkit::ImageVisual::Property::URL] = "invalid.jpg"; map[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = "invalid.png"; gImageView1 = ImageView::New(); // request invalid image, to make loading failed fast. @@ -4015,6 +4037,57 @@ int UtcDaliImageViewSetImageOnResourceReadySignal06(void) END_TEST; } +int UtcDaliImageViewSetImageOnResourceReadySignal07(void) +{ + tet_infoline("Test texturemanager's remove image & mask queue works well within signal handler 02."); + + ToolkitTestApplication application; + + gResourceReadySignalCounter = 0; + + Property::Map map; + map[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_1; + + // Clear image view for clear test + + if(gImageView1) + { + gImageView1.Reset(); + } + if(gImageView2) + { + gImageView2.Reset(); + } + + gImageView1 = ImageView::New(); + gImageView1.SetProperty(Toolkit::ImageView::Property::IMAGE, map); + gImageView1.ResourceReadySignal().Connect(&OnResourceReadySignal07); + application.GetScene().Add(gImageView1); + + application.SendNotification(); + application.Render(); + + // Load gImageView1 + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DALI_TEST_EQUALS(gResourceReadySignalCounter, 1, TEST_LOCATION); + + tet_infoline("load image1 done"); + + // Load gImageView2 and mask + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + DALI_TEST_EQUALS(gResourceReadySignalCounter, 1, TEST_LOCATION); + + // gImageView2 mask apply done + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DALI_TEST_EQUALS(gResourceReadySignalCounter, 2, TEST_LOCATION); + + tet_infoline("load image2 done"); + END_TEST; +} + int UtcDaliImageViewUseSameUrlWithAnimatedImageVisual(void) { tet_infoline("Test multiple views with same image in animated image visual"); diff --git a/dali-toolkit/internal/text/controller/text-controller-impl.cpp b/dali-toolkit/internal/text/controller/text-controller-impl.cpp index e5086d6..8b6d8cb 100644 --- a/dali-toolkit/internal/text/controller/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/controller/text-controller-impl.cpp @@ -1917,7 +1917,6 @@ void Controller::Impl::SetDefaultColor(const Vector4& color) if(!IsShowingPlaceholderText()) { mModel->mVisualModel->SetTextColor(color); - mModel->mLogicalModel->mColorRuns.Clear(); mOperationsPending = static_cast(mOperationsPending | COLOR); RequestRelayout(); } diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 5543d79..467b80e 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -974,7 +974,8 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect { // Generate the outline if enabled const uint16_t outlineWidth = mModel->GetOutlineWidth(); - if(outlineWidth != 0u && RENDER_OVERLAY_STYLE != behaviour) + const float outlineAlpha = mModel->GetOutlineColor().a; + if(outlineWidth != 0u && fabsf(outlineAlpha) > Math::MACHINE_EPSILON_1 && RENDER_OVERLAY_STYLE != behaviour) { // Create the image buffer for outline Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs); @@ -987,7 +988,8 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect // Generate the shadow if enabled const Vector2& shadowOffset = mModel->GetShadowOffset(); - if(RENDER_OVERLAY_STYLE != behaviour && (fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1)) + const float shadowAlpha = mModel->GetShadowColor().a; + if(RENDER_OVERLAY_STYLE != behaviour && fabsf(shadowAlpha) > Math::MACHINE_EPSILON_1 && (fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1)) { // Create the image buffer for shadow Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs); diff --git a/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp b/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp index 0c89aad..ab237a3 100644 --- a/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp +++ b/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp @@ -37,8 +37,8 @@ constexpr auto INITIAL_HASH_NUMBER = size_t{0u}; constexpr auto DEFAULT_NUMBER_OF_LOCAL_LOADER_THREADS = size_t{4u}; constexpr auto DEFAULT_NUMBER_OF_REMOTE_LOADER_THREADS = size_t{8u}; -constexpr auto TEXTURE_INDEX = 0u; ///< The Index for texture -constexpr auto MASK_TEXTURE_INDEX = 1u; ///< The Index for mask texture +constexpr auto TEXTURE_INDEX = 0u; ///< The Index for texture +constexpr auto MASK_TEXTURE_INDEX = 1u; ///< The Index for mask texture constexpr auto NUMBER_OF_LOCAL_LOADER_THREADS_ENV = "DALI_TEXTURE_LOCAL_THREADS"; constexpr auto NUMBER_OF_REMOTE_LOADER_THREADS_ENV = "DALI_TEXTURE_REMOTE_THREADS"; @@ -710,30 +710,40 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU if(textureCacheIndex != INVALID_CACHE_INDEX) { TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID; - TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]); - if(textureInfo.maskTextureId != INVALID_TEXTURE_ID) + TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]); + // We only need to consider maskTextureId when texture's loadState is not CANCELLED. Because it is already deleted. + if(textureInfo.loadState != LoadState::CANCELLED) { - maskTextureId = textureInfo.maskTextureId; + if(textureInfo.maskTextureId != INVALID_TEXTURE_ID) + { + maskTextureId = textureInfo.maskTextureId; + } } // the case that LoadingQueue is working. if(mLoadingQueueTextureId != INVALID_TEXTURE_ID) { // If textureId is not same, this observer need to delete when ProcessRemoveQueue() is called. - TextureUploadObserver* queueObserver = nullptr; - if(mLoadingQueueTextureId != textureId) + // If textureId is same, we should not call RemoveTextureObserver. + // Because ObserverDestroyed signal already disconnected in NotifyObservers + TextureUploadObserver* queueObserver = observer; + if(mLoadingQueueTextureId == textureId) { - queueObserver = observer; + queueObserver = nullptr; } - // Remove textureId after NotifyObserver finished - if(maskTextureId != INVALID_TEXTURE_ID) + // Remove element from the mLoadQueue + for(auto&& element : mLoadQueue) { - if(textureInfo.loadState != LoadState::CANCELLED) + if(element.mTextureId == textureId && element.mObserver == observer) { - mRemoveQueue.PushBack(QueueElement(maskTextureId, nullptr)); + // Do not erase the item. We will clear it later in ProcessLoadQueue(). + element.mTextureId = INVALID_TEXTURE_ID; + element.mObserver = nullptr; + break; } } + mRemoveQueue.PushBack(QueueElement(textureId, queueObserver)); } else @@ -741,6 +751,9 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU // Remove its observer RemoveTextureObserver(textureInfo, observer); + // Remove textureId in CacheManager. Now, textureInfo is invalidate. + mTextureCacheManager.RemoveCache(textureInfo); + // Remove maskTextureId in CacheManager if(maskTextureId != INVALID_TEXTURE_ID) { @@ -748,31 +761,9 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU if(maskCacheIndex != INVALID_CACHE_INDEX) { TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]); - - // Only Remove maskTexture when texture's loadState is not CANCELLED. because it is already deleted. - if(textureInfo.loadState != LoadState::CANCELLED) - { - mTextureCacheManager.RemoveCache(maskTextureInfo); - } + mTextureCacheManager.RemoveCache(maskTextureInfo); } } - - // Remove textureId in CacheManager - mTextureCacheManager.RemoveCache(textureInfo); - } - } - - if(observer) - { - // Remove element from the LoadQueue - for(auto&& element : mLoadQueue) - { - if(element.mObserver == observer) - { - // Do not erase the item. We will clear it later in ProcessLoadQueue(). - element.mObserver = nullptr; - break; - } } } } @@ -885,7 +876,10 @@ void TextureManager::QueueLoadTexture(const TextureManager::TextureInfo& texture const auto& textureId = textureInfo.textureId; mLoadQueue.PushBack(QueueElement(textureId, observer)); - observer->DestructionSignal().Connect(this, &TextureManager::ObserverDestroyed); + if(observer) + { + observer->DestructionSignal().Connect(this, &TextureManager::ObserverDestroyed); + } } void TextureManager::LoadTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer) @@ -915,7 +909,7 @@ void TextureManager::ProcessLoadQueue() { for(auto&& element : mLoadQueue) { - if(!element.mObserver) + if(element.mTextureId == INVALID_TEXTURE_ID) { continue; } @@ -926,7 +920,10 @@ void TextureManager::ProcessLoadQueue() TextureInfo& textureInfo(mTextureCacheManager[cacheIndex]); if((textureInfo.loadState == LoadState::UPLOADED) || (textureInfo.loadState == LoadState::LOAD_FINISHED && textureInfo.storageType == StorageType::RETURN_PIXEL_BUFFER)) { - EmitLoadComplete(element.mObserver, textureInfo, true); + if(element.mObserver) + { + EmitLoadComplete(element.mObserver, textureInfo, true); + } } else if(textureInfo.loadState == LoadState::LOADING) { @@ -945,15 +942,11 @@ void TextureManager::ProcessLoadQueue() void TextureManager::ProcessRemoveQueue() { - TextureCacheIndex textureCacheIndex = INVALID_CACHE_INDEX; for(auto&& element : mRemoveQueue) { - textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(element.mTextureId); - if(textureCacheIndex != INVALID_CACHE_INDEX) + if(element.mTextureId != INVALID_TEXTURE_ID) { - TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]); - RemoveTextureObserver(textureInfo, element.mObserver); - mTextureCacheManager.RemoveCache(textureInfo); + Remove(element.mTextureId, element.mObserver); } } mRemoveQueue.Clear(); @@ -1124,10 +1117,13 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex UploadTextures(pixelBuffers, maskTextureInfo); } - // Search the cache, checking if any texture has this texture id as a - // maskTextureId: + // Search the cache, checking if any texture has this texture id as a maskTextureId const std::size_t size = mTextureCacheManager.size(); + // Keep notify observer required textureIds. + // Note : NotifyObservers can change mTextureCacheManager cache struct. We should check id's validation before notify. + std::vector notifyRequiredTextureIds; + // TODO : Refactorize here to not iterate whole cached image. for(TextureCacheIndex cacheIndex = TextureCacheIndex(TextureManagerType::TEXTURE_CACHE_INDEX_TYPE_LOCAL, 0u); cacheIndex.GetIndex() < size; ++cacheIndex.detailValue.index) { @@ -1153,8 +1149,7 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex pixelBuffers.push_back(textureInfo.pixelBuffer); UploadTextures(pixelBuffers, textureInfo); - // notify mask texture set. - NotifyObservers(textureInfo, true); + notifyRequiredTextureIds.push_back(textureInfo.textureId); } } else @@ -1164,10 +1159,22 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex std::vector pixelBuffers; pixelBuffers.push_back(textureInfo.pixelBuffer); UploadTextures(pixelBuffers, textureInfo); - NotifyObservers(textureInfo, true); + + notifyRequiredTextureIds.push_back(textureInfo.textureId); } } } + + // Notify textures are masked + for(const auto textureId : notifyRequiredTextureIds) + { + TextureCacheIndex textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureId); + if(textureCacheIndex != INVALID_CACHE_INDEX) + { + TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]); + NotifyObservers(textureInfo, true); + } + } } void TextureManager::ApplyMask(TextureManager::TextureInfo& textureInfo, const TextureManager::TextureId& maskTextureId) @@ -1210,7 +1217,7 @@ void TextureManager::UploadTextures(std::vector& pixelBuffer for(auto&& pixelBuffer : pixelBuffers) { - Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight()); + Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight()); PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer); texture.Upload(pixelData); textureInfo.textures.push_back(texture); @@ -1314,7 +1321,8 @@ void TextureManager::ObserverDestroyed(TextureUploadObserver* observer) { if(element.mObserver == observer) { - element.mObserver = nullptr; + element.mTextureId = INVALID_TEXTURE_ID; + element.mObserver = nullptr; } } } @@ -1346,7 +1354,7 @@ void TextureManager::EmitLoadComplete(TextureUploadObserver* observer, TextureMa TextureSet TextureManager::GetTextureSet(const TextureManager::TextureId& textureId) { - TextureSet textureSet; + TextureSet textureSet; TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId); if(loadState == TextureManager::LoadState::UPLOADED) { @@ -1406,8 +1414,8 @@ void TextureManager::RemoveTextureObserver(TextureManager::TextureInfo& textureI // Remove its observer if(observer) { - const auto iterEnd = textureInfo.observerList.End(); - const auto iter = std::find(textureInfo.observerList.Begin(), iterEnd, observer); + const auto iterEnd = textureInfo.observerList.End(); + const auto iter = std::find(textureInfo.observerList.Begin(), iterEnd, observer); if(iter != iterEnd) { // Disconnect and remove the observer. diff --git a/dali-toolkit/internal/transition/transition-base-impl.cpp b/dali-toolkit/internal/transition/transition-base-impl.cpp index 5ee926e..5a88901 100644 --- a/dali-toolkit/internal/transition/transition-base-impl.cpp +++ b/dali-toolkit/internal/transition/transition-base-impl.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. @@ -70,36 +70,6 @@ Property::Map GetOriginalProperties(Dali::Toolkit::Control control) return propertyMap; } -/** - * @brief Computes and center position by using transform properties. - * @param[in] anchorPoint anchorPoint of an actor. - * @param[in] positionUsesAnchorPoint positionUsesAnchorPoint of an actor. - * @param[in] size size of an actor. - * @param[in] scale scale of an actor. - * @param[in] orientation orientation of an actor. - */ -Vector3 CalculateCenterPosition( - const Vector3& anchorPoint, - const bool positionUsesAnchorPoint, - const Vector3& size, - const Vector3& scale, - const Quaternion& orientation) -{ - Vector3 centerPosition; - const Vector3 half(0.5f, 0.5f, 0.5f); - const Vector3 topLeft(0.0f, 0.0f, 0.5f); - // Calculate the center-point by applying the scale and rotation on the anchor point. - centerPosition = (half - anchorPoint) * size * scale; - centerPosition *= orientation; - - // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position. - if(!positionUsesAnchorPoint) - { - centerPosition -= (topLeft - anchorPoint) * size; - } - return centerPosition; -} - } // anonymous namespace TransitionBasePtr TransitionBase::New() @@ -161,7 +131,7 @@ void TransitionBase::TransitionWithChild(bool transitionWithChild) void TransitionBase::PreProcess(Dali::Animation animation) { - mAnimation = animation; + mAnimation = animation; // Retrieve original property map of mTarget to backup and to reset after transition is finished. mOriginalPropertyMap = GetOriginalProperties(mTarget); mMoveTargetChildren = false; @@ -183,11 +153,11 @@ void TransitionBase::Play() // Set world transform and color to the target control to make it independent of the parent control and its transition. // The properties will be returned at the TransitionFinished() method. - Matrix targetWorldTransform = GetWorldTransform(mTarget); + Matrix targetWorldTransform = DevelActor::GetWorldTransform(mTarget); Vector3 targetPosition, targetScale; Quaternion targetOrientation; targetWorldTransform.GetTransformComponents(targetPosition, targetOrientation, targetScale); - Vector4 targetColor = GetWorldColor(mTarget); + Vector4 targetColor = DevelActor::GetWorldColor(mTarget); mTarget.SetProperties(PROPERTY_MAP_INDEPENDENT_CONTROL); mTarget[Dali::Actor::Property::POSITION] = targetPosition; @@ -282,141 +252,6 @@ void TransitionBase::TransitionFinished() mAnimation.Reset(); } -Matrix TransitionBase::GetWorldTransform(Dali::Actor actor) -{ - enum InheritanceMode - { - DONT_INHERIT_TRANSFORM = 0, - INHERIT_POSITION = 1, - INHERIT_SCALE = 2, - INHERIT_ORIENTATION = 4, - INHERIT_ALL = INHERIT_POSITION | INHERIT_SCALE | INHERIT_ORIENTATION, - }; - - std::vector descentList; - std::vector inheritanceModeList; - Dali::Actor currentActor = actor; - int inheritance = 0; - do - { - inheritance = (static_cast(currentActor.GetProperty(Dali::Actor::Property::INHERIT_ORIENTATION)) << 2) + - (static_cast(currentActor.GetProperty(Dali::Actor::Property::INHERIT_SCALE)) << 1) + - static_cast(currentActor.GetProperty(Dali::Actor::Property::INHERIT_POSITION)); - inheritanceModeList.push_back(static_cast(inheritance)); - descentList.push_back(currentActor); - currentActor = currentActor.GetParent(); - } while(inheritance != DONT_INHERIT_TRANSFORM && currentActor); - - Matrix worldMatrix; - Vector3 localPosition; - for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i) - { - Vector3 anchorPoint = descentList[i].GetProperty(Dali::Actor::Property::ANCHOR_POINT); - Vector3 parentOrigin = descentList[i].GetProperty(Dali::Actor::Property::PARENT_ORIGIN); - bool positionUsesAnchorPoint = descentList[i].GetProperty(Dali::Actor::Property::POSITION_USES_ANCHOR_POINT); - Vector3 size = descentList[i].GetProperty(Dali::Actor::Property::SIZE); - Vector3 actorPosition = descentList[i].GetProperty(Dali::Actor::Property::POSITION); - Quaternion localOrientation = descentList[i].GetProperty(Dali::Actor::Property::ORIENTATION); - Vector3 localScale = descentList[i].GetProperty(Dali::Actor::Property::SCALE); - - Vector3 centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation); - if(inheritanceModeList[i] != DONT_INHERIT_TRANSFORM && descentList[i].GetParent()) - { - Matrix localMatrix; - Vector3 parentSize = descentList[i + 1].GetProperty(Dali::Actor::Property::SIZE); - if(inheritanceModeList[i] == INHERIT_ALL) - { - localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize; - localMatrix.SetTransformComponents(localScale, localOrientation, localPosition); - - //Update the world matrix - Matrix tempMatrix; - Matrix::Multiply(tempMatrix, localMatrix, worldMatrix); - worldMatrix = tempMatrix; - } - else - { - Vector3 parentPosition, parentScale; - Quaternion parentOrientation; - worldMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale); - - if((inheritanceModeList[i] & INHERIT_SCALE) == 0) - { - //Don't inherit scale - localScale /= parentScale; - } - - if((inheritanceModeList[i] & INHERIT_ORIENTATION) == 0) - { - //Don't inherit orientation - parentOrientation.Invert(); - localOrientation = parentOrientation * localOrientation; - } - - if((inheritanceModeList[i] & INHERIT_POSITION) == 0) - { - localMatrix.SetTransformComponents(localScale, localOrientation, Vector3::ZERO); - Matrix tempMatrix; - Matrix::Multiply(tempMatrix, localMatrix, worldMatrix); - worldMatrix = tempMatrix; - worldMatrix.SetTranslation(actorPosition + centerPosition); - } - else - { - localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize; - localMatrix.SetTransformComponents(localScale, localOrientation, localPosition); - Matrix tempMatrix; - Matrix::Multiply(tempMatrix, localMatrix, worldMatrix); - worldMatrix = tempMatrix; - } - } - } - else - { - localPosition = actorPosition + centerPosition; - worldMatrix.SetTransformComponents(localScale, localOrientation, localPosition); - } - } - - return worldMatrix; -} - -Vector4 TransitionBase::GetWorldColor(Dali::Actor actor) -{ - std::vector descentList; - std::vector inheritanceModeList; - Dali::Actor currentActor = actor; - Dali::ColorMode inheritance = Dali::ColorMode::USE_OWN_MULTIPLY_PARENT_ALPHA; - do - { - inheritance = currentActor.GetProperty(Dali::Actor::Property::COLOR_MODE); - inheritanceModeList.push_back(inheritance); - descentList.push_back(currentActor); - currentActor = currentActor.GetParent(); - } while(inheritance != Dali::ColorMode::USE_OWN_COLOR && currentActor); - - Vector4 worldColor; - for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i) - { - if(inheritanceModeList[i] == USE_OWN_COLOR || i == descentList.size() - 1) - { - worldColor = descentList[i].GetProperty(Dali::Actor::Property::COLOR); - } - else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_ALPHA) - { - Vector4 ownColor = descentList[i].GetProperty(Dali::Actor::Property::COLOR); - worldColor = Vector4(ownColor.r, ownColor.g, ownColor.b, ownColor.a * worldColor.a); - } - else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_COLOR) - { - Vector4 ownColor = descentList[i].GetProperty(Dali::Actor::Property::COLOR); - worldColor *= ownColor; - } - } - - return worldColor; -} - } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/transition/transition-base-impl.h b/dali-toolkit/internal/transition/transition-base-impl.h index b194e52..73e30dd 100644 --- a/dali-toolkit/internal/transition/transition-base-impl.h +++ b/dali-toolkit/internal/transition/transition-base-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_TRANSITION_BASE_H /* - * 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. @@ -126,7 +126,6 @@ public: } protected: - /** * @brief Set property map which will be used as a animation start properties. * @param[in] propertyMap propertyMap that will be used as a start value of transition. @@ -163,18 +162,6 @@ protected: } /** - * @brief Gets world transform of input Actor. - * @param[in] actor actor for get world transform. - */ - Matrix GetWorldTransform(Dali::Actor actor); - - /** - * @brief Gets world color of input Actor. - * @param[in] actor actor for get world color. - */ - Vector4 GetWorldColor(Dali::Actor actor); - - /** * @brief Returns whether this transition will be applied to children of target or not. */ bool IsTransitionWithChild() const @@ -256,19 +243,19 @@ private: } private: - Dali::Toolkit::Control mTarget; ///< Target that will be animated. - Dali::Actor mCopiedActor; ///< Copied View that will replace mTarget during transition - Dali::Animation mAnimation; ///< Property animations for the transition of mTarget - AlphaFunction mAlphaFunction; ///< Alpha function that will applied for the property animation - Property::Map mStartPropertyMap; ///< Start properties to be animated. (world transform) - Property::Map mFinishPropertyMap; ///< Finish properties to be animated. (world transform) - Property::Map mOriginalPropertyMap; ///< Original properties of mTarget to be used to restore after the transition is finished. - Dali::TimePeriod mTimePeriod; ///< TimePeriod of transition - bool mTransitionWithChild; ///< True, if mTarget transition is inherit to its child Actors. - ///< If this is false, the child Actors are moved to the child of mCopiedActor that will have original properties of target Actor during Transition. - bool mMoveTargetChildren; ///< Flag, if mTransitionWithChild is false and mTarget has children than True. - bool mIsAppearingTransition; ///< True, if this transition is appearing transition. - bool mIsPairTransition; ///< True, if this transition is started from a Control to another Control. + Dali::Toolkit::Control mTarget; ///< Target that will be animated. + Dali::Actor mCopiedActor; ///< Copied View that will replace mTarget during transition + Dali::Animation mAnimation; ///< Property animations for the transition of mTarget + AlphaFunction mAlphaFunction; ///< Alpha function that will applied for the property animation + Property::Map mStartPropertyMap; ///< Start properties to be animated. (world transform) + Property::Map mFinishPropertyMap; ///< Finish properties to be animated. (world transform) + Property::Map mOriginalPropertyMap; ///< Original properties of mTarget to be used to restore after the transition is finished. + Dali::TimePeriod mTimePeriod; ///< TimePeriod of transition + bool mTransitionWithChild; ///< True, if mTarget transition is inherit to its child Actors. + ///< If this is false, the child Actors are moved to the child of mCopiedActor that will have original properties of target Actor during Transition. + bool mMoveTargetChildren; ///< Flag, if mTransitionWithChild is false and mTarget has children than True. + bool mIsAppearingTransition; ///< True, if this transition is appearing transition. + bool mIsPairTransition; ///< True, if this transition is started from a Control to another Control. }; } // namespace Internal diff --git a/dali-toolkit/internal/transition/transition-impl.cpp b/dali-toolkit/internal/transition/transition-impl.cpp index 78ba8db..3f78a6f 100644 --- a/dali-toolkit/internal/transition/transition-impl.cpp +++ b/dali-toolkit/internal/transition/transition-impl.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. @@ -82,7 +82,7 @@ Transition::~Transition() void Transition::OnPlay() { - Dali::Toolkit::Control sourceControl = mSourceControl.GetHandle(); + Dali::Toolkit::Control sourceControl = mSourceControl.GetHandle(); Dali::Toolkit::Control destinationControl = mDestinationControl.GetHandle(); if(!sourceControl || !sourceControl[Dali::Actor::Property::CONNECTED_TO_SCENE] || !destinationControl || !destinationControl[Dali::Actor::Property::CONNECTED_TO_SCENE]) @@ -92,12 +92,12 @@ void Transition::OnPlay() } //Make startPropertyMap and finishPropertyMap to use for property animation. - Matrix sourceWorldTransform = GetWorldTransform(sourceControl); + Matrix sourceWorldTransform = DevelActor::GetWorldTransform(sourceControl); Vector3 sourcePosition, sourceScale; Quaternion sourceOrientation; sourceWorldTransform.GetTransformComponents(sourcePosition, sourceOrientation, sourceScale); - Matrix destinationWorldTransform = GetWorldTransform(destinationControl); + Matrix destinationWorldTransform = DevelActor::GetWorldTransform(destinationControl); Vector3 destinationPosition, destinationScale; Quaternion destinationOrientation; destinationWorldTransform.GetTransformComponents(destinationPosition, destinationOrientation, destinationScale); @@ -115,8 +115,8 @@ void Transition::OnPlay() startPropertyMap.Insert(Dali::Actor::Property::SCALE, sourceScale); finishPropertyMap.Insert(Dali::Actor::Property::SCALE, destinationScale); - Vector4 sourceColor = GetWorldColor(sourceControl); - Vector4 destinationColor = GetWorldColor(destinationControl); + Vector4 sourceColor = DevelActor::GetWorldColor(sourceControl); + Vector4 destinationColor = DevelActor::GetWorldColor(destinationControl); startPropertyMap.Insert(Dali::Actor::Property::COLOR, sourceColor); finishPropertyMap.Insert(Dali::Actor::Property::COLOR, destinationColor); diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 73cc003..33fb992 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -29,7 +29,7 @@ namespace Toolkit { const unsigned int TOOLKIT_MAJOR_VERSION = 2; const unsigned int TOOLKIT_MINOR_VERSION = 1; -const unsigned int TOOLKIT_MICRO_VERSION = 41; +const unsigned int TOOLKIT_MICRO_VERSION = 42; const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 18e1669..7635931 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali2-toolkit Summary: Dali 3D engine Toolkit -Version: 2.1.41 +Version: 2.1.42 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT