From: David Steele Date: Wed, 23 Jul 2014 13:17:28 +0000 (+0100) Subject: Added text renderer culling X-Git-Tag: dali_1.0.2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F66%2F25066%2F4;p=platform%2Fcore%2Fuifw%2Fdali-core.git Added text renderer culling Text renderers can use the same culling algorithm as images; have moved the 2D OBB culling algorithm to a new file; changed the interface slightly (to pass a potentially uncentered bounding box) Change-Id: Ic4379fdc6e7a25f39377bab2c1169697bef0e641 Signed-off-by: David Steele --- diff --git a/automated-tests/src/dali-internal/CMakeLists.txt b/automated-tests/src/dali-internal/CMakeLists.txt index 9728100..08fbd2c 100644 --- a/automated-tests/src/dali-internal/CMakeLists.txt +++ b/automated-tests/src/dali-internal/CMakeLists.txt @@ -14,6 +14,7 @@ SET(TC_SOURCES utc-Dali-Internal-Text.cpp utc-Dali-Internal-ResourceClient.cpp utc-Dali-Internal-Image-Culling.cpp + utc-Dali-Internal-Text-Culling.cpp ) LIST(APPEND TC_SOURCES diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-Image-Culling.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-Image-Culling.cpp index 57c5a47..29af606 100644 --- a/automated-tests/src/dali-internal/utc-Dali-Internal-Image-Culling.cpp +++ b/automated-tests/src/dali-internal/utc-Dali-Internal-Image-Culling.cpp @@ -150,7 +150,7 @@ void TestImageInside( TestApplication& application, int width, int height ) } -void RepositionActor(TestApplication& application, Actor actor, float x, float y, bool inside) +bool RepositionActor(TestApplication& application, Actor actor, float x, float y, bool inside) { TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace(); @@ -158,20 +158,12 @@ void RepositionActor(TestApplication& application, Actor actor, float x, float y actor.SetPosition( x, y, 0.0f); application.SendNotification(); application.Render(16); - if( inside ) - { - bool found = drawTrace.FindMethod( "DrawArrays" ); - if( ! found ) tet_printf( "Not drawn: Position:(%3.0f, %3.0f)\n", x, y ); - DALI_TEST_CHECK( found ); - } - else - { - bool found = drawTrace.FindMethod( "DrawArrays" ); - if( found ) tet_printf( "Drawn when not needed: Position:(%3.0f, %3.0f)\n", x, y ); - DALI_TEST_CHECK( ! found ); - } + + bool found = drawTrace.FindMethod( "DrawArrays" ); + return (inside && found) || (!inside && !found); } + void RepositionActorWithAngle(TestApplication& application, Actor actor, float x, float y, float angle, bool inside) { TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace(); @@ -289,6 +281,8 @@ void OBBTestImageAtBoundary( TestApplication& application, int width, int height tet_printf("Testing Stage Size: (%3.0f, %3.0f) image size:(%3.0f, %3.0f) \n", stageSize.x, stageSize.y, imageSize.x, imageSize.y); + int successCount = 0; + int totalCount = 0; for( int i=0; i<100; i++ ) { float x1 = -stageSize.x/2.0f - imageSize.x*i/200.0f; @@ -311,12 +305,16 @@ void OBBTestImageAtBoundary( TestApplication& application, int width, int height float x = ((stageSize.x+imageSize.x/2.0f)/21.0f) * j; float y = ((stageSize.y+imageSize.y/2.0f)/21.0f) * j; - RepositionActor( application, imageActor, x1, y, true ); - RepositionActor( application, imageActor, x2, y, true ); - RepositionActor( application, imageActor, x, y1, true ); - RepositionActor( application, imageActor, x, y2, true ); + if(RepositionActor( application, imageActor, x1, y, true )) successCount++; + if(RepositionActor( application, imageActor, x2, y, true )) successCount++; + if(RepositionActor( application, imageActor, x, y1, true )) successCount++; + if(RepositionActor( application, imageActor, x, y2, true )) successCount++; + + totalCount += 4; } } + DALI_TEST_EQUALS(successCount, totalCount, TEST_LOCATION); + tet_printf( "Test succeeded with %d passes out of %d tests\n", successCount, totalCount); } @@ -384,6 +382,9 @@ void OBBTestImageOutsideBoundary( TestApplication& application, int width, int h tet_printf("Testing Stage Size: (%3.0f, %3.0f) image size:(%3.0f, %3.0f)\n", stageSize.x, stageSize.y, imageSize.x, imageSize.y); + int successCount=0; + int totalCount=0; + for( int i=0; i<=100; i++ ) { float x1 = -stageSize.x/2.0f - imageSize.x * (1.5f + i/100.0f); @@ -396,12 +397,15 @@ void OBBTestImageOutsideBoundary( TestApplication& application, int width, int h float x = (stageSize.x/17.0f) * j; // use larger intervals to test more area float y = (stageSize.y/17.0f) * j; - RepositionActor( application, imageActor, x1, y, false ); - RepositionActor( application, imageActor, x2, y, false ); - RepositionActor( application, imageActor, x, y1, false ); - RepositionActor( application, imageActor, x, y2, false ); + if(RepositionActor( application, imageActor, x1, y, false )) successCount++; + if(RepositionActor( application, imageActor, x2, y, false )) successCount++; + if(RepositionActor( application, imageActor, x, y1, false )) successCount++; + if(RepositionActor( application, imageActor, x, y2, false )) successCount++; + totalCount+=4; } } + DALI_TEST_EQUALS(successCount, totalCount, TEST_LOCATION); + tet_printf( "Test succeeded with %d passes out of %d tests\n", successCount, totalCount); } void TestPlaneOfImages(TestApplication& application, float z) @@ -791,8 +795,6 @@ int UtcDaliImageCulling_Plane04(void) END_TEST; } - - int UtcDaliImageCulling_Disable(void) { tet_infoline("Test that culling can be disabled"); @@ -814,17 +816,16 @@ int UtcDaliImageCulling_Disable(void) DALI_TEST_EQUALS( imageSize, Vector3(width, height, std::min(width, height)), TEST_LOCATION); imageSize.z = 0.0f; - float radius = imageSize.Length() * 0.5f; // Radius of bounding box tet_infoline("Setting cull mode to false\n"); Stage::GetCurrent().GetRenderTaskList().GetTask(0).SetCullMode(false); - float x1 = -stageSize.x/2.0f - imageSize.x; - float x2 = stageSize.x/2.0f + imageSize.x; - float y1 = -stageSize.y/2.0f - imageSize.y; - float y2 = stageSize.y/2.0f + imageSize.y; + float x1 = -stageSize.x - imageSize.x; + float x2 = stageSize.x + imageSize.x; + float y1 = -stageSize.y - imageSize.y; + float y2 = stageSize.y + imageSize.y; - // Positioning actors well outside stage, with no culling, they should still be drawn. + // Positioning actors outside stage, with no culling, they should still be drawn. RepositionActorOutside( application, imageActor, x1, y1, true ); RepositionActorOutside( application, imageActor, x2, y1, true ); RepositionActorOutside( application, imageActor, x1, y2, true ); diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-Text-Culling.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-Text-Culling.cpp new file mode 100644 index 0000000..6fb1bf6 --- /dev/null +++ b/automated-tests/src/dali-internal/utc-Dali-Internal-Text-Culling.cpp @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include +#include + +#include + +using namespace Dali; + +void utc_dali_internal_text_culling_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void utc_dali_internal_text_culling_cleanup(void) +{ + test_return_value = TET_PASS; +} + + +namespace +{ +#define NUM_ROWS 9 +#define NUM_COLS 9 +#define NUM_ROWS_PER_PANE 3 +#define NUM_COLS_PER_PANE 3 + + +TextActor CreateOnStageActor(TestApplication& application, Text text, int width, int height, bool testDraw) +{ + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TestPlatformAbstraction& platform = application.GetPlatform(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + + TextActor textActor = TextActor::New(text); + textActor.SetParentOrigin(ParentOrigin::CENTER); + textActor.SetSize(width, height); + Stage::GetCurrent().Add(textActor); + + application.SendNotification(); + application.Render(16); + + Integration::ResourceRequest* request = platform.GetRequest(); + DALI_TEST_CHECK( request != NULL ); + DALI_TEST_CHECK( request->GetType() != NULL ); + DALI_TEST_CHECK( request->GetType()->id == Integration::ResourceText ); + + Integration::TextResourceType* textRequest = static_cast(request->GetType()); + + std::string font("Font"); + Integration::GlyphSet* set = platform.GetGlyphData(*textRequest, font, true); + platform.SetResourceLoaded( request->GetId(), Integration::ResourceText, Integration::ResourcePointer(set) ); + + application.SendNotification(); + application.Render(16); + + platform.ClearReadyResources(); + + if(testDraw) + { + DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) ); + } + return textActor; +} + + +void TestTextInside( TestApplication& application, int width, int height ) +{ + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + + std::string text("Text"); + + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + textActor.SetPosition(0.0f, 0.0f, 0.0f); + + Vector3 textSize = textActor.GetCurrentSize(); + DALI_TEST_EQUALS( textSize, Vector3(width, height, std::min(width, height)), TEST_LOCATION); + + drawTrace.Reset(); + textActor.SetParentOrigin(ParentOrigin::TOP_LEFT); + application.SendNotification(); + application.Render(16); + DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) ); + + drawTrace.Reset(); + textActor.SetParentOrigin(ParentOrigin::TOP_RIGHT); + application.SendNotification(); + application.Render(16); + DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) ); + + drawTrace.Reset(); + textActor.SetParentOrigin(ParentOrigin::BOTTOM_RIGHT); + application.SendNotification(); + application.Render(16); + DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) ); + + drawTrace.Reset(); + textActor.SetParentOrigin(ParentOrigin::BOTTOM_LEFT); + application.SendNotification(); + application.Render(16); + DALI_TEST_CHECK( drawTrace.FindMethod( "DrawElements" ) ); +} + + +bool RepositionActor(TestApplication& application, Actor actor, float x, float y, bool inside) +{ + TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace(); + + drawTrace.Reset(); + actor.SetPosition( x, y, 0.0f); + application.SendNotification(); + application.Render(16); + + bool found = drawTrace.FindMethod( "DrawElements" ); + bool result = (inside && found) || (!inside && !found); + return result; +} + + +void RepositionActorWithAngle(TestApplication& application, Actor actor, float x, float y, float angle, bool inside) +{ + TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace(); + + drawTrace.Reset(); + actor.SetPosition( x, y, 0.0f); + actor.SetRotation( Degree(angle), Vector3::ZAXIS ); + application.SendNotification(); + application.Render(16); + if( inside ) + { + bool found = drawTrace.FindMethod( "DrawElements" ); + if( ! found ) tet_printf( "Not drawn: Position:(%3.0f, %3.0f)\n", x, y ); + DALI_TEST_CHECK( found ); + } + else + { + bool found = drawTrace.FindMethod( "DrawElements" ); + if( found ) tet_printf( "Drawn when not needed: Position:(%3.0f, %3.0f)\n", x, y ); + DALI_TEST_CHECK( ! found ); + } +} + +void RepositionActorOutside(TestApplication& application, Actor actor, float x, float y, bool drawn ) +{ + TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace(); + + drawTrace.Reset(); + actor.SetPosition( x, y, 0.0f); + application.SendNotification(); + application.Render(16); + if( drawn ) + { + bool found = drawTrace.FindMethod( "DrawElements" ); + if( ! found ) tet_printf( "Not drawn: Position:(%3.0f, %3.0f)\n", x, y ); + DALI_TEST_CHECK( found ); + } + else + { + bool found = drawTrace.FindMethod( "DrawElements" ); + if( found ) tet_printf( "Drawn unnecessarily: Position:(%3.0f, %3.0f)\n", x, y ); + DALI_TEST_CHECK( ! found ); + } +} + +void OBBTestTextAtBoundary( TestApplication& application, int width, int height ) +{ + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + + Vector2 stageSize = Stage::GetCurrent().GetSize(); + + std::string text("Text"); + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + + Vector3 textSize = textActor.GetCurrentSize(); + DALI_TEST_EQUALS( textSize, Vector3(width, height, std::min(width, height)), TEST_LOCATION); + + textSize.z = 0.0f; + tet_printf("Testing Stage Size: (%3.0f, %3.0f) text size:(%3.0f, %3.0f) \n", + stageSize.x, stageSize.y, textSize.x, textSize.y); + + int successCount = 0; + int totalCount = 0; + for( int i=0; i<100; i++ ) + { + float x1 = -stageSize.x/2.0f - textSize.x*i/200.0f; + float x2 = stageSize.x/2.0f + textSize.x*i/200.0f; + float y1 = -stageSize.y/2.0f - textSize.y*i/200.0f; + float y2 = stageSize.y/2.0f + textSize.y*i/200.0f; + + //tet_printf("Testing i=%d\n",i); + + // Test paths marked with dots + // + . . . . . . + // .\_ ^ + // . \_ | within radius + // . \ v + // . +----- + // . | Stage + + for( int j=-10; j<=10; j++ ) + { + float x = ((stageSize.x+textSize.x/2.0f)/21.0f) * j; + float y = ((stageSize.y+textSize.y/2.0f)/21.0f) * j; + + if(RepositionActor( application, textActor, x1, y, true )) successCount++; + if(RepositionActor( application, textActor, x2, y, true )) successCount++; + if(RepositionActor( application, textActor, x, y1, true )) successCount++; + if(RepositionActor( application, textActor, x, y2, true )) successCount++; + + totalCount += 4; + } + } + DALI_TEST_EQUALS(successCount, totalCount, TEST_LOCATION); + tet_printf( "Test succeeded with %d passes out of %d tests\n", successCount, totalCount); +} + + +void OBBTestTextOutsideBoundary( TestApplication& application, int width, int height ) +{ + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + + Vector2 stageSize = Stage::GetCurrent().GetSize(); + + std::string text("Text"); + + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + Vector3 textSize = textActor.GetCurrentSize(); + DALI_TEST_EQUALS( textSize, Vector3(width, height, std::min(width, height)), TEST_LOCATION); + + textSize.z = 0.0f; + tet_printf("Testing Stage Size: (%3.0f, %3.0f) text size:(%3.0f, %3.0f)\n", + stageSize.x, stageSize.y, textSize.x, textSize.y); + + int successCount=0; + int totalCount=0; + + for( int i=0; i<=100; i++ ) + { + float x1 = -stageSize.x/2.0f - textSize.x * (1.5f + i/100.0f); + float x2 = stageSize.x/2.0f + textSize.x * (1.5f + i/100.0f); + float y1 = -stageSize.y/2.0f - textSize.y * (1.5f + i/100.0f); + float y2 = stageSize.y/2.0f + textSize.y * (1.5f + i/100.0f); + + for( int j=-10; j<=10; j++ ) + { + float x = (stageSize.x/17.0f) * j; // use larger intervals to test more area + float y = (stageSize.y/17.0f) * j; + + if(RepositionActor( application, textActor, x1, y, false )) successCount++; + if(RepositionActor( application, textActor, x2, y, false )) successCount++; + if(RepositionActor( application, textActor, x, y1, false )) successCount++; + if(RepositionActor( application, textActor, x, y2, false )) successCount++; + totalCount+=4; + } + } + DALI_TEST_EQUALS(successCount, totalCount, TEST_LOCATION); + tet_printf( "Test succeeded with %d passes out of %d tests\n", successCount, totalCount); +} + + +} // namespace + +int UtcDaliTextCulling_Inside01(void) +{ + tet_infoline( "Testing that 80x80 text positioned inside the stage is drawn\n"); + + TestApplication application; + + TestTextInside(application, 80, 80); + + END_TEST; +} + +int UtcDaliTextCulling_Inside02(void) +{ + tet_infoline( "Testing that 120x40 text positioned inside the stage is drawn\n"); + + TestApplication application; + + TestTextInside(application, 120, 40); + + END_TEST; +} + +int UtcDaliTextCulling_Inside03(void) +{ + tet_infoline( "Testing that 40x120 text positioned inside the stage is drawn\n"); + + TestApplication application; + + TestTextInside(application, 40, 120); + + END_TEST; +} + +int UtcDaliTextCulling_Inside04(void) +{ + tet_infoline( "Testing that 500x2 text positioned inside the stage is drawn\n"); + TestApplication application; + TestTextInside(application, 500, 2); + END_TEST; +} + +int UtcDaliTextCulling_Inside05(void) +{ + tet_infoline( "Testing that 2x500 text positioned inside the stage is drawn\n"); + TestApplication application; + TestTextInside(application, 2, 500); + END_TEST; +} + + +int UtcDaliTextCulling_WithinBoundary01(void) +{ + tet_infoline("Test that 80x80 text positioned outside the stage but with bounding box intersecting the stage is drawn\n"); + + TestApplication application; + OBBTestTextAtBoundary( application, 80, 80); + END_TEST; +} +int UtcDaliTextCulling_WithinBoundary02(void) +{ + tet_infoline("Test that 120x40 text positioned outside the stage but with bounding box intersecting the stage is drawn\n"); + + TestApplication application; + OBBTestTextAtBoundary( application, 120, 40 ); + END_TEST; +} +int UtcDaliTextCulling_WithinBoundary03(void) +{ + tet_infoline("Test that 40x120 text positioned outside the stage but with bounding box intersecting the stage is drawn\n"); + + TestApplication application; + OBBTestTextAtBoundary( application, 40, 120); + END_TEST; +} + +int UtcDaliTextCulling_WithinBoundary04(void) +{ + tet_infoline("Test that 500x2 texts positioned outside the stage but with bounding box intersecting the stage is drawn\n"); + + TestApplication application; + OBBTestTextAtBoundary( application, 500, 2 ); + END_TEST; +} + +int UtcDaliTextCulling_WithinBoundary05(void) +{ + tet_infoline("Test that 2x500 texts positioned outside the stage but with bounding box intersecting the stage is drawn\n"); + + TestApplication application; + OBBTestTextAtBoundary( application, 2, 500 ); + END_TEST; +} + +int UtcDaliTextCulling_OutsideBoundary01(void) +{ + tet_infoline("Test that 80x80 text positioned outside the stage by more than 2 times\n" + "the radius of the bounding circle is not drawn\n"); + + TestApplication application; + OBBTestTextOutsideBoundary( application, 80, 80 ); + END_TEST; +} + +int UtcDaliTextCulling_OutsideBoundary02(void) +{ + tet_infoline("Test that 120x40 text positioned outside the stage by more than 2 times\n" + "the radius of the bounding circle is not drawn\n"); + + TestApplication application; + OBBTestTextOutsideBoundary( application, 120, 40 ); + END_TEST; +} +int UtcDaliTextCulling_OutsideBoundary03(void) +{ + tet_infoline("Test that 40x120 text positioned outside the stage by more than 2 times\n" + "the radius of the bounding circle is not drawn\n"); + + TestApplication application; + OBBTestTextOutsideBoundary( application, 40, 120 ); + END_TEST; +} + +int UtcDaliTextCulling_OutsideBoundary04(void) +{ + tet_infoline("Test that 500x2 text positioned outside the stage by more than 2 times\n" + "the radius of the bounding circle is not drawn\n"); + + TestApplication application; + OBBTestTextOutsideBoundary( application, 500, 2 ); + END_TEST; +} + +int UtcDaliTextCulling_OutsideBoundary05(void) +{ + tet_infoline("Test that 2x500 text positioned outside the stage by more than 2 times\n" + "the radius of the bounding circle is not drawn\n"); + + TestApplication application; + OBBTestTextOutsideBoundary( application, 2, 500 ); + END_TEST; +} + +int UtcDaliTextCulling_OutsideIntersect01(void) +{ + TestApplication application; + + tet_infoline("Test that actors positioned outside the stage with bounding boxes also\n" + "outside the stage but intersecting it are still drawn"); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + Vector2 stageSize = Stage::GetCurrent().GetSize(); + + float width = stageSize.x*5.0f; + float height = stageSize.y*0.2f; + std::string text("Text"); + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + + RepositionActor( application, textActor, stageSize.x*1.2f, 0.0f, true); + RepositionActor( application, textActor, stageSize.x*1.2f, -stageSize.y*0.55f, true); + RepositionActor( application, textActor, stageSize.x*1.2f, stageSize.y*0.55f, true); + END_TEST; +} + +int UtcDaliTextCulling_OutsideIntersect02(void) +{ + TestApplication application; + + tet_infoline("Test that actors positioned outside the stage with bounding boxes also\n" + "outside the stage that cross planes are not drawn"); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + Vector2 stageSize = Stage::GetCurrent().GetSize(); + + float width = stageSize.x*5.0f; + float height = stageSize.y*0.2f; + std::string text("Text"); + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + + RepositionActor( application, textActor, stageSize.x*10.0f, stageSize.y*0.5f, false); + RepositionActor( application, textActor, -stageSize.x*10.0f, stageSize.y*0.5f, false); + RepositionActor( application, textActor, stageSize.x*10.0f, -stageSize.y*0.5f, false); + RepositionActor( application, textActor, -stageSize.x*10.0f, -stageSize.y*0.5f, false); + END_TEST; +} + +int UtcDaliTextCulling_OutsideIntersect03(void) +{ + TestApplication application; + + tet_infoline("Test that text actor larger than the stage, positioned outside the stage \n" + "with bounding boxes also outside the stage but intersecting it is still drawn\n"); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + Vector2 stageSize = Stage::GetCurrent().GetSize(); + + // Try an actor bigger than the stage, with center outside stage + float width = stageSize.x*5.0f; + float height = stageSize.y*5.0f; + std::string text("Text"); + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + + RepositionActor( application, textActor, stageSize.x*1.2f, 0.0f, true); + RepositionActor( application, textActor, stageSize.x*1.2f, -stageSize.y*1.1f, true); + RepositionActor( application, textActor, stageSize.x*1.2f, stageSize.y*1.1f, true); + + END_TEST; +} + +int UtcDaliTextCulling_OutsideIntersect04(void) +{ + TestApplication application; + + tet_infoline("Test that text actors positioned outside the stage, with bounding boxes\n" + "also outside the stage but intersecting it, and angled at 45 degrees to\n" + "the corners are still drawn\n"); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + Vector2 stageSize = Stage::GetCurrent().GetSize(); + + // Test text at 45 degrees outside corners of stage + float width = 400.0f; + float height = 200.0f; + std::string text("Text"); + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + + RepositionActorWithAngle( application, textActor, -stageSize.x*0.55f, -stageSize.y*0.55, 135.0f, true); + RepositionActorWithAngle( application, textActor, -stageSize.x*0.55f, stageSize.y*0.55, 225.0f, true); + RepositionActorWithAngle( application, textActor, stageSize.x*0.55f, -stageSize.y*0.55, 45.0f, true); + RepositionActorWithAngle( application, textActor, stageSize.x*0.55f, stageSize.y*0.55, 315.0f, true); + + END_TEST; +} + + +int UtcDaliTextCulling_Disable(void) +{ + tet_infoline("Test that culling can be disabled"); + + TestApplication application; + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TestPlatformAbstraction& platformAbstraction = application.GetPlatform(); + TraceCallStack& platformTrace = platformAbstraction.GetTrace(); + + TraceCallStack& drawTrace = glAbstraction.GetDrawTrace(); + drawTrace.Enable(true); + + Vector2 stageSize = Stage::GetCurrent().GetSize(); + float width=80; + float height=80; + std::string text("Text"); + + + TextActor textActor = CreateOnStageActor(application, text, width, height, true); + Vector3 textSize = textActor.GetCurrentSize(); + DALI_TEST_EQUALS( textSize, Vector3(width, height, std::min(width, height)), TEST_LOCATION); + + textSize.z = 0.0f; + + tet_infoline("Setting cull mode to false\n"); + Stage::GetCurrent().GetRenderTaskList().GetTask(0).SetCullMode(false); + + float x1 = -stageSize.x - textSize.x; + float x2 = stageSize.x + textSize.x; + float y1 = -stageSize.y - textSize.y; + float y2 = stageSize.y + textSize.y; + + // Positioning actors outside stage, with no culling, they should still be drawn. + RepositionActorOutside( application, textActor, x1, y1, true ); + RepositionActorOutside( application, textActor, x2, y1, true ); + RepositionActorOutside( application, textActor, x1, y2, true ); + RepositionActorOutside( application, textActor, x2, y2, true ); + + tet_infoline("Setting cull mode to true\n"); + Stage::GetCurrent().GetRenderTaskList().GetTask(0).SetCullMode(true); + + RepositionActorOutside( application, textActor, x1, y1, false ); + RepositionActorOutside( application, textActor, x2, y1, false ); + RepositionActorOutside( application, textActor, x1, y2, false ); + RepositionActorOutside( application, textActor, x2, y2, false ); + + END_TEST; +} diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp index 6b6a8f8..4f749ce 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp @@ -86,7 +86,19 @@ void TestPlatformAbstraction::GetClosestImageSize( Integration::ResourcePointer */ void TestPlatformAbstraction::LoadResource(const Integration::ResourceRequest& request) { - mTrace.PushCall("LoadResource", ""); + std::ostringstream out; + out << "Type:"; + if( request.GetType()->id == Integration::ResourceText ) + { + out << "Text"; + } + else + { + out << request.GetType()->id; + } + out << ", Path: " << request.GetPath() << std::endl ; + + mTrace.PushCall("LoadResource", out.str()); if(mRequest != NULL) { delete mRequest; diff --git a/dali/internal/common/text-vertex-buffer.h b/dali/internal/common/text-vertex-buffer.h index 4c234b2..1459ace 100644 --- a/dali/internal/common/text-vertex-buffer.h +++ b/dali/internal/common/text-vertex-buffer.h @@ -21,6 +21,7 @@ // INTERNAL INCLUDES #include #include +#include #include namespace Dali @@ -38,7 +39,8 @@ struct TextVertexBuffer { std::vector mVertices; ///< List of vertices (coordinates and texture coordinates) unsigned int mTextureId; ///< Texture id - Vector2 mVertexMax; ///< Maximum extent of 2d vertex array + Vector2 mVertexMax; ///< Calculated unskewed geometry size + Vector2 mGeometryExtent; ///< Actual extents of geometry }; } // namespace Internal diff --git a/dali/internal/event/text/generator/text-vertex-generator.cpp b/dali/internal/event/text/generator/text-vertex-generator.cpp index 6ce9e0d..05f2872 100644 --- a/dali/internal/event/text/generator/text-vertex-generator.cpp +++ b/dali/internal/event/text/generator/text-vertex-generator.cpp @@ -22,6 +22,7 @@ #include #include #include +#include // EXTERNAL INCLUDES #include // for std::sin @@ -35,6 +36,10 @@ namespace Internal namespace // unnamed namespace { +#if defined(DEBUG_ENABLED) +Debug::Filter* gTextVertsLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_TEXT_VERTEX_FILTER" ); +#endif + typedef std::vector VertexBuffer; void RepositionData( TextVertexBuffer& buffer ) @@ -91,6 +96,9 @@ void RepositionData( TextVertexBuffer& buffer ) vertex.mX -= offset.x; vertex.mY -= offset.y; } + + buffer.mGeometryExtent.width = maxX - minX; + buffer.mGeometryExtent.height = maxY - minY; } void AddVertex( VertexBuffer& vertexBuffer, @@ -407,6 +415,11 @@ TextVertexBuffer* TextVertexGenerator::Generate( const TextArray& text, DebugVertexBuffer( vertexBuffer ); #endif + DALI_LOG_INFO(gTextVertsLogFilter, Debug::General, "TextVertexBuffer for %c%c%c...: Calculated Extents:(%5.2f, %5.2f)\n Geometry Extents:(%5.2f, %5.2f )\n", + text.size()>0?(char)text[0]:' ', text.size()>1?(char)text[1]:' ', text.size()>2?(char)text[2]:' ', + textVertexBuffer->mVertexMax.x,textVertexBuffer->mVertexMax.y, + textVertexBuffer->mGeometryExtent.width,textVertexBuffer->mGeometryExtent.height); + return textVertexBuffer; } diff --git a/dali/internal/file.list b/dali/internal/file.list index e0f0775..a02838c 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -120,6 +120,7 @@ internal_src_files = \ $(internal_src_dir)/event/text/resource/debug/glyph-resource-debug.cpp \ $(internal_src_dir)/event/text/generator/text-vertex-generator.cpp \ \ + $(internal_src_dir)/render/common/culling-algorithms.cpp \ $(internal_src_dir)/render/common/performance-monitor.cpp \ $(internal_src_dir)/render/common/render-algorithms.cpp \ $(internal_src_dir)/render/common/render-debug.cpp \ @@ -144,6 +145,7 @@ internal_src_files = \ $(internal_src_dir)/render/renderers/scene-graph-image-renderer.cpp \ $(internal_src_dir)/render/renderers/scene-graph-mesh-renderer.cpp \ $(internal_src_dir)/render/renderers/scene-graph-renderer.cpp \ + $(internal_src_dir)/render/renderers/scene-graph-renderer-debug.cpp \ $(internal_src_dir)/render/renderers/scene-graph-text-renderer.cpp \ $(internal_src_dir)/render/shaders/custom-uniform.cpp \ $(internal_src_dir)/render/shaders/program.cpp \ diff --git a/dali/internal/render/common/culling-algorithms.cpp b/dali/internal/render/common/culling-algorithms.cpp new file mode 100644 index 0000000..d60f7ef --- /dev/null +++ b/dali/internal/render/common/culling-algorithms.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "culling-algorithms.h" + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ + +bool Is2dBoxOutsideClipSpace(const Matrix& modelMatrix, + const Matrix& modelViewProjectionMatrix, + const Rect& boundingBox ) +{ + // First, calculate if the center is inside clip space: + + // Downside is mvp matrix calc per renderer per frame + // and up to 4 matrix * vector calls. + const Matrix& mvp = modelViewProjectionMatrix; + const Vector4 translation = mvp.GetTranslation(); + + // Upside is point test is very simple: + if( -translation.w <= translation.x && translation.x <= translation.w && + -translation.w <= translation.y && translation.y <= translation.w && + -translation.w <= translation.z && translation.z <= translation.w) + { + // Definitely inside clip space - don't do any more processing + return false; + } + + // Transform oriented bounding box to clip space: + Vector4 topLeft( boundingBox.x, boundingBox.y, 0.0f, 1.0f); + Vector4 topRight( boundingBox.x + boundingBox.width, boundingBox.y, 0.0f, 1.0f); + Vector4 bottomLeft( boundingBox.x, boundingBox.y + boundingBox.height, 0.0f, 1.0f); + Vector4 bottomRight(boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height, 0.0f, 1.0f); + + Vector4 topLeftClip = mvp * topLeft; + if( -topLeftClip.w <= topLeftClip.x && topLeftClip.x <= topLeftClip.w && + -topLeftClip.w <= topLeftClip.y && topLeftClip.y <= topLeftClip.w && + -topLeftClip.w <= topLeftClip.z && topLeftClip.z <= topLeftClip.w ) + { + // Definitely inside clip space - don't do any more processing + return false; + } + + Vector4 bottomRightClip = mvp * bottomRight; + if( -bottomRightClip.w <= bottomRightClip.x && bottomRightClip.x <= bottomRightClip.w && + -bottomRightClip.w <= bottomRightClip.y && bottomRightClip.y <= bottomRightClip.w && + -bottomRightClip.w <= bottomRightClip.z && bottomRightClip.z <= bottomRightClip.w ) + { + // Definitely inside clip space - don't do any more processing + return false; + } + + Vector4 topRightClip = mvp * topRight; + if( -topRightClip.w <= topRightClip.x && topRightClip.x <= topRightClip.w && + -topRightClip.w <= topRightClip.y && topRightClip.y <= topRightClip.w && + -topRightClip.w <= topRightClip.z && topRightClip.z <= topRightClip.w ) + { + // Definitely inside clip space - don't do any more processing + return false; + } + + Vector4 bottomLeftClip = mvp * bottomLeft; + if( -bottomLeftClip.w <= bottomLeftClip.x && bottomLeftClip.x <= bottomLeftClip.w && + -bottomLeftClip.w <= bottomLeftClip.y && bottomLeftClip.y <= bottomLeftClip.w && + -bottomLeftClip.w <= bottomLeftClip.z && bottomLeftClip.z <= bottomLeftClip.w ) + { + // Definitely inside clip space - don't do any more processing + return false; + } + + // Check to see if all four points are outside each plane + + unsigned int insideLeftPlaneCount=0; + unsigned int insideRightPlaneCount=0; + unsigned int insideTopPlaneCount=0; + unsigned int insideBottomPlaneCount=0; + + if(-topLeftClip.w <= topLeftClip.x) { insideLeftPlaneCount++; } + if(-topRightClip.w <= topRightClip.x){ insideLeftPlaneCount++; } + if(-bottomRightClip.w <= bottomRightClip.x) {insideLeftPlaneCount++;} + if(-bottomLeftClip.w <= bottomLeftClip.x) {insideLeftPlaneCount++;} + + if( insideLeftPlaneCount == 0 ) + { + return true; + } + + if(topLeftClip.x <= topLeftClip.w) { insideRightPlaneCount++;} + if(topRightClip.x <= topRightClip.w) { insideRightPlaneCount++; } + if(bottomRightClip.x <= bottomRightClip.w) { insideRightPlaneCount++; } + if(bottomLeftClip.x <= bottomLeftClip.w ) { insideRightPlaneCount++; } + + if( insideRightPlaneCount == 0 ) + { + return true; + } + + if(-topLeftClip.w <= topLeftClip.y ) {insideTopPlaneCount++; } + if(-topRightClip.w <= topRightClip.y) {insideTopPlaneCount++; } + if(-bottomRightClip.w <= bottomRightClip.y) {insideTopPlaneCount++;} + if(-bottomLeftClip.w <= bottomLeftClip.y) { insideTopPlaneCount++;} + + if( insideTopPlaneCount == 0 ) + { + return true; + } + + if(topLeftClip.y <= topLeftClip.w) { insideBottomPlaneCount++; } + if(topRightClip.y <= topRightClip.w) { insideBottomPlaneCount++; } + if(bottomRightClip.y <= bottomRightClip.w) { insideBottomPlaneCount++; } + if(bottomLeftClip.y <= bottomLeftClip.w) { insideBottomPlaneCount++; } + + if( insideBottomPlaneCount == 0 ) + { + return true; + } + + // Test if any planes are bisected, if they are, then there is likely to + // be an intersection into clip space. + + if( insideLeftPlaneCount < 4 ) + { + return false; + } + if( insideRightPlaneCount < 4 ) + { + return false; + } + if( insideTopPlaneCount < 4 ) + { + return false; + } + if( insideBottomPlaneCount < 4 ) + { + return false; + } + + return true; +} + + +} // SceneGraph +} // Internal +} // Dali diff --git a/dali/internal/render/common/culling-algorithms.h b/dali/internal/render/common/culling-algorithms.h new file mode 100644 index 0000000..b2e451e --- /dev/null +++ b/dali/internal/render/common/culling-algorithms.h @@ -0,0 +1,46 @@ +#ifndef _DALI_INTERNAL_SCENE_GRAPH_CULLING_ALGORITHMS_H_ +#define _DALI_INTERNAL_SCENE_GRAPH_CULLING_ALGORITHMS_H_ + +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ + +/** + * Determine if the given bounding box is outside clip space (given by the + * model view projection matrix). + * @param[in] modelMatrix The world matrix of the bounding box. + * @param[in] modelViewProjectionMatrix The clip space matrix + * @param[in] boundingBox The bounding box of the geometry in object space + * @return true if the bounding box is outside clip space + */ +bool Is2dBoxOutsideClipSpace(const Matrix& modelMatrix, + const Matrix& modelViewProjectionMatrix, + const Rect& boundingBox ); +} // SceneGraph +} // Internal +} // Dali + +#endif //_DALI_INTERNAL_SCENE_GRAPH_CULLING_ALGORITHMS_H_ diff --git a/dali/internal/render/common/render-debug.cpp b/dali/internal/render/common/render-debug.cpp index d5995d4..6a512bd 100644 --- a/dali/internal/render/common/render-debug.cpp +++ b/dali/internal/render/common/render-debug.cpp @@ -137,7 +137,7 @@ void PrintRendererCount( unsigned int frameCount, unsigned int rendererCount ) { if( frameCount % 120 == 30 ) // Print every 2 seconds reg { - Debug::LogMessage( Debug::DebugInfo, "ImageRenderer Total # renderers: %u\n", rendererCount ); + Debug::LogMessage( Debug::DebugInfo, "Renderer Total # renderers: %u\n", rendererCount ); } } @@ -145,7 +145,7 @@ void PrintCullCount( unsigned int frameCount, unsigned int culledCount ) { if( frameCount % 120 == 30 ) // Print every 2 seconds reg { - Debug::LogMessage( Debug::DebugInfo, "ImageRenderer # Culled renderers: %u\n", culledCount ); + Debug::LogMessage( Debug::DebugInfo, "Renderer # Culled renderers: %u\n", culledCount ); } } diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.cpp b/dali/internal/render/renderers/scene-graph-image-renderer.cpp index 370aa92..c44b29b 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-image-renderer.cpp @@ -21,11 +21,13 @@ // EXTERNAL INCLUDES #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -228,7 +230,12 @@ void ImageRenderer::ResolveGeometryTypes( BufferIndex bufferIndex, GeometryType& bool ImageRenderer::IsOutsideClipSpace( const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix ) { mContext->IncrementRendererCount(); - if(IsOutsideClipSpaceImpl( modelMatrix, modelViewProjectionMatrix ) ) + + Rect boundingBox( mGeometrySize.x * -0.5f, mGeometrySize.y * -0.5f, mGeometrySize.x, mGeometrySize.y ); + + DEBUG_BOUNDING_BOX( *mContext, boundingBox, modelViewProjectionMatrix ); + + if(Is2dBoxOutsideClipSpace( modelMatrix, modelViewProjectionMatrix, boundingBox ) ) { mContext->IncrementCulledCount(); return true; @@ -817,138 +824,6 @@ ImageRenderer::ImageRenderer( RenderDataProvider& dataprovider ) { } -// Frustum culling using clip space and oriented bounding box checks -bool ImageRenderer::IsOutsideClipSpaceImpl(const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix) -{ - // First, calculate if the center is inside clip space: - - // Downside is mvp matrix calc per renderer per frame - // and up to 4 matrix * vector calls. - const Matrix& mvp = modelViewProjectionMatrix; - const Vector4 translation = mvp.GetTranslation(); - - // Upside is point test is very simple: - if( -translation.w <= translation.x && translation.x <= translation.w && - -translation.w <= translation.y && translation.y <= translation.w && - -translation.w <= translation.z && translation.z <= translation.w) - { - // Definitely inside clip space - don't do any more processing - return false; - } - - // Transform oriented bounding box to clip space: - Vector4 topLeft( mGeometrySize.x * -0.5f, mGeometrySize.y * -0.5f, 0.0f, 1.0f); - Vector4 topRight( mGeometrySize.x * 0.5f, mGeometrySize.y * -0.5f, 0.0f, 1.0f); - Vector4 bottomLeft( mGeometrySize.x * -0.5f, mGeometrySize.y * 0.5f, 0.0f, 1.0f); - Vector4 bottomRight(mGeometrySize.x * 0.5f, mGeometrySize.y * 0.5f, 0.0f, 1.0f); - - Vector4 topLeftClip = mvp * topLeft; - if( -topLeftClip.w <= topLeftClip.x && topLeftClip.x <= topLeftClip.w && - -topLeftClip.w <= topLeftClip.y && topLeftClip.y <= topLeftClip.w && - -topLeftClip.w <= topLeftClip.z && topLeftClip.z <= topLeftClip.w ) - { - // Definitely inside clip space - don't do any more processing - return false; - } - - Vector4 bottomRightClip = mvp * bottomRight; - if( -bottomRightClip.w <= bottomRightClip.x && bottomRightClip.x <= bottomRightClip.w && - -bottomRightClip.w <= bottomRightClip.y && bottomRightClip.y <= bottomRightClip.w && - -bottomRightClip.w <= bottomRightClip.z && bottomRightClip.z <= bottomRightClip.w ) - { - // Definitely inside clip space - don't do any more processing - return false; - } - - Vector4 topRightClip = mvp * topRight; - if( -topRightClip.w <= topRightClip.x && topRightClip.x <= topRightClip.w && - -topRightClip.w <= topRightClip.y && topRightClip.y <= topRightClip.w && - -topRightClip.w <= topRightClip.z && topRightClip.z <= topRightClip.w ) - { - // Definitely inside clip space - don't do any more processing - return false; - } - - Vector4 bottomLeftClip = mvp * bottomLeft; - if( -bottomLeftClip.w <= bottomLeftClip.x && bottomLeftClip.x <= bottomLeftClip.w && - -bottomLeftClip.w <= bottomLeftClip.y && bottomLeftClip.y <= bottomLeftClip.w && - -bottomLeftClip.w <= bottomLeftClip.z && bottomLeftClip.z <= bottomLeftClip.w ) - { - // Definitely inside clip space - don't do any more processing - return false; - } - - // Check to see if all four points are outside each plane (AABB would cut this processing - // in half) - - unsigned int insideLeftPlaneCount=0; - unsigned int insideRightPlaneCount=0; - unsigned int insideTopPlaneCount=0; - unsigned int insideBottomPlaneCount=0; - - if(-topLeftClip.w <= topLeftClip.x) { insideLeftPlaneCount++; } - if(-topRightClip.w <= topRightClip.x){ insideLeftPlaneCount++; } - if(-bottomRightClip.w <= bottomRightClip.x) {insideLeftPlaneCount++;} - if(-bottomLeftClip.w <= bottomLeftClip.x) {insideLeftPlaneCount++;} - - if( insideLeftPlaneCount == 0 ) - { - return true; - } - - if(topLeftClip.x <= topLeftClip.w) { insideRightPlaneCount++;} - if(topRightClip.x <= topRightClip.w) { insideRightPlaneCount++; } - if(bottomRightClip.x <= bottomRightClip.w) { insideRightPlaneCount++; } - if(bottomLeftClip.x <= bottomLeftClip.w ) { insideRightPlaneCount++; } - - if( insideRightPlaneCount == 0 ) - { - return true; - } - - if(-topLeftClip.w <= topLeftClip.y ) {insideTopPlaneCount++; } - if(-topRightClip.w <= topRightClip.y) {insideTopPlaneCount++; } - if(-bottomRightClip.w <= bottomRightClip.y) {insideTopPlaneCount++;} - if(-bottomLeftClip.w <= bottomLeftClip.y) { insideTopPlaneCount++;} - - if( insideTopPlaneCount == 0 ) - { - return true; - } - - if(topLeftClip.y <= topLeftClip.w) { insideBottomPlaneCount++; } - if(topRightClip.y <= topRightClip.w) { insideBottomPlaneCount++; } - if(bottomRightClip.y <= bottomRightClip.w) { insideBottomPlaneCount++; } - if(bottomLeftClip.y <= bottomLeftClip.w) { insideBottomPlaneCount++; } - - if( insideBottomPlaneCount == 0 ) - { - return true; - } - - // Test if any planes are bisected, if they are, then there is likely to - // be an intersection into clip space. - - if( insideLeftPlaneCount < 4 ) - { - return false; - } - if( insideRightPlaneCount < 4 ) - { - return false; - } - if( insideTopPlaneCount < 4 ) - { - return false; - } - if( insideBottomPlaneCount < 4 ) - { - return false; - } - - return true; -} - } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.h b/dali/internal/render/renderers/scene-graph-image-renderer.h index 764bc4f..0017573 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.h +++ b/dali/internal/render/renderers/scene-graph-image-renderer.h @@ -204,13 +204,6 @@ private: // Undefined ImageRenderer& operator=(const ImageRenderer& rhs); - /** - * @param modelMatrix - * @param modelViewProjectionMatrix - * @return true if the renderer is outside clip space and doesn't need rendering - */ - bool IsOutsideClipSpaceImpl(const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix); - private: Texture* mTexture; diff --git a/dali/internal/render/renderers/scene-graph-renderer-debug.cpp b/dali/internal/render/renderers/scene-graph-renderer-debug.cpp new file mode 100644 index 0000000..f60e546 --- /dev/null +++ b/dali/internal/render/renderers/scene-graph-renderer-debug.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "scene-graph-renderer-debug.h" +#include +#include +#include +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ + +namespace +{ +#if defined ( DEBUG_ENABLED ) + +// Create shader for debug drawing +const std::string DEBUG_DRAW_VERTEX_SHADER( + "attribute mediump vec3 aPosition;\n" + "uniform mediump mat4 uMvpMatrix;\n" + "void main()\n" + "{\n" + " gl_Position = uMvpMatrix * vec4(aPosition, 1.0);\n" + "}\n" ); + +const std::string DEBUG_DRAW_FRAGMENT_SHADER( + "uniform lowp vec4 uColor;\n" + "void main()\n" + "{\n" + " gl_FragColor = uColor;\n" + "}\n" ); + +static Program* gDebugProgram(NULL); ///< a simple debug shader + +#endif +} // anonymous namespace + +void DebugBoundingBox(Context& context, Rect boundingBox, const Matrix& mvp) +{ +#if defined ( DEBUG_ENABLED ) + if( gDebugProgram == NULL ) + { + Integration::ShaderDataPtr shaderData( new Integration::ShaderData( DEBUG_DRAW_VERTEX_SHADER, DEBUG_DRAW_FRAGMENT_SHADER ) ); + const Integration::ResourceId dummyId(99999999); + gDebugProgram = Program::New( dummyId, shaderData.Get(), context, true ); + } + + context.SetBlend( false ); + context.CullFace( CullNone ); + + const unsigned int numPoints=8; + GLfloat vertices[numPoints*3] = { + boundingBox.x, boundingBox.y, 0.0f, + boundingBox.x, boundingBox.y + boundingBox.height, 0.0f, + + boundingBox.x, boundingBox.y + boundingBox.height, 0.0f, + boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height, 0.0f, + + boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height, 0.0f, + boundingBox.x + boundingBox.width, boundingBox.y, 0.0f, + + boundingBox.x + boundingBox.width, boundingBox.y, 0.0f, + boundingBox.x, boundingBox.y, 0.0f, + }; + + gDebugProgram->Use(); + + GpuBuffer vertexBuffer(context,GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW); + vertexBuffer.UpdateDataBuffer(numPoints * 3 * sizeof(float), &vertices[0]); + vertexBuffer.Bind(); + + GLint positionLoc = gDebugProgram->GetAttribLocation(Program::ATTRIB_POSITION); + context.VertexAttribPointer( positionLoc, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), 0 ); + context.EnableVertexAttributeArray( positionLoc ); + + GLint mvpLoc = gDebugProgram->GetUniformLocation(Program::UNIFORM_MVP_MATRIX); + if( mvpLoc != Program::UNIFORM_UNKNOWN ) + { + gDebugProgram->SetUniformMatrix4fv( mvpLoc, 1, mvp.AsFloat() ); + } + GLint colorLoc = gDebugProgram->GetUniformLocation(Program::UNIFORM_COLOR); + if( colorLoc != Program::UNIFORM_UNKNOWN ) + { + gDebugProgram->SetUniform4f( colorLoc, 0.0f, 1.0f, 1.0f, 1.0f ); + } + + context.DrawArrays(GL_LINES, 0, numPoints); + + context.DisableVertexAttributeArray( positionLoc ); +#endif +} + + +} // SceneGraph +} // Internal +} // Dali diff --git a/dali/internal/render/renderers/scene-graph-renderer-debug.h b/dali/internal/render/renderers/scene-graph-renderer-debug.h new file mode 100644 index 0000000..9f91c14 --- /dev/null +++ b/dali/internal/render/renderers/scene-graph-renderer-debug.h @@ -0,0 +1,50 @@ +#ifndef __DALI_INTERNAL_SCENEGRAPH_RENDERER_DEBUG_H__ +#define __DALI_INTERNAL_SCENEGRAPH_RENDERER_DEBUG_H__ + +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +// Uncomment to debug bounding boxes of objects +//#define DEBUG_DISPLAY_BOUNDING_BOX 1 + +namespace Dali +{ +namespace Internal +{ +class Context; + +namespace SceneGraph +{ +class RenderDataProvider; + +void DebugBoundingBox(Context& context, Rect boundingBox, const Matrix& mvp); + +#if defined(DEBUG_ENABLED) && defined(DEBUG_DISPLAY_BOUNDING_BOX) +#define DEBUG_BOUNDING_BOX( context, boundingBox, mvp ) \ + DebugBoundingBox( context, boundingBox, mvp ) +#else +#define DEBUG_BOUNDING_BOX( context, boundingBox, mvp ) +#endif + +} // SceneGraph +} // Internal +} // Dali + + +#endif // __DALI_INTERNAL_SCENEGRAPH_RENDERER_DEBUG_H__ diff --git a/dali/internal/render/renderers/scene-graph-renderer.cpp b/dali/internal/render/renderers/scene-graph-renderer.cpp index 55fdbdd..352d578 100644 --- a/dali/internal/render/renderers/scene-graph-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-renderer.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,8 @@ namespace Internal namespace { + + static Matrix gModelViewProjectionMatrix( false ); ///< a shared matrix to calculate the MVP matrix, dont want to store it locally to reduce storage overhead static Matrix3 gNormalMatrix; ///< a shared matrix to calculate normal matrix, dont want to store it locally to reduce storage overhead @@ -99,6 +102,7 @@ inline void SetMatrices( Program& program, program.SetUniformMatrix3fv( loc, 1, gNormalMatrix.AsFloat() ); } } + } namespace SceneGraph @@ -183,6 +187,7 @@ void Renderer::Render( BufferIndex bufferIndex, return; } } + // Take the program into use so we can send uniforms to it program.Use(); @@ -240,6 +245,7 @@ void Renderer::Render( BufferIndex bufferIndex, Renderer::Renderer( RenderDataProvider& dataprovider ) : mDataProvider( dataprovider ), mContext( NULL ), + mTextureCache( NULL ), mShader( NULL ), mSamplerBitfield( ImageSampler::DefaultOptions() ), diff --git a/dali/internal/render/renderers/scene-graph-renderer.h b/dali/internal/render/renderers/scene-graph-renderer.h index dfb26bb..c44e0d3 100644 --- a/dali/internal/render/renderers/scene-graph-renderer.h +++ b/dali/internal/render/renderers/scene-graph-renderer.h @@ -157,7 +157,7 @@ private: virtual void ResolveGeometryTypes( BufferIndex bufferIndex, GeometryType& outType, ShaderSubTypes& outSubType ) = 0; /** - * Checks if renderer's is culled. + * Checks if renderer is culled. * @param[in] modelMatrix The model matrix. * @param[in] modelViewProjectionMatrix The MVP matrix. * @return \e true if it is. Otherwise \e false. @@ -186,7 +186,6 @@ private: BlendingOptions mBlendingOptions; bool mUseBlend:1; ///< True if blending should be enabled, 1 bit is enough CullFaceMode mCullFaceMode:3; ///< cullface enum, 3 bits is enough - }; } // namespace SceneGraph diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.cpp b/dali/internal/render/renderers/scene-graph-text-renderer.cpp index 81d7c0f..1c2a857 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-text-renderer.cpp @@ -25,13 +25,15 @@ #include #include #include +#include #include -#include #include +#include +#include #include #include -#include #include +#include using namespace std; @@ -180,9 +182,7 @@ void TextRenderer::SetVertexData( TextVertexBuffer* vertexData ) // Get inverted text size, as this is faster for the shader to operate on, // and shader won't throw any errors performing a multiplication rather than a divide by zero // on a bad size value. - mInvTextSize = vertexData->mVertexMax; - mInvTextSize.x = mInvTextSize.x > Math::MACHINE_EPSILON_1 ? 1.0f / mInvTextSize.x : 1.0f; - mInvTextSize.y = mInvTextSize.y > Math::MACHINE_EPSILON_1 ? 1.0f / mInvTextSize.y : 1.0f; + mGeometryExtent = vertexData->mGeometryExtent; } else { @@ -334,7 +334,17 @@ void TextRenderer::ResolveGeometryTypes( BufferIndex bufferIndex, GeometryType& bool TextRenderer::IsOutsideClipSpace( const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix ) { - return false; // @todo add implementation + mContext->IncrementRendererCount(); + + Rect boundingBox(mGeometryExtent.width*-0.5f, mGeometryExtent.height*-0.5f, mGeometryExtent.width, mGeometryExtent.height); + DEBUG_BOUNDING_BOX( *mContext, boundingBox, modelViewProjectionMatrix ); + + if(Is2dBoxOutsideClipSpace( modelMatrix, modelViewProjectionMatrix, boundingBox ) ) + { + mContext->IncrementCulledCount(); + return true; + } + return false; } void TextRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix ) @@ -452,7 +462,12 @@ void TextRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Ma { const Vector4& color = mTextParameters->GetGradientColor(); program.SetUniform4f( gradientColorLoc, color.r, color.g, color.b, color.a ); - program.SetUniform2f( textSizeLoc, mInvTextSize.width, mInvTextSize.height ); + + Vector2 invTextSize( mGeometryExtent ); + invTextSize.x = invTextSize.x > Math::MACHINE_EPSILON_1 ? 1.0f / invTextSize.x : 1.0f; + invTextSize.y = invTextSize.y > Math::MACHINE_EPSILON_1 ? 1.0f / invTextSize.y : 1.0f; + + program.SetUniform2f( textSizeLoc, invTextSize.width, invTextSize.height ); } } @@ -496,6 +511,7 @@ void TextRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Ma mContext->DisableVertexAttributeArray( positionLoc ); mContext->DisableVertexAttributeArray( texCoordLoc ); + } TextRenderer::TextRenderer( RenderDataProvider& dataprovider ) @@ -505,7 +521,7 @@ TextRenderer::TextRenderer( RenderDataProvider& dataprovider ) mVertexBuffer(), mIndexBuffer(), mTextParameters(), - mInvTextSize(), + mGeometryExtent(), mTextureId( 0 ), mSmoothing( Dali::TextStyle::DEFAULT_SMOOTH_EDGE_DISTANCE_FIELD ), mPixelSize(0.0f) diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.h b/dali/internal/render/renderers/scene-graph-text-renderer.h index 7310e9a..fdb18ad 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.h +++ b/dali/internal/render/renderers/scene-graph-text-renderer.h @@ -185,12 +185,12 @@ private: OwnerPointer< GpuBuffer > mIndexBuffer; ///< GPU Buffer containing Index information OwnerPointer< TextParameters > mTextParameters; ///< Optional text parameters - Vector2 mInvTextSize; ///< 1.0 / (2D size of Vertices in vertex buffer (max extent - min extent)) + Vector2 mGeometryExtent; // actual geometry extent + ResourceId mTextureId; float mSmoothing; float mPixelSize; - }; } // namespace SceneGraph