firstTime = false;
auto bridge = Accessibility::Bridge::GetCurrentBridge();
Dali::Stage stage = Dali::Stage::GetCurrent();
- auto accessible = Accessibility::Accessible::Get( stage.GetRootLayer(), true );
+ auto accessible = Accessibility::Accessible::Get( stage.GetRootLayer() );
bridge->AddTopLevelWindow( accessible );
bridge->SetApplicationName( "TestApp" );
bridge->Initialize();
wr->Encode(reply, std::tuple<Address>{ {"bus", "root"} });
return reply;
};
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible/root", "org.a11y.atspi.Socket", "Unembed", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
+ wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible/root", "org.a11y.atspi.Socket", "Embedded", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
+ return wr->newReplyMessage(m);
+ };
wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "PropertyChange", MethodType::Method}] =
[wr](const MessagePtr &m) -> MessagePtr {
return wr->newReplyMessage(m);
namespace
{
-const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-%02d.png";
-const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif";
+const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-%02d.png";
+const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif";
+const char* TEST_MASK_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
} // namespace
void CopyUrlsIntoArray(Property::Array& urls, int startIndex = 0)
.Add(ImageVisual::Property::PIXEL_AREA, Vector4())
.Add(ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT)
.Add(ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT)
+ .Add(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME)
+ .Add(ImageVisual::Property::MASK_CONTENT_SCALE, 1.6f)
+ .Add(ImageVisual::Property::CROP_TO_MASK, true)
.Add(DevelVisual::Property::CORNER_RADIUS, 22.2f)
.Add(DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE)
.Add(DevelVisual::Property::BORDERLINE_WIDTH, 33.3f)
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<float>(), 0.3f, TEST_LOCATION);
+ // Check mask properties
+ value = resultMap.Find(ImageVisual::Property::ALPHA_MASK_URL, Property::STRING);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_CHECK(value->Get<std::string>() == TEST_MASK_IMAGE_FILE_NAME);
+
+ value = resultMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE, Property::FLOAT);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<float>(), 1.6f, TEST_LOCATION);
+
+ value = resultMap.Find(ImageVisual::Property::CROP_TO_MASK, Property::BOOLEAN);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+
+ Vector2 naturalSize;
+ animatedImageVisual.GetNaturalSize(naturalSize);
+ DALI_TEST_EQUALS(naturalSize, Vector2(100, 100), TEST_LOCATION);
+
// request AnimatedImageVisual with an URL
Visual::Base animatedImageVisual2 = factory.CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions());
resultMap.Clear();
.Add("pixelArea", Vector4())
.Add("wrapModeU", WrapMode::REPEAT)
.Add("wrapModeV", WrapMode::DEFAULT)
+ .Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME)
+ .Add("maskContentScale", 1.6f)
+ .Add("cropToMask", true)
.Add("cornerRadius", Vector4(50.0f, 25.0f, 12.5f, 33.0f))
.Add("cornerRadiusPolicy", Visual::Transform::Policy::RELATIVE)
.Add("borderlineWidth", 20.0f)
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<float>(), -1.0f, TEST_LOCATION);
+ // Check mask properties
+ value = resultMap.Find(ImageVisual::Property::ALPHA_MASK_URL, "alphaMaskUrl");
+ DALI_TEST_CHECK(value);
+ DALI_TEST_CHECK(value->Get<std::string>() == TEST_MASK_IMAGE_FILE_NAME);
+
+ value = resultMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE, "maskContentScale");
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<float>(), 1.6f, TEST_LOCATION);
+
+ value = resultMap.Find(ImageVisual::Property::CROP_TO_MASK, "cropToMask");
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+
END_TEST;
}
.Add("pixelArea", Vector4())
.Add("wrapModeU", WrapMode::REPEAT)
.Add("wrapModeV", WrapMode::DEFAULT)
+ .Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME)
+ .Add("maskContentScale", 1.6f)
+ .Add("cropToMask", true)
.Add("cornerRadius", 50.5f));
Property::Map resultMap;
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<float>(), 0.0f, TEST_LOCATION);
+ // Check mask properties
+ value = resultMap.Find(ImageVisual::Property::ALPHA_MASK_URL, "alphaMaskUrl");
+ DALI_TEST_CHECK(value);
+ DALI_TEST_CHECK(value->Get<std::string>() == TEST_MASK_IMAGE_FILE_NAME);
+
+ value = resultMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE, "maskContentScale");
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<float>(), 1.6f, TEST_LOCATION);
+
+ value = resultMap.Find(ImageVisual::Property::CROP_TO_MASK, "cropToMask");
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+
END_TEST;
}
END_TEST;
}
+
+int UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask(void)
+{
+ ToolkitTestApplication application;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+ propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS, 0.23f);
+ propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE);
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+ DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ application.SendNotification();
+ application.Render(20);
+
+ // The first frame is loaded synchronously and load next batch with masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::GetTimerCount(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 2, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliAnimatedImageVisualJumpToAction(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask01(void)
+{
+ ToolkitTestApplication application;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+
+ // load two frame(batch size), load mask image, and request two masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(5), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 2, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.SendNotification();
+ application.Render(20);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliAnimatedImageVisualMultiImage01(void)
{
ToolkitTestApplication application;
DALI_TEST_EQUALS(actorFrame, Vector4(5.0f, 5.0f, ITEM_SIZE.width + 5, ITEM_SIZE.height + 5), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor1Frame, Vector4(0.0f, 0.0f, ITEM_SIZE.width, ITEM_SIZE.height), TEST_LOCATION);
DALI_TEST_EQUALS(actor2Frame, Vector4(ITEM_SIZE.width, 0.0f, ITEM_SIZE.width * 2, ITEM_SIZE.height), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor1Frame, Vector4(0.0f, 0.0f, ITEM_SIZE.width, ITEM_SIZE.height), TEST_LOCATION);
DALI_TEST_EQUALS(actor2Frame, Vector4(0.0f, ITEM_SIZE.height, ITEM_SIZE.width, ITEM_SIZE.height * 2), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor2Frame, Vector4(root.z - ITEM_SIZE.width, root.w - (ITEM_SIZE.height * 2), root.z, root.w - ITEM_SIZE.height), TEST_LOCATION);
DALI_TEST_EQUALS(actor3Frame, Vector4(root.z - ITEM_SIZE.width, root.w - ITEM_SIZE.height, root.z, root.w), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(flexNode->GetFlexWidth(), 480.0f, TEST_LOCATION);
DALI_TEST_EQUALS(flexNode->GetFlexHeight(), 800.0f, TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor3Frame, Vector4(ITEM_SIZE.width * 2, 0.0f, ITEM_SIZE.width * 3, ITEM_SIZE.height), TEST_LOCATION);
DALI_TEST_EQUALS(actor4Frame, Vector4(0.0, ITEM_SIZE.height, ITEM_SIZE.width, ITEM_SIZE.height * 2), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor2Frame, Vector4(0.0f, 0.0f, ITEM_SIZE.width, ITEM_SIZE.height), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_NOT_EQUALS(actor1Frame, actor1FrameRemoved, 0.1, TEST_LOCATION);
DALI_TEST_NOT_EQUALS(actor2Frame, actor2FrameRemoved, 0.1, TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor1Frame, Vector4(5.0f, 5.0f, ITEM_SIZE.width + 5, ITEM_SIZE.height + 5), TEST_LOCATION);
DALI_TEST_EQUALS(actor2Frame, Vector4(5 + ITEM_SIZE.width, 5.0f, (ITEM_SIZE.width * 2) + 5, ITEM_SIZE.height + 5), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor1Frame, Vector4(0.0f, 0.0f, ITEM_SIZE_CALLBACK_TEST.width, ITEM_SIZE_CALLBACK_TEST.height), TEST_LOCATION);
DALI_TEST_EQUALS(actor2Frame, Vector4(0.0f, ITEM_SIZE_CALLBACK_TEST.height, ITEM_SIZE.width, ITEM_SIZE_CALLBACK_TEST.height + ITEM_SIZE.height), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor1Frame, Vector4(0.0f, 0.0f, ITEM_SIZE.width, ITEM_SIZE.height), TEST_LOCATION);
DALI_TEST_EQUALS(actor2Frame, Vector4(0.0f, 0.0f, ITEM_SIZE.width, ITEM_SIZE.height), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor1Frame, Vector4(0.0f, 0.0f, ITEM_SIZE.width * 2, ITEM_SIZE.height), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
DALI_TEST_EQUALS(actor2Frame, Vector4(basis, 0.0f, basis + (root.z - basis) / 2, ITEM_SIZE.height), TEST_LOCATION);
DALI_TEST_EQUALS(actor3Frame, Vector4(basis + (root.z - basis) / 2, 0.0f, root.z, ITEM_SIZE.height), TEST_LOCATION);
+ delete flexNode;
+
END_TEST;
}
mDefines(other.mDefines),
mHints(other.mHints),
mUniforms(other.mUniforms),
- mUseBuiltInShader(false)
+ mUseBuiltInShader(other.mUseBuiltInShader)
{
}
/*
- * 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.
Node::~Node()
{
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Destructor() >> \n");
+ // Destruct child Flex::Node first
+ mImpl->mChildNodes.clear();
+
if(mImpl->mYogaNode)
{
- YGNodeFreeRecursive(mImpl->mYogaNode);
+ YGNodeFree(mImpl->mYogaNode);
mImpl->mYogaNode = nullptr;
}
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Destructor() <<\n");
#define DALI_TOOLKIT_LAYOUTING_FLEX_NODE_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.
private:
struct Impl;
std::unique_ptr<Impl> mImpl;
-
}; // Node
} // namespace Flex
void WebView::WebViewAccessible::SetRemoteChildAddress(Dali::Accessibility::Address address)
{
- mRemoteChild.SetAddress(std::move(address));
+ mRemoteChild.SetAddress(address);
OnChildrenChanged();
+
+ if(address)
+ {
+ Accessibility::Bridge::GetCurrentBridge()->EmbedAtkSocket(GetAddress(), address);
+ }
}
#undef GET_ENUM_STRING
if(mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::LOCALE ||
(mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::INHERIT && !mIsLayoutDirectionChanged))
{
- return static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(actor).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+ Window window = DevelWindow::Get(actor);
+ return static_cast<Dali::LayoutDirection::Type>(window ? window.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>() : LayoutDirection::LEFT_TO_RIGHT);
}
else
{
}
}
-TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading animatedImageLoading,
- const uint32_t& frameIndex,
- TextureManager::TextureId& textureId,
- const Dali::SamplingMode::Type& samplingMode,
- const Dali::WrapMode::Type& wrapModeU,
- const Dali::WrapMode::Type& wrapModeV,
- const bool& synchronousLoading,
- const bool& useCache,
- TextureUploadObserver* textureObserver)
+TextureSet TextureManager::LoadAnimatedImageTexture(
+ Dali::AnimatedImageLoading animatedImageLoading,
+ const uint32_t& frameIndex,
+ TextureManager::TextureId& textureId,
+ MaskingDataPointer& maskInfo,
+ const Dali::SamplingMode::Type& samplingMode,
+ const Dali::WrapMode::Type& wrapModeU,
+ const Dali::WrapMode::Type& wrapModeV,
+ const bool& synchronousLoading,
+ const bool& useCache,
+ TextureUploadObserver* textureObserver)
{
TextureSet textureSet;
}
else
{
+ if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
+ {
+ Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true);
+ if(maskPixelBuffer)
+ {
+ pixelBuffer.ApplyMask(maskPixelBuffer, maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
+ }
+ else
+ {
+ DALI_LOG_ERROR("TextureManager::LoadAnimatedImageTexture: Synchronous mask image loading is failed\n");
+ }
+ }
PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
if(!textureSet)
{
}
else
{
- auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
- textureId = RequestLoadInternal(animatedImageLoading.GetUrl(), INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, UseAtlas::NO_ATLAS, false, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiply, animatedImageLoading, frameIndex, false, useCache);
+ TextureId alphaMaskId = INVALID_TEXTURE_ID;
+ float contentScaleFactor = 1.0f;
+ bool cropToMask = false;
+ if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
+ {
+ maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl);
+ alphaMaskId = maskInfo->mAlphaMaskId;
+ contentScaleFactor = maskInfo->mContentScaleFactor;
+ cropToMask = maskInfo->mCropToMask;
+ }
+
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ textureId = RequestLoadInternal(animatedImageLoading.GetUrl(), alphaMaskId, contentScaleFactor, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiply, animatedImageLoading, frameIndex, false, useCache);
+
TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
{
* @param[in] animatedImageLoading The AnimatedImageLoading that contain the animated image information
* @param[in] frameIndex The frame index to load.
* @param[out] textureId The textureId of the frame
+ * @param[in, out] maskInfo Mask info structure
* @param[in] samplingMode The SamplingMode to use
* @param[in] wrapModeU Horizontal Wrap mode
* @param[in] wrapModeV Vertical Wrap mode
TextureSet LoadAnimatedImageTexture(Dali::AnimatedImageLoading animatedImageLoading,
const uint32_t& frameIndex,
TextureManager::TextureId& textureId,
+ MaskingDataPointer& maskInfo,
const Dali::SamplingMode::Type& samplingMode,
const Dali::WrapMode::Type& wrapModeU,
const Dali::WrapMode::Type& wrapModeV,
if(mAnimatedImageLoading)
{
- mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired());
+ mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired());
}
else if(mImageUrls)
{
uint16_t cacheSize = std::max(std::min(std::max(batchSize, mCacheSize), numUrls), MINIMUM_CACHESIZE);
if(cacheSize < numUrls)
{
- mImageCache = new RollingImageCache(textureManager, *mImageUrls, *this, cacheSize, batchSize, mFrameDelay);
+ mImageCache = new RollingImageCache(textureManager, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay);
}
else
{
- mImageCache = new FixedImageCache(textureManager, *mImageUrls, *this, batchSize, mFrameDelay);
+ mImageCache = new FixedImageCache(textureManager, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay);
}
}
mCurrentLoopIndex(FIRST_LOOP),
mLoadPolicy(Toolkit::ImageVisual::LoadPolicy::ATTACHED),
mReleasePolicy(Toolkit::ImageVisual::ReleasePolicy::DETACHED),
+ mMaskingData(),
mFrameCount(0),
mImageSize(),
mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
{
if(mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0)
{
+ if(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid() &&
+ mMaskingData->mCropToMask)
+ {
+ ImageDimensions dimensions = Dali::GetClosestImageSize(mMaskingData->mAlphaMaskUrl.GetUrl());
+ if(dimensions != ImageDimensions(0, 0))
+ {
+ mImageSize = dimensions;
+ naturalSize.x = dimensions.GetWidth();
+ naturalSize.y = dimensions.GetHeight();
+ return;
+ }
+ }
+
if(mImageUrl.IsValid())
{
mImageSize = mAnimatedImageLoading.GetImageSize();
map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior);
+ if(mMaskingData != nullptr)
+ {
+ map.Insert(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl());
+ map.Insert(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor);
+ map.Insert(Toolkit::ImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask);
+ }
+
map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
map.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, mReleasePolicy);
}
{
DoSetProperty(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, 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 == LOAD_POLICY_NAME)
{
DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second);
break;
}
+ case Toolkit::ImageVisual::Property::ALPHA_MASK_URL:
+ {
+ std::string alphaUrl = "";
+ if(value.Get(alphaUrl))
+ {
+ AllocateMaskData();
+ mMaskingData->mAlphaMaskUrl = alphaUrl;
+ }
+ break;
+ }
+
+ case Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE:
+ {
+ float scale = 1.0f;
+ if(value.Get(scale))
+ {
+ AllocateMaskData();
+ mMaskingData->mContentScaleFactor = scale;
+ }
+ break;
+ }
+
+ case Toolkit::ImageVisual::Property::CROP_TO_MASK:
+ {
+ bool crop = false;
+ if(value.Get(crop))
+ {
+ AllocateMaskData();
+ mMaskingData->mCropToMask = crop;
+ }
+ break;
+ }
+
case Toolkit::ImageVisual::Property::RELEASE_POLICY:
{
int releasePolicy = 0;
return textureSet;
}
+void AnimatedImageVisual::AllocateMaskData()
+{
+ if(!mMaskingData)
+ {
+ mMaskingData.reset(new TextureManager::MaskingData());
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
*/
TextureSet SetLoadingFailed();
+ /**
+ * @brief Allocate mask data.
+ * This is allocated only once.
+ */
+ void AllocateMaskData();
+
// Undefined
AnimatedImageVisual(const AnimatedImageVisual& animatedImageVisual);
int16_t mLoopCount;
int16_t mCurrentLoopIndex;
- // Variables for image visual policy.
+ // Variables for image visual properties.
Dali::Toolkit::ImageVisual::LoadPolicy::Type mLoadPolicy;
Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy;
+ TextureManager::MaskingDataPointer mMaskingData;
// Shared variables
uint32_t mFrameCount; // Number of frames
constexpr uint32_t FIRST_FRAME_INDEX = 0u;
} // namespace
-FixedImageCache::FixedImageCache(
- TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer, uint32_t batchSize, uint32_t interval)
-: ImageCache(textureManager, observer, batchSize, interval),
+FixedImageCache::FixedImageCache(TextureManager& textureManager,
+ UrlList& urlList,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint32_t batchSize,
+ uint32_t interval)
+: ImageCache(textureManager, maskingData, observer, batchSize, interval),
mImageUrls(urlList),
mFront(FIRST_FRAME_INDEX)
{
bool synchronousLoading = false;
bool atlasingStatus = false;
bool loadingStatus = false;
- TextureManager::MaskingDataPointer maskInfo = nullptr;
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mTextureManager.LoadTexture(
- url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, maskInfo, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
+ url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
mRequestingLoad = false;
}
{
mTextureManager.Remove(mImageUrls[i].mTextureId, this);
mImageUrls[i].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+
+ if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+ {
+ // In the CPU alpha masking, each frame increases reference count of masking texture.
+ // We should call TextureManager::Remove to decrease reference count when each frame is removed.
+ mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
+ }
}
}
mReadyFlags.clear();
mLoadState = TextureManager::LoadState::NOT_STARTED;
+ if(mMaskingData)
+ {
+ mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ }
}
void FixedImageCache::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
/**
* Constructor.
* @param[in] textureManager The texture manager
- * @param[in] urlList List of urls to cache
- * @param[in] observer FrameReady observer
- * @param[in] batchSize The size of a batch to load
- * @param[in] interval Time interval between each frame
+ * @param[in] urlList List of urls to cache
+ * @param[in] maskingData Masking data to be applied.
+ * @param[in] observer FrameReady observer
+ * @param[in] batchSize The size of a batch to load
+ * @param[in] interval Time interval between each frame
*
* This will start loading textures immediately, according to the
* batch and cache sizes. The cache is as large as the number of urls.
*/
- FixedImageCache(TextureManager& textureManager,
- UrlList& urlList,
- ImageCache::FrameReadyObserver& observer,
- uint32_t batchSize,
- uint32_t interval);
+ FixedImageCache(TextureManager& textureManager,
+ UrlList& urlList,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint32_t batchSize,
+ uint32_t interval);
~FixedImageCache() override;
{
namespace Internal
{
-ImageCache::ImageCache(TextureManager& textureManager,
- ImageCache::FrameReadyObserver& observer,
- uint32_t batchSize,
- uint32_t interval)
+ImageCache::ImageCache(TextureManager& textureManager,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint32_t batchSize,
+ uint32_t interval)
: mTextureManager(textureManager),
mObserver(observer),
+ mMaskingData(maskingData),
mBatchSize(batchSize),
mInterval(interval),
mLoadState(TextureManager::LoadState::NOT_STARTED),
* @param[in] textureManager The texture manager
* @param[in] urlList List of urls to cache
* @param[in] observer FrameReady observer
+ * @param[in] maskingData Masking data to be applied.
* @param[in] batchSize The size of a batch to load
- * @param[in] interval Time interval(ms) between each frame
+ * @param[in] interval Time interval(ms) between each frame
*
* This will start loading textures immediately, according to the
* batch and cache sizes. The cache is as large as the number of urls.
*/
- ImageCache(TextureManager& textureManager,
- ImageCache::FrameReadyObserver& observer,
- uint32_t batchSize,
- uint32_t interval);
+ ImageCache(TextureManager& textureManager,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint32_t batchSize,
+ uint32_t interval);
virtual ~ImageCache();
*/
void TextureManagerDestroyed() final;
+ void AllocateMaskData();
+
protected:
- TextureManager& mTextureManager;
- FrameReadyObserver& mObserver;
- uint32_t mBatchSize;
- uint32_t mInterval;
- TextureManager::LoadState mLoadState;
- bool mRequestingLoad : 1;
- bool mTextureManagerAlive : 1;
+ TextureManager& mTextureManager;
+ FrameReadyObserver& mObserver;
+ TextureManager::MaskingDataPointer& mMaskingData;
+ uint32_t mBatchSize;
+ uint32_t mInterval;
+ TextureManager::LoadState mLoadState;
+ bool mRequestingLoad : 1;
+ bool mTextureManagerAlive : 1;
};
-} //namespace Internal
-} //namespace Toolkit
-} //namespace Dali
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
#endif // DALI_TOOLKIT_INTERNAL_IMAGE_CACHE_H
static constexpr uint32_t FIRST_FRAME_INDEX = 0u;
} // namespace
-RollingAnimatedImageCache::RollingAnimatedImageCache(
- TextureManager& textureManager, AnimatedImageLoading& animatedImageLoading, ImageCache::FrameReadyObserver& observer, uint16_t cacheSize, uint16_t batchSize, bool isSynchronousLoading)
-: ImageCache(textureManager, observer, batchSize, 0u),
+RollingAnimatedImageCache::RollingAnimatedImageCache(TextureManager& textureManager,
+ AnimatedImageLoading& animatedImageLoading,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint16_t cacheSize,
+ uint16_t batchSize,
+ bool isSynchronousLoading)
+: ImageCache(textureManager, maskingData, observer, batchSize, 0u),
mAnimatedImageLoading(animatedImageLoading),
mFrameCount(SINGLE_IMAGE_COUNT),
mFrameIndex(FIRST_FRAME_INDEX),
bool popExist = false;
while(!mQueue.IsEmpty() && mQueue.Front().mFrameNumber != frameIndex)
{
- ImageFrame imageFrame = mQueue.PopFront();
- mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this);
- mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID;
- popExist = true;
+ PopFrontCache();
+ popExist = true;
}
TextureSet textureSet;
TextureSet textureSet = mTextureManager.LoadAnimatedImageTexture(mAnimatedImageLoading,
frameIndex,
loadTextureId,
+ mMaskingData,
SamplingMode::BOX_THEN_LINEAR,
Dali::WrapMode::Type::DEFAULT,
Dali::WrapMode::Type::DEFAULT,
return mImageUrls[mQueue[index].mFrameNumber].mTextureId;
}
+void RollingAnimatedImageCache::PopFrontCache()
+{
+ ImageFrame imageFrame = mQueue.PopFront();
+ mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this);
+ mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+
+ if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+ {
+ mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
+ if(mQueue.IsEmpty())
+ {
+ mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ }
+ }
+}
+
void RollingAnimatedImageCache::ClearCache()
{
while(mTextureManagerAlive && !mQueue.IsEmpty())
{
- ImageFrame imageFrame = mQueue.PopFront();
- mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this);
- mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+ PopFrontCache();
}
mLoadWaitingQueue.clear();
mLoadState = TextureManager::LoadState::NOT_STARTED;
public:
/**
* @brief Constructor.
- * @param[in] textureManager The texture manager
- * @param[in] animatedImageLoader The loaded animated image
- * @param[in] observer FrameReady observer
- * @param[in] cacheSize The size of the cache
- * @param[in] batchSize The size of a batch to load
+ * @param[in] textureManager The texture manager
+ * @param[in] animatedImageLoading The loaded animated image
+ * @param[in] maskingData Masking data to be applied.
+ * @param[in] observer FrameReady observer
+ * @param[in] cacheSize The size of the cache
+ * @param[in] batchSize The size of a batch to load
* @param[in] isSynchronousLoading The flag to define whether to load first frame synchronously
*
* This will start loading textures immediately, according to the
* batch and cache sizes.
*/
- RollingAnimatedImageCache(TextureManager& textureManager,
- AnimatedImageLoading& animatedImageLoader,
- ImageCache::FrameReadyObserver& observer,
- uint16_t cacheSize,
- uint16_t batchSize,
- bool isSynchronousLoading);
+ RollingAnimatedImageCache(TextureManager& textureManager,
+ AnimatedImageLoading& animatedImageLoading,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint16_t cacheSize,
+ uint16_t batchSize,
+ bool isSynchronousLoading);
/**
* @brief Destructor
*/
void MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval);
+ /**
+ * @brief Pop front entity of Cache.
+ */
+ void PopFrontCache();
+
protected:
/**
* @copydoc Toolkit::TextureUploadObserver::LoadComplete()
{
namespace Internal
{
-RollingImageCache::RollingImageCache(
- TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer, uint16_t cacheSize, uint16_t batchSize, uint32_t interval)
-: ImageCache(textureManager, observer, batchSize, interval),
+RollingImageCache::RollingImageCache(TextureManager& textureManager,
+ UrlList& urlList,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint16_t cacheSize,
+ uint16_t batchSize,
+ uint32_t interval)
+: ImageCache(textureManager, maskingData, observer, batchSize, interval),
mImageUrls(urlList),
mQueue(cacheSize)
{
bool popExist = false;
while(!mQueue.IsEmpty() && mQueue.Front().mUrlIndex != frameIndex)
{
- ImageFrame imageFrame = mQueue.PopFront();
- mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
- mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+ PopFrontCache();
popExist = true;
}
bool synchronousLoading = false;
bool atlasingStatus = false;
bool loadingStatus = false;
- TextureManager::MaskingDataPointer maskInfo = nullptr;
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID;
TextureSet textureSet = mTextureManager.LoadTexture(
- url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, maskInfo, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
+ url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
mImageUrls[imageFrame.mUrlIndex].mTextureId = loadTextureId;
mRequestingLoad = false;
return mImageUrls[mQueue[index].mUrlIndex].mTextureId;
}
+void RollingImageCache::PopFrontCache()
+{
+ ImageFrame imageFrame = mQueue.PopFront();
+ mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
+ mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+
+ if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+ {
+ mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
+ if(mQueue.IsEmpty())
+ {
+ mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ }
+ }
+}
+
void RollingImageCache::ClearCache()
{
while(mTextureManagerAlive && !mQueue.IsEmpty())
{
- ImageFrame imageFrame = mQueue.PopFront();
- mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
- mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+ PopFrontCache();
}
mLoadState = TextureManager::LoadState::NOT_STARTED;
}
/**
* Constructor.
* @param[in] textureManager The texture manager
- * @param[in] urlList List of urls to cache
- * @param[in] observer FrameReady observer
- * @param[in] cacheSize The size of the cache
- * @param[in] batchSize The size of a batch to load
- * @param[in] interval Time interval between each frame
+ * @param[in] urlList List of urls to cache
+ * @param[in] maskingData Masking data to be applied.
+ * @param[in] observer FrameReady observer
+ * @param[in] cacheSize The size of the cache
+ * @param[in] batchSize The size of a batch to load
+ * @param[in] interval Time interval between each frame
*
* This will start loading textures immediately, according to the
* batch and cache sizes.
*/
- RollingImageCache(TextureManager& textureManager,
- UrlList& urlList,
- ImageCache::FrameReadyObserver& observer,
- uint16_t cacheSize,
- uint16_t batchSize,
- uint32_t interval);
+ RollingImageCache(TextureManager& textureManager,
+ UrlList& urlList,
+ TextureManager::MaskingDataPointer& maskingData,
+ ImageCache::FrameReadyObserver& observer,
+ uint16_t cacheSize,
+ uint16_t batchSize,
+ uint32_t interval);
/**
* Destructor
TextureManager::TextureId GetCachedTextureId(int index) const;
/**
- * @brief Check if the front frame has become ready - if so, inform observer
- *
- * @param[in] wasReady Readiness before call.
+ * @brief Pop front entity of Cache.
*/
- void CheckFrontFrame(bool wasReady);
+ void PopFrontCache();
protected:
/**
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 21;
+const unsigned int TOOLKIT_MICRO_VERSION = 22;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.1.21
+Version: 2.1.22
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT