From e6757fc2f8c05d6da32f329a874b0ae129abf3d4 Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Wed, 3 Aug 2016 14:14:45 +0100 Subject: [PATCH] Wrap Mode support for ImageVisual Change-Id: Ie21e985867a800438e066fc78c98d640bbd76977 --- .../src/dali-toolkit/utc-Dali-Visual.cpp | 27 +++ .../src/dali-toolkit/utc-Dali-VisualFactory.cpp | 183 +++++++++++++++++- .../internal/visuals/image/batch-image-visual.cpp | 7 +- .../internal/visuals/image/batch-image-visual.h | 4 +- .../internal/visuals/image/image-visual.cpp | 211 ++++++++++++++++----- dali-toolkit/internal/visuals/image/image-visual.h | 27 +-- .../internal/visuals/npatch/npatch-visual.cpp | 2 +- dali-toolkit/internal/visuals/svg/svg-visual.cpp | 12 +- dali-toolkit/internal/visuals/svg/svg-visual.h | 4 +- .../internal/visuals/visual-base-data-impl.h | 5 +- .../internal/visuals/visual-factory-cache.cpp | 23 +++ .../internal/visuals/visual-factory-cache.h | 18 ++ .../internal/visuals/visual-factory-impl.cpp | 49 +---- .../internal/visuals/visual-factory-impl.h | 14 -- .../public-api/visuals/image-visual-properties.h | 34 +++- 15 files changed, 471 insertions(+), 149 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index ef9dab8..f3667bc 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -512,6 +512,9 @@ int UtcDaliVisualGetPropertyMap5(void) propertyMap.Insert( ImageVisual::Property::DESIRED_HEIGHT, 30 ); propertyMap.Insert( ImageVisual::Property::FITTING_MODE, FittingMode::FIT_HEIGHT ); propertyMap.Insert( ImageVisual::Property::SAMPLING_MODE, SamplingMode::BOX_THEN_NEAREST ); + propertyMap.Insert( ImageVisual::Property::PIXEL_AREA, Vector4( 0.25f, 0.25f, 0.5f, 0.5f ) ); + propertyMap.Insert( ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT ); + propertyMap.Insert( ImageVisual::Property::WRAP_MODE_V, WrapMode::MIRRORED_REPEAT ); propertyMap.Insert( "synchronousLoading", true ); Visual::Base imageVisual = factory.CreateVisual(propertyMap); @@ -545,6 +548,18 @@ int UtcDaliVisualGetPropertyMap5(void) DALI_TEST_CHECK( value ); DALI_TEST_CHECK( value->Get() == 30 ); + value = resultMap.Find( ImageVisual::Property::PIXEL_AREA, Property::VECTOR4 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), Vector4( 0.25f, 0.25f, 0.5f, 0.5f ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( ImageVisual::Property::WRAP_MODE_U, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == WrapMode::REPEAT); + + value = resultMap.Find( ImageVisual::Property::WRAP_MODE_V, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == WrapMode::MIRRORED_REPEAT); + value = resultMap.Find( "synchronousLoading", Property::BOOLEAN ); DALI_TEST_CHECK( value ); DALI_TEST_CHECK( value->Get() == true ); @@ -578,6 +593,18 @@ int UtcDaliVisualGetPropertyMap5(void) DALI_TEST_CHECK( value ); DALI_TEST_CHECK( value->Get() == 200 ); + value = resultMap.Find( ImageVisual::Property::PIXEL_AREA, Property::VECTOR4 ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get(), Vector4( 0.f, 0.f, 1.f, 1.f ), Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + value = resultMap.Find( ImageVisual::Property::WRAP_MODE_U, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == WrapMode::DEFAULT); + + value = resultMap.Find( ImageVisual::Property::WRAP_MODE_V, Property::INTEGER ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get() == WrapMode::DEFAULT); + value = resultMap.Find( "synchronousLoading", Property::BOOLEAN ); DALI_TEST_CHECK( value ); DALI_TEST_CHECK( value->Get() == false ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp index 53eee06..79b2f69 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -33,13 +34,17 @@ typedef NinePatchImage::StretchRanges StretchRanges; const char* TEST_IMAGE_FILE_NAME = "gallery_image_01.jpg"; const char* TEST_NPATCH_FILE_NAME = "gallery_image_01.9.png"; - const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg"; const char* TEST_OBJ_FILE_NAME = TEST_RESOURCE_DIR "/Cube.obj"; const char* TEST_MTL_FILE_NAME = TEST_RESOURCE_DIR "/ToyRobot-Metal.mtl"; const char* TEST_SIMPLE_OBJ_FILE_NAME = TEST_RESOURCE_DIR "/Cube-Points-Only.obj"; const char* TEST_SIMPLE_MTL_FILE_NAME = TEST_RESOURCE_DIR "/ToyRobot-Metal-Simple.mtl"; +// resolution: 34*34, pixel format: RGBA8888 +static const char* gImage_34_RGBA = TEST_RESOURCE_DIR "/icon-edit.png"; +// resolution: 600*600, pixel format: RGB888 +static const char* gImage_600_RGB = TEST_RESOURCE_DIR "/test-image-600.jpg"; + Integration::Bitmap* CreateBitmap( unsigned int imageWidth, unsigned int imageHeight, unsigned int initialColor, Pixel::Format pixelFormat ) { Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_RETAIN ); @@ -251,7 +256,7 @@ int UtcDaliVisualFactoryGet(void) VisualFactory newFactory = VisualFactory::Get(); DALI_TEST_CHECK( newFactory ); - // Check that renderer factory is a singleton + // Check that visual factory is a singleton DALI_TEST_CHECK(factory == newFactory); END_TEST; @@ -572,7 +577,7 @@ int UtcDaliVisualFactoryDefaultOffsetsGradientVisual(void) int UtcDaliVisualFactoryGetImageVisual1(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliVisualFactoryGetImageVisual1: Request image renderer with a Property::Map" ); + tet_infoline( "UtcDaliVisualFactoryGetImageVisual1: Request image visual with a Property::Map" ); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK( factory ); @@ -612,7 +617,7 @@ int UtcDaliVisualFactoryGetImageVisual1(void) int UtcDaliVisualFactoryGetImageVisual2(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliVisualFactoryGetImageVisual2: Request image renderer with an image handle" ); + tet_infoline( "UtcDaliVisualFactoryGetImageVisual2: Request image visual with an image handle" ); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK( factory ); @@ -643,10 +648,170 @@ int UtcDaliVisualFactoryGetImageVisual2(void) END_TEST; } +int UtcDaliVisualFactoryGetImageVisual3(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualFactoryGetImageVisual3: Request image visual with a Property::Map, test custom wrap mode and pixel area with atlasing" ); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + // Test wrap mode with atlasing. Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + const int width=34; + const int height=34; + const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f); + + Property::Map propertyMap; + propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE ); + propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA ); + propertyMap.Insert( ImageVisual::Property::DESIRED_WIDTH, width ); + propertyMap.Insert( ImageVisual::Property::DESIRED_HEIGHT, height ); + propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true ); + propertyMap.Insert( ImageVisual::Property::PIXEL_AREA, pixelArea ); + propertyMap.Insert( ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT ); + propertyMap.Insert( ImageVisual::Property::WRAP_MODE_V, WrapMode::REPEAT ); + + Visual::Base visual = factory.CreateVisual( propertyMap ); + DALI_TEST_CHECK( visual ); + + Actor actor = Actor::New(); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); + texParameterTrace.Enable( true ); + + actor.SetSize( 200.f, 200.f ); + Stage::GetCurrent().Add( actor ); + visual.SetOnStage( actor ); + + // loading started + application.SendNotification(); + application.Render(); + application.Render(); + application.SendNotification(); + BitmapLoader loader = BitmapLoader::GetLatestCreated(); + DALI_TEST_CHECK( loader ); + loader.WaitForLoading();// waiting until the image to be loaded + DALI_TEST_CHECK( loader.IsLoaded() ); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION ); + + // WITH atlasing, the wrapping is handled manually in shader, so the following gl function should not be called + std::stringstream out; + out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT; + DALI_TEST_CHECK( !texParameterTrace.FindMethodAndParams("TexParameteri", out.str()) ); + out.str(""); + out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_REPEAT; + DALI_TEST_CHECK( !texParameterTrace.FindMethodAndParams("TexParameteri", out.str()) ); + + // test the uniforms which used to handle the wrap mode + Renderer renderer = actor.GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + + Property::Value pixelAreaValue = renderer.GetProperty( renderer.GetPropertyIndex( "pixelArea" ) ); + DALI_TEST_EQUALS( pixelAreaValue.Get(), pixelArea, TEST_LOCATION ); + Vector4 pixelAreaUniform; + DALI_TEST_CHECK( gl.GetUniformValue( "pixelArea", pixelAreaUniform ) ); + DALI_TEST_EQUALS( pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + Property::Value wrapModeValue = renderer.GetProperty( renderer.GetPropertyIndex( "wrapMode" ) ); + Vector2 wrapMode( WrapMode::MIRRORED_REPEAT-1, WrapMode::REPEAT-1 ); + DALI_TEST_EQUALS( wrapModeValue.Get(), wrapMode, TEST_LOCATION ); + Vector2 wrapModeUniform; + DALI_TEST_CHECK( gl.GetUniformValue( "wrapMode", wrapModeUniform ) ); + DALI_TEST_EQUALS( wrapMode, wrapModeUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + visual.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + + END_TEST; +} + +int UtcDaliVisualFactoryGetImageVisual4(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliVisualFactoryGetImageVisual4: Request image visual with a Property::Map, test custom wrap mode and pixel area without atlasing" ); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + // Test wrap mode without atlasing. Image with a size bigger than 512*512 will NOT be uploaded as a part of the atlas. + const int width=600; + const int height=600; + const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f); + + Property::Map propertyMap; + propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE ); + propertyMap.Insert( ImageVisual::Property::URL, gImage_600_RGB ); + propertyMap.Insert( ImageVisual::Property::DESIRED_WIDTH, width ); + propertyMap.Insert( ImageVisual::Property::DESIRED_HEIGHT, height ); + propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true ); + propertyMap.Insert( ImageVisual::Property::PIXEL_AREA, pixelArea ); + propertyMap.Insert( ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT ); + propertyMap.Insert( ImageVisual::Property::WRAP_MODE_V, WrapMode::REPEAT ); + + Visual::Base visual = factory.CreateVisual( propertyMap ); + DALI_TEST_CHECK( visual ); + + Actor actor = Actor::New(); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); + texParameterTrace.Enable( true ); + + actor.SetSize( 200.f, 200.f ); + Stage::GetCurrent().Add( actor ); + visual.SetOnStage( actor ); + + // loading started + application.SendNotification(); + application.Render(); + application.Render(); + application.SendNotification(); + BitmapLoader loader = BitmapLoader::GetLatestCreated(); + DALI_TEST_CHECK( loader ); + loader.WaitForLoading();// waiting until the image to be loaded + DALI_TEST_CHECK( loader.IsLoaded() ); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + + DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION ); + + // WITHOUT atlasing, the wrapping is handled by setting gl texture parameters + std::stringstream out; + out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT; + DALI_TEST_CHECK( texParameterTrace.FindMethodAndParams("TexParameteri", out.str()) ); + out.str(""); + out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_REPEAT; + DALI_TEST_CHECK( texParameterTrace.FindMethodAndParams("TexParameteri", out.str()) ); + + // test the uniforms which used to handle the wrap mode + Renderer renderer = actor.GetRendererAt( 0u ); + DALI_TEST_CHECK( renderer ); + + Property::Value pixelAreaValue = renderer.GetProperty( renderer.GetPropertyIndex( "pixelArea" ) ); + DALI_TEST_EQUALS( pixelAreaValue.Get(), pixelArea, TEST_LOCATION ); + Vector4 pixelAreaUniform; + DALI_TEST_CHECK( gl.GetUniformValue( "pixelArea", pixelAreaUniform ) ); + DALI_TEST_EQUALS( pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + Property::Index wrapModeIndex = renderer.GetPropertyIndex( "wrapMode" ); + DALI_TEST_CHECK(wrapModeIndex == Property::INVALID_INDEX); + + visual.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + + END_TEST; +} + int UtcDaliVisualFactoryGetNPatchVisual1(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch renderer with a Property::Map" ); + tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map" ); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK( factory ); @@ -705,7 +870,7 @@ int UtcDaliVisualFactoryGetNPatchVisual1(void) int UtcDaliVisualFactoryGetNPatchVisual2(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual2: Request n-patch renderer with a Property::Map" ); + tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual2: Request n-patch visual with a Property::Map" ); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK( factory ); @@ -773,7 +938,7 @@ int UtcDaliVisualFactoryGetNPatchVisual2(void) int UtcDaliVisualFactoryGetNPatchVisual3(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual3: Request 9-patch renderer with an image url" ); + tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual3: Request 9-patch visual with an image url" ); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK( factory ); @@ -971,7 +1136,7 @@ int UtcDaliVisualFactoryGetSvgVisual(void) END_TEST; } -//Creates a mesh renderer from the given propertyMap and tries to load it on stage in the given application. +//Creates a mesh visual from the given propertyMap and tries to load it on stage in the given application. //This is expected to succeed, which will then pass the test. void MeshVisualLoadsCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplication& application ) { @@ -1514,7 +1679,7 @@ int UtcDaliVisualFactoryGetPrimitiveVisual8(void) END_TEST; } -//Test if primitive shape renderer handles the case of not being passed a specific shape to use. +//Test if primitive shape visual handles the case of not being passed a specific shape to use. int UtcDaliVisualFactoryGetPrimitiveVisualN1(void) { //Set up test application first, so everything else can be handled. diff --git a/dali-toolkit/internal/visuals/image/batch-image-visual.cpp b/dali-toolkit/internal/visuals/image/batch-image-visual.cpp index 12bfdad..5e24418 100644 --- a/dali-toolkit/internal/visuals/image/batch-image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/batch-image-visual.cpp @@ -88,9 +88,8 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( } //unnamed namespace -BatchImageVisual::BatchImageVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ) +BatchImageVisual::BatchImageVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ), - mAtlasManager( atlasManager ), mDesiredSize() { } @@ -191,7 +190,7 @@ void BatchImageVisual::InitializeRenderer( const std::string& imageUrl ) { if( !mImpl->mRenderer ) { - TextureSet textureSet = mAtlasManager.Add( + TextureSet textureSet = mFactoryCache.GetAtlasManager()->Add( mAtlasRect, imageUrl, mDesiredSize ); @@ -281,7 +280,7 @@ void BatchImageVisual::CleanCache(const std::string& url) mImpl->mRenderer.Reset(); if( mFactoryCache.CleanRendererCache( url ) ) { - mAtlasManager.Remove( textureSet, mAtlasRect ); + mFactoryCache.GetAtlasManager()->Remove( textureSet, mAtlasRect ); } } diff --git a/dali-toolkit/internal/visuals/image/batch-image-visual.h b/dali-toolkit/internal/visuals/image/batch-image-visual.h index 750e28f..71f85f9 100644 --- a/dali-toolkit/internal/visuals/image/batch-image-visual.h +++ b/dali-toolkit/internal/visuals/image/batch-image-visual.h @@ -40,9 +40,8 @@ public: * @brief Constructor. * * @param[in] factoryCache The VisualFactoryCache object - * @param[in] atlasManager The atlasManager object */ - BatchImageVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ); + BatchImageVisual( VisualFactoryCache& factoryCache ); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -110,7 +109,6 @@ private: private: - ImageAtlasManager& mAtlasManager; Vector4 mAtlasRect; std::string mImageUrl; Dali::ImageDimensions mDesiredSize; diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index e430c7b..6d980f6 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -57,6 +57,8 @@ const char * const IMAGE_FITTING_MODE( "fittingMode" ); const char * const IMAGE_SAMPLING_MODE( "samplingMode" ); const char * const IMAGE_DESIRED_WIDTH( "desiredWidth" ); const char * const IMAGE_DESIRED_HEIGHT( "desiredHeight" ); +const char * const IMAGE_WRAP_MODE_U("wrapModeU"); +const char * const IMAGE_WRAP_MODE_V("wrapModeV"); const char * const SYNCHRONOUS_LOADING( "synchronousLoading" ); const char * const BATCHING_ENABLED( "batchingEnabled" ); @@ -80,7 +82,16 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, NO_FILTER ) DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::SamplingMode, DONT_CARE ) DALI_ENUM_TO_STRING_TABLE_END( SAMPLING_MODE ) +// wrap modes +DALI_ENUM_TO_STRING_TABLE_BEGIN( WRAP_MODE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, DEFAULT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, CLAMP_TO_EDGE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, REPEAT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, MIRRORED_REPEAT ) +DALI_ENUM_TO_STRING_TABLE_END( WRAP_MODE ) + const std::string PIXEL_AREA_UNIFORM_NAME = "pixelArea"; +const std::string WRAP_MODE_UNIFORM_NAME = "wrapMode"; const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); @@ -90,7 +101,6 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n uniform mediump mat4 uMvpMatrix;\n uniform mediump vec3 uSize;\n - uniform mediump vec4 uAtlasRect;\n uniform mediump vec4 pixelArea; varying mediump vec2 vTexCoord;\n \n @@ -100,12 +110,12 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( vertexPosition.xyz *= uSize;\n vertexPosition = uMvpMatrix * vertexPosition;\n \n - vTexCoord = mix( uAtlasRect.xy, uAtlasRect.zw, pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) ) );\n + vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n gl_Position = vertexPosition;\n }\n ); -const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( +const char* FRAGMENT_SHADER_NO_ATLAS = DALI_COMPOSE_SHADER( varying mediump vec2 vTexCoord;\n uniform sampler2D sTexture;\n uniform lowp vec4 uColor;\n @@ -116,6 +126,42 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( }\n ); +const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + uniform lowp vec4 uColor;\n + \n + void main()\n + {\n + mediump vec2 texCoord = mix( uAtlasRect.xy, uAtlasRect.zw, clamp( vTexCoord, 0.0, 1.0 ) );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor;\n + }\n +); + +const char* FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + // WrapMode -- 0: CLAMP; 1: REPEAT; 2: REFLECT; + uniform lowp vec2 wrapMode;\n + uniform lowp vec4 uColor;\n + \n + mediump float wrapCoordinate( mediump float coordinate, lowp float wrap )\n + {\n + if( abs(wrap-2.0) < 0.5 )\n // REFLECT + return 1.0-abs(fract(coordinate*0.5)*2.0 - 1.0);\n + else \n// warp == 0 or 1 + return mix( clamp( coordinate, 0.0, 1.0 ), fract( coordinate ), wrap);\n + }\n + void main()\n + {\n + mediump vec2 texCoord = mix( uAtlasRect.xy, uAtlasRect.zw, + vec2( wrapCoordinate( vTexCoord.x, wrapMode.x ), wrapCoordinate( vTexCoord.y, wrapMode.y ) ) );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor;\n + }\n +); + Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridSize ) { Geometry geometry; @@ -139,12 +185,14 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS } //unnamed namespace -ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ) +ImageVisual::ImageVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ), - mAtlasManager( atlasManager ), + mPixelArea( FULL_TEXTURE_RECT ), mDesiredSize(), mFittingMode( FittingMode::DEFAULT ), mSamplingMode( SamplingMode::DEFAULT ), + mWrapModeU( WrapMode::DEFAULT ), + mWrapModeV( WrapMode::DEFAULT ), mNativeFragmentShaderCode( ), mNativeImageFlag( false ) { @@ -193,6 +241,24 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) desiredHeightValue->Get( desiredHeight ); } + Property::Value* pixelAreaValue = propertyMap.Find( Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME ); + if( pixelAreaValue ) + { + pixelAreaValue->Get( mPixelArea ); + } + + Property::Value* wrapModeValueU = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_U, IMAGE_WRAP_MODE_U ); + if( wrapModeValueU ) + { + Scripting::GetEnumerationProperty( *wrapModeValueU, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeU ); + } + + Property::Value* wrapModeValueV = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_V, IMAGE_WRAP_MODE_V ); + if( wrapModeValueV ) + { + Scripting::GetEnumerationProperty( *wrapModeValueV, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeV ); + } + mDesiredSize = ImageDimensions( desiredWidth, desiredHeight ); } @@ -245,11 +311,6 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) } } -void ImageVisual::SetSize( const Vector2& size ) -{ - Visual::Base::SetSize( size ); -} - void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const { if(mImage) @@ -275,15 +336,6 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const naturalSize = Vector2::ZERO; } -void ImageVisual::SetClipRect( const Rect& clipRect ) -{ - Visual::Base::SetClipRect( clipRect ); -} - -void ImageVisual::SetOffset( const Vector2& offset ) -{ -} - Renderer ImageVisual::CreateRenderer() const { Geometry geometry; @@ -300,23 +352,24 @@ Renderer ImageVisual::CreateRenderer() const { geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - shader = GetImageShader(mFactoryCache); + shader = GetImageShader( mFactoryCache, + mImpl->mFlags & Impl::IS_ATLASING_APPLIED, + mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE ); } else { geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() ) { - shader = GetImageShader(mFactoryCache); + shader = GetImageShader(mFactoryCache, false, true); } else { shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader, - mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER : mImpl->mCustomShader->mFragmentShader, + mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER_NO_ATLAS : 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 ); } } @@ -337,7 +390,6 @@ Renderer ImageVisual::CreateNativeImageRenderer() const geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); shader = Shader::New( VERTEX_SHADER, mNativeFragmentShaderCode ); - shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } else @@ -348,7 +400,6 @@ Renderer ImageVisual::CreateNativeImageRenderer() const 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 ); } } @@ -356,7 +407,6 @@ Renderer ImageVisual::CreateNativeImageRenderer() const TextureSet textureSet = TextureSet::New(); Renderer renderer = Renderer::New( geometry, shader ); renderer.SetTextures( textureSet ); - return renderer; } @@ -383,7 +433,7 @@ Image ImageVisual::LoadImage( const std::string& url, bool synchronousLoading ) if( !mPixels ) { // use broken image - return VisualFactory::GetBrokenVisualImage(); + return VisualFactoryCache::GetBrokenVisualImage(); } Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() ); image.Upload( mPixels, 0, 0 ); @@ -407,13 +457,15 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin { // use broken image textureSet = TextureSet::New(); - TextureSetImage( textureSet, 0u, VisualFactory::GetBrokenVisualImage() ); + TextureSetImage( textureSet, 0u, VisualFactoryCache::GetBrokenVisualImage() ); } else { - textureSet = mAtlasManager.Add(textureRect, mPixels ); + textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels ); + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; if( !textureSet ) // big image, no atlasing { + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() ); image.Upload( mPixels, 0, 0 ); textureSet = TextureSet::New(); @@ -423,9 +475,11 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin } else { - textureSet = mAtlasManager.Add(textureRect, url, mDesiredSize, mFittingMode, mSamplingMode ); + textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, mSamplingMode ); + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; if( !textureSet ) // big image, no atlasing { + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode ); resourceImage.LoadingFinishedSignal().Connect( this, &ImageVisual::OnImageLoaded ); textureSet = TextureSet::New(); @@ -433,6 +487,13 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin } } + if( !(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) ) + { + Sampler sampler = Sampler::New(); + sampler.SetWrapMode( mWrapModeU, mWrapModeV ); + textureSet.SetSampler( 0u, sampler ); + } + return textureSet; } @@ -450,28 +511,46 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl ) ( strncasecmp( imageUrl.c_str(), HTTP_URL, sizeof(HTTP_URL) -1 ) != 0 ) && // ignore remote images ( strncasecmp( imageUrl.c_str(), HTTPS_URL, sizeof(HTTPS_URL) -1 ) != 0 ) ) { - mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl ); - if( !mImpl->mRenderer ) + bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; + bool cacheable = defaultWrapMode && mPixelArea == FULL_TEXTURE_RECT; + + mImpl->mFlags &= ~Impl::IS_FROM_CACHE; + if( cacheable ) // fetch the renderer from cache if exist + { + mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl ); + mImpl->mFlags |= Impl::IS_FROM_CACHE; + } + + if( !mImpl->mRenderer ) // new renderer is needed { Vector4 atlasRect; TextureSet textureSet = CreateTextureSet(atlasRect, imageUrl, IsSynchronousResourceLoading() ); Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - Shader shader( GetImageShader(mFactoryCache) ); + Shader shader( GetImageShader(mFactoryCache, mImpl->mFlags & Impl::IS_ATLASING_APPLIED, defaultWrapMode) ); mImpl->mRenderer = Renderer::New( geometry, shader ); mImpl->mRenderer.SetTextures( textureSet ); - if( atlasRect != FULL_TEXTURE_RECT ) + + if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas { mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); + if( !defaultWrapMode ) // custom wrap mode, renderer is not cached. + { + Vector2 wrapMode(mWrapModeU-WrapMode::CLAMP_TO_EDGE, mWrapModeV-WrapMode::CLAMP_TO_EDGE); + wrapMode.Clamp( Vector2::ZERO, Vector2( 2.f, 2.f ) ); + mImpl->mRenderer.RegisterProperty( WRAP_MODE_UNIFORM_NAME, wrapMode ); + } } - mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer ); - } - mImpl->mFlags |= Impl::IS_FROM_CACHE; + // save the renderer to cache only when default wrap mode and default pixel area is used + if( cacheable ) + { + mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer ); + } + } } else { // for custom shader or remote image, renderer is not cached and atlas is not applied - mImpl->mFlags &= ~Impl::IS_FROM_CACHE; mImpl->mRenderer = CreateRenderer(); Image image = LoadImage( imageUrl, IsSynchronousResourceLoading() ); @@ -501,6 +580,11 @@ void ImageVisual::DoSetOnStage( Actor& actor ) { InitializeRenderer( mImage ); } + + if( mPixelArea != FULL_TEXTURE_RECT ) + { + mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea ); + } } void ImageVisual::DoSetOffStage( Actor& actor ) @@ -546,18 +630,46 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::ImageVisual::Property::FITTING_MODE, mFittingMode ); map.Insert( Toolkit::ImageVisual::Property::SAMPLING_MODE, mSamplingMode ); + + 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 ); } -Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache ) +Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ) { - Shader shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER ); - if( !shader ) + Shader shader; + if( atlasing ) { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader ); - shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + if( defaultTextureWrapping ) + { + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader ); + } + } + else + { + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP, shader ); + } + } + } + else + { + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader ); + } } + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); return shader; } @@ -697,6 +809,9 @@ void ImageVisual::ApplyImageToSampler( const Image& image ) mImpl->mRenderer.SetTextures( textureSet ); } TextureSetImage( textureSet, 0u, image ); + Sampler sampler = Sampler::New(); + sampler.SetWrapMode( mWrapModeU, mWrapModeV ); + textureSet.SetSampler( 0u, sampler ); } } @@ -704,7 +819,7 @@ void ImageVisual::OnImageLoaded( ResourceImage image ) { if( image.GetLoadingState() == Dali::ResourceLoadingFailed ) { - Image brokenImage = VisualFactory::GetBrokenVisualImage(); + Image brokenImage = VisualFactoryCache::GetBrokenVisualImage(); if( mImpl->mRenderer ) { ApplyImageToSampler( brokenImage ); @@ -727,7 +842,7 @@ void ImageVisual::CleanCache(const std::string& url) mImpl->mRenderer.Reset(); if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX ) { - mAtlasManager.Remove( textureSet, atlasRect ); + mFactoryCache.GetAtlasManager()->Remove( textureSet, atlasRect ); } } @@ -748,7 +863,7 @@ void ImageVisual::SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage ) } else { - mNativeFragmentShaderCode += FRAGMENT_SHADER; + mNativeFragmentShaderCode += FRAGMENT_SHADER_NO_ATLAS; } if( customSamplerTypename ) diff --git a/dali-toolkit/internal/visuals/image/image-visual.h b/dali-toolkit/internal/visuals/image/image-visual.h index baad92f..64b3f4b 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@ -20,7 +20,6 @@ // INTERNAL INCLUDES #include -#include // EXTERNAL INCLUDES #include @@ -81,9 +80,8 @@ public: * @brief Constructor. * * @param[in] factoryCache The VisualFactoryCache object - * @param[in] atlasManager The atlasManager object */ - ImageVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ); + ImageVisual( VisualFactoryCache& factoryCache ); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -93,26 +91,11 @@ public: public: // from Visual /** - * @copydoc Visual::SetSize - */ - virtual void SetSize( const Vector2& size ); - - /** * @copydoc Visual::GetNaturalSize */ virtual void GetNaturalSize( Vector2& naturalSize ) const; /** - * @copydoc Visual::SetClipRect - */ - virtual void SetClipRect( const Rect& clipRect ); - - /** - * @copydoc Visual::SetOffset - */ - virtual void SetOffset( const Vector2& offset ); - - /** * @copydoc Visual::CreatePropertyMap */ virtual void DoCreatePropertyMap( Property::Map& map ) const; @@ -138,8 +121,10 @@ public: /** * Get the standard image rendering shader. * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] atlasing Whether texture atlasing is applied. + * @param[in] defaultTextureWrapping Whether the default texture wrap mode is applied. */ - static Shader GetImageShader( VisualFactoryCache& factoryCache ); + static Shader GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ); /** * @brief Sets the image of this visual to the resource at imageUrl @@ -252,13 +237,15 @@ private: private: Image mImage; - ImageAtlasManager& mAtlasManager; PixelData mPixels; + Vector4 mPixelArea; std::string mImageUrl; Dali::ImageDimensions mDesiredSize; Dali::FittingMode::Type mFittingMode; Dali::SamplingMode::Type mSamplingMode; + Dali::WrapMode::Type mWrapModeU; + Dali::WrapMode::Type mWrapModeV; std::string mNativeFragmentShaderCode; bool mNativeImageFlag; diff --git a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp index fb13383..7ef3a6e 100644 --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp @@ -522,7 +522,7 @@ void NPatchVisual::InitializeFromImage( NinePatchImage nPatch ) void NPatchVisual::InitializeFromBrokenImage() { - mCroppedImage = VisualFactory::GetBrokenVisualImage(); + mCroppedImage = VisualFactoryCache::GetBrokenVisualImage(); mImageSize = ImageDimensions( mCroppedImage.GetWidth(), mCroppedImage.GetHeight() ); mStretchPixelsX.Clear(); diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index f73df9f..4179d4d 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -52,10 +53,9 @@ namespace Toolkit namespace Internal { -SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ) +SvgVisual::SvgVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ), mAtlasRect( FULL_TEXTURE_RECT ), - mAtlasManager( atlasManager ), mParsedImage( NULL ) { // the rasterized image is with pre-multiplied alpha format @@ -94,7 +94,7 @@ void SvgVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap ) void SvgVisual::DoSetOnStage( Actor& actor ) { - Shader shader = ImageVisual::GetImageShader( mFactoryCache ); + Shader shader = ImageVisual::GetImageShader( mFactoryCache, true, true ); Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); if( !geometry ) { @@ -198,11 +198,11 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData ) TextureSet currentTextureSet = mImpl->mRenderer.GetTextures(); if( mAtlasRect != FULL_TEXTURE_RECT ) { - mAtlasManager.Remove( currentTextureSet, mAtlasRect ); + mFactoryCache.GetAtlasManager()->Remove( currentTextureSet, mAtlasRect ); } Vector4 atlasRect; - TextureSet textureSet = mAtlasManager.Add(atlasRect, rasterizedPixelData ); + TextureSet textureSet = mFactoryCache.GetAtlasManager()->Add(atlasRect, rasterizedPixelData ); if( textureSet ) // atlasing { if( textureSet != currentTextureSet ) @@ -211,11 +211,13 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData ) } mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); mAtlasRect = atlasRect; + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; } else // no atlasing { Atlas texture = Atlas::New( rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight() ); texture.Upload( rasterizedPixelData, 0, 0 ); + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; if( mAtlasRect == FULL_TEXTURE_RECT ) { diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.h b/dali-toolkit/internal/visuals/svg/svg-visual.h index e4e97da..d841621 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.h +++ b/dali-toolkit/internal/visuals/svg/svg-visual.h @@ -20,7 +20,6 @@ // INTERNAL INCLUDES #include -#include struct NSVGimage; @@ -52,7 +51,7 @@ public: * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object */ - SvgVisual( VisualFactoryCache& factoryCache, ImageAtlasManager& atlasManager ); + SvgVisual( VisualFactoryCache& factoryCache ); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -136,7 +135,6 @@ private: private: Vector4 mAtlasRect; - ImageAtlasManager& mAtlasManager; std::string mImageUrl; NSVGimage* mParsedImage; diff --git a/dali-toolkit/internal/visuals/visual-base-data-impl.h b/dali-toolkit/internal/visuals/visual-base-data-impl.h index 3ffdafb..fb8ae32 100644 --- a/dali-toolkit/internal/visuals/visual-base-data-impl.h +++ b/dali-toolkit/internal/visuals/visual-base-data-impl.h @@ -43,8 +43,9 @@ struct Base::Impl { IS_ON_STAGE = 1, IS_FROM_CACHE = 1 << 1, - IS_PREMULTIPLIED_ALPHA = 1 << 2, - IS_SYNCHRONOUS_RESOURCE_LOADING = 1 << 3 + IS_ATLASING_APPLIED = 1<<2, + IS_PREMULTIPLIED_ALPHA = 1 << 3, + IS_SYNCHRONOUS_RESOURCE_LOADING = 1 << 4 }; struct CustomShader diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.cpp b/dali-toolkit/internal/visuals/visual-factory-cache.cpp index 404f2ec..da86201 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-cache.cpp @@ -19,10 +19,17 @@ // EXTERNAL HEADER #include +#include // INTERNAL HEADER #include #include +#include + +namespace +{ +const char * const BROKEN_VISUAL_IMAGE_URL( DALI_IMAGE_DIR "broken.png"); +} namespace Dali { @@ -179,6 +186,17 @@ Geometry VisualFactoryCache::CreateQuadGeometry() return geometry; } +ImageAtlasManagerPtr VisualFactoryCache::GetAtlasManager() +{ + if( !mAtlasManager ) + { + mAtlasManager = new ImageAtlasManager(); + mAtlasManager->SetBrokenImage( BROKEN_VISUAL_IMAGE_URL ); + } + + return mAtlasManager; +} + SvgRasterizeThread* VisualFactoryCache::GetSVGRasterizationThread() { if( !mSvgRasterizeThread ) @@ -309,6 +327,11 @@ Geometry VisualFactoryCache::CreateBatchQuadGeometry( Vector4 texCoords ) return geometry; } +Image VisualFactoryCache::GetBrokenVisualImage() +{ + return ResourceImage::New( BROKEN_VISUAL_IMAGE_URL ); +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index 2c2210a..6f67a66 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -39,6 +39,9 @@ namespace Toolkit namespace Internal { +class ImageAtlasManager; +typedef IntrusivePtr ImageAtlasManagerPtr; + /** * Caches shaders and geometries. Owned by VisualFactory. */ @@ -60,6 +63,8 @@ public: GRADIENT_SHADER_RADIAL_BOUNDING_BOX, IMAGE_SHADER, BATCH_IMAGE_SHADER, + IMAGE_SHADER_ATLAS_DEFAULT_WRAP, + IMAGE_SHADER_ATLAS_CUSTOM_WRAP, NINE_PATCH_SHADER, SVG_SHADER, SHADER_TYPE_MAX = SVG_SHADER @@ -130,6 +135,12 @@ public: */ static Geometry CreateBatchQuadGeometry( Vector4 texCoords ); + /** + * @brief Returns an image to be used when a visual has failed to correctly render + * @return The broken image handle. + */ + static Image GetBrokenVisualImage(); + public: /** @@ -170,6 +181,12 @@ public: Renderer GetDebugRenderer(); /** + * Get the image atlas manager. + * @return A pointer pointing to the atlas manager + */ + ImageAtlasManagerPtr GetAtlasManager(); + + /** * Get the SVG rasterization thread. * @return A pointer pointing to the SVG rasterization thread. */ @@ -230,6 +247,7 @@ private: Renderer mDebugRenderer; + ImageAtlasManagerPtr mAtlasManager; SvgRasterizeThread* mSvgRasterizeThread; }; diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.cpp b/dali-toolkit/internal/visuals/visual-factory-impl.cpp index df9cbb3..80f4420 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@ -40,14 +40,8 @@ #include #include #include -#include #include -namespace -{ -const char * const BROKEN_VISUAL_IMAGE_URL( DALI_IMAGE_DIR "broken.png"); -} - namespace Dali { @@ -149,8 +143,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property batchingEnabledValue->Get( batchingEnabled ); if( batchingEnabled ) { - CreateAtlasManager(); - visualPtr = new BatchImageVisual( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) ); + visualPtr = new BatchImageVisual( *( mFactoryCache.Get() ) ); break; } } @@ -158,20 +151,16 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property { visualPtr = new NPatchVisual( *( mFactoryCache.Get() ) ); } + else if( SvgVisual::IsSvgUrl( imageUrl ) ) + { + visualPtr = new SvgVisual( *( mFactoryCache.Get() ) ); + } else { - CreateAtlasManager(); - - if( SvgVisual::IsSvgUrl( imageUrl ) ) - { - visualPtr = new SvgVisual( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) ); - } - else - { - visualPtr = new ImageVisual( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) ); - } + visualPtr = new ImageVisual( *( mFactoryCache.Get() ) ); } } + break; } @@ -230,8 +219,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Image& image ) } else { - CreateAtlasManager(); - ImageVisual* visualPtr = new ImageVisual( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) ); + ImageVisual* visualPtr = new ImageVisual( *( mFactoryCache.Get() ) ); Actor actor; visualPtr->SetImage( actor, image ); @@ -260,15 +248,13 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, Image } else if( SvgVisual::IsSvgUrl( url ) ) { - CreateAtlasManager(); - SvgVisual* visualPtr = new SvgVisual( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) ); + SvgVisual* visualPtr = new SvgVisual( *( mFactoryCache.Get() ) ); visualPtr->SetImage( url, size ); return Toolkit::Visual::Base( visualPtr ); } else { - CreateAtlasManager(); - ImageVisual* visualPtr = new ImageVisual( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) ); + ImageVisual* visualPtr = new ImageVisual( *( mFactoryCache.Get() )); Actor actor; visualPtr->SetImage( actor, url, size ); @@ -276,21 +262,6 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, Image } } -Image VisualFactory::GetBrokenVisualImage() -{ - return ResourceImage::New( BROKEN_VISUAL_IMAGE_URL ); -} - -void VisualFactory::CreateAtlasManager() -{ - if( !mAtlasManager ) - { - Shader shader = ImageVisual::GetImageShader( *( mFactoryCache.Get() ) ); - mAtlasManager = new ImageAtlasManager(); - mAtlasManager->SetBrokenImage( BROKEN_VISUAL_IMAGE_URL ); - } -} - } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.h b/dali-toolkit/internal/visuals/visual-factory-impl.h index f6e8d9c..484a688 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.h +++ b/dali-toolkit/internal/visuals/visual-factory-impl.h @@ -36,9 +36,6 @@ namespace Internal class VisualFactoryCache; typedef IntrusivePtr VisualFactoryCachePtr; -class ImageAtlasManager; -typedef IntrusivePtr ImageAtlasManagerPtr; - /** * @copydoc Toolkit::VisualFactory */ @@ -68,11 +65,6 @@ public: */ Toolkit::Visual::Base CreateVisual( const std::string& image, ImageDimensions size ); -public: - /** - * @brief Returns an image to be used when a visual has failed to correctly render - */ - static Image GetBrokenVisualImage(); protected: @@ -84,11 +76,6 @@ protected: private: /** - * Prepare the atlas manager - */ - void CreateAtlasManager(); - - /** * Undefined copy constructor. */ VisualFactory(const VisualFactory&); @@ -101,7 +88,6 @@ private: private: VisualFactoryCachePtr mFactoryCache; - ImageAtlasManagerPtr mAtlasManager; bool mDebugEnabled; }; diff --git a/dali-toolkit/public-api/visuals/image-visual-properties.h b/dali-toolkit/public-api/visuals/image-visual-properties.h index 7d46ac7..882f932 100644 --- a/dali-toolkit/public-api/visuals/image-visual-properties.h +++ b/dali-toolkit/public-api/visuals/image-visual-properties.h @@ -103,9 +103,41 @@ enum * @brief This enables Image visuals to automatically be converted to Batch-Image visuals. * @details Name "batchingEnabled", type Property::BOOLEAN. * @SINCE_1_2.0 - * @note Optional. For Image visuals only. Not to be used with NPatch or SVG images. + * @note Optional. If not specified, the default is false. + * @note For Image visuals only. Not to be used with NPatch or SVG images. */ BATCHING_ENABLED, + + /** + * @brief The image area to be displayed. + * @details Name "pixelArea", type Property::VECTOR4. + * It is a rectangular area. + * The first two elements indicate the top-left position of the area, and the last two elements are the area width and height respectively. + * @SINCE_1_2.1 + * @note Optional. If not specified, the default value is [0.0, 0.0, 1.0, 1.0], i.e. the entire area of the image. + * @note For Normal Quad images only. + */ + PIXEL_AREA, + + /** + * @brief The wrap mode for u coordinate. + * @details Name "wrapModeU", type Dali::WrapMode::Type (Property::INTEGER) or Property::STRING + * It decides how the texture should be sampled when the u coordinate exceeds the range of 0.0 to 1.0. + * @SINCE_1_2.1 + * @note Optional. If not specified, the default is CLAMP. + * @note For Normal QUAD image only. + */ + WRAP_MODE_U, + + /** + * @brief The wrap mode for v coordinate. + * @details Name "wrapModeV", type Dali::WrapMode::Type (Property::INTEGER) or Property::STRING + * it decides how the texture should be sampled when the v coordinate exceeds the range of 0.0 to 1.0. + * @SINCE_1_2.1 + * @note Optional. If not specified, the default is CLAMP. + * @note For Normal QUAD image only. + */ + WRAP_MODE_V, }; } // namespace Property -- 2.7.4