From: Eunki, Hong Date: Fri, 1 Apr 2022 13:27:23 +0000 (+0900) Subject: Make n-patch image show broken image X-Git-Tag: dali_2.1.17~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=145f62f674d8ae90930470756889e2346f7aa118 Make n-patch image show broken image Due to the visual-factory-cache.cpp's UpdateBorkenImageRenderer assumed that inputed renderer is normal image's renderer, n-patch visual didn't show broken image well. This patch re-create renderer when we use not-image-renderer. Change-Id: I93ee8e7c87901e0bed5c843adb38066b8c184342 Signed-off-by: Eunki, Hong --- 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 13464d3..6999ffa 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 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include <../dali-toolkit/dali-toolkit-test-utils/dummy-control.h> #include @@ -253,3 +254,46 @@ int UtcDaliArcVisualCreateInstancePropertyMap(void) END_TEST; } +int UtcDaliVisualUpdateBrokenImageRenderer(void) +{ + ToolkitTestApplication application; + tet_infoline( "UpdateBrokenImageRenderer Test" ); + + Toolkit::Internal::VisualFactoryCache* factoryCache = new Toolkit::Internal::VisualFactoryCache(false); + + std::string defaultBrokenImageUrl = "not-9patch.png"; + + // Set default broken image + factoryCache->SetBrokenImageUrl(defaultBrokenImageUrl, std::vector()); + + //Created dummy renderer + Geometry geometry = factoryCache->GetGeometry(Toolkit::Internal::VisualFactoryCache::QUAD_GEOMETRY); + Shader shader = Shader::New("foo","bar"); + Renderer renderer = Renderer::New(geometry, shader); + + DALI_TEST_CHECK(renderer); + + // renderer doesn't changed. + factoryCache->UpdateBrokenImageRenderer(renderer, Vector2::ZERO, true); + Shader testShader1 = renderer.GetShader(); + + // Get default image renderer. + factoryCache->UpdateBrokenImageRenderer(renderer, Vector2::ZERO, false); + Shader testShader2 = renderer.GetShader(); + + // Get default image renderer but nine patch. + // Note : This API behavior can be changed. (DALi don't consider about default BrokenImageUrl is failed. + defaultBrokenImageUrl = "yes-9patch.9.png"; + factoryCache->SetBrokenImageUrl(defaultBrokenImageUrl, std::vector()); + factoryCache->UpdateBrokenImageRenderer(renderer, Vector2::ZERO, false); + Shader testShader3 = renderer.GetShader(); + + DALI_TEST_CHECK(testShader1 != factoryCache->GetShader(Toolkit::Internal::VisualFactoryCache::IMAGE_SHADER)); + DALI_TEST_CHECK(testShader1 != factoryCache->GetShader(Toolkit::Internal::VisualFactoryCache::NINE_PATCH_SHADER)); + DALI_TEST_CHECK(testShader2 == factoryCache->GetShader(Toolkit::Internal::VisualFactoryCache::IMAGE_SHADER)); + DALI_TEST_CHECK(testShader3 == factoryCache->GetShader(Toolkit::Internal::VisualFactoryCache::NINE_PATCH_SHADER)); + + delete factoryCache; + + END_TEST; +} diff --git a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp index 71d8cba..98d6d30 100644 --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp @@ -451,6 +451,32 @@ void NPatchVisual::ApplyTextureAndUniforms() { 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); + textureSet.SetTexture(1, texture); + mImpl->mRenderer.RegisterProperty(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA, + AUXILIARY_IMAGE_ALPHA_NAME, + mAuxiliaryImageAlpha); + } + mImpl->mRenderer.SetTextures(textureSet); } else { @@ -463,34 +489,8 @@ void NPatchVisual::ApplyTextureAndUniforms() { imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); } - mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); - } - - 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); + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize, false); } - mImpl->mRenderer.SetTextures(textureSet); // Register transform properties mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.cpp b/dali-toolkit/internal/visuals/visual-factory-cache.cpp index a65c779..d7932d2 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-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. @@ -22,12 +22,13 @@ #include // INTERNAL INCLUDES +#include +#include #include #include #include #include -#include -#include +#include #include namespace Dali @@ -36,6 +37,10 @@ namespace Toolkit { namespace Internal { +namespace +{ +const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); +} VisualFactoryCache::VisualFactoryCache(bool preMultiplyOnLoad) : mSvgRasterizeThread(NULL), @@ -221,10 +226,10 @@ Texture VisualFactoryCache::GetBrokenVisualImage(uint32_t brokenIndex) Devel::PixelBuffer pixelBuffer = LoadImageFromFile(mBrokenImageInfoContainer[brokenIndex].url); if(pixelBuffer) { - pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer - mBrokenImageInfoContainer[brokenIndex].texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight()); + pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer + mBrokenImageInfoContainer[brokenIndex].texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight()); mBrokenImageInfoContainer[brokenIndex].texture.Upload(pixelData); - mBrokenImageInfoContainer[brokenIndex].width = pixelData.GetWidth(); + mBrokenImageInfoContainer[brokenIndex].width = pixelData.GetWidth(); mBrokenImageInfoContainer[brokenIndex].height = pixelData.GetHeight(); } } @@ -270,7 +275,7 @@ Geometry VisualFactoryCache::GetNPatchGeometry(int index) geometry = GetGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY); if(!geometry) { - geometry = NPatchHelper::CreateGridGeometry(Uint16Pair(3,3)); + geometry = NPatchHelper::CreateGridGeometry(Uint16Pair(3, 3)); SaveGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY, geometry); } } @@ -286,7 +291,7 @@ Geometry VisualFactoryCache::GetNPatchGeometry(int index) geometry = GetGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY); if(!geometry) { - geometry = NPatchHelper::CreateGridGeometry(Uint16Pair(3,3)); + geometry = NPatchHelper::CreateGridGeometry(Uint16Pair(3, 3)); SaveGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY, geometry); } } @@ -337,16 +342,15 @@ void VisualFactoryCache::ApplyTextureAndUniforms(Renderer& renderer, int index) TextureSet textureSet; if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE) { - textureSet = data->GetTextures(); + textureSet = data->GetTextures(); mBrokenImageInfoContainer[index].texture = textureSet.GetTexture(0); NPatchHelper::ApplyTextureAndUniforms(renderer, data); renderer.SetTextures(textureSet); } } -void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vector2& size) +void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vector2& size, const bool& rendererIsImage) { - bool useDefaultBrokenImage = false; if(mBrokenImageInfoContainer.size() == 0) { @@ -354,7 +358,7 @@ void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vec } // Load Information for broken image - for(uint32_t index = 0; (index < mBrokenImageInfoContainer.size()) && !useDefaultBrokenImage; index++) + for(uint32_t index = 0; (index < mBrokenImageInfoContainer.size()) && !useDefaultBrokenImage; index++) { if(mBrokenImageInfoContainer[index].width == 0 && mBrokenImageInfoContainer[index].height == 0) { @@ -365,16 +369,16 @@ void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vec if(mBrokenImageInfoContainer[index].visualType == VisualUrl::Type::N_PATCH) { const NPatchData* data; - Rect border; - mBrokenImageInfoContainer[index].npatchId = mNPatchLoader.Load( mTextureManager, NULL, mBrokenImageInfoContainer[index].url, border, mPreMultiplyOnLoad, true); + Rect border; + mBrokenImageInfoContainer[index].npatchId = mNPatchLoader.Load(mTextureManager, NULL, mBrokenImageInfoContainer[index].url, border, mPreMultiplyOnLoad, true); if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE) { - mBrokenImageInfoContainer[index].width = data->GetCroppedWidth(); + mBrokenImageInfoContainer[index].width = data->GetCroppedWidth(); mBrokenImageInfoContainer[index].height = data->GetCroppedHeight(); } else { - DALI_LOG_ERROR("Can't update renderer for broken image. maybe image loading is failed [index:%d] [path:%s] \n",index, mBrokenImageInfoContainer[index].url.c_str()); + DALI_LOG_ERROR("Can't update renderer for broken image. maybe image loading is failed [index:%d] [path:%s] \n", index, mBrokenImageInfoContainer[index].url.c_str()); useDefaultBrokenImage = true; } } @@ -382,7 +386,7 @@ void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vec { if(!GetBrokenVisualImage(index)) { - DALI_LOG_ERROR("Can't update renderer for broken image. maybe image loading is failed [index:%d] [path:%s] \n",index, mBrokenImageInfoContainer[index].url.c_str()); + DALI_LOG_ERROR("Can't update renderer for broken image. maybe image loading is failed [index:%d] [path:%s] \n", index, mBrokenImageInfoContainer[index].url.c_str()); useDefaultBrokenImage = true; } } @@ -401,24 +405,42 @@ void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vec mBrokenImageInfoContainer[defaultBrokenIndex].url = mDefaultBrokenImageUrl; VisualUrl visualUrl(mBrokenImageInfoContainer[defaultBrokenIndex].url); mBrokenImageInfoContainer[defaultBrokenIndex].visualType = visualUrl.GetType(); - mUseDefaultBrokenImageOnly = true; + mUseDefaultBrokenImageOnly = true; } // Set Texutre to renderer int brokenIndex = GetProperBrokenImageIndex(size); if(GetBrokenImageVisualType(brokenIndex) == VisualUrl::N_PATCH) { + DALI_LOG_ERROR("Broken npatch?"); // Set geometry and shader for npatch Geometry geometry = GetNPatchGeometry(brokenIndex); - Shader shader = GetNPatchShader(brokenIndex); + Shader shader = GetNPatchShader(brokenIndex); renderer.SetGeometry(geometry); renderer.SetShader(shader); ApplyTextureAndUniforms(renderer, brokenIndex); } else { - Texture brokenImage = GetBrokenVisualImage(brokenIndex); - TextureSet textureSet = TextureSet::New(); + DALI_LOG_ERROR("Broken single image"); + // Create single image renderer only if rederer is not use normal ImageShader. i.e. npatch visual. + if(!rendererIsImage) + { + Geometry geometry = GetGeometry(QUAD_GEOMETRY); + Shader shader = GetShader(IMAGE_SHADER); + if(!shader) + { + std::string vertexShader = std::string(Dali::Shader::GetVertexShaderPrefix() + SHADER_IMAGE_VISUAL_SHADER_VERT.data()); + std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + SHADER_IMAGE_VISUAL_SHADER_FRAG.data()); + shader = Shader::New(vertexShader, fragmentShader); + shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); + SaveShader(IMAGE_SHADER, shader); + } + renderer.SetGeometry(geometry); + renderer.SetShader(shader); + } + Texture brokenImage = GetBrokenVisualImage(brokenIndex); + TextureSet textureSet = TextureSet::New(); textureSet.SetTexture(0u, brokenImage); renderer.SetTextures(textureSet); } @@ -428,7 +450,7 @@ int32_t VisualFactoryCache::GetProperBrokenImageIndex(const Vector2& size) { // Sets the default broken type int32_t returnIndex = 0; - if((size.width == 0 || size.height == 0) || mUseDefaultBrokenImageOnly ) + if((size.width == 0 || size.height == 0) || mUseDefaultBrokenImageOnly) { // To do : Need to add observer about size return returnIndex; diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index 3ed626f..417f4d4 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -201,8 +201,11 @@ public: * @brief Update the broken image Renderer object * @param[in,out] renderer renderer for broken image * @param[in] size the size of actor + * @param[in] rendererIsImage True if input renderer use image shader already. + * If true, we don't need to create new renderer when broken image is single image. + * Most of user experience use normal images. So It can reduce runtime. */ - void UpdateBrokenImageRenderer(Renderer& renderer, const Vector2& size); + void UpdateBrokenImageRenderer(Renderer& renderer, const Vector2& size, const bool& rendererIsImage = true); public: /**