X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fimage%2Fimage-visual.cpp;h=b558cfde60a0ae5ad99125a952a6692f925d9169;hb=ab5c560f8956e7b795b7cc2072d06a61aef103b7;hp=27c91e2d8eba7463acddc800b1b8a32cd40b3dc3;hpb=95bc87993608242c8eaff49551ae85b4b78c4de7;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 27c91e2..b558cfd 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 @@ -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,10 +466,54 @@ 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); + } +} + void ImageVisual::GetNaturalSize( Vector2& naturalSize ) { if(mImage) @@ -468,11 +528,34 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) naturalSize.y = mDesiredSize.GetHeight(); return; } + + else 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() && mImageUrl.GetLocation() == VisualUrl::LOCAL ) { ImageDimensions dimensions = Dali::GetClosestImageSize( mImageUrl.GetUrl() ); - naturalSize.x = dimensions.GetWidth(); - naturalSize.y = dimensions.GetHeight(); + + 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; } @@ -511,7 +594,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 +674,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 +729,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 ); @@ -704,7 +807,6 @@ void ImageVisual::InitializeRenderer( const Image& image ) // don't reuse CreateTextureSet TextureSet textures = TextureSet::New(); - // Renderer can't be shared if mImage is NativeImage NativeImage nativeImage = NativeImage::DownCast( image ); if( nativeImage ) { @@ -809,6 +911,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 @@ -905,7 +1013,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 ) @@ -926,6 +1034,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 @@ -962,6 +1074,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