/*
- * 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.
// EXTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/common/stage.h>
#include <dali/devel-api/rendering/renderer-devel.h>
#include <dali/integration-api/debug.h>
-#include <dali/devel-api/common/stage.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/utility/npatch-helper.h>
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
#include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
#include <dali-toolkit/internal/visuals/npatch-loader.h>
-#include <dali-toolkit/devel-api/utility/npatch-helper.h>
#include <dali-toolkit/internal/visuals/rendering-addon.h>
#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
#include <dali-toolkit/internal/visuals/visual-base-impl.h>
{
namespace Internal
{
+namespace
+{
+const int CUSTOM_PROPERTY_COUNT(5); // fixed(3),stretch,aux
+}
/////////////////NPatchVisual////////////////
// Load the auxiliary image
auto preMultiplyOnLoading = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mAuxiliaryPixelBuffer = textureManager.LoadPixelBuffer(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, synchronousLoading, this, true, preMultiplyOnLoading);
+
+ // If synchronousLoading is true, we can check the auxiliaryResource's statue now.
+ if(synchronousLoading)
+ {
+ mAuxiliaryResourceStatus = mAuxiliaryPixelBuffer ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED;
+ }
}
}
mImpl->mRenderer.SetShader(shader);
mPlacementActor = actor;
- if(data->GetLoadingState() != NPatchData::LoadingState::LOADING)
+ // If all reasources are already loaded, apply textures and uniforms now
+ // else, will be completed uploaded at LoadComplete function asynchronously.
+ if(data->GetLoadingState() != NPatchData::LoadingState::LOADING &&
+ (!mAuxiliaryUrl.IsValid() || mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::PREPARING))
{
if(RenderingAddOn::Get().IsValid())
{
mPlacementActor.Reset();
// npatch loaded and ready to display
- ResourceReady(Toolkit::Visual::ResourceStatus::READY);
+ if(data->GetLoadingState() != NPatchData::LoadingState::LOAD_COMPLETE ||
+ (mAuxiliaryUrl.IsValid() && mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::READY))
+ {
+ ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
+ }
+ else
+ {
+ ResourceReady(Toolkit::Visual::ResourceStatus::READY);
+ }
}
}
}
{
if(mImpl->mRenderer)
{
- mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+ mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
}
}
+bool NPatchVisual::IsResourceReady() const
+{
+ return (mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::READY ||
+ mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED);
+}
+
void NPatchVisual::DoCreatePropertyMap(Property::Map& map) const
{
map.Clear();
mImageUrl(),
mAuxiliaryUrl(),
mId(NPatchData::INVALID_NPATCH_DATA_ID),
+ mAuxiliaryResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
mBorderOnly(false),
mBorder(),
mAuxiliaryImageAlpha(0.0f),
Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
Shader shader = mImageVisualShaderFactory.GetShader(
mFactoryCache,
- ImageVisualShaderFeature::FeatureBuilder()
- );
+ ImageVisualShaderFeature::FeatureBuilder());
- mImpl->mRenderer = Renderer::New(geometry, shader);
+ mImpl->mRenderer = VisualRenderer::New(geometry, shader);
+ mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
//Register transform properties
- mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+ mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
}
Geometry NPatchVisual::CreateGeometry()
Uint16Pair gridSize(2 * data->GetStretchPixelsX().Size() + 1, 2 * data->GetStretchPixelsY().Size() + 1);
if(!data->GetRenderingMap())
{
- geometry = !mBorderOnly ? NPatchHelper::CreateGridGeometry(gridSize) : NPatchHelper::CreateBorderGeometry(gridSize);
+ geometry = !mBorderOnly ? NPatchHelper::CreateGridGeometry(gridSize) : NPatchHelper::CreateBorderGeometry(gridSize);
}
else
{
uint32_t elementCount[2];
- geometry = !mBorderOnly ? RenderingAddOn::Get().CreateGeometryGrid(data->GetRenderingMap(), gridSize, elementCount) : NPatchHelper::CreateBorderGeometry(gridSize);
+ geometry = !mBorderOnly ? RenderingAddOn::Get().CreateGeometryGrid(data->GetRenderingMap(), gridSize, elementCount) : NPatchHelper::CreateBorderGeometry(gridSize);
if(mImpl->mRenderer)
{
RenderingAddOn::Get().SubmitRenderTask(mImpl->mRenderer, data->GetRenderingMap());
auto fragmentShader = mAuxiliaryPixelBuffer ? SHADER_NPATCH_VISUAL_MASK_SHADER_FRAG
: SHADER_NPATCH_VISUAL_SHADER_FRAG;
- auto shaderType = mAuxiliaryPixelBuffer ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
- : VisualFactoryCache::NINE_PATCH_SHADER;
+ auto shaderType = mAuxiliaryPixelBuffer ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
+ : VisualFactoryCache::NINE_PATCH_SHADER;
// ask loader for the regions
if(mLoader.GetNPatchData(mId, data))
{
textureSet = data->GetTextures();
NPatchHelper::ApplyTextureAndUniforms(mImpl->mRenderer, data);
+
+ if(mAuxiliaryPixelBuffer)
+ {
+ // If the auxiliary image is smaller than the un-stretched NPatch, use CPU resizing to enlarge it to the
+ // same size as the unstretched NPatch. This will give slightly higher quality results than just relying
+ // on GL interpolation alone.
+ if(mAuxiliaryPixelBuffer.GetWidth() < data->GetCroppedWidth() &&
+ mAuxiliaryPixelBuffer.GetHeight() < data->GetCroppedHeight())
+ {
+ mAuxiliaryPixelBuffer.Resize(data->GetCroppedWidth(), data->GetCroppedHeight());
+ }
+
+ // Note, this resets mAuxiliaryPixelBuffer handle
+ auto auxiliaryPixelData = Devel::PixelBuffer::Convert(mAuxiliaryPixelBuffer);
+
+ auto texture = Texture::New(TextureType::TEXTURE_2D,
+ auxiliaryPixelData.GetPixelFormat(),
+ auxiliaryPixelData.GetWidth(),
+ auxiliaryPixelData.GetHeight());
+ texture.Upload(auxiliaryPixelData);
+
+ // TODO : This code exist due to the texture cache manager hold TextureSet, not Texture.
+ // If we call textureSet.SetTexture(1, texture) directly, the cached TextureSet also be changed.
+ // We should make pass utc-Dali-VisualFactory.cpp UtcDaliNPatchVisualAuxiliaryImage02().
+ TextureSet tempTextureSet = TextureSet::New();
+ tempTextureSet.SetTexture(0, textureSet.GetTexture(0));
+ tempTextureSet.SetTexture(1, texture);
+ textureSet = tempTextureSet;
+
+ mImpl->mRenderer.RegisterProperty(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA,
+ AUXILIARY_IMAGE_ALPHA_NAME,
+ mAuxiliaryImageAlpha);
+ }
+ mImpl->mRenderer.SetTextures(textureSet);
}
else
{
DALI_LOG_ERROR("The N patch image '%s' is not a valid N patch image\n", mImageUrl.GetUrl().c_str());
textureSet = TextureSet::New();
- Actor actor = mPlacementActor.GetHandle();
+ Actor actor = mPlacementActor.GetHandle();
Vector2 imageSize = Vector2::ZERO;
if(actor)
{
imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
}
- mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize);
- Texture croppedImage = mImpl->mRenderer.GetTextures().GetTexture(0);
- textureSet.SetTexture(0u, croppedImage);
- mImpl->mRenderer.RegisterProperty("uFixed[0]", Vector2::ZERO);
- mImpl->mRenderer.RegisterProperty("uFixed[1]", Vector2::ZERO);
- mImpl->mRenderer.RegisterProperty("uFixed[2]", Vector2::ZERO);
- mImpl->mRenderer.RegisterProperty("uStretchTotal", Vector2(croppedImage.GetWidth(), croppedImage.GetHeight()));
+ mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize, false);
}
- if(mAuxiliaryPixelBuffer)
- {
- // If the auxiliary image is smaller than the un-stretched NPatch, use CPU resizing to enlarge it to the
- // same size as the unstretched NPatch. This will give slightly higher quality results than just relying
- // on GL interpolation alone.
- if(mAuxiliaryPixelBuffer.GetWidth() < data->GetCroppedWidth() &&
- mAuxiliaryPixelBuffer.GetHeight() < data->GetCroppedHeight())
- {
- mAuxiliaryPixelBuffer.Resize(data->GetCroppedWidth(), data->GetCroppedHeight());
- }
-
- // Note, this resets mAuxiliaryPixelBuffer handle
- auto auxiliaryPixelData = Devel::PixelBuffer::Convert(mAuxiliaryPixelBuffer);
-
- auto texture = Texture::New(TextureType::TEXTURE_2D,
- auxiliaryPixelData.GetPixelFormat(),
- auxiliaryPixelData.GetWidth(),
- auxiliaryPixelData.GetHeight());
- texture.Upload(auxiliaryPixelData);
- textureSet.SetTexture(1, texture);
- mImpl->mRenderer.RegisterProperty(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA,
- AUXILIARY_IMAGE_ALPHA_NAME,
- mAuxiliaryImageAlpha);
- }
- 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);
}
Geometry NPatchVisual::GetNinePatchGeometry(VisualFactoryCache::GeometryType subType)
void NPatchVisual::SetResource()
{
- const NPatchData* data;
- if(mImpl->mRenderer && mLoader.GetNPatchData(mId, data))
- {
- Geometry geometry = CreateGeometry();
- Shader shader = CreateShader();
-
- mImpl->mRenderer.SetGeometry(geometry);
- mImpl->mRenderer.SetShader(shader);
+ Geometry geometry = CreateGeometry();
+ Shader shader = CreateShader();
- Actor actor = mPlacementActor.GetHandle();
- if(actor)
- {
- ApplyTextureAndUniforms();
- actor.AddRenderer(mImpl->mRenderer);
- mPlacementActor.Reset();
+ mImpl->mRenderer.SetGeometry(geometry);
+ mImpl->mRenderer.SetShader(shader);
- // npatch loaded and ready to display
- ResourceReady(Toolkit::Visual::ResourceStatus::READY);
- }
+ Actor actor = mPlacementActor.GetHandle();
+ if(actor)
+ {
+ ApplyTextureAndUniforms();
+ actor.AddRenderer(mImpl->mRenderer);
+ mPlacementActor.Reset();
}
}
void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
{
- if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE)
+ if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE) // For the Url.
{
- EnablePreMultipliedAlpha(textureInformation.preMultiplied);
- if(!loadSuccess)
+ if(loadSuccess)
{
- // Image loaded and ready to display
- ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
- }
-
- if(mAuxiliaryPixelBuffer || !mAuxiliaryUrl.IsValid())
- {
- SetResource();
+ EnablePreMultipliedAlpha(textureInformation.preMultiplied);
}
}
- else // for the ReturnType::PIXEL_BUFFER
+ else // For the AuxiliaryUrl : ReturnType::PIXEL_BUFFER
{
if(loadSuccess && textureInformation.url == mAuxiliaryUrl.GetUrl())
{
- mAuxiliaryPixelBuffer = textureInformation.pixelBuffer;
- SetResource();
+ mAuxiliaryPixelBuffer = textureInformation.pixelBuffer;
+ mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::READY;
}
else
{
- // Image loaded and ready to display
- ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
+ mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
+ }
+ }
+ // If auxiliaryUrl didn't set || auxiliaryUrl load done.
+ if(!mAuxiliaryUrl.IsValid() || mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::PREPARING)
+ {
+ const NPatchData* data;
+ // and.. If Url loading done.
+ if(mImpl->mRenderer && mLoader.GetNPatchData(mId, data) && data->GetLoadingState() != NPatchData::LoadingState::LOADING)
+ {
+ SetResource();
+ // npatch loaded and ready to display
+ if(data->GetLoadingState() != NPatchData::LoadingState::LOAD_COMPLETE ||
+ (mAuxiliaryUrl.IsValid() && mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::READY))
+ {
+ ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
+ }
+ else
+ {
+ ResourceReady(Toolkit::Visual::ResourceStatus::READY);
+ }
}
}
}