X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fsvg%2Fsvg-visual.cpp;h=a92f7f837fd0fe22ba54327592ea04fa9d0da176;hp=25e84fd5c6d5669d6629bf2e3c566f30cbfd5b24;hb=e8a53a0a591085c6b7470feac4f9cea85cc8ae6e;hpb=e0c063be9e7ecde0e5665079289489d456828abf diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index 25e84fd..a92f7f8 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.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. @@ -27,7 +27,6 @@ #include // EXTERNAL INCLUDES -#include #include #include @@ -39,6 +38,8 @@ namespace Internal { namespace { +const int CUSTOM_PROPERTY_COUNT(6); // atlas + corner/border + // property name const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); @@ -47,7 +48,6 @@ const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties) { SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl)); - svgVisual->Load(); svgVisual->SetProperties(properties); svgVisual->Initialize(); return svgVisual; @@ -56,7 +56,6 @@ SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderF SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl) { SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl)); - svgVisual->Load(); svgVisual->Initialize(); return svgVisual; } @@ -70,7 +69,7 @@ SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& mDefaultWidth(0), mDefaultHeight(0), mPlacementActor(), - mVisualSize(Vector2::ZERO), + mRasterizedSize(Vector2::ZERO), mLoadFailed(false), mAttemptAtlasing(false) { @@ -84,9 +83,24 @@ SvgVisual::~SvgVisual() void SvgVisual::OnInitialize() { - Shader shader = GenerateShader(); + Shader shader = GenerateShader(); Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY); - mImpl->mRenderer = Renderer::New(geometry, shader); + mImpl->mRenderer = VisualRenderer::New(geometry, shader); + mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT); + + Vector2 dpi = Stage::GetCurrent().GetDpi(); + float meanDpi = (dpi.height + dpi.width) * 0.5f; + + SvgTaskPtr newTask = new SvgLoadingTask(this, mVectorRenderer, mImageUrl, meanDpi); + + if(IsSynchronousLoadingRequired() && mImageUrl.IsLocalResource()) + { + newTask->Process(); + } + else + { + mFactoryCache.GetSVGRasterizationThread()->AddTask(newTask); + } } void SvgVisual::DoSetProperties(const Property::Map& propertyMap) @@ -148,7 +162,7 @@ void SvgVisual::DoSetOnScene(Actor& actor) mImpl->mRenderer.SetTextures(textureSet); // Register transform properties - mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); + mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); // Defer the rasterisation task until we get given a size (by Size Negotiation algorithm) @@ -158,7 +172,7 @@ void SvgVisual::DoSetOnScene(Actor& actor) if(mLoadFailed) { Vector2 imageSize = Vector2::ZERO; - imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); @@ -166,8 +180,11 @@ void SvgVisual::DoSetOnScene(Actor& actor) } else { - // SVG visual needs it's size set before it can be rasterized hence set ResourceReady once on stage - ResourceReady(Toolkit::Visual::ResourceStatus::READY); + if(mImpl->mEventObserver) + { + // SVG visual needs it's size set before it can be rasterized hence request relayout once on stage + mImpl->mEventObserver->RelayoutRequest(*this); + } } } @@ -179,13 +196,31 @@ void SvgVisual::DoSetOffScene(Actor& actor) mPlacementActor.Reset(); // Reset the visual size to zero so that when adding the actor back to stage the SVG rasterization is forced - mVisualSize = Vector2::ZERO; + mRasterizedSize = Vector2::ZERO; } void SvgVisual::GetNaturalSize(Vector2& naturalSize) { - naturalSize.x = mDefaultWidth; - naturalSize.y = mDefaultHeight; + if(mLoadFailed && mImpl->mRenderer) + { + // Load failed, use broken image size + auto textureSet = mImpl->mRenderer.GetTextures(); + if(textureSet && textureSet.GetTextureCount()) + { + auto texture = textureSet.GetTexture(0); + if(texture) + { + naturalSize.x = texture.GetWidth(); + naturalSize.y = texture.GetHeight(); + return; + } + } + } + else + { + naturalSize.x = mDefaultWidth; + naturalSize.y = mDefaultHeight; + } } void SvgVisual::DoCreatePropertyMap(Property::Map& map) const @@ -205,31 +240,12 @@ void SvgVisual::DoCreateInstancePropertyMap(Property::Map& map) const // Do nothing } -void SvgVisual::Load() +void SvgVisual::EnablePreMultipliedAlpha(bool preMultiplied) { - // load remote resource on svg rasterize thread. - if(mImageUrl.IsLocalResource()) + // Make always enable pre multiplied alpha whether preMultiplied value is false. + if(!preMultiplied) { - Dali::Vector buffer; - if(Dali::FileLoader::ReadFile(mImageUrl.GetUrl(), buffer)) - { - buffer.PushBack('\0'); - - Vector2 dpi = Stage::GetCurrent().GetDpi(); - float meanDpi = (dpi.height + dpi.width) * 0.5f; - if(!mVectorRenderer.Load(buffer, meanDpi)) - { - mLoadFailed = true; - DALI_LOG_ERROR("SvgVisual::Load: Failed to load file! [%s]\n", mImageUrl.GetUrl().c_str()); - return; - } - mVectorRenderer.GetDefaultSize(mDefaultWidth, mDefaultHeight); - } - else - { - mLoadFailed = true; - DALI_LOG_ERROR("SvgVisual::Load: Failed to read file! [%s]\n", mImageUrl.GetUrl().c_str()); - } + DALI_LOG_WARNING("Note : SvgVisual cannot disable PreMultipliedAlpha\n"); } } @@ -240,15 +256,12 @@ void SvgVisual::AddRasterizationTask(const Vector2& size) unsigned int width = static_cast(size.width); unsigned int height = static_cast(size.height); - Vector2 dpi = Stage::GetCurrent().GetDpi(); - float meanDpi = (dpi.height + dpi.width) * 0.5f; + SvgTaskPtr newTask = new SvgRasterizingTask(this, mVectorRenderer, width, height); - RasterizingTaskPtr newTask = new RasterizingTask(this, mVectorRenderer, mImageUrl, meanDpi, width, height); if(IsSynchronousLoadingRequired() && mImageUrl.IsLocalResource()) { - newTask->Load(); - newTask->Rasterize(); - ApplyRasterizedImage(newTask->GetVectorRenderer(), newTask->GetPixelData(), newTask->IsLoaded()); + newTask->Process(); + ApplyRasterizedImage(newTask->GetPixelData(), newTask->HasSucceeded()); } else { @@ -257,78 +270,92 @@ void SvgVisual::AddRasterizationTask(const Vector2& size) } } -void SvgVisual::ApplyRasterizedImage(VectorImageRenderer vectorRenderer, PixelData rasterizedPixelData, bool isLoaded) +void SvgVisual::ApplyRasterizedImage(PixelData rasterizedPixelData, bool success) { - if(isLoaded && rasterizedPixelData && IsOnScene()) + if(success) { - TextureSet currentTextureSet = mImpl->mRenderer.GetTextures(); - if(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) + if(mDefaultWidth == 0 || mDefaultHeight == 0) { - mFactoryCache.GetAtlasManager()->Remove(currentTextureSet, mAtlasRect); + mVectorRenderer.GetDefaultSize(mDefaultWidth, mDefaultHeight); } - TextureSet textureSet; - - if(mAttemptAtlasing && !mImpl->mCustomShader) + // Rasterization success + if(rasterizedPixelData && IsOnScene()) { - Vector4 atlasRect; - textureSet = mFactoryCache.GetAtlasManager()->Add(atlasRect, rasterizedPixelData); - if(textureSet) // atlasing + mRasterizedSize.x = static_cast(rasterizedPixelData.GetWidth()); + mRasterizedSize.y = static_cast(rasterizedPixelData.GetHeight()); + + TextureSet currentTextureSet = mImpl->mRenderer.GetTextures(); + if(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) { - if(textureSet != currentTextureSet) - { - mImpl->mRenderer.SetTextures(textureSet); - } - mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, atlasRect); - mAtlasRect = atlasRect; - mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + mFactoryCache.GetAtlasManager()->Remove(currentTextureSet, mAtlasRect); } - } - if(!textureSet) // no atlasing - mAttemptAtlasing is false or adding to atlas is failed - { - Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888, rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight()); - texture.Upload(rasterizedPixelData); - mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; + TextureSet textureSet; - if(mAtlasRect == FULL_TEXTURE_RECT) + if(mAttemptAtlasing && !mImpl->mCustomShader) { - textureSet = currentTextureSet; + Vector4 atlasRect; + textureSet = mFactoryCache.GetAtlasManager()->Add(atlasRect, rasterizedPixelData); + if(textureSet) // atlasing + { + if(textureSet != currentTextureSet) + { + mImpl->mRenderer.SetTextures(textureSet); + } + mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, atlasRect); + mAtlasRect = atlasRect; + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + } } - else + + if(!textureSet) // no atlasing - mAttemptAtlasing is false or adding to atlas is failed { - textureSet = TextureSet::New(); - mImpl->mRenderer.SetTextures(textureSet); + Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888, rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight()); + texture.Upload(rasterizedPixelData); + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; - mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT); - mAtlasRect = FULL_TEXTURE_RECT; + if(mAtlasRect == FULL_TEXTURE_RECT) + { + textureSet = currentTextureSet; + } + else + { + textureSet = TextureSet::New(); + mImpl->mRenderer.SetTextures(textureSet); + + mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT); + mAtlasRect = FULL_TEXTURE_RECT; + } + + if(textureSet) + { + textureSet.SetTexture(0, texture); + } } - if(textureSet) + // Rasterized pixels are uploaded to texture. If weak handle is holding a placement actor, it is the time to add the renderer to actor. + Actor actor = mPlacementActor.GetHandle(); + if(actor) { - textureSet.SetTexture(0, texture); + actor.AddRenderer(mImpl->mRenderer); + // reset the weak handle so that the renderer only get added to actor once + mPlacementActor.Reset(); } - } - // Rasterized pixels are uploaded to texture. If weak handle is holding a placement actor, it is the time to add the renderer to actor. - Actor actor = mPlacementActor.GetHandle(); - if(actor) - { - actor.AddRenderer(mImpl->mRenderer); - // reset the weak handle so that the renderer only get added to actor once - mPlacementActor.Reset(); + // Svg loaded and ready to display + ResourceReady(Toolkit::Visual::ResourceStatus::READY); } - - // Svg loaded and ready to display - ResourceReady(Toolkit::Visual::ResourceStatus::READY); } - else if(!isLoaded || !rasterizedPixelData) + else if(!success && !mLoadFailed) { + mLoadFailed = true; + Actor actor = mPlacementActor.GetHandle(); if(actor) { Vector2 imageSize = Vector2::ZERO; - imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); } @@ -343,25 +370,19 @@ void SvgVisual::OnSetTransform() if(IsOnScene() && !mLoadFailed) { - if(visualSize != mVisualSize) + if(visualSize != mRasterizedSize || mDefaultWidth == 0 || mDefaultHeight == 0) { + mRasterizedSize = visualSize; AddRasterizationTask(visualSize); - mVisualSize = visualSize; } } if(mImpl->mRenderer) { - mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); + mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); } } -bool SvgVisual::IsResourceReady() const -{ - return (mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::READY || - mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED); -} - void SvgVisual::UpdateShader() { if(mImpl->mRenderer) @@ -379,10 +400,9 @@ Shader SvgVisual::GenerateShader() const shader = mImageVisualShaderFactory.GetShader( mFactoryCache, ImageVisualShaderFeature::FeatureBuilder() - .EnableTextureAtlas(mAttemptAtlasing) - .EnableRoundedCorner(IsRoundedCornerRequired()) - .EnableBorderline(IsBorderlineRequired()) - ); + .EnableTextureAtlas(mAttemptAtlasing) + .EnableRoundedCorner(IsRoundedCornerRequired()) + .EnableBorderline(IsBorderlineRequired())); } else {