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
{
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);
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<int>(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;
+}
// 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();
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);
}
}
+void OnResourceReadySignal07(Control control)
+{
+ gResourceReadySignalCounter++;
+ // Load masked image
+ tet_printf("rc %d %d\n", gResourceReadySignalCounter, static_cast<bool>(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)
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.
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");
if(!IsShowingPlaceholderText())
{
mModel->mVisualModel->SetTextColor(color);
- mModel->mLogicalModel->mColorRuns.Clear();
mOperationsPending = static_cast<OperationsMask>(mOperationsPending | COLOR);
RequestRelayout();
}
{
// 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);
// 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);
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";
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
// 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)
{
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;
- }
}
}
}
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)
{
for(auto&& element : mLoadQueue)
{
- if(!element.mObserver)
+ if(element.mTextureId == INVALID_TEXTURE_ID)
{
continue;
}
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)
{
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();
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<TextureId> 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)
{
pixelBuffers.push_back(textureInfo.pixelBuffer);
UploadTextures(pixelBuffers, textureInfo);
- // notify mask texture set.
- NotifyObservers(textureInfo, true);
+ notifyRequiredTextureIds.push_back(textureInfo.textureId);
}
}
else
std::vector<Devel::PixelBuffer> 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)
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);
{
if(element.mObserver == observer)
{
- element.mObserver = nullptr;
+ element.mTextureId = INVALID_TEXTURE_ID;
+ element.mObserver = nullptr;
}
}
}
TextureSet TextureManager::GetTextureSet(const TextureManager::TextureId& textureId)
{
- TextureSet textureSet;
+ TextureSet textureSet;
TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
{
// 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.
/*
- * 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.
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()
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;
// 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;
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<Dali::Actor> descentList;
- std::vector<InheritanceMode> inheritanceModeList;
- Dali::Actor currentActor = actor;
- int inheritance = 0;
- do
- {
- inheritance = (static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_ORIENTATION)) << 2) +
- (static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_SCALE)) << 1) +
- static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_POSITION));
- inheritanceModeList.push_back(static_cast<InheritanceMode>(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<Vector3>(Dali::Actor::Property::ANCHOR_POINT);
- Vector3 parentOrigin = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::PARENT_ORIGIN);
- bool positionUsesAnchorPoint = descentList[i].GetProperty<bool>(Dali::Actor::Property::POSITION_USES_ANCHOR_POINT);
- Vector3 size = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::SIZE);
- Vector3 actorPosition = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::POSITION);
- Quaternion localOrientation = descentList[i].GetProperty<Quaternion>(Dali::Actor::Property::ORIENTATION);
- Vector3 localScale = descentList[i].GetProperty<Vector3>(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<Vector3>(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<Dali::Actor> descentList;
- std::vector<Dali::ColorMode> inheritanceModeList;
- Dali::Actor currentActor = actor;
- Dali::ColorMode inheritance = Dali::ColorMode::USE_OWN_MULTIPLY_PARENT_ALPHA;
- do
- {
- inheritance = currentActor.GetProperty<Dali::ColorMode>(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<Vector4>(Dali::Actor::Property::COLOR);
- }
- else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_ALPHA)
- {
- Vector4 ownColor = descentList[i].GetProperty<Vector4>(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<Vector4>(Dali::Actor::Property::COLOR);
- worldColor *= ownColor;
- }
- }
-
- return worldColor;
-}
-
} // namespace Internal
} // namespace Toolkit
#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.
}
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.
}
/**
- * @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
}
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
/*
- * 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.
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])
}
//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);
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);
{
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
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