#include <dali-toolkit/internal/texture-manager/texture-manager-impl.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/image-visual-shader-feature-builder.h>
#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
#include <dali-toolkit/internal/visuals/visual-base-impl.h>
#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
Dali::SamplingMode::Type samplingMode)
: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::IMAGE),
mPixelArea(FULL_TEXTURE_RECT),
+ mPixelAreaIndex(Property::INVALID_INDEX),
mPlacementActor(),
mImageUrl(imageUrl),
mMaskingData(),
case Toolkit::ImageVisual::Property::PIXEL_AREA:
{
value.Get(mPixelArea);
+
+ if(DALI_UNLIKELY(mImpl->mRenderer))
+ {
+ // Unusual case. SetProperty called after OnInitialize().
+ // Assume that DoAction call UPDATE_PROPERTY.
+ mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(mPixelAreaIndex, PIXEL_AREA_UNIFORM_NAME, mPixelArea);
+ }
break;
}
EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
// Set new TextureSet with fast track loading task
- mFastTrackLoadingTask = new FastTrackLoadingTask(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mOrientationCorrection, preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF, MakeCallback(this, &ImageVisual::FastLoadComplete));
+ mFastTrackLoadingTask = new FastTrackLoadingTask(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mOrientationCorrection, preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF, mFactoryCache.GetLoadYuvPlanes(), MakeCallback(this, &ImageVisual::FastLoadComplete));
TextureSet textureSet = TextureSet::New();
- textureSet.SetTexture(0u, mFastTrackLoadingTask->mTexture);
+ if(!mFastTrackLoadingTask->mLoadPlanesAvaliable)
+ {
+ DALI_ASSERT_ALWAYS(mFastTrackLoadingTask->mTextures.size() >= 1u);
+ textureSet.SetTexture(0u, mFastTrackLoadingTask->mTextures[0]);
+ }
+ else
+ {
+ DALI_ASSERT_ALWAYS(mFastTrackLoadingTask->mTextures.size() >= 3u);
+ textureSet.SetTexture(0u, mFastTrackLoadingTask->mTextures[0]);
+ textureSet.SetTexture(1u, mFastTrackLoadingTask->mTextures[1]);
+ textureSet.SetTexture(2u, mFastTrackLoadingTask->mTextures[2]);
+
+ // We cannot determine what kind of shader will be used.
+ // Just use unified shader, and then change shader after load completed.
+ mNeedUnifiedYuvAndRgb = true;
+ UpdateShader();
+ }
mImpl->mRenderer.SetTextures(textureSet);
Dali::AsyncTaskManager::Get().AddTask(mFastTrackLoadingTask);
if(mPixelArea != FULL_TEXTURE_RECT)
{
- mImpl->mRenderer.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, mPixelArea);
+ mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(mPixelAreaIndex, PIXEL_AREA_UNIFORM_NAME, mPixelArea);
}
if(mLoadState == TextureManager::LoadState::LOAD_FINISHED)
map.Insert(Toolkit::ImageVisual::Property::FITTING_MODE, mFittingMode);
map.Insert(Toolkit::ImageVisual::Property::SAMPLING_MODE, mSamplingMode);
- map.Insert(Toolkit::ImageVisual::Property::PIXEL_AREA, mPixelArea);
+ if(mImpl->mRenderer && mPixelAreaIndex != Property::INVALID_INDEX)
+ {
+ // Update values from Renderer
+ Vector4 pixelArea = mImpl->mRenderer.GetProperty<Vector4>(mPixelAreaIndex);
+ map.Insert(Toolkit::ImageVisual::Property::PIXEL_AREA, pixelArea);
+ }
+ else
+ {
+ map.Insert(Toolkit::ImageVisual::Property::PIXEL_AREA, mPixelArea);
+ }
+
map.Insert(Toolkit::ImageVisual::Property::WRAP_MODE_U, mWrapModeU);
map.Insert(Toolkit::ImageVisual::Property::WRAP_MODE_V, mWrapModeV);
// Change premultiplied alpha flag after change renderer.
EnablePreMultipliedAlpha(mFastTrackLoadingTask->mPremultiplied);
+
+ if(mFastTrackLoadingTask->mLoadPlanesAvaliable)
+ {
+ if(mFastTrackLoadingTask->mPlanesLoaded)
+ {
+ // Let we use regular yuv cases.
+ mNeedYuvToRgb = true;
+ }
+ else
+ {
+ // Let we use regular image cases.
+ mNeedYuvToRgb = false;
+
+ auto textureSet = mImpl->mRenderer.GetTextures();
+ DALI_ASSERT_ALWAYS(textureSet && textureSet.GetTextureCount() > 0u && "Previous texture set must exist!");
+
+ Dali::TextureSet newTextureSet = TextureSet::New();
+ newTextureSet.SetTexture(0u, textureSet.GetTexture(0u));
+ mImpl->mRenderer.SetTextures(newTextureSet);
+ }
+
+ // We can specify what kind of shader we need to use now. Update shader.
+ mNeedUnifiedYuvAndRgb = false;
+ UpdateShader();
+ }
}
else
{
- resourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
- mLoadState = TextureManager::LoadState::LOAD_FAILED;
+ resourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
+ mLoadState = TextureManager::LoadState::LOAD_FAILED;
// Change renderer as broken.
ShowBrokenImage();
void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureInformation)
{
Toolkit::Visual::ResourceStatus resourceStatus;
+ if(DALI_UNLIKELY(mImpl == nullptr))
+ {
+ DALI_LOG_ERROR("Fatal error!! already destroyed object callback called! ImageVisual : %p, url : %s\n", this, mImageUrl.GetUrl().c_str());
+ return;
+ }
if(mImpl->mRenderer)
{
if(textureInformation.useAtlasing)
{
Shader shader;
- bool usesWholeTexture = true;
const bool useStandardShader = !mImpl->mCustomShader;
const bool useNativeImage = (mTextures && DevelTexture::IsNative(mTextures.GetTexture(0)));
// Create and cache the standard shader
shader = mImageVisualShaderFactory.GetShader(
mFactoryCache,
- ImageVisualShaderFeature::FeatureBuilder()
+ ImageVisualShaderFeatureBuilder()
.EnableTextureAtlas(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED && !useNativeImage)
.ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE)
.EnableRoundedCorner(IsRoundedCornerRequired())
.EnableBorderline(IsBorderlineRequired())
.SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture())
.EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering)
- .EnableYuvToRgb(mNeedYuvToRgb));
+ .EnableYuvToRgb(mNeedYuvToRgb, mNeedUnifiedYuvAndRgb));
}
else
{
+ bool usesWholeTexture = true;
std::string_view vertexShaderView;
std::string_view fragmentShaderView;
{
shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints);
}
+
+ if(usesWholeTexture)
+ {
+ shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
+ }
}
- if(usesWholeTexture)
+ return shader;
+}
+
+Dali::Property ImageVisual::OnGetPropertyObject(Dali::Property::Key key)
+{
+ if((key.type == Property::Key::INDEX && key.indexKey == Toolkit::ImageVisual::Property::PIXEL_AREA) || (key.type == Property::Key::STRING && key.stringKey == PIXEL_AREA_UNIFORM_NAME))
{
- shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
+ if(DALI_LIKELY(mImpl->mRenderer))
+ {
+ if(mPixelAreaIndex == Property::INVALID_INDEX)
+ {
+ mPixelAreaIndex = mImpl->mRenderer.RegisterProperty(mPixelAreaIndex, PIXEL_AREA_UNIFORM_NAME, mPixelArea);
+ }
+ return Dali::Property(mImpl->mRenderer, mPixelAreaIndex);
+ }
}
- return shader;
+ Handle handle;
+ return Dali::Property(handle, Property::INVALID_INDEX);
}
void ImageVisual::CheckMaskTexture()