X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fimage%2Fimage-visual.cpp;h=ee0042ab3a535939ecfe6545c9c95c315e11491a;hp=f589f41e1ff3ecbb7bb47051b890133b8e26717e;hb=58ae307297125b55c93c38a631a8745c6a7c51f1;hpb=77a90be65b5182ddc69a30f29e3b1b609241ade4 diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index f589f41..ee0042a 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -21,10 +21,10 @@ // EXTERNAL HEADERS #include // for strlen() #include +#include #include #include #include -#include #include #include #include @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -62,6 +62,7 @@ const char * const IMAGE_DESIRED_WIDTH( "desiredWidth" ); const char * const IMAGE_DESIRED_HEIGHT( "desiredHeight" ); const char * const SYNCHRONOUS_LOADING( "synchronousLoading" ); const char * const IMAGE_ATLASING("atlasing"); +const char * const ALPHA_MASK_URL("alphaMaskUrl"); // fitting modes DALI_ENUM_TO_STRING_TABLE_BEGIN( FITTING_MODE ) @@ -261,6 +262,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, mPixelArea( FULL_TEXTURE_RECT ), mPlacementActor(), mImageUrl( imageUrl ), + mMaskingData( NULL ), mDesiredSize( size ), mTextureId( TextureManager::INVALID_TEXTURE_ID ), mFittingMode( fittingMode ), @@ -279,6 +281,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image ) mPixelArea( FULL_TEXTURE_RECT ), mPlacementActor(), mImageUrl(), + mMaskingData( NULL ), mDesiredSize(), mTextureId( TextureManager::INVALID_TEXTURE_ID ), mFittingMode( FittingMode::DEFAULT ), @@ -292,6 +295,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image ) ImageVisual::~ImageVisual() { + delete mMaskingData; } void ImageVisual::DoSetProperties( const Property::Map& propertyMap ) @@ -342,6 +346,18 @@ void ImageVisual::DoSetProperties( const Property::Map& propertyMap ) { DoSetProperty( Toolkit::DevelImageVisual::Property::ATLASING, keyValue.second ); } + else if ( keyValue.first == ALPHA_MASK_URL ) + { + DoSetProperty( Toolkit::DevelImageVisual::Property::ALPHA_MASK_URL, keyValue.second ); + } + else if ( keyValue.first == MASK_CONTENT_SCALE_NAME ) + { + DoSetProperty( Toolkit::DevelImageVisual::Property::MASK_CONTENT_SCALE, keyValue.second ); + } + else if ( keyValue.first == CROP_TO_MASK_NAME ) + { + DoSetProperty( Toolkit::DevelImageVisual::Property::CROP_TO_MASK, keyValue.second ); + } } } @@ -450,7 +466,51 @@ void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& v { bool atlasing = false; mAttemptAtlasing = value.Get( atlasing ); + break; + } + + case Toolkit::DevelImageVisual::Property::ALPHA_MASK_URL: + { + std::string alphaUrl; + if( value.Get( alphaUrl ) ) + { + AllocateMaskData(); + // Immediately trigger the alpha mask loading (it may just get a cached value) + mMaskingData->SetImage( alphaUrl ); + } + break; + } + + case Toolkit::DevelImageVisual::Property::MASK_CONTENT_SCALE: + { + float scale; + if( value.Get( scale ) ) + { + AllocateMaskData(); + mMaskingData->mContentScaleFactor = scale; + } + break; } + + case Toolkit::DevelImageVisual::Property::CROP_TO_MASK: + { + bool crop=false; + if( value.Get( crop ) ) + { + AllocateMaskData(); + mMaskingData->mCropToMask = crop; + } + break; + } + } +} + +void ImageVisual::AllocateMaskData() +{ + if( mMaskingData == NULL ) + { + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + mMaskingData = new MaskingData(textureManager); } } @@ -468,13 +528,51 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) naturalSize.y = mDesiredSize.GetHeight(); return; } - else if( mImageUrl.IsValid() && mImageUrl.GetLocation() == VisualUrl::LOCAL ) + else if( mImpl->mRenderer ) // Check if we have a loaded image { - ImageDimensions dimensions = Dali::GetClosestImageSize( mImageUrl.GetUrl() ); - naturalSize.x = dimensions.GetWidth(); - naturalSize.y = dimensions.GetHeight(); + auto textureSet = mImpl->mRenderer.GetTextures(); + + if( textureSet ) + { + auto texture = textureSet.GetTexture(0); + naturalSize.x = texture.GetWidth(); + naturalSize.y = texture.GetHeight(); + return; + } + } + + if( mMaskingData != NULL && mMaskingData->mAlphaMaskUrl.IsValid() && + mMaskingData->mCropToMask ) + { + ImageDimensions dimensions = Dali::GetClosestImageSize( mMaskingData->mAlphaMaskUrl.GetUrl() ); + if( dimensions != ImageDimensions( 0, 0 ) ) + { + naturalSize.x = dimensions.GetWidth(); + naturalSize.y = dimensions.GetHeight(); + } return; } + else if( mImageUrl.IsValid() ) + { + if( mImageUrl.GetProtocolType() == VisualUrl::LOCAL ) + { + ImageDimensions dimensions = Dali::GetClosestImageSize( mImageUrl.GetUrl() ); + + if( dimensions != ImageDimensions( 0, 0 ) ) + { + naturalSize.x = dimensions.GetWidth(); + naturalSize.y = dimensions.GetHeight(); + } + else + { + Image brokenImage = VisualFactoryCache::GetBrokenVisualImage(); + + naturalSize.x = brokenImage.GetWidth(); + naturalSize.y = brokenImage.GetWidth(); + } + return; + } + } naturalSize = Vector2::ZERO; } @@ -511,7 +609,10 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet ) } } - shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_ON ); // Set default to align + // Set pixel align off as default. + // ToDo: Pixel align causes issues such as rattling image animation. + // We should trun it off until issues are resolved + shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF ); mImpl->mRenderer = Renderer::New( geometry, shader ); if( textureSet ) @@ -588,9 +689,12 @@ void ImageVisual::LoadResourceSynchronously() { if( mImageUrl.IsValid() ) { - BitmapLoader loader = BitmapLoader::New( mImageUrl.GetUrl(), mDesiredSize, mFittingMode, mSamplingMode ); - loader.Load(); - mPixels = loader.GetPixelData(); + Devel::PixelBuffer pixelBuffer = LoadImageFromFile( mImageUrl.GetUrl(), mDesiredSize, mFittingMode, mSamplingMode ); + + if( pixelBuffer ) + { + mPixels = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer + } mTextureLoading = false; } } @@ -640,8 +744,22 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, bool synchronous { mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; TextureManager& textureManager = mFactoryCache.GetTextureManager(); - mTextureId = textureManager.RequestLoad( mImageUrl, mDesiredSize, mFittingMode, - mSamplingMode, TextureManager::NO_ATLAS, this ); + if( mMaskingData == NULL ) + { + mTextureId = textureManager.RequestLoad( mImageUrl, mDesiredSize, mFittingMode, + mSamplingMode, TextureManager::NO_ATLAS, this ); + } + else + { + mTextureId = textureManager.RequestLoad( mImageUrl, + mMaskingData->mAlphaMaskId, + mMaskingData->mContentScaleFactor, + mDesiredSize, + mFittingMode, mSamplingMode, + TextureManager::NO_ATLAS, + mMaskingData->mCropToMask, + this ); + } TextureManager::LoadState loadState = textureManager.GetTextureState( mTextureId ); @@ -669,7 +787,7 @@ void ImageVisual::InitializeRenderer() { mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; - if( ! mImpl->mCustomShader && mImageUrl.GetLocation() == VisualUrl::LOCAL ) + if( ! mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL ) { bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; @@ -808,6 +926,12 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::ImageVisual::Property::WRAP_MODE_V, mWrapModeV ); map.Insert( Toolkit::DevelImageVisual::Property::ATLASING, mAttemptAtlasing ); + if( mMaskingData != NULL ) + { + map.Insert( Toolkit::DevelImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl() ); + map.Insert( Toolkit::DevelImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor ); + map.Insert( Toolkit::DevelImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask ); + } } void ImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const @@ -904,7 +1028,7 @@ void ImageVisual::UploadCompleted() } // From Texture Manager -void ImageVisual::UploadComplete( bool loadingSuccess, TextureSet textureSet, bool usingAtlas, const Vector4& atlasRectangle ) +void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, TextureSet textureSet, bool usingAtlas, const Vector4& atlasRectangle ) { Actor actor = mPlacementActor.GetHandle(); if( actor ) @@ -925,6 +1049,10 @@ void ImageVisual::UploadComplete( bool loadingSuccess, TextureSet textureSet, bo else { Image brokenImage = VisualFactoryCache::GetBrokenVisualImage(); + + textureSet = TextureSet::New(); + mImpl->mRenderer.SetTextures( textureSet ); + ApplyImageToSampler( brokenImage ); } // Image loaded and ready to display @@ -961,6 +1089,36 @@ void ImageVisual::RemoveTexture(const std::string& url) } } + +ImageVisual::MaskingData::MaskingData( TextureManager& textureManager ) +: mTextureManager( textureManager ), + mAlphaMaskUrl(), + mAlphaMaskId( TextureManager::INVALID_TEXTURE_ID ), + mContentScaleFactor( 1.0f ), + mCropToMask( true ) +{ +} + +ImageVisual::MaskingData::~MaskingData() +{ + if( Stage::IsInstalled() ) + { + // TextureManager could have been deleted before the actor that contains this + // ImageVisual is destroyed (e.g. due to stage shutdown). Ensure the stage + // is still valid before accessing texture manager. + if( mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID ) + { + mTextureManager.Remove( mAlphaMaskId ); + } + } +} + +void ImageVisual::MaskingData::SetImage( const std::string& maskUrl ) +{ + mAlphaMaskUrl = maskUrl; + mAlphaMaskId = mTextureManager.RequestMaskLoad( mAlphaMaskUrl ); +} + } // namespace Internal } // namespace Toolkit