From b1d3acc2fd5e456d7a65a962e6fa4e1d2b71cdaf Mon Sep 17 00:00:00 2001 From: Chu Hoang Date: Tue, 22 Sep 2015 14:21:17 +0100 Subject: [PATCH] Implemented n-patch rendering for NPatchRenderer. Change-Id: Ic7304dc47483cc228dce9e715be9bc0bb46a081e --- .../src/dali-toolkit/utc-Dali-RendererFactory.cpp | 390 +++++++++++---------- .../controls/renderers/npatch/npatch-renderer.cpp | 125 ++++++- .../controls/renderers/npatch/npatch-renderer.h | 2 - 3 files changed, 310 insertions(+), 207 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp index a570b72..391bc74 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp @@ -27,6 +27,8 @@ using namespace Dali::Toolkit; namespace { +typedef NinePatchImage::StretchRanges StretchRanges; + const char* TEST_IMAGE_FILE_NAME = "gallery_image_01.jpg"; const char* TEST_NPATCH_FILE_NAME = "gallery_image_01.9.jpg"; @@ -63,27 +65,38 @@ void InitialiseRegionsToZeroAlpha( Integration::Bitmap* image, unsigned int imag } } -void AddStretchRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const Vector4& requiredStretchBorder, Pixel::Format pixelFormat ) +void AddStretchRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const StretchRanges& stretchRangesX, const StretchRanges& stretchRangesY, Pixel::Format pixelFormat ) { PixelBuffer* pixbuffer = image->GetBuffer(); unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat ); - for( unsigned int column = requiredStretchBorder.x; column < imageWidth - requiredStretchBorder.z; ++column ) + for(StretchRanges::ConstIterator it = stretchRangesX.Begin(); it != stretchRangesX.End(); ++it) { - unsigned int pixelOffset = column * bytesPerPixel; - pixbuffer[ pixelOffset ] = 0x00; - pixbuffer[ pixelOffset + 1 ] = 0x00; - pixbuffer[ pixelOffset + 2 ] = 0x00; - pixbuffer[ pixelOffset + 3 ] = 0xFF; + const Uint16Pair& range = *it; + //since the stretch range is in the cropped image space, we need to offset by 1 to get it to the uncropped image space + for( unsigned int column = range.GetX() + 1u; column < range.GetY() + 1u; ++column ) + { + unsigned int pixelOffset = column * bytesPerPixel; + pixbuffer[ pixelOffset ] = 0x00; + pixbuffer[ pixelOffset + 1 ] = 0x00; + pixbuffer[ pixelOffset + 2 ] = 0x00; + pixbuffer[ pixelOffset + 3 ] = 0xFF; + } } - for( unsigned int row = requiredStretchBorder.y; row < imageHeight - requiredStretchBorder.w; ++row ) + + for(StretchRanges::ConstIterator it = stretchRangesY.Begin(); it != stretchRangesY.End(); ++it) { - unsigned int pixelOffset = row * imageWidth * bytesPerPixel; - pixbuffer[ pixelOffset ] = 0x00; - pixbuffer[ pixelOffset + 1 ] = 0x00; - pixbuffer[ pixelOffset + 2 ] = 0x00; - pixbuffer[ pixelOffset + 3 ] = 0xFF; + const Uint16Pair& range = *it; + //since the stretch range is in the cropped image space, we need to offset by 1 to get it to the uncropped image space + for( unsigned int row = range.GetX() + 1u; row < range.GetY() + 1u; ++row ) + { + unsigned int pixelOffset = row * imageWidth * bytesPerPixel; + pixbuffer[ pixelOffset ] = 0x00; + pixbuffer[ pixelOffset + 1 ] = 0x00; + pixbuffer[ pixelOffset + 2 ] = 0x00; + pixbuffer[ pixelOffset + 3 ] = 0xFF; + } } } @@ -120,7 +133,8 @@ void AddChildRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth Integration::ResourcePointer CustomizeNinePatch( TestApplication& application, unsigned int ninePatchImageWidth, unsigned int ninePatchImageHeight, - const Vector4& requiredStretchBorder, + const StretchRanges& stretchRangesX, + const StretchRanges& stretchRangesY, bool addChildRegion = false, Vector4 requiredChildRegion = Vector4::ZERO ) { @@ -136,7 +150,7 @@ Integration::ResourcePointer CustomizeNinePatch( TestApplication& application, InitialiseRegionsToZeroAlpha( bitmap, ninePatchImageWidth, ninePatchImageHeight, pixelFormat ); tet_infoline("Add Stretch regions to Bitmap"); - AddStretchRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder, pixelFormat ); + AddStretchRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY, pixelFormat ); if( addChildRegion ) { @@ -151,6 +165,40 @@ Integration::ResourcePointer CustomizeNinePatch( TestApplication& application, return resourcePtr; } +void TestControlRendererRender( ToolkitTestApplication& application, Actor& actor, ControlRenderer& controlRenderer, Integration::ResourcePointer resourcePtr = Integration::ResourcePointer(), std::size_t expectedSamplers = 0) +{ + actor.SetSize( 200.f, 200.f ); + Stage::GetCurrent().Add( actor ); + controlRenderer.SetSize( Vector2(200.f, 200.f) ); + controlRenderer.SetOnStage( actor ); + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == expectedSamplers ); + + application.SendNotification(); + application.Render(); + + if( resourcePtr ) + { + Integration::ResourceRequest* request = application.GetPlatform().GetRequest(); + if(request) + { + application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, resourcePtr ); + } + } + + application.Render(); + application.SendNotification(); + + if( resourcePtr ) + { + DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc)); + } + + DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + +} + } // namespace @@ -234,19 +282,10 @@ int UtcDaliRendererFactoryGetColorRenderer1(void) DALI_TEST_CHECK( controlRenderer ); Actor actor = Actor::New(); - actor.SetSize(200.f, 200.f); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize(Vector2(200.f, 200.f)); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - - TestGlAbstraction& gl = application.GetGlAbstraction(); - - application.SendNotification(); - application.Render(0); + TestControlRendererRender( application, actor, controlRenderer ); Vector4 actualValue(Vector4::ZERO); + TestGlAbstraction& gl = application.GetGlAbstraction(); DALI_TEST_CHECK( gl.GetUniformValue( "uBlendColor", actualValue ) ); DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION ); @@ -266,19 +305,10 @@ int UtcDaliRendererFactoryGetColorRenderer2(void) DALI_TEST_CHECK( controlRenderer ); Actor actor = Actor::New(); - actor.SetSize(200.f, 200.f); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize(Vector2(200.f, 200.f)); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - - TestGlAbstraction& gl = application.GetGlAbstraction(); - - application.SendNotification(); - application.Render(0); + TestControlRendererRender( application, actor, controlRenderer ); Vector4 actualValue(Vector4::ZERO); + TestGlAbstraction& gl = application.GetGlAbstraction(); DALI_TEST_CHECK( gl.GetUniformValue( "uBlendColor", actualValue ) ); DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION ); @@ -402,20 +432,9 @@ int UtcDaliRendererFactoryGetLinearGradientRenderer(void) ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap); DALI_TEST_CHECK( controlRenderer ); - Actor actor = Actor::New(); - Vector2 size(200.f, 200.f); - actor.SetSize(size); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetOnStage( actor ); - controlRenderer.SetSize(size); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - // A lookup texture is generated and pass to shader as sampler - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); - - application.SendNotification(); - application.Render(0); + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u ); controlRenderer.SetOffStage( actor ); DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); @@ -453,26 +472,15 @@ int UtcDaliRendererFactoryGetRadialGradientRenderer(void) ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap); DALI_TEST_CHECK( controlRenderer ); - Actor actor = Actor::New(); - Vector2 size(200.f, 200.f); - actor.SetSize(size); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize(size); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - // A lookup texture is generated and pass to shader as sampler - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); - - TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(0); + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u ); Matrix3 alignMatrix( radius, 0.f, 0.f, 0.f, radius, 0.f, center.x, center.y, 1.f ); alignMatrix.Invert(); Matrix3 actualValue( Matrix3::IDENTITY ); + TestGlAbstraction& gl = application.GetGlAbstraction(); DALI_TEST_CHECK( gl.GetUniformValue( "uAlignmentMatrix", actualValue ) ); DALI_TEST_EQUALS( actualValue, alignMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION ); @@ -495,31 +503,9 @@ int UtcDaliRendererFactoryGetImageRenderer1(void) DALI_TEST_CHECK( controlRenderer ); Actor actor = Actor::New(); - actor.SetSize( 200.f, 200.f ); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize( Vector2(200.f, 200.f) ); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)), 1u ); TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(); - - Integration::ResourceRequest* request = application.GetPlatform().GetRequest(); - if(request) - { - application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD))); - } - - application.Render(); - application.SendNotification(); - - DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc)); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - int textureUnit = -1; DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); @@ -542,29 +528,9 @@ int UtcDaliRendererFactoryGetImageRenderer2(void) ControlRenderer controlRenderer = factory.GetControlRenderer( image ); Actor actor = Actor::New(); - actor.SetSize( 200.f, 200.f ); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize( Vector2(200.f, 200.f) ); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)), 1u ); TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(); - - Integration::ResourceRequest* request = application.GetPlatform().GetRequest(); - if(request) - { - application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD))); - } - - application.Render(); - application.SendNotification(); - - DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc)); - int textureUnit = -1; DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); @@ -575,99 +541,173 @@ int UtcDaliRendererFactoryGetImageRenderer2(void) int UtcDaliRendererFactoryGetNPatchRenderer1(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer1: Request n-patch renderer with a Property::Map" ); + tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer1: Request 9-patch renderer with a Property::Map" ); RendererFactory factory = RendererFactory::Get(); DALI_TEST_CHECK( factory ); const unsigned int ninePatchImageHeight = 18; const unsigned int ninePatchImageWidth = 28; - const Vector4 requiredStretchBorder( 3, 4, 5, 6 ); - Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder ); + StretchRanges stretchRangesX; + stretchRangesX.PushBack( Uint16Pair( 2, 3 ) ); + StretchRanges stretchRangesY; + stretchRangesY.PushBack( Uint16Pair( 4, 5 ) ); + Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY ); Property::Map propertyMap; propertyMap.Insert( "renderer-type", "n-patch-renderer" ); propertyMap.Insert( "image-url", TEST_NPATCH_FILE_NAME ); + { + tet_infoline( "whole grid" ); + ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap ); + DALI_TEST_CHECK( controlRenderer ); - ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap ); - DALI_TEST_CHECK( controlRenderer ); + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u ); - Actor actor = Actor::New(); - actor.SetSize( 200.f, 200.f ); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize( Vector2(200.f, 200.f) ); - controlRenderer.SetOnStage( actor ); + TestGlAbstraction& gl = application.GetGlAbstraction(); + int textureUnit = -1; + DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); + DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); + } - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + propertyMap.Insert( "border-only", true ); + { + tet_infoline( "border only" ); + ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap ); + DALI_TEST_CHECK( controlRenderer ); - TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(); + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u ); - Integration::ResourceRequest* request = application.GetPlatform().GetRequest(); - if(request) - { - application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, ninePatchResource ); + TestGlAbstraction& gl = application.GetGlAbstraction(); + int textureUnit = -1; + DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); + DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); } - application.Render(); - application.SendNotification(); + END_TEST; +} - DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc)); +int UtcDaliRendererFactoryGetNPatchRenderer2(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer2: Request n-patch renderer with a Property::Map" ); - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); - int textureUnit = -1; - DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); - DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); + const unsigned int ninePatchImageWidth = 18; + const unsigned int ninePatchImageHeight = 28; + StretchRanges stretchRangesX; + stretchRangesX.PushBack( Uint16Pair( 2, 3 ) ); + stretchRangesX.PushBack( Uint16Pair( 5, 7 ) ); + stretchRangesX.PushBack( Uint16Pair( 12, 15 ) ); + StretchRanges stretchRangesY; + stretchRangesY.PushBack( Uint16Pair( 4, 5 ) ); + stretchRangesY.PushBack( Uint16Pair( 8, 12 ) ); + stretchRangesY.PushBack( Uint16Pair( 15, 16 ) ); + stretchRangesY.PushBack( Uint16Pair( 25, 27 ) ); + Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY ); - controlRenderer.SetOffStage( actor ); - DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + Property::Map propertyMap; + propertyMap.Insert( "renderer-type", "n-patch-renderer" ); + propertyMap.Insert( "image-url", TEST_NPATCH_FILE_NAME ); + { + ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap ); + DALI_TEST_CHECK( controlRenderer ); + + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u ); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + int textureUnit = -1; + DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); + DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); + + controlRenderer.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + } + + propertyMap.Insert( "border-only", true ); + { + tet_infoline( "border only" ); + ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap ); + DALI_TEST_CHECK( controlRenderer ); + + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u ); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + int textureUnit = -1; + DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); + DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); + + controlRenderer.SetOffStage( actor ); + DALI_TEST_CHECK( actor.GetRendererCount() == 0u ); + } END_TEST; } -int UtcDaliRendererFactoryGetNPatchRenderer2(void) +int UtcDaliRendererFactoryGetNPatchRenderer3(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer2: Request n-patch renderer with an image url" ); + tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer3: Request 9-patch renderer with an image url" ); RendererFactory factory = RendererFactory::Get(); DALI_TEST_CHECK( factory ); const unsigned int ninePatchImageHeight = 18; const unsigned int ninePatchImageWidth = 28; - const Vector4 requiredStretchBorder( 3, 4, 5, 6 ); - Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder ); + StretchRanges stretchRangesX; + stretchRangesX.PushBack( Uint16Pair( 2, 3 ) ); + StretchRanges stretchRangesY; + stretchRangesY.PushBack( Uint16Pair( 4, 5 ) ); + Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY ); ControlRenderer controlRenderer = factory.GetControlRenderer( TEST_NPATCH_FILE_NAME ); DALI_TEST_CHECK( controlRenderer ); Actor actor = Actor::New(); - actor.SetSize( 200.f, 200.f ); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize( Vector2(200.f, 200.f) ); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u ); TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(); + int textureUnit = -1; + DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); + DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); - Integration::ResourceRequest* request = application.GetPlatform().GetRequest(); - if(request) - { - application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, ninePatchResource ); - } + END_TEST; +} - application.Render(); - application.SendNotification(); +int UtcDaliRendererFactoryGetNPatchRenderer4(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer4: Request n-patch renderer with an image url" ); + + RendererFactory factory = RendererFactory::Get(); + DALI_TEST_CHECK( factory ); + + const unsigned int ninePatchImageHeight = 18; + const unsigned int ninePatchImageWidth = 28; + StretchRanges stretchRangesX; + stretchRangesX.PushBack( Uint16Pair( 2, 3 ) ); + stretchRangesX.PushBack( Uint16Pair( 5, 7 ) ); + stretchRangesX.PushBack( Uint16Pair( 12, 15 ) ); + StretchRanges stretchRangesY; + stretchRangesY.PushBack( Uint16Pair( 4, 5 ) ); + stretchRangesY.PushBack( Uint16Pair( 8, 12 ) ); + stretchRangesY.PushBack( Uint16Pair( 15, 16 ) ); + stretchRangesY.PushBack( Uint16Pair( 25, 27 ) ); + Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY ); + + ControlRenderer controlRenderer = factory.GetControlRenderer( TEST_NPATCH_FILE_NAME ); + DALI_TEST_CHECK( controlRenderer ); - DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc)); + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u ); + TestGlAbstraction& gl = application.GetGlAbstraction(); int textureUnit = -1; DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); @@ -689,18 +729,9 @@ int UtcDaliRendererFactoryGetNPatchRendererN1(void) DALI_TEST_CHECK( controlRenderer ); Actor actor = Actor::New(); - actor.SetSize( 200.f, 200.f ); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize( Vector2(200.f, 200.f) ); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u ); TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(); - int textureUnit = -1; DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); @@ -726,18 +757,9 @@ int UtcDaliRendererFactoryGetNPatchRendererN2(void) DALI_TEST_CHECK( controlRenderer ); Actor actor = Actor::New(); - actor.SetSize( 200.f, 200.f ); - Stage::GetCurrent().Add( actor ); - controlRenderer.SetSize( Vector2(200.f, 200.f) ); - controlRenderer.SetOnStage( actor ); - - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u ); + TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u ); TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(); - int textureUnit = -1; DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) ); DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION ); @@ -750,23 +772,17 @@ int UtcDaliRendererFactoryResetRenderer1(void) ToolkitTestApplication application; tet_infoline( "UtcDaliRendererFactoryResetRenderer1" ); - Actor actor = Actor::New(); - actor.SetSize(200.f, 200.f); - Stage::GetCurrent().Add( actor ); - RendererFactory factory = RendererFactory::Get(); DALI_TEST_CHECK( factory ); ControlRenderer controlRenderer = factory.GetControlRenderer( Color::RED ); DALI_TEST_CHECK( controlRenderer ); - controlRenderer.SetSize(Vector2(200.f, 200.f)); - controlRenderer.SetOnStage( actor ); - DALI_TEST_CHECK( actor.GetRendererCount() == 1u ); - TestGlAbstraction& gl = application.GetGlAbstraction(); - application.SendNotification(); - application.Render(0); + Actor actor = Actor::New(); + TestControlRendererRender( application, actor, controlRenderer ); + Vector4 actualValue(Vector4::ZERO); + TestGlAbstraction& gl = application.GetGlAbstraction(); DALI_TEST_CHECK( gl.GetUniformValue( "uBlendColor", actualValue ) ); DALI_TEST_EQUALS( actualValue, Color::RED, TEST_LOCATION ); diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp index 63e2f5d..cd23466 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp @@ -49,6 +49,32 @@ const char * const BORDER_ONLY("border-only"); std::string TEXTURE_UNIFORM_NAME = "sTexture"; +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 vec2 uNinePatchFactorsX[ FACTOR_SIZE_X ];\n + uniform mediump vec2 uNinePatchFactorsY[ FACTOR_SIZE_Y ];\n + \n + void main()\n + {\n + mediump vec2 fixedFactor = vec2( uNinePatchFactorsX[ int( ( aPosition.x + 1.0 ) * 0.5 ) ].x, uNinePatchFactorsY[ int( ( aPosition.y + 1.0 ) * 0.5 ) ].x );\n + mediump vec2 stretch = vec2( uNinePatchFactorsX[ int( ( aPosition.x ) * 0.5 ) ].y, uNinePatchFactorsY[ int( ( aPosition.y ) * 0.5 ) ].y );\n + \n + mediump vec2 fixedTotal = vec2( uNinePatchFactorsX[ FACTOR_SIZE_X - 1 ].x, uNinePatchFactorsY[ FACTOR_SIZE_Y - 1 ].x );\n + mediump vec2 stretchTotal = vec2( uNinePatchFactorsX[ FACTOR_SIZE_X - 1 ].y, uNinePatchFactorsY[ FACTOR_SIZE_Y - 1 ].y );\n + \n + mediump vec4 vertexPosition = vec4( ( fixedFactor + ( uSize.xy - fixedTotal ) * stretch / stretchTotal ), 0.0, 1.0 );\n + vertexPosition.xy -= uSize.xy * vec2( 0.5, 0.5 );\n + vertexPosition = uMvpMatrix * vertexPosition;\n + \n + vTexCoord = ( fixedFactor + stretch ) / ( fixedTotal + stretchTotal );\n + \n + gl_Position = vertexPosition;\n + }\n +); + const char* VERTEX_SHADER_3X3 = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n varying mediump vec2 vTexCoord;\n @@ -146,6 +172,37 @@ void AddVertex( Vector< Vector2 >& vertices, unsigned int x, unsigned int y ) vertices.PushBack( Vector2( x, y ) ); } +void RegisterStretchProperties( Sampler& sampler, const char * uniformName, const NinePatchImage::StretchRanges& stretchPixels, uint16_t imageExtent) +{ + uint16_t prevEnd = 0; + uint16_t prevFix = 0; + uint16_t prevStretch = 0; + unsigned int i = 1; + for( NinePatchImage::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i ) + { + uint16_t start = it->GetX(); + uint16_t end = it->GetY(); + + uint16_t fix = prevFix + start - prevEnd; + uint16_t stretch = prevStretch + end - start; + + std::stringstream uniform; + uniform << uniformName << "[" << i << "]"; + sampler.RegisterProperty( uniform.str(), Vector2( fix, stretch ) ); + + prevEnd = end; + prevFix = fix; + prevStretch = stretch; + } + + { + prevFix += imageExtent - prevEnd; + std::stringstream uniform; + uniform << uniformName << "[" << i << "]"; + sampler.RegisterProperty( uniform.str(), Vector2( prevFix, prevStretch ) ); + } +} + } //unnamed namespace /////////////////NPatchRenderer//////////////// @@ -218,30 +275,51 @@ void NPatchRenderer::SetOffset( const Vector2& offset ) void NPatchRenderer::InitializeRenderer( Renderer& renderer ) { Geometry geometry; - if( !mBorderOnly ) + Shader shader; + if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 ) { - geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY ); - if( !geometry ) + if( !mBorderOnly ) { - geometry = CreateGeometry( Uint16Pair( 3, 3 ) ); - mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY, geometry ); + geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY ); + if( !geometry ) + { + geometry = CreateGeometry( Uint16Pair( 3, 3 ) ); + mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY, geometry ); + } } - } - else - { - geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY ); - if( !geometry ) + else + { + geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY ); + if( !geometry ) + { + geometry = CreateGeometryBorder( Uint16Pair( 3, 3 ) ); + mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry ); + } + } + + shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER ); + if( !shader ) { - geometry = CreateGeometryBorder( Uint16Pair( 3, 3 ) ); - mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry ); + shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER ); + mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader ); } } + else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0) + { + Uint16Pair gridSize( 2 * mStretchPixelsX.Size() + 1, 2 * mStretchPixelsY.Size() + 1 ); + geometry = !mBorderOnly ? CreateGeometry( gridSize ) : CreateGeometryBorder( gridSize ); + + std::stringstream vertexShader; + vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n" + << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n" + << VERTEX_SHADER; - Shader shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER ); - if( !shader ) + shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER ); + } + else { - shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER ); - mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader ); + DALI_LOG_ERROR("The 9 patch image '%s' doesn't have any valid stretch borders and so is not a valid 9 patch image\n", mImageUrl.c_str() ); + CreateErrorImage(); } if( !renderer ) @@ -273,6 +351,8 @@ void NPatchRenderer::DoSetOnStage( Actor& actor ) { InitialiseFromImage( mImage ); } + + InitializeRenderer( mImpl->mRenderer ); } if( mCroppedImage ) @@ -374,6 +454,7 @@ void NPatchRenderer::CreateErrorImage() mStretchPixelsX.PushBack( Uint16Pair( 0, mImageSize.GetWidth() ) ); mStretchPixelsY.Clear(); mStretchPixelsY.PushBack( Uint16Pair( 0, mImageSize.GetHeight() ) ); + } void NPatchRenderer::ApplyImageToSampler() @@ -397,9 +478,9 @@ void NPatchRenderer::ApplyImageToSampler() material.AddSampler( sampler ); } - if( mStretchPixelsX.Size() > 0 && mStretchPixelsY.Size() > 0 ) + if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 ) { - //only 9 patch supported for now + //special case for 9 patch Uint16Pair stretchX = mStretchPixelsX[ 0 ]; Uint16Pair stretchY = mStretchPixelsY[ 0 ]; @@ -411,6 +492,14 @@ void NPatchRenderer::ApplyImageToSampler() sampler.RegisterProperty( "uFixed[2]", Vector2( mImageSize.GetWidth() - stretchWidth, mImageSize.GetHeight() - stretchHeight ) ); sampler.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) ); } + else + { + sampler.RegisterProperty( "uNinePatchFactorsX[0]", Vector2::ZERO ); + sampler.RegisterProperty( "uNinePatchFactorsY[0]", Vector2::ZERO ); + + RegisterStretchProperties( sampler, "uNinePatchFactorsX", mStretchPixelsX, mImageSize.GetWidth() ); + RegisterStretchProperties( sampler, "uNinePatchFactorsY", mStretchPixelsY, mImageSize.GetHeight() ); + } } } diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h index 77ba2a4..bbb069c 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h @@ -183,8 +183,6 @@ private: NinePatchImage mImage; ///< The image to render if the renderer was set from an NinePatchImage, empty otherwise Image mCroppedImage; - Geometry mNinePatchGeometry; - Geometry mNinePatchBorderGeometry; std::string mImageUrl; ///< The url to the image resource to render if the renderer was set from an image resource url, empty otherwise NinePatchImage::StretchRanges mStretchPixelsX; -- 2.7.4