From 62e7c0f3e8795fc597fbaa1a76abd42fb837e536 Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Tue, 12 Jan 2016 15:23:12 +0000 Subject: [PATCH] PixelArea support for ImageView Change-Id: Ie9caace6fe18146d120f11665237fc4bec661aec --- .../src/dali-toolkit/utc-Dali-ImageView.cpp | 38 ++++++++++++ .../controls/image-view/image-view-impl.cpp | 14 +++-- .../internal/controls/image-view/image-view-impl.h | 12 +--- .../controls/renderers/image/image-renderer.cpp | 69 +++++++++------------- .../controls/renderers/image/image-renderer.h | 2 - .../public-api/controls/image-view/image-view.h | 9 ++- 6 files changed, 84 insertions(+), 60 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 2feeee2..b00e79f 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -246,6 +246,44 @@ int UtcDaliImageViewSetGetProperty01(void) END_TEST; } +int UtcDaliImageViewSetGetProperty02(void) +{ + ToolkitTestApplication application; + + Image image = CreateBufferImage( 10, 10, Color::WHITE ); + ImageView imageView = ImageView::New(image); + Vector4 fullImageRect( 0.f, 0.f, 1.f, 1.f ); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + TestGlAbstraction& gl = application.GetGlAbstraction(); + + Vector4 pixelAreaUniform; + DALI_TEST_CHECK( gl.GetUniformValue( "pixelArea", pixelAreaUniform ) ); + DALI_TEST_EQUALS( pixelAreaUniform, fullImageRect, TEST_LOCATION ); + + Property::Value value = imageView.GetProperty( ImageView::Property::PIXEL_AREA ); + Vector4 pixelAreaValue; + DALI_TEST_CHECK( value.Get(pixelAreaValue) ); + DALI_TEST_EQUALS( pixelAreaValue, fullImageRect, TEST_LOCATION ); + + Vector4 pixelAreaSet( 0.2f, 0.2f, 0.3f, 0.3f ); + imageView.SetProperty( ImageView::Property::PIXEL_AREA, pixelAreaSet); + + application.SendNotification(); + application.Render(); + + value = imageView.GetProperty( ImageView::Property::PIXEL_AREA ); + value.Get(pixelAreaValue); + DALI_TEST_EQUALS( pixelAreaValue, pixelAreaSet, TEST_LOCATION ); + + DALI_TEST_CHECK( gl.GetUniformValue( "pixelArea", pixelAreaUniform ) ); + DALI_TEST_EQUALS( pixelAreaUniform, pixelAreaSet, TEST_LOCATION ); + + END_TEST; +} int UtcDaliImageViewSizeWithBackground(void) { ToolkitTestApplication application; diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp index e98f539..aaab3b6 100644 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp @@ -35,6 +35,8 @@ BaseHandle Create() DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ImageView, Toolkit::Control, Create ); DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "resourceUrl", STRING, RESOURCE_URL ) DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "image", MAP, IMAGE ) + +DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, ImageView, "pixelArea", Vector4(0.f, 0.f, 1.f, 1.f), PIXEL_AREA ) DALI_TYPE_REGISTRATION_END() } // anonymous namespace @@ -145,7 +147,10 @@ void ImageView::SetImage( const std::string& url, ImageDimensions size ) void ImageView::SetDepthIndex( int depthIndex ) { - mRenderer.SetDepthIndex( depthIndex ); + if( mRenderer ) + { + mRenderer.SetDepthIndex( depthIndex ); + } } Vector3 ImageView::GetNaturalSize() @@ -154,10 +159,10 @@ Vector3 ImageView::GetNaturalSize() size.x = mImageSize.GetWidth(); size.y = mImageSize.GetHeight(); - size.z = std::min(size.x, size.y); if( size.x > 0 && size.y > 0 ) { + size.z = std::min(size.x, size.y); return size; } else @@ -191,6 +196,7 @@ float ImageView::GetWidthForHeight( float height ) } } + /////////////////////////////////////////////////////////// // // Private methods @@ -218,7 +224,6 @@ void ImageView::OnStageDisconnection() Control::OnStageDisconnection(); } - /////////////////////////////////////////////////////////// // // Properties @@ -273,11 +278,11 @@ Property::Value ImageView::GetProperty( BaseObject* object, Property::Index prop if ( imageview ) { + ImageView& impl = GetImpl( imageview ); switch ( propertyIndex ) { case Toolkit::ImageView::Property::RESOURCE_URL: { - ImageView& impl = GetImpl( imageview ); if ( !impl.mUrl.empty() ) { value = impl.mUrl; @@ -287,7 +292,6 @@ Property::Value ImageView::GetProperty( BaseObject* object, Property::Index prop case Toolkit::ImageView::Property::IMAGE: { - ImageView& impl = GetImpl( imageview ); if ( !impl.mUrl.empty() ) { value = impl.mUrl; diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.h b/dali-toolkit/internal/controls/image-view/image-view-impl.h index 86437ff..19d75ac 100644 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.h +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.h @@ -38,7 +38,7 @@ namespace Internal { class ImageView : public Control { - protected: +protected: /** * Construct a new ImageView. @@ -50,8 +50,6 @@ class ImageView : public Control */ virtual ~ImageView(); - - public: /** * Create a new ImageView. @@ -131,14 +129,6 @@ private: // From Control virtual float GetWidthForHeight( float height ); private: - /** - * Attaches mImage member to the renderer, creating the renderers, samplers, meshes and materials if needed - * - * @pre mImage has been initialised - */ - void AttachImage(); - -private: // Undefined ImageView( const ImageView& ); ImageView& operator=( const ImageView& ); diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp index da77f95..8b13a4e 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp @@ -71,15 +71,17 @@ const char * const NO_FILTER("noFilter"); const char * const DONT_CARE("dontCare"); const std::string TEXTURE_UNIFORM_NAME = "sTexture"; -const std::string TEXTURE_RECT_UNIFORM_NAME = "uTextureRect"; +const std::string ATLAS_RECT_UNIFORM_NAME = "uAtlasRect"; +const std::string PIXEL_AREA_UNIFORM_NAME = "pixelArea"; const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n - varying mediump vec2 vTexCoord;\n uniform mediump mat4 uMvpMatrix;\n uniform mediump vec3 uSize;\n - uniform mediump vec4 uTextureRect;\n + uniform mediump vec4 uAtlasRect;\n + uniform mediump vec4 pixelArea; + varying mediump vec2 vTexCoord;\n \n void main()\n {\n @@ -87,7 +89,7 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( vertexPosition.xyz *= uSize;\n vertexPosition = uMvpMatrix * vertexPosition;\n \n - vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5));\n + vTexCoord = mix( uAtlasRect.xy, uAtlasRect.zw, pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) ) );\n gl_Position = vertexPosition;\n }\n ); @@ -197,7 +199,6 @@ Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gri ImageRenderer::ImageRenderer( RendererFactoryCache& factoryCache, ImageAtlasManager& atlasManager ) : ControlRenderer( factoryCache ), mAtlasManager( atlasManager ), - mTextureRect( FULL_TEXTURE_RECT ), mDesiredSize(), mFittingMode( FittingMode::DEFAULT ), mSamplingMode( SamplingMode::DEFAULT ) @@ -397,6 +398,11 @@ Renderer ImageRenderer::CreateRenderer() const shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader, mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER : mImpl->mCustomShader->mFragmentShader, mImpl->mCustomShader->mHints ); + if( mImpl->mCustomShader->mVertexShader.empty() ) + { + shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + } } } @@ -421,20 +427,19 @@ void ImageRenderer::InitializeRenderer( const std::string& imageUrl ) mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl ); if( !mImpl->mRenderer ) { - Material material = mAtlasManager.Add(mTextureRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode ); + Vector4 atlasRect; + Material material = mAtlasManager.Add(atlasRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode ); if( material ) { Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); mImpl->mRenderer = Renderer::New( geometry, material ); - SetTextureRectUniform(mTextureRect); + mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); } else // big image, atlasing is not applied { mImpl->mRenderer = CreateRenderer(); - mTextureRect = FULL_TEXTURE_RECT; - SetTextureRectUniform(mTextureRect); - ResourceImage image = Dali::ResourceImage::New( imageUrl ); + ResourceImage image = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode ); image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded ); Material material = mImpl->mRenderer.GetMaterial(); material.AddTexture( image, TEXTURE_UNIFORM_NAME ); @@ -442,11 +447,7 @@ void ImageRenderer::InitializeRenderer( const std::string& imageUrl ) mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer ); } - else - { - Property::Value textureRect = mImpl->mRenderer.GetProperty( mImpl->mRenderer.GetPropertyIndex(TEXTURE_RECT_UNIFORM_NAME) ); - textureRect.Get( mTextureRect ); - } + mImpl->mFlags |= Impl::IS_FROM_CACHE; } else @@ -458,15 +459,6 @@ void ImageRenderer::InitializeRenderer( const std::string& imageUrl ) ResourceImage resourceImage = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode ); resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded ); ApplyImageToSampler( resourceImage ); - - // custom vertex shader does not need texture rect uniform - if( mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty() ) - { - return; - } - - mTextureRect = FULL_TEXTURE_RECT; - SetTextureRectUniform( mTextureRect ); } } @@ -480,13 +472,6 @@ void ImageRenderer::InitializeRenderer( const Image& image ) { ApplyImageToSampler( image ); } - - // default shader or custom shader with the default image vertex shader - if( !mImpl->mCustomShader || mImpl->mCustomShader->mVertexShader.empty() ) - { - mTextureRect = FULL_TEXTURE_RECT; - SetTextureRectUniform( mTextureRect ); - } } @@ -622,6 +607,8 @@ Shader ImageRenderer::GetImageShader( RendererFactoryCache& factoryCache ) { shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, shader ); + shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } return shader; } @@ -740,22 +727,22 @@ void ImageRenderer::OnImageLoaded( ResourceImage image ) } } -void ImageRenderer::SetTextureRectUniform( const Vector4& textureRect ) +void ImageRenderer::CleanCache(const std::string& url) { - if( mImpl->mRenderer ) + Material material = mImpl->mRenderer.GetMaterial(); + + Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f ); + Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME ); + if( index != Property::INVALID_INDEX ) { - // Register/Set property. - mImpl->mRenderer.RegisterProperty( TEXTURE_RECT_UNIFORM_NAME, textureRect ); + Property::Value atlasRectValue = mImpl->mRenderer.GetProperty( index ); + atlasRectValue.Get( atlasRect ); } -} -void ImageRenderer::CleanCache(const std::string& url) -{ - Material material = mImpl->mRenderer.GetMaterial(); mImpl->mRenderer.Reset(); - if( mFactoryCache.CleanRendererCache( url ) ) + if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX ) { - mAtlasManager.Remove( material, mTextureRect ); + mAtlasManager.Remove( material, atlasRect ); } } diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.h b/dali-toolkit/internal/controls/renderers/image/image-renderer.h index c11c6b0..2a8af0f 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.h +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.h @@ -212,13 +212,11 @@ private: private: Image mImage; ImageAtlasManager& mAtlasManager; - Vector4 mTextureRect; std::string mImageUrl; Dali::ImageDimensions mDesiredSize; Dali::FittingMode::Type mFittingMode; Dali::SamplingMode::Type mSamplingMode; - }; } // namespace Internal diff --git a/dali-toolkit/public-api/controls/image-view/image-view.h b/dali-toolkit/public-api/controls/image-view/image-view.h index efbc884..b5f7db7 100644 --- a/dali-toolkit/public-api/controls/image-view/image-view.h +++ b/dali-toolkit/public-api/controls/image-view/image-view.h @@ -52,7 +52,10 @@ public: enum PropertyRange { PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1, - PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices + PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, ///< Reserve property indices + + ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, ///< @since DALi 1.1.18 + ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000 ///< Reserve animatable property indices, @since DALi 1.1.18 }; /** @@ -62,8 +65,12 @@ public: { enum { + // Event side properties RESOURCE_URL = PROPERTY_START_INDEX, ///< name "resourceUrl", @deprecated DALi 1.1.16 Use IMAGE instead. type string IMAGE, ///< name "image", @see SetImage(), type string if it is a url, map otherwise + + // Animatable properties + PIXEL_AREA = ANIMATABLE_PROPERTY_START_INDEX, ///< name "pixelArea", @since DALi 1.1.18 type Vector4, Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0]. }; }; -- 2.7.4