const char* TEST_MASK_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
const char* TEST_ROTATED_IMAGE = TEST_RESOURCE_DIR "/keyboard-Landscape.jpg";
const char* TEST_YUV420_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1-yuv420.jpg";
+const char* TEST_N_PATCH_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/heartsframe.9.png";
constexpr auto LOAD_IMAGE_YUV_PLANES_ENV = "DALI_LOAD_IMAGE_YUV_PLANES_ENV";
END_TEST;
}
+int UtcDaliImageVisualReleasePolicy09(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliImageVisualReleasePolicy09 Destroyed Policy with N-Patch, Texture should be deleted when visual destroyed");
+
+ Property::Map propertyMapNPatchReleasePolicy;
+ propertyMapNPatchReleasePolicy.Insert(Visual::Property::TYPE, Visual::N_PATCH);
+ propertyMapNPatchReleasePolicy.Insert(ImageVisual::Property::URL, TEST_N_PATCH_IMAGE_FILE_NAME);
+ propertyMapNPatchReleasePolicy.Insert(DevelImageVisual::Property::AUXILIARY_IMAGE, TEST_MASK_IMAGE_FILE_NAME);
+ propertyMapNPatchReleasePolicy.Insert(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA, 0.9f);
+ propertyMapNPatchReleasePolicy.Insert(ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED);
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base imageVisual = factory.CreateVisual(propertyMapNPatchReleasePolicy);
+ DALI_TEST_CHECK(imageVisual);
+
+ // Setup debug trace
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ tet_infoline("Register visual with control and ensure it has the only handle");
+ DummyControl actor = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+ imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive.
+
+ actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+
+ // Wait for image to load
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(0);
+ // Test renderer and texture created
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION);
+
+ DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+ tet_infoline("Destroy visual by UnRegistering visual with control, check renderer is destroyed");
+ dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL);
+ DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
+ application.SendNotification();
+ application.Render();
+
+ // Test texture removed after visual destroyed.
+ tet_infoline("Ensure texture is deleted after visual destroyed");
+ DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 2, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliImageVisualLoadPolicy01(void)
{
ToolkitTestApplication application;
#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-atlas-manager.h>
#include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
#include <dali-toolkit/internal/visuals/npatch-loader.h>
#include <dali-toolkit/internal/visuals/rendering-addon.h>
}
}
- if(!mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && (mAuxiliaryUrl.IsLocalResource() || mAuxiliaryUrl.IsBufferResource()))
+ if(mAuxiliaryTextureId == TextureManager::INVALID_TEXTURE_ID && mAuxiliaryUrl.IsValid() && (mAuxiliaryUrl.IsLocalResource() || mAuxiliaryUrl.IsBufferResource()))
{
+ auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader
+ ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+ : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+ TextureManager::MaskingDataPointer maskingDataPtr = nullptr;
+ ImageAtlasManagerPtr imageAtlasManagerPtr = nullptr;
+
+ bool atlasing = false;
+ auto atlasRect = Vector4::ZERO;
+ auto atlasRectSize = Dali::ImageDimensions();
+
+ bool loadingStatus = false;
+
// 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);
+ mAuxiliaryTextureSet = textureManager.LoadTexture(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, maskingDataPtr, synchronousLoading, mAuxiliaryTextureId, atlasRect, atlasRectSize, atlasing, loadingStatus, WrapMode::DEFAULT, WrapMode::DEFAULT, this, nullptr, imageAtlasManagerPtr, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad);
// If synchronousLoading is true, we can check the auxiliaryResource's status now.
if(synchronousLoading)
{
- mAuxiliaryResourceStatus = mAuxiliaryPixelBuffer ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED;
+ mAuxiliaryResourceStatus = (mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u) ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED;
}
}
}
}
}
- if(mAuxiliaryPixelBuffer)
+ if(mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u)
{
- naturalSize.x = std::max(naturalSize.x, float(mAuxiliaryPixelBuffer.GetWidth()));
- naturalSize.y = std::max(naturalSize.y, float(mAuxiliaryPixelBuffer.GetHeight()));
+ naturalSize.x = std::max(naturalSize.x, float(mAuxiliaryTextureSet.GetTexture(0u).GetWidth()));
+ naturalSize.y = std::max(naturalSize.y, float(mAuxiliaryTextureSet.GetTexture(0u).GetHeight()));
}
}
void NPatchVisual::DoSetOffScene(Actor& actor)
{
- if((mId != NPatchData::INVALID_NPATCH_DATA_ID) && mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED)
+ if(mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED)
{
- mLoader.Remove(mId, this);
- mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
- mId = NPatchData::INVALID_NPATCH_DATA_ID;
+ if(mId != NPatchData::INVALID_NPATCH_DATA_ID)
+ {
+ mLoader.Remove(mId, this);
+ mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
+ mId = NPatchData::INVALID_NPATCH_DATA_ID;
+ }
+ if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
+ {
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+ textureManager.Remove(mAuxiliaryTextureId, this);
+ mAuxiliaryTextureId = TextureManager::INVALID_TEXTURE_ID;
+ mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
+ mAuxiliaryTextureSet.Reset();
+ }
}
actor.RemoveRenderer(mImpl->mRenderer);
mImageUrl(),
mAuxiliaryUrl(),
mId(NPatchData::INVALID_NPATCH_DATA_ID),
+ mAuxiliaryTextureSet(),
+ mAuxiliaryTextureId(TextureManager::INVALID_TEXTURE_ID),
mAuxiliaryResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
mBorderOnly(false),
mBorder(),
NPatchVisual::~NPatchVisual()
{
- if(Stage::IsInstalled() && (mId != NPatchData::INVALID_NPATCH_DATA_ID) && (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER))
+ if(Stage::IsInstalled())
{
- mLoader.Remove(mId, this);
- mId = NPatchData::INVALID_NPATCH_DATA_ID;
+ if(mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER)
+ {
+ if(mId != NPatchData::INVALID_NPATCH_DATA_ID)
+ {
+ mLoader.Remove(mId, this);
+ mId = NPatchData::INVALID_NPATCH_DATA_ID;
+ }
+ if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
+ {
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+ textureManager.Remove(mAuxiliaryTextureId, this);
+ mAuxiliaryTextureId = TextureManager::INVALID_TEXTURE_ID;
+ mAuxiliaryTextureSet.Reset();
+ }
+ }
}
}
NPatchUtility::StretchRanges::SizeType xStretchCount = 0;
NPatchUtility::StretchRanges::SizeType yStretchCount = 0;
- 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 fragmentShader = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? SHADER_NPATCH_VISUAL_MASK_SHADER_FRAG
+ : SHADER_NPATCH_VISUAL_SHADER_FRAG;
+ auto shaderType = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? 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(mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY)
{
- // 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);
+ DALI_ASSERT_ALWAYS(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID);
+ DALI_ASSERT_ALWAYS(mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u);
// 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);
+ tempTextureSet.SetTexture(1, mAuxiliaryTextureSet.GetTexture(0));
textureSet = tempTextureSet;
mImpl->mRenderer.RegisterProperty(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA,
void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
{
- if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE) // For the Url.
+ if(textureInformation.url.length() > 0) // For the Url.
{
- if(textureInformation.textureId != TextureManager::INVALID_TEXTURE_ID)
+ if(DALI_UNLIKELY(mId == NPatchData::INVALID_NPATCH_DATA_ID))
{
- if(mId == NPatchData::INVALID_NPATCH_DATA_ID)
- {
- // Special case when mLoader.Load call LoadComplete function before mId setup.
- // We can overwrite mId.
- mId = static_cast<NPatchData::NPatchDataId>(textureInformation.textureId);
- }
+ // Special case when mLoader.Load call LoadComplete function before mId setup.
+ // We can overwrite mId.
+ mId = static_cast<NPatchData::NPatchDataId>(textureInformation.textureId);
}
if(loadSuccess)
{
EnablePreMultipliedAlpha(textureInformation.preMultiplied);
}
}
- else // For the AuxiliaryUrl : ReturnType::PIXEL_BUFFER
+ else // For the AuxiliaryUrl
{
- if(loadSuccess && textureInformation.url == mAuxiliaryUrl.GetUrl())
+ if(DALI_UNLIKELY(mAuxiliaryTextureId == TextureManager::INVALID_TEXTURE_ID))
+ {
+ // Special case when TextureManager.LoadTexture call LoadComplete function before mAuxiliaryTextureId setup.
+ // We can overwrite mAuxiliaryTextureId.
+ mAuxiliaryTextureId = textureInformation.textureId;
+ }
+ if(loadSuccess)
{
- mAuxiliaryPixelBuffer = textureInformation.pixelBuffer;
+ mAuxiliaryTextureSet = textureInformation.textureSet;
mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::READY;
}
else
mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
}
}
+
// If auxiliaryUrl didn't required OR auxiliaryUrl load done.
if(!mAuxiliaryUrl.IsValid() || mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::PREPARING)
{