From: seungho Date: Tue, 28 Dec 2021 08:28:07 +0000 (+0900) Subject: Add DesiredWidth/Height and samplingMode in animated image visual X-Git-Tag: dali_2.2.4~3^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F95%2F284695%2F6;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Add DesiredWidth/Height and samplingMode in animated image visual Let AnimatedImageVisual also use DesiredSize / FittingMode / SamplingMode feature. Change-Id: Icd2205738a6d9c7af0f2aa06c7887ac9ea85b576 --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp index 4134db6..77b2d14 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp @@ -39,8 +39,9 @@ using namespace Toolkit; namespace { const char* TEST_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json"; +const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif"; -} +} // namespace int UtcDaliVisualAction(void) { @@ -185,6 +186,43 @@ int UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap(void) END_TEST; } +int UtcDaliAnimatedImageVisualCreateInstancePropertyMap(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliAnimatedImageVisualCreateInstancePropertyMap"); + + Property::Map propertyMap; + propertyMap.Add(Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE) + .Add(ImageVisual::Property::URL, TEST_GIF_FILE_NAME) + .Add(ImageVisual::Property::DESIRED_WIDTH, 10) + .Add(ImageVisual::Property::DESIRED_HEIGHT, 12); + + // request AnimatedVectorImageVisual with a property map + VisualFactory factory = VisualFactory::Get(); + Visual::Base visual = factory.CreateVisual(propertyMap); + Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(visual); + + Property::Map resultMap; + visualImpl.CreateInstancePropertyMap(resultMap); + + // check the property values from the returned map from a visual + DALI_TEST_EQUALS(resultMap.Count(), 3u, TEST_LOCATION); + + Property::Value* value = resultMap.Find(Toolkit::Visual::Property::TYPE, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == Visual::ANIMATED_IMAGE); + + value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == 10); + + value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == 12); + + END_TEST; +} + int UtcDaliAnimatedVectorImageVisualSetProperties(void) { ToolkitTestApplication application; diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp index 9870308..3c23a06 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp @@ -80,6 +80,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void) .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::FITTING_MODE, FittingMode::FIT_WIDTH) + .Add(ImageVisual::Property::SAMPLING_MODE, SamplingMode::NEAREST) + .Add(ImageVisual::Property::DESIRED_WIDTH, 154) + .Add(ImageVisual::Property::DESIRED_HEIGHT, 79) .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) @@ -101,6 +105,30 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void) DALI_TEST_CHECK(value); DALI_TEST_CHECK(value->Get() == TEST_GIF_FILE_NAME); + value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_U, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == WrapMode::REPEAT); + + value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_V, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == WrapMode::DEFAULT); + + value = resultMap.Find(Toolkit::ImageVisual::Property::FITTING_MODE, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == FittingMode::FIT_WIDTH); + + value = resultMap.Find(Toolkit::ImageVisual::Property::SAMPLING_MODE, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == SamplingMode::NEAREST); + + value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == 154); + + value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == 79); + value = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4); DALI_TEST_CHECK(value); DALI_TEST_EQUALS(value->Get(), Vector4(22.2f, 22.2f, 22.2f, 22.2f), TEST_LOCATION); @@ -138,9 +166,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void) DALI_TEST_CHECK(value); DALI_TEST_CHECK(value->Get() == DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + // Natural size getted as desired size Vector2 naturalSize; animatedImageVisual.GetNaturalSize(naturalSize); - DALI_TEST_EQUALS(naturalSize, Vector2(100, 100), TEST_LOCATION); + DALI_TEST_EQUALS(naturalSize, Vector2(154, 79), TEST_LOCATION); // request AnimatedImageVisual with an URL Visual::Base animatedImageVisual2 = factory.CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions()); @@ -155,6 +184,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void) DALI_TEST_CHECK(value); DALI_TEST_CHECK(value->Get() == TEST_GIF_FILE_NAME); + // Natural size getted as image size + animatedImageVisual2.GetNaturalSize(naturalSize); + DALI_TEST_EQUALS(naturalSize, Vector2(50, 50), TEST_LOCATION); + END_TEST; } @@ -179,6 +212,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap02(void) .Add("pixelArea", Vector4()) .Add("wrapModeU", WrapMode::REPEAT) .Add("wrapModeV", WrapMode::DEFAULT) + .Add("fittingMode", FittingMode::FIT_WIDTH) + .Add("samplingMode", SamplingMode::NEAREST) + .Add("desiredWidth", 154) + .Add("desiredHeight", 79) .Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME) .Add("maskContentScale", 1.6f) .Add("cropToMask", true) @@ -222,6 +259,30 @@ int UtcDaliAnimatedImageVisualGetPropertyMap02(void) DALI_TEST_CHECK(value); DALI_TEST_EQUALS(value->Get(), 11, TEST_LOCATION); + value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_U, "wrapModeU"); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == WrapMode::REPEAT); + + value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_V, "wrapModeV"); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == WrapMode::DEFAULT); + + value = resultMap.Find(Toolkit::ImageVisual::Property::FITTING_MODE, "fittingMode"); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == FittingMode::FIT_WIDTH); + + value = resultMap.Find(Toolkit::ImageVisual::Property::SAMPLING_MODE, "samplingMode"); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == SamplingMode::NEAREST); + + value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_WIDTH, "desiredWidth"); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == 154); + + value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, "desiredHeight"); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == 79); + value = resultMap.Find(Toolkit::DevelVisual::Property::CORNER_RADIUS, "cornerRadius"); DALI_TEST_CHECK(value); DALI_TEST_EQUALS(value->Get(), Vector4(50.0f, 25.0f, 12.5f, 33.0f), TEST_LOCATION); @@ -359,6 +420,11 @@ int UtcDaliAnimatedImageVisualGetPropertyMap03(void) DALI_TEST_CHECK(value); DALI_TEST_CHECK(value->Get() == DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + // Natural size getted as masked image size + Vector2 naturalSize; + animatedImageVisual.GetNaturalSize(naturalSize); + DALI_TEST_EQUALS(naturalSize, Vector2(100, 100), TEST_LOCATION); + END_TEST; } @@ -1792,7 +1858,7 @@ int UtcDaliAnimatedImageVisualWrapMode(void) // Test wrap mode in animated image visual. const int width = 950; const int height = 1080; - const Vector4 pixelArea(0.0f, 0.0f, 950/ 40, 1.0f); + const Vector4 pixelArea(0.0f, 0.0f, 950 / 40, 1.0f); Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); @@ -1848,3 +1914,72 @@ int UtcDaliAnimatedImageVisualWrapMode(void) END_TEST; } + +int UtcDaliAnimatedImageVisualDesiredSize(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliAnimatedImageVisualDesiredSize"); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + + // Set desiredWidth < 37 and desiredHeight < 50, which is smaller than original image's size. + int desiredWidth = 15; + int desiredHeight = 20; + + Visual::Base visual = VisualFactory::Get().CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions(desiredWidth, desiredHeight)); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(true); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + application.GetScene().Add(actor); + + application.SendNotification(); + application.Render(); + + // Trigger count is 2 - first frame and second frame. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + textureTrace.Enable(true); + textureTrace.EnableLogging(true); + + application.SendNotification(); + application.Render(); + + { + std::stringstream out; + out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight; + DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str())); + } + + // Unparent to make next trigger + actor.Unparent(); + + application.SendNotification(); + application.Render(); + + // Set visual size + actor.SetProperty(Actor::Property::SIZE, Vector2(300.0f, 300.0f)); + application.GetScene().Add(actor); + + application.SendNotification(); + application.Render(); + + // Trigger count is 2 - first frame and second frame. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + textureTrace.Reset(); + + application.SendNotification(); + application.Render(); + + { + std::stringstream out; + out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight; + DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str())); // The size should not be changed + } + + END_TEST; +} \ No newline at end of file diff --git a/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp b/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp index 7ce566e..0a0338f 100644 --- a/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp +++ b/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp @@ -19,8 +19,8 @@ #include "async-image-loader-impl.h" // EXTERNAL INCLUDES -#include #include +#include namespace Dali { @@ -49,7 +49,19 @@ uint32_t AsyncImageLoader::LoadAnimatedImage(Dali::AnimatedImageLoading uint32_t frameIndex, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) { - LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, preMultiplyOnLoad,MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage)); + LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage)); + Dali::AsyncTaskManager::Get().AddTask(loadingTask); + return mLoadTaskId; +} + +uint32_t AsyncImageLoader::LoadAnimatedImage(Dali::AnimatedImageLoading animatedImageLoading, + uint32_t frameIndex, + Dali::ImageDimensions desiredSize, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) +{ + LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, desiredSize, fittingMode, samplingMode, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage)); Dali::AsyncTaskManager::Get().AddTask(loadingTask); return mLoadTaskId; } @@ -64,7 +76,7 @@ uint32_t AsyncImageLoader::Load(const VisualUrl& url, { LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad, loadPlanes, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage)); AsyncTaskManager::Get().AddTask(loadingTask); - mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask,mLoadTaskId)); + mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask, mLoadTaskId)); return mLoadTaskId; } @@ -77,7 +89,7 @@ uint32_t AsyncImageLoader::LoadEncodedImageBuffer(const EncodedImageBuffer& { LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, encodedImageBuffer, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage)); Dali::AsyncTaskManager::Get().AddTask(loadingTask); - mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask,mLoadTaskId)); + mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask, mLoadTaskId)); return mLoadTaskId; } @@ -89,7 +101,7 @@ uint32_t AsyncImageLoader::ApplyMask(Devel::PixelBuffer pi { LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, pixelBuffer, maskPixelBuffer, contentScale, cropToMask, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage)); Dali::AsyncTaskManager::Get().AddTask(loadingTask); - mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask,mLoadTaskId)); + mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask, mLoadTaskId)); return mLoadTaskId; } @@ -160,8 +172,8 @@ void AsyncImageLoader::ProcessLoadedImage(LoadingTaskPtr task) void AsyncImageLoader::RemoveCompletedTask() { std::uint32_t loadingTaskId; - auto end = mLoadingTasks.end(); - auto endCompletedIter = mCompletedTaskIds.end(); + auto end = mLoadingTasks.end(); + auto endCompletedIter = mCompletedTaskIds.end(); for(std::vector::iterator iter = mLoadingTasks.begin(); iter != end; ++iter) { loadingTaskId = (*iter).loadId; diff --git a/dali-toolkit/internal/image-loader/async-image-loader-impl.h b/dali-toolkit/internal/image-loader/async-image-loader-impl.h index a75fa32..c23b102 100644 --- a/dali-toolkit/internal/image-loader/async-image-loader-impl.h +++ b/dali-toolkit/internal/image-loader/async-image-loader-impl.h @@ -36,7 +36,7 @@ using LoadingTaskPtr = IntrusivePtr; struct AsyncImageLoadingInfo { - AsyncImageLoadingInfo(LoadingTaskPtr loadingTask,std::uint32_t loadId) + AsyncImageLoadingInfo(LoadingTaskPtr loadingTask, std::uint32_t loadId) : loadingTask(loadingTask), loadId(loadId) { @@ -67,6 +67,24 @@ public: DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad); /** + * @brief Starts an animated image loading task. + * @param[in] asyncImageLoader The ayncImageLoader + * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image + * @param[in] frameIndex The frame index of a frame to be loaded frame + * @param[in] dimensions The width and height to fit the loaded image to + * @param[in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter + * @param[in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size + * @param[in] preMultiplyOnLoad ON if the image color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask. + * @return The loading task id + */ + uint32_t LoadAnimatedImage(Dali::AnimatedImageLoading animatedImageLoading, + uint32_t frameIndex, + Dali::ImageDimensions desiredSize, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad); + + /** * @brief Starts an image loading task. * @param[in] url The URL of the image file to load * @param[in] dimensions The width and height to fit the loaded image to diff --git a/dali-toolkit/internal/image-loader/loading-task.cpp b/dali-toolkit/internal/image-loader/loading-task.cpp index 29f3bdb..11f83a8 100644 --- a/dali-toolkit/internal/image-loader/loading-task.cpp +++ b/dali-toolkit/internal/image-loader/loading-task.cpp @@ -38,8 +38,30 @@ LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLo id(id), textureId(TextureManagerType::INVALID_TEXTURE_ID), dimensions(), - fittingMode(), - samplingMode(), + fittingMode(FittingMode::SCALE_TO_FILL), + samplingMode(SamplingMode::BOX_THEN_LINEAR), + preMultiplyOnLoad(preMultiplyOnLoad), + maskPixelBuffer(), + contentScale(1.0f), + animatedImageLoading(animatedImageLoading), + frameIndex(frameIndex), + orientationCorrection(), + isMaskTask(false), + cropToMask(false), + loadPlanes(false), + isReady(true) +{ +} + +LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback) +: AsyncTask(callback), + url(), + encodedImageBuffer(), + id(id), + textureId(TextureManagerType::INVALID_TEXTURE_ID), + dimensions(dimensions), + fittingMode(fittingMode), + samplingMode(samplingMode), preMultiplyOnLoad(preMultiplyOnLoad), maskPixelBuffer(), contentScale(1.0f), @@ -149,7 +171,7 @@ void LoadingTask::Load() Devel::PixelBuffer pixelBuffer; if(animatedImageLoading) { - pixelBuffer = animatedImageLoading.LoadFrame(frameIndex); + pixelBuffer = animatedImageLoading.LoadFrame(frameIndex, dimensions, fittingMode, samplingMode); } else if(encodedImageBuffer) { diff --git a/dali-toolkit/internal/image-loader/loading-task.h b/dali-toolkit/internal/image-loader/loading-task.h index 09208b4..6072856 100644 --- a/dali-toolkit/internal/image-loader/loading-task.h +++ b/dali-toolkit/internal/image-loader/loading-task.h @@ -19,19 +19,19 @@ // EXTERNAL INCLUDES #include +#include #include -#include #include #include #include #include #include #include +#include #include #include #include #include -#include namespace Dali { @@ -39,7 +39,6 @@ namespace Toolkit { namespace Internal { - class LoadingTask; using LoadingTaskPtr = IntrusivePtr; @@ -66,6 +65,26 @@ public: /** * Constructor. * @param [in] id of the task + * @param [in] animatedImageLoading The AnimatedImageLoading to load animated image + * @param [in] frameIndex The frame index of a frame to be loaded frame + * @param [in] dimensions The width and height to fit the loaded image to + * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter + * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size + * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask. + * @param [in] callback The callback that is called when the operation is completed. + */ + LoadingTask(uint32_t id, + Dali::AnimatedImageLoading animatedImageLoading, + uint32_t frameIndex, + Dali::ImageDimensions dimensions, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, + CallbackBase* callback); + + /** + * Constructor. + * @param [in] id of the task * @param [in] url The URL of the image file to load. * @param [in] size The width and height to fit the loaded image to, 0.0 means whole image * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter. @@ -188,7 +207,7 @@ public: bool isMaskTask : 1; ///< whether this task is for mask or not bool cropToMask : 1; ///< Whether to crop the content to the mask size bool loadPlanes : 1; ///< Whether to load image planes - bool isReady : 1; ///< Whether this task ready to run + bool isReady : 1; ///< Whether this task ready to run }; } // namespace Internal diff --git a/dali-toolkit/internal/texture-manager/texture-async-loading-helper.cpp b/dali-toolkit/internal/texture-manager/texture-async-loading-helper.cpp index 87d3fa6..9927ea2 100644 --- a/dali-toolkit/internal/texture-manager/texture-async-loading-helper.cpp +++ b/dali-toolkit/internal/texture-manager/texture-async-loading-helper.cpp @@ -44,9 +44,12 @@ TextureAsyncLoadingHelper::TextureAsyncLoadingHelper(TextureManager& textureMana void TextureAsyncLoadingHelper::LoadAnimatedImage(const TextureManager::TextureId& textureId, Dali::AnimatedImageLoading animatedImageLoading, const std::uint32_t& frameIndex, + const Dali::ImageDimensions& desiredSize, + const Dali::FittingMode::Type& fittingMode, + const Dali::SamplingMode::Type& samplingMode, const DevelAsyncImageLoader::PreMultiplyOnLoad& preMultiplyOnLoad) { - LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, preMultiplyOnLoad, MakeCallback(this, &TextureAsyncLoadingHelper::AsyncLoadComplete)); + LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, desiredSize, fittingMode, samplingMode, preMultiplyOnLoad, MakeCallback(this, &TextureAsyncLoadingHelper::AsyncLoadComplete)); loadingTask->SetTextureId(textureId); Dali::AsyncTaskManager::Get().AddTask(loadingTask); } @@ -81,7 +84,6 @@ void TextureAsyncLoadingHelper::ApplyMask(const TextureManager::TextureId& const bool& cropToMask, const DevelAsyncImageLoader::PreMultiplyOnLoad& preMultiplyOnLoad) { - LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, pixelBuffer, maskPixelBuffer, contentScale, cropToMask, preMultiplyOnLoad, MakeCallback(this, &TextureAsyncLoadingHelper::AsyncLoadComplete)); loadingTask->SetTextureId(textureId); Dali::AsyncTaskManager::Get().AddTask(loadingTask); diff --git a/dali-toolkit/internal/texture-manager/texture-async-loading-helper.h b/dali-toolkit/internal/texture-manager/texture-async-loading-helper.h index d993737..15e1d4e 100644 --- a/dali-toolkit/internal/texture-manager/texture-async-loading-helper.h +++ b/dali-toolkit/internal/texture-manager/texture-async-loading-helper.h @@ -31,7 +31,6 @@ namespace Toolkit { namespace Internal { - /** * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container */ @@ -49,11 +48,18 @@ public: * @param[in] textureId TextureId to reference the texture that will be loaded * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image * @param[in] frameIndex The frame index of a frame to be loaded frame + * @param[in] desiredSize The size the image is likely to appear at. + * This can be set to 0,0 for automatic + * @param[in] fittingMode The FittingMode to use + * @param[in] samplingMode The SamplingMode to use * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask. */ void LoadAnimatedImage(const TextureManager::TextureId& textureId, Dali::AnimatedImageLoading animatedImageLoading, const std::uint32_t& frameIndex, + const Dali::ImageDimensions& desiredSize, + const Dali::FittingMode::Type& fittingMode, + const Dali::SamplingMode::Type& samplingMode, const DevelAsyncImageLoader::PreMultiplyOnLoad& preMultiplyOnLoad); /** diff --git a/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp b/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp index 8930d2d..0984e2f 100644 --- a/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp +++ b/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp @@ -33,7 +33,7 @@ namespace { -constexpr auto INITIAL_HASH_NUMBER = size_t{0u}; +constexpr auto INITIAL_HASH_NUMBER = size_t{0u}; constexpr auto TEXTURE_INDEX = 0u; ///< The Index for texture constexpr auto MASK_TEXTURE_INDEX = 1u; ///< The Index for mask texture @@ -135,6 +135,8 @@ TextureSet TextureManager::LoadAnimatedImageTexture( const uint32_t& frameIndex, TextureManager::TextureId& textureId, MaskingDataPointer& maskInfo, + const Dali::ImageDimensions& desiredSize, + const Dali::FittingMode::Type& fittingMode, const Dali::SamplingMode::Type& samplingMode, const bool& synchronousLoading, TextureUploadObserver* textureObserver, @@ -147,7 +149,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture( Devel::PixelBuffer pixelBuffer; if(animatedImageLoading) { - pixelBuffer = animatedImageLoading.LoadFrame(frameIndex); + pixelBuffer = animatedImageLoading.LoadFrame(frameIndex, desiredSize, fittingMode, samplingMode); } if(!pixelBuffer) { @@ -158,7 +160,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture( Texture maskTexture; if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid()) { - Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true); + Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), desiredSize, fittingMode, samplingMode, true); if(maskPixelBuffer) { if(!maskInfo->mPreappliedMasking) @@ -213,7 +215,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture( } } - textureId = RequestLoadInternal(url, alphaMaskId, contentScaleFactor, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false); + textureId = RequestLoadInternal(url, alphaMaskId, contentScaleFactor, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false); TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId); if(loadState == TextureManager::LoadState::UPLOADED) @@ -875,10 +877,10 @@ void TextureManager::LoadTexture(TextureManager::TextureInfo& textureInfo, Textu textureInfo.loadState = LoadState::LOADING; if(!textureInfo.loadSynchronously) { - auto premultiplyOnLoad = (textureInfo.preMultiplyOnLoad && textureInfo.maskTextureId == INVALID_TEXTURE_ID) ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF; + auto premultiplyOnLoad = (textureInfo.preMultiplyOnLoad && textureInfo.maskTextureId == INVALID_TEXTURE_ID) ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF; if(textureInfo.animatedImageLoading) { - mAsyncLoader->LoadAnimatedImage(textureInfo.textureId, textureInfo.animatedImageLoading, textureInfo.frameIndex, premultiplyOnLoad); + mAsyncLoader->LoadAnimatedImage(textureInfo.textureId, textureInfo.animatedImageLoading, textureInfo.frameIndex, textureInfo.desiredSize, textureInfo.fittingMode, textureInfo.samplingMode, premultiplyOnLoad); } else { @@ -1194,7 +1196,7 @@ void TextureManager::ApplyMask(TextureManager::TextureInfo& textureInfo, const T DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::ApplyMask(): url:%s sync:%s\n", textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously ? "T" : "F"); - textureInfo.loadState = LoadState::MASK_APPLYING; + textureInfo.loadState = LoadState::MASK_APPLYING; auto premultiplyOnLoad = textureInfo.preMultiplyOnLoad ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF; mAsyncLoader->ApplyMask(textureInfo.textureId, pixelBuffer, maskPixelBuffer, textureInfo.scaleFactor, textureInfo.cropToMask, premultiplyOnLoad); } diff --git a/dali-toolkit/internal/texture-manager/texture-manager-impl.h b/dali-toolkit/internal/texture-manager/texture-manager-impl.h index 791553c..54db840 100644 --- a/dali-toolkit/internal/texture-manager/texture-manager-impl.h +++ b/dali-toolkit/internal/texture-manager/texture-manager-impl.h @@ -21,9 +21,9 @@ #include #include #include +#include #include #include -#include // INTERNAL INCLUDES #include @@ -119,6 +119,8 @@ public: * @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] desiredSize The size the image is likely to appear at. This can be set to 0, 0 for automatic + * @param[in] fittingMode The FittingMode to use * @param[in] samplingMode The SamplingMode to use * @param[in] synchronousLoading true if the frame should be loaded synchronously * @param[in] textureObserver The client object should inherit from this and provide the "LoadCompleted" virtual. @@ -133,6 +135,8 @@ public: const uint32_t& frameIndex, TextureManager::TextureId& textureId, MaskingDataPointer& maskInfo, + const Dali::ImageDimensions& desiredSize, + const Dali::FittingMode::Type& fittingMode, const Dali::SamplingMode::Type& samplingMode, const bool& synchronousLoading, TextureUploadObserver* textureObserver, @@ -612,7 +616,6 @@ private: */ void EmitLoadComplete(TextureUploadObserver* observer, TextureManager::TextureInfo& textureInfo, const bool& success); - /** * @brief Remove observer in textureInfo * @@ -648,14 +651,14 @@ private: */ void ObserverDestroyed(TextureUploadObserver* observer); -private: // Member Variables: - TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures - std::unique_ptr mAsyncLoader; ///< The Asynchronous image loader used to provide all local async loads - Dali::Vector mLifecycleObservers; ///< Lifecycle observers of texture manager - Dali::Vector mLoadQueue; ///< Queue of textures to load after NotifyObservers - Dali::Vector mRemoveQueue; ///< Queue of textures to remove after NotifyObservers - TextureManager::TextureId mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued. - bool mLoadYuvPlanes; ///< A global flag to specify if the image should be loaded as yuv planes +private: // Member Variables: + TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures + std::unique_ptr mAsyncLoader; ///< The Asynchronous image loader used to provide all local async loads + Dali::Vector mLifecycleObservers; ///< Lifecycle observers of texture manager + Dali::Vector mLoadQueue; ///< Queue of textures to load after NotifyObservers + Dali::Vector mRemoveQueue; ///< Queue of textures to remove after NotifyObservers + TextureManager::TextureId mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued. + bool mLoadYuvPlanes; ///< A global flag to specify if the image should be loaded as yuv planes }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp index db00ff5..3e8387f 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -49,6 +49,26 @@ namespace { const int CUSTOM_PROPERTY_COUNT(5); // ltr, wrap, pixel area, crop to mask, mask texture ratio +// fitting modes +DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SHRINK_TO_FIT) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SCALE_TO_FILL) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, FIT_WIDTH) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, FIT_HEIGHT) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, DEFAULT) +DALI_ENUM_TO_STRING_TABLE_END(FITTING_MODE) + +// sampling modes +DALI_ENUM_TO_STRING_TABLE_BEGIN(SAMPLING_MODE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, BOX) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, NEAREST) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, LINEAR) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, BOX_THEN_NEAREST) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, BOX_THEN_LINEAR) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, NO_FILTER) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, DONT_CARE) +DALI_ENUM_TO_STRING_TABLE_END(SAMPLING_MODE) + // stop behavior DALI_ENUM_TO_STRING_TABLE_BEGIN(STOP_BEHAVIOR) DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME) @@ -124,7 +144,7 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, " AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties) { - AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory)); + AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory, ImageDimensions())); visual->InitializeAnimatedImage(imageUrl); visual->SetProperties(properties); @@ -135,7 +155,7 @@ AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Property::Array& imageUrls, const Property::Map& properties) { - AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory)); + AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory, ImageDimensions())); visual->mImageUrls = new ImageCache::UrlList(); visual->mImageUrls->reserve(imageUrls.Count()); @@ -154,9 +174,9 @@ AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache return visual; } -AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl) +AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size) { - AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory)); + AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory, size)); visual->InitializeAnimatedImage(imageUrl); visual->Initialize(); @@ -178,7 +198,7 @@ void AnimatedImageVisual::CreateImageCache() if(mAnimatedImageLoading) { - mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize, mWrapModeU, mWrapModeV, IsSynchronousLoadingRequired(), mFactoryCache.GetPreMultiplyOnLoad()); + mImageCache = new RollingAnimatedImageCache(textureManager, mDesiredSize, mFittingMode, mSamplingMode, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize, mWrapModeU, mWrapModeV, IsSynchronousLoadingRequired(), mFactoryCache.GetPreMultiplyOnLoad()); } else if(mImageUrls) { @@ -189,11 +209,11 @@ void AnimatedImageVisual::CreateImageCache() uint16_t cacheSize = std::max(std::min(std::max(batchSize, mCacheSize), numUrls), MINIMUM_CACHESIZE); if(cacheSize < numUrls) { - mImageCache = new RollingImageCache(textureManager, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay); + mImageCache = new RollingImageCache(textureManager, mDesiredSize, mFittingMode, mSamplingMode, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay); } else { - mImageCache = new FixedImageCache(textureManager, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay); + mImageCache = new FixedImageCache(textureManager, mDesiredSize, mFittingMode, mSamplingMode, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay); } } @@ -203,7 +223,7 @@ void AnimatedImageVisual::CreateImageCache() } } -AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory) +AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, ImageDimensions desiredSize) : Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::ANIMATED_IMAGE), mFrameDelayTimer(), mPlacementActor(), @@ -223,11 +243,14 @@ AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, Image mLoadPolicy(Toolkit::ImageVisual::LoadPolicy::ATTACHED), mReleasePolicy(Toolkit::ImageVisual::ReleasePolicy::DETACHED), mMaskingData(), + mDesiredSize(desiredSize), mFrameCount(0), mImageSize(), mActionStatus(DevelAnimatedImageVisual::Action::PLAY), mWrapModeU(WrapMode::DEFAULT), mWrapModeV(WrapMode::DEFAULT), + mFittingMode(FittingMode::SCALE_TO_FILL), + mSamplingMode(SamplingMode::BOX_THEN_LINEAR), mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME), mStartFirstFrame(false), mIsJumpTo(false) @@ -249,6 +272,14 @@ AnimatedImageVisual::~AnimatedImageVisual() void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize) { + if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0) + { + naturalSize.x = mDesiredSize.GetWidth(); + naturalSize.y = mDesiredSize.GetHeight(); + return; + } + + naturalSize = Vector2::ZERO; if(mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0) { if(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid() && @@ -325,11 +356,21 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy); map.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, mReleasePolicy); + map.Insert(Toolkit::ImageVisual::Property::FITTING_MODE, mFittingMode); + map.Insert(Toolkit::ImageVisual::Property::SAMPLING_MODE, mSamplingMode); + map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth()); + map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight()); } void AnimatedImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const { - // Do nothing + map.Clear(); + map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::ANIMATED_IMAGE); + if(mImageUrl.IsValid()) + { + map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth()); + map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight()); + } } void AnimatedImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) @@ -466,6 +507,22 @@ void AnimatedImageVisual::DoSetProperties(const Property::Map& propertyMap) { DoSetProperty(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second); } + else if(keyValue.first == IMAGE_FITTING_MODE) + { + DoSetProperty(Toolkit::ImageVisual::Property::FITTING_MODE, keyValue.second); + } + else if(keyValue.first == IMAGE_SAMPLING_MODE) + { + DoSetProperty(Toolkit::ImageVisual::Property::SAMPLING_MODE, keyValue.second); + } + else if(keyValue.first == IMAGE_DESIRED_WIDTH) + { + DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_WIDTH, keyValue.second); + } + else if(keyValue.first == IMAGE_DESIRED_HEIGHT) + { + DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second); + } } } // Load image immediately if LOAD_POLICY requires it @@ -654,6 +711,50 @@ void AnimatedImageVisual::DoSetProperty(Property::Index index, mLoadPolicy = Toolkit::ImageVisual::LoadPolicy::Type(loadPolicy); break; } + + case Toolkit::ImageVisual::Property::FITTING_MODE: + { + int fittingMode = 0; + Scripting::GetEnumerationProperty(value, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, fittingMode); + mFittingMode = Dali::FittingMode::Type(fittingMode); + break; + } + + case Toolkit::ImageVisual::Property::SAMPLING_MODE: + { + int samplingMode = 0; + Scripting::GetEnumerationProperty(value, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, samplingMode); + mSamplingMode = Dali::SamplingMode::Type(samplingMode); + break; + } + + case Toolkit::ImageVisual::Property::DESIRED_WIDTH: + { + float desiredWidth = 0.0f; + if(value.Get(desiredWidth)) + { + mDesiredSize.SetWidth(desiredWidth); + } + else + { + DALI_LOG_ERROR("AnimatedImageVisual: desiredWidth property has incorrect type\n"); + } + break; + } + + case Toolkit::ImageVisual::Property::DESIRED_HEIGHT: + { + float desiredHeight = 0.0f; + if(value.Get(desiredHeight)) + { + mDesiredSize.SetHeight(desiredHeight); + } + else + { + DALI_LOG_ERROR("AnimatedImageVisual: desiredHeight property has incorrect type\n"); + } + break; + } } } diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h index 8fc0f59..243b989 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_ANIMATED_IMAGE_VISUAL_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. @@ -111,8 +111,9 @@ public: * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL to animated image resource to use + * @param[in] size The width and height of the image. The visual size will be used if these are 0. */ - static AnimatedImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl); + static AnimatedImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size = ImageDimensions()); public: // from Visual /** @@ -141,8 +142,9 @@ protected: * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object * @param[in] shaderFactory The ImageVisualShaderFactory object + * @param[in] desiredSize The width and height of the image. The visual size will be used if these are 0. */ - AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory); + AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, ImageDimensions desiredSize); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -284,6 +286,7 @@ private: Dali::Toolkit::ImageVisual::LoadPolicy::Type mLoadPolicy; Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy; TextureManager::MaskingDataPointer mMaskingData; + Dali::ImageDimensions mDesiredSize; // Shared variables uint32_t mFrameCount; // Number of frames @@ -291,11 +294,13 @@ private: DevelAnimatedImageVisual::Action::Type mActionStatus; - Dali::WrapMode::Type mWrapModeU : 3; - Dali::WrapMode::Type mWrapModeV : 3; - DevelImageVisual::StopBehavior::Type mStopBehavior : 2; - bool mStartFirstFrame : 1; - bool mIsJumpTo : 1; + Dali::WrapMode::Type mWrapModeU : 3; + Dali::WrapMode::Type mWrapModeV : 3; + Dali::FittingMode::Type mFittingMode : 3; + Dali::SamplingMode::Type mSamplingMode : 4; + DevelImageVisual::StopBehavior::Type mStopBehavior : 2; + bool mStartFirstFrame : 1; + bool mIsJumpTo : 1; }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp index 7cb6ce3..c40f802 100644 --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp @@ -36,12 +36,15 @@ constexpr uint32_t FIRST_FRAME_INDEX = 0u; } // namespace FixedImageCache::FixedImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, UrlList& urlList, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, uint32_t batchSize, uint32_t interval) -: ImageCache(textureManager, maskingData, observer, batchSize, interval), +: ImageCache(textureManager, size, fittingMode, samplingMode, maskingData, observer, batchSize, interval), mImageUrls(urlList), mFront(FIRST_FRAME_INDEX) { @@ -132,7 +135,7 @@ void FixedImageCache::LoadBatch() Dali::ImageDimensions textureRectSize; auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; - mTextureManager.LoadTexture(url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); + mTextureManager.LoadTexture(url, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); mRequestingLoad = false; } } diff --git a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h index c798a66..90e2c8f 100644 --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h @@ -33,6 +33,9 @@ public: /** * Constructor. * @param[in] textureManager The texture manager + * @param[in] size The width and height to fit the loaded image to. + * @param[in] fittingMode The FittingMode of the resource to load + * @param[in] samplingMode The SamplingMode of the resource to load * @param[in] urlList List of urls to cache * @param[in] maskingData Masking data to be applied. * @param[in] observer FrameReady observer @@ -43,6 +46,9 @@ public: * batch and cache sizes. The cache is as large as the number of urls. */ FixedImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, UrlList& urlList, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, diff --git a/dali-toolkit/internal/visuals/animated-image/image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/image-cache.cpp index 59f0520..3b5131f 100644 --- a/dali-toolkit/internal/visuals/animated-image/image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/image-cache.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. @@ -23,6 +23,9 @@ namespace Toolkit namespace Internal { ImageCache::ImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, uint32_t batchSize, @@ -30,6 +33,9 @@ ImageCache::ImageCache(TextureManager& textureManager, : mTextureManager(textureManager), mObserver(observer), mMaskingData(maskingData), + mDesiredSize(size), + mFittingMode(fittingMode), + mSamplingMode(samplingMode), mBatchSize(batchSize), mInterval(interval), mLoadState(TextureManager::LoadState::NOT_STARTED), diff --git a/dali-toolkit/internal/visuals/animated-image/image-cache.h b/dali-toolkit/internal/visuals/animated-image/image-cache.h index d3b6b0a..f65d60b 100644 --- a/dali-toolkit/internal/visuals/animated-image/image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/image-cache.h @@ -59,8 +59,10 @@ public: /** * @brief Constructor. * @param[in] textureManager The texture manager - * @param[in] urlList List of urls to cache - * @param[in] observer FrameReady observer + * @param[in] size The width and height to fit the loaded image to. + * @param[in] fittingMode The FittingMode of the resource to load + * @param[in] samplingMode The SamplingMode of the resource to load + * @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 @@ -69,6 +71,9 @@ public: * batch and cache sizes. The cache is as large as the number of urls. */ ImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, uint32_t batchSize, @@ -140,6 +145,9 @@ protected: TextureManager& mTextureManager; FrameReadyObserver& mObserver; TextureManager::MaskingDataPointer& mMaskingData; + Dali::ImageDimensions mDesiredSize; + Dali::FittingMode::Type mFittingMode : 3; + Dali::SamplingMode::Type mSamplingMode : 4; uint32_t mBatchSize; uint32_t mInterval; TextureManager::LoadState mLoadState; diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp index bd6c5a7..995ea60 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp @@ -61,6 +61,9 @@ static constexpr uint32_t FIRST_FRAME_INDEX = 0u; } // namespace RollingAnimatedImageCache::RollingAnimatedImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, AnimatedImageLoading& animatedImageLoading, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, @@ -70,7 +73,7 @@ RollingAnimatedImageCache::RollingAnimatedImageCache(TextureManager& const Dali::WrapMode::Type& wrapModeV, bool isSynchronousLoading, bool preMultiplyOnLoad) -: ImageCache(textureManager, maskingData, observer, batchSize, 0u), +: ImageCache(textureManager, size, fittingMode, samplingMode, maskingData, observer, batchSize, 0u), mImageUrl(animatedImageLoading.GetUrl()), mAnimatedImageLoading(animatedImageLoading), mFrameCount(SINGLE_IMAGE_COUNT), @@ -207,7 +210,9 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b frameIndex, loadTextureId, mMaskingData, - SamplingMode::BOX_THEN_LINEAR, + mDesiredSize, + mFittingMode, + mSamplingMode, synchronousLoading, this, preMultiplyOnLoading); @@ -263,8 +268,8 @@ TextureSet RollingAnimatedImageCache::GetFrontTextureSet() const { DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "RollingAnimatedImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[0].mFrameNumber); - TextureManager::TextureId textureId = GetCachedTextureId(0); - TextureSet textureSet = mTextureManager.GetTextureSet(textureId); + TextureManager::TextureId textureId = GetCachedTextureId(0); + TextureSet textureSet = mTextureManager.GetTextureSet(textureId); if(textureSet) { Sampler sampler = Sampler::New(); diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h index 8fed2d7..c827e40 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h @@ -42,7 +42,10 @@ public: /** * @brief Constructor. * @param[in] textureManager The texture manager - * @param[in] animatedImageLoading The loaded animated image + * @param[in] size The width and height to fit the loaded image to. + * @param[in] fittingMode The FittingMode of the resource to load + * @param[in] samplingMode The SamplingMode of the resource to load + * @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 @@ -56,6 +59,9 @@ public: * batch and cache sizes. */ RollingAnimatedImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, AnimatedImageLoading& animatedImageLoading, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp index f0dbb94..19f025d 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp @@ -58,13 +58,16 @@ namespace Toolkit namespace Internal { RollingImageCache::RollingImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, UrlList& urlList, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, uint16_t cacheSize, uint16_t batchSize, uint32_t interval) -: ImageCache(textureManager, maskingData, observer, batchSize, interval), +: ImageCache(textureManager, size, fittingMode, samplingMode, maskingData, observer, batchSize, interval), mImageUrls(urlList), mQueue(cacheSize) { @@ -168,7 +171,7 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex) TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID; TextureSet textureSet = mTextureManager.LoadTexture( - url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); + url, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); mImageUrls[imageFrame.mUrlIndex].mTextureId = loadTextureId; mRequestingLoad = false; @@ -180,8 +183,8 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex) TextureSet RollingImageCache::GetFrontTextureSet() const { - TextureManager::TextureId textureId = GetCachedTextureId(0); - TextureSet textureSet = mTextureManager.GetTextureSet(textureId); + TextureManager::TextureId textureId = GetCachedTextureId(0); + TextureSet textureSet = mTextureManager.GetTextureSet(textureId); if(textureSet) { Sampler sampler = Sampler::New(); diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h index e01f17f..8fbaad6 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h @@ -38,6 +38,9 @@ public: /** * Constructor. * @param[in] textureManager The texture manager + * @param[in] size The width and height to fit the loaded image to. + * @param[in] fittingMode The FittingMode of the resource to load + * @param[in] samplingMode The SamplingMode of the resource to load * @param[in] urlList List of urls to cache * @param[in] maskingData Masking data to be applied. * @param[in] observer FrameReady observer @@ -49,6 +52,9 @@ public: * batch and cache sizes. */ RollingImageCache(TextureManager& textureManager, + ImageDimensions size, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, UrlList& urlList, TextureManager::MaskingDataPointer& maskingData, ImageCache::FrameReadyObserver& observer, @@ -141,8 +147,8 @@ private: bool mReady = false; }; - std::vector& mImageUrls; - CircularQueue mQueue; + std::vector& mImageUrls; + CircularQueue mQueue; }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.cpp b/dali-toolkit/internal/visuals/visual-factory-impl.cpp index 60fb25e..a975aa8 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@ -338,7 +338,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageD case VisualUrl::GIF: case VisualUrl::WEBP: { - visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl); + visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size); break; } case VisualUrl::JSON: