From 581ce717f8421e80aa4192d66b91a3e4e1de3563 Mon Sep 17 00:00:00 2001 From: Ferran Sole Date: Thu, 4 Aug 2016 10:45:19 +0100 Subject: [PATCH] VR: Merge devel/master into devel/new_vr branch Change-Id: I84ff41ef1add19d2b9a15494d519bdd19f8e705b --- automated-tests/patch-coverage.pl | 197 +++++++- .../dali-test-suite-utils.cpp | 48 ++ .../dali-test-suite-utils/dali-test-suite-utils.h | 41 ++ .../test-trace-call-stack.cpp | 12 + .../dali-test-suite-utils/test-trace-call-stack.h | 13 + automated-tests/src/dali/utc-Dali-Actor.cpp | 270 +++++++++- automated-tests/src/dali/utc-Dali-Handle.cpp | 128 ++++- .../src/dali/utc-Dali-HitTestAlgorithm.cpp | 58 +-- .../src/dali/utc-Dali-HoverProcessing.cpp | 27 +- automated-tests/src/dali/utc-Dali-Layer.cpp | 55 +++ automated-tests/src/dali/utc-Dali-Renderer.cpp | 134 ++--- automated-tests/src/dali/utc-Dali-Scripting.cpp | 7 +- .../src/dali/utc-Dali-TouchDataProcessing.cpp | 26 +- .../src/dali/utc-Dali-TouchProcessing.cpp | 26 +- automated-tests/src/dali/utc-Dali-WeakHandle.cpp | 17 + dali/devel-api/object/weak-handle.cpp | 9 +- dali/internal/common/core-impl.cpp | 14 +- dali/internal/common/core-impl.h | 10 +- dali/internal/common/type-abstraction-enums.h | 2 +- dali/internal/event/actors/actor-impl.cpp | 154 +++--- dali/internal/event/actors/actor-impl.h | 15 +- dali/internal/event/actors/layer-impl.h | 8 +- dali/internal/event/common/object-impl.cpp | 80 ++- dali/internal/event/common/object-impl.h | 18 +- dali/internal/event/common/property-metadata.h | 5 + dali/internal/event/events/gesture-processor.cpp | 4 +- .../event/events/hit-test-algorithm-impl.cpp | 336 ++++++------- .../event/events/hit-test-algorithm-impl.h | 9 +- dali/internal/event/rendering/renderer-impl.cpp | 52 +- dali/internal/event/rendering/renderer-impl.h | 1 - dali/internal/file.list | 5 +- dali/internal/render/common/render-algorithms.cpp | 402 +++++++++------ dali/internal/render/common/render-debug.cpp | 36 +- dali/internal/render/common/render-debug.h | 8 + dali/internal/render/common/render-item.cpp | 2 +- dali/internal/render/common/render-item.h | 12 +- dali/internal/render/common/render-list.h | 64 +-- dali/internal/render/common/render-manager.cpp | 6 +- .../render/data-providers/uniform-name-cache.cpp | 67 --- .../render/data-providers/uniform-name-cache.h | 82 ---- dali/internal/render/renderers/render-renderer.cpp | 34 +- dali/internal/render/renderers/render-renderer.h | 59 +-- dali/internal/render/renderers/render-texture.cpp | 18 +- dali/internal/render/renderers/render-texture.h | 9 - .../update/manager/prepare-render-instructions.cpp | 543 --------------------- .../update/manager/prepare-render-instructions.h | 102 ---- .../internal/update/manager/process-render-tasks.h | 61 --- .../manager/render-instruction-processor.cpp | 474 ++++++++++++++++++ .../update/manager/render-instruction-processor.h | 151 ++++++ ...-render-tasks.cpp => render-task-processor.cpp} | 223 +++++---- .../update/manager/render-task-processor.h | 91 ++++ dali/internal/update/manager/transform-manager.cpp | 12 +- dali/internal/update/manager/update-algorithms.cpp | 2 +- .../update/manager/update-manager-debug.cpp | 12 +- .../internal/update/manager/update-manager-debug.h | 15 +- dali/internal/update/manager/update-manager.cpp | 43 +- dali/internal/update/manager/update-manager.h | 12 +- dali/internal/update/nodes/node.cpp | 33 +- dali/internal/update/nodes/node.h | 157 ++++-- dali/internal/update/nodes/scene-graph-layer.cpp | 1 - dali/internal/update/nodes/scene-graph-layer.h | 21 +- .../update/rendering/scene-graph-renderer.cpp | 43 +- .../update/rendering/scene-graph-renderer.h | 35 +- dali/public-api/actors/actor-enumerations.h | 100 ++-- dali/public-api/actors/actor.h | 127 +++-- dali/public-api/actors/camera-actor.h | 4 +- dali/public-api/actors/layer.h | 11 +- dali/public-api/animation/animation.h | 2 + dali/public-api/animation/constraint.h | 4 + dali/public-api/animation/key-frames.h | 2 + dali/public-api/animation/linear-constrainer.h | 2 + dali/public-api/animation/path.h | 2 + dali/public-api/common/stage.h | 2 + dali/public-api/dali-core-version.cpp | 4 +- dali/public-api/events/gesture-detector.h | 2 + .../events/long-press-gesture-detector.h | 3 +- dali/public-api/events/pan-gesture-detector.h | 2 + dali/public-api/events/pinch-gesture-detector.h | 2 + dali/public-api/events/tap-gesture-detector.h | 5 +- dali/public-api/events/touch-data.h | 2 + dali/public-api/images/resource-image.h | 4 + dali/public-api/math/quaternion.h | 2 + dali/public-api/object/base-handle.h | 9 + dali/public-api/object/handle.cpp | 10 + dali/public-api/object/handle.h | 51 ++ dali/public-api/object/object-registry.h | 2 + dali/public-api/object/property-notification.h | 2 + dali/public-api/object/property.cpp | 3 +- dali/public-api/object/property.h | 1 + dali/public-api/object/type-info.h | 2 + dali/public-api/object/type-registry.h | 2 + dali/public-api/render-tasks/render-task-list.h | 3 + dali/public-api/render-tasks/render-task.h | 2 + dali/public-api/rendering/renderer.h | 60 +-- dali/public-api/shader-effects/shader-effect.h | 2 + doc/dali-core-doc.h | 16 +- packaging/dali.spec | 2 +- 97 files changed, 2987 insertions(+), 2073 deletions(-) delete mode 100644 dali/internal/render/data-providers/uniform-name-cache.cpp delete mode 100644 dali/internal/render/data-providers/uniform-name-cache.h delete mode 100644 dali/internal/update/manager/prepare-render-instructions.cpp delete mode 100644 dali/internal/update/manager/prepare-render-instructions.h delete mode 100644 dali/internal/update/manager/process-render-tasks.h create mode 100644 dali/internal/update/manager/render-instruction-processor.cpp create mode 100644 dali/internal/update/manager/render-instruction-processor.h rename dali/internal/update/manager/{process-render-tasks.cpp => render-task-processor.cpp} (51%) create mode 100644 dali/internal/update/manager/render-task-processor.h diff --git a/automated-tests/patch-coverage.pl b/automated-tests/patch-coverage.pl index 68754eb..c19953b 100755 --- a/automated-tests/patch-coverage.pl +++ b/automated-tests/patch-coverage.pl @@ -45,16 +45,14 @@ our $repo = Git->repository(); our $debug=0; our $pd_debug=0; our $opt_cached; -our $opt_head; -#our $opt_workingtree; -#our $opt_diff=1; our $opt_help; -our $opt_verbose; +our $opt_output; our $opt_quiet; +our $opt_verbose; my %options = ( "cached" => { "optvar"=>\$opt_cached, "desc"=>"Use index" }, - "head" => { "optvar"=>\$opt_head, "desc"=>"Use git show" }, + "output:s" => { "optvar"=>\$opt_output, "desc"=>"Generate html output"}, "help" => { "optvar"=>\$opt_help, "desc"=>""}, "quiet" => { "optvar"=>\$opt_quiet, "desc"=>""}, "verbose" => { "optvar"=>\$opt_verbose, "desc"=>"" }); @@ -323,6 +321,7 @@ sub get_coverage # output for the patch. sub run_diff { + #print "run_diff(" . join(" ", @_) . ")\n"; my ($fh, $c) = $repo->command_output_pipe(@_); our @patch=(); while(<$fh>) @@ -332,6 +331,8 @@ sub run_diff } $repo->command_close_pipe($fh, $c); + print "Patch size: " . scalar(@patch) . "\n" if $debug; + # @patch has slurped diff for all files... my $filesref = parse_diff ( \@patch ); show_patch_lines($filesref) if $debug; @@ -344,6 +345,7 @@ sub run_diff for my $file (keys(%$filesref)) { my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); if($suffix eq ".cpp" || $suffix eq ".c" || $suffix eq ".h") { get_coverage($file, $filesref); @@ -353,7 +355,6 @@ sub run_diff return $filesref; } - sub calc_patch_coverage_percentage { my $filesref = shift; @@ -362,6 +363,9 @@ sub calc_patch_coverage_percentage foreach my $file (keys(%$filesref)) { + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); + my $covered_lines = 0; my $uncovered_lines = 0; @@ -401,7 +405,7 @@ sub calc_patch_coverage_percentage my $percent = 0; if($total_exec > 0) { $percent = 100 * $total_covered_lines / $total_exec; } - return $percent; + return [ $total_exec, $percent ]; } sub patch_output @@ -480,6 +484,117 @@ sub patch_output } +sub patch_html_output +{ + my $filesref = shift; + + open( my $filehandle, ">", $opt_output ) || die "Can't open $opt_output for writing:$!\n"; + + my $OUTPUT_FH = select; + select $filehandle; + print < + + +Patch Coverage + + +EOH + + foreach my $file (keys(%$filesref)) + { + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); + + my $patchref = $filesref->{$file}->{"patch"}; + my $b_lines_ref = $filesref->{$file}->{"b_lines"}; + my $coverage_ref = $filesref->{$file}->{"coverage"}; + print "

$file

\n"; + + if($coverage_ref) + { + if( $coverage_ref->{"covered_lines"} > 0 + || + $coverage_ref->{"uncovered_lines"} > 0 ) + { + print "

Covered: " . + $coverage_ref->{"covered_lines"} . "

" . + "

Uncovered: " . + $coverage_ref->{"uncovered_lines"} . "

"; + } + } + else + { + print "

"; + my $span=0; + if($suffix eq ".cpp" || $suffix eq ".c" || $suffix eq ".h") + { + print ""; + $span=1; + } + print "No coverage found"; + print "" if $span; + } + print "

"; + + for my $patch (@$patchref) + { + my $hunkstr="Hunk: " . $patch->[0]; + if( $patch->[1] > 1 ) + { + $hunkstr .= " - " . ($patch->[0]+$patch->[1]-1); + } + print "

" . $hunkstr . "

"; + + print "
";
+            for(my $i = 0; $i < $patch->[1]; $i++ )
+            {
+                my $line = $i + $patch->[0];
+                my $num_line_digits=log($line)/log(10);
+                for $i (0..(6-$num_line_digits-1))
+                {
+                    print " ";
+                }
+                print "$line  ";
+
+                if($coverage_ref)
+                {
+                    my $color;
+                    if($coverage_ref->{"covered"}->{$line})
+                    {
+                        print("");
+                    }
+                    elsif($coverage_ref->{"uncovered"}->{$line})
+                    {
+                        print("");
+                    }
+                    else
+                    {
+                        #print("");
+                    }
+                    my $src=$coverage_ref->{"src"}->{$line};
+                    chomp($src);
+                    #print $color, "$src\n", RESET;
+                    print "$src\n";
+                }
+                else
+                {
+                    # We don't have coverage data, so print it from the patch instead.
+                    my $src = $b_lines_ref->{$line};
+                    print "$src\n";
+                }
+            }
+            print "<\pre>\n";
+        }
+    }
+
+    print $filehandle "
\n\n\n"; + close $filehandle; + select $OUTPUT_FH; +} + + ################################################################################ ## MAIN ## ################################################################################ @@ -492,30 +607,82 @@ chdir "build/tizen"; my @cmd=('--no-pager','diff','--no-ext-diff','-U0','--no-color'); my $status = $repo->command("status", "-s"); -if( $status eq "" ) +if( $status eq "" && !scalar(@ARGV)) { - # There are no changes in the index or working tree. Use the last patch instead + # There are no changes in the index or working tree, and + # no diff arguments to append. Use the last patch instead. push @cmd, ('HEAD~1','HEAD'); } -elsif($opt_cached) # TODO: Remove this option. Instead, need full diff +else { - push @cmd, "--cached"; + # detect if there are only cached changes or only working tree changes + my $cached = 0; + my $working = 0; + for my $fstat ( split(/\n/, $status) ) + { + if(substr( $fstat, 0, 1 ) ne " "){ $cached++; } + if(substr( $fstat, 1, 1 ) ne " "){ $working++; } + } + if($cached > 0 ) + { + if($working == 0) + { + push @cmd, "--cached"; + } + else + { + die "Both cached & working files - cannot get correct patch from git\n"; + # Would have to diff from separate clone. + } + } } push @cmd, @ARGV; my $filesref = run_diff(@cmd); -my $percent = calc_patch_coverage_percentage($filesref); -if( ! $opt_quiet ) +chdir $cwd; + +# Check how many actual source files there are in the patch +my $filecount = 0; +foreach my $file (keys(%$filesref)) +{ + my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$}); + next if($path !~ /^dali/); + next if($suffix ne ".cpp" && $suffix ne ".c" && $suffix ne ".h"); + $filecount++; +} +if( $filecount == 0 ) +{ + print "No source files found\n"; + exit 0; # Exit with no error. +} + +my $percentref = calc_patch_coverage_percentage($filesref); +if($percentref->[0] == 0) +{ + print "No coverable lines found\n"; + exit 0; +} +my $percent = $percentref->[1]; + +my $color=BOLD RED; +if($opt_output) +{ + print "Outputing to $opt_output\n" if $debug; + patch_html_output($filesref); +} +elsif( ! $opt_quiet ) { patch_output($filesref); - my $color=BOLD RED; if($percent>=90) { $color=GREEN; } - printf("Percentage of change covered: $color %5.2f%\n" . RESET, $percent); + print RESET; } + +printf("Percentage of change covered: %5.2f%\n", $percent); + exit($percent<90); diff --git a/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.cpp b/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.cpp index 467bb52..b50f506 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.cpp @@ -337,3 +337,51 @@ BufferImage CreateBufferImage() { return CreateBufferImage(4, 4, Color::WHITE); } + +namespace Test +{ + +struct ObjectDestructionFunctor +{ + // Create a ObjectDestructionFunctor passing in a Dali::RefObject* to be monitored and a bool variable. + // Create ObjectRegistry instance and connect to the ObjectDestroyedSignal passing in the above functor for the callback. + // Get the ObjectPointer (Actor::GetObjectPtr) of the Actor to be checked for destruction and assign it to the Dali::RefObject* + // Check the bool variable which would be true when object destroyed. + ObjectDestructionFunctor( Dali::RefObject* objectPtr, bool& refObjectDestroyed ) + : refObjectPointerToCheck( objectPtr ), + refObjectDestroyedBoolean( refObjectDestroyed ) + { + refObjectDestroyed = false; + } + + void operator()( const Dali::RefObject* objectPointer ) + { + if ( refObjectPointerToCheck == objectPointer ) + { + refObjectDestroyedBoolean = true; + } + } + + Dali::RefObject* refObjectPointerToCheck; + bool& refObjectDestroyedBoolean; +}; + +ObjectDestructionTracker::ObjectDestructionTracker() + :mRefObjectDestroyed( false) +{ +} + +void ObjectDestructionTracker::Start( Actor actor ) +{ + ObjectDestructionFunctor destructionFunctor( actor.GetObjectPtr(), mRefObjectDestroyed ); + + ObjectRegistry objectRegistry = Stage::GetCurrent().GetObjectRegistry(); + objectRegistry.ObjectDestroyedSignal().Connect( this, destructionFunctor ); +} + +bool ObjectDestructionTracker::IsDestroyed() +{ + return mRefObjectDestroyed; +} + +} // namespace Test diff --git a/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.h b/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.h index 7f81872..8cefb7c 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.h +++ b/automated-tests/src/dali/dali-test-suite-utils/dali-test-suite-utils.h @@ -499,4 +499,45 @@ struct DefaultFunctionCoverage BufferImage CreateBufferImage(); BufferImage CreateBufferImage(int width, int height, const Vector4& color); +// Test namespace to prevent pollution of Dali namespace, add Test helper functions here +namespace Test +{ +/** + * @brief + * + * Helper to check object destruction occurred + * 1) In main part of code create an ObjectDestructionTracker + * 2) Within sub section of main create object Actor test and call Start with Actor to test for destruction + * 3) Perform code which is expected to destroy Actor + * 4) Back in main part of code use IsDestroyed() to test if Actor was destroyed + */ +class ObjectDestructionTracker : public ConnectionTracker +{ +public: + + /** + * @brief Call in main part of code + */ + ObjectDestructionTracker(); + + /** + * @brief Call in sub bock of code where the Actor being checked is still alive. + * + * @param[in] actor Actor to be checked for destruction + */ + void Start( Actor actor ); + + /** + * @brief Call to check if Actor alive or destroyed. + * + * @return bool true if Actor was destroyed + */ + bool IsDestroyed(); + +private: + bool mRefObjectDestroyed; +}; + +} // namespace Test + #endif // __DALI_TEST_SUITE_UTILS_H__ diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp index 3f2e6e5..0054e59 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp @@ -130,6 +130,18 @@ bool TraceCallStack::FindMethodAndParams(std::string method, const NamedParams& return FindIndexFromMethodAndParams( method, params ) > -1; } +bool TraceCallStack::FindMethodAndParamsFromStartIndex( std::string method, std::string params, size_t& startIndex ) const +{ + for( size_t i = startIndex; i < mCallStack.size(); ++i ) + { + if( ( mCallStack[i].method.compare( method ) == 0 ) && ( mCallStack[i].paramList.compare( params ) == 0 ) ) + { + startIndex = i; + return true; + } + } + return false; +} /** * Search for a method in the stack with the given parameter list diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h index 137bfaf..e1882ea 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h @@ -102,6 +102,19 @@ public: bool FindMethodAndParams(std::string method, const NamedParams& params) const; /** + * Search for a method in the stack with the given parameter list. + * The search is done from a given index. + * This allows the order of methods and parameters to be checked. + * @param[in] method The name of the method + * @param[in] params A comma separated list of parameter values + * @param[in/out] startIndex The method index to start looking from. + * This is updated if a method is found so subsequent + * calls can search for methods occuring after this one. + * @return True if the method was in the stack + */ + bool FindMethodAndParamsFromStartIndex( std::string method, std::string params, size_t& startIndex ) const; + + /** * Search for a method in the stack with the given parameter list * @param[in] method The name of the method * @param[in] params A comma separated list of parameter values diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index f4f3fcc..a6eaa9c 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -2500,17 +2500,11 @@ int UtcDaliActorSetDrawMode(void) DALI_TEST_CHECK( DrawMode::OVERLAY_2D == a.GetDrawMode() ); // Check Actor is overlay - a.SetDrawMode( DrawMode::STENCIL ); - app.SendNotification(); - app.Render(1); - - DALI_TEST_CHECK( DrawMode::STENCIL == a.GetDrawMode() ); // Check Actor is stencil, not overlay - a.SetDrawMode( DrawMode::NORMAL ); app.SendNotification(); app.Render(1); - DALI_TEST_CHECK( DrawMode::NORMAL == a.GetDrawMode() ); // Check Actor is not stencil + DALI_TEST_CHECK( DrawMode::NORMAL == a.GetDrawMode() ); // Check Actor is normal END_TEST; } @@ -2855,6 +2849,9 @@ const PropertyStringIndex PROPERTY_TABLE[] = { "padding", Actor::Property::PADDING, Property::VECTOR4 }, { "minimumSize", Actor::Property::MINIMUM_SIZE, Property::VECTOR2 }, { "maximumSize", Actor::Property::MAXIMUM_SIZE, Property::VECTOR2 }, + { "inheritPosition", Actor::Property::INHERIT_POSITION, Property::BOOLEAN }, + { "batchParent", Actor::Property::BATCH_PARENT, Property::BOOLEAN }, + { "clippingMode", Actor::Property::CLIPPING_MODE, Property::STRING }, }; const unsigned int PROPERTY_TABLE_COUNT = sizeof( PROPERTY_TABLE ) / sizeof( PROPERTY_TABLE[0] ); } // unnamed namespace @@ -3550,3 +3547,262 @@ int UtcDaliActorRemoveRendererN(void) END_TEST; } + +// Clipping test helper functions: +Actor CreateActorWithContent() +{ + BufferImage image = BufferImage::New( 16u, 16u ); + Actor actor = CreateRenderableActor( image ); + + // Setup dimensions and position so actor is not skipped by culling. + actor.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS ); + actor.SetSize( 16.0f, 16.0f ); + actor.SetParentOrigin( ParentOrigin::CENTER ); + actor.SetAnchorPoint( AnchorPoint::CENTER ); + + return actor; +} + +void GenerateTrace( TestApplication& application, TraceCallStack& enabledDisableTrace, TraceCallStack& stencilTrace ) +{ + enabledDisableTrace.Reset(); + stencilTrace.Reset(); + enabledDisableTrace.Enable( true ); + stencilTrace.Enable( true ); + + application.SendNotification(); + application.Render(); + + enabledDisableTrace.Enable( false ); + stencilTrace.Enable( false ); +} + +void CheckColorMask( TestGlAbstraction& glAbstraction, bool maskValue ) +{ + const TestGlAbstraction::ColorMaskParams& colorMaskParams = glAbstraction.GetColorMaskParams(); + + DALI_TEST_EQUALS( colorMaskParams.red, maskValue, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.green, maskValue, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.blue, maskValue, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.alpha, maskValue, TEST_LOCATION ); +} + +int UtcDaliActorPropertyClippingP(void) +{ + // This test checks the clippingMode property. + tet_infoline( "Testing Actor::Property::CLIPPING_MODE P" ); + TestApplication application; + + Actor actor = Actor::New(); + + // Check default clippingEnabled value. + Property::Value getValue( actor.GetProperty( Actor::Property::CLIPPING_MODE ) ); + + int value = 0; + bool getValueResult = getValue.Get( value ); + DALI_TEST_CHECK( getValueResult ); + + if( getValueResult ) + { + DALI_TEST_EQUALS( value, ClippingMode::DISABLED, TEST_LOCATION ); + } + + // Check setting the property. + actor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + + // Check the new value was set. + getValue = actor.GetProperty( Actor::Property::CLIPPING_MODE ); + getValueResult = getValue.Get( value ); + DALI_TEST_CHECK( getValueResult ); + + if( getValueResult ) + { + DALI_TEST_EQUALS( value, ClippingMode::CLIP_CHILDREN, TEST_LOCATION ); + } + + END_TEST; +} + +int UtcDaliActorPropertyClippingN(void) +{ + // Negative test case for Clipping. + tet_infoline( "Testing Actor::Property::CLIPPING_MODE N" ); + TestApplication application; + + Actor actor = Actor::New(); + + // Check default clippingEnabled value. + Property::Value getValue( actor.GetProperty( Actor::Property::CLIPPING_MODE ) ); + + int value = 0; + bool getValueResult = getValue.Get( value ); + DALI_TEST_CHECK( getValueResult ); + + if( getValueResult ) + { + DALI_TEST_EQUALS( value, ClippingMode::DISABLED, TEST_LOCATION ); + } + + // Check setting an invalid property value won't change the current property value. + actor.SetProperty( Actor::Property::CLIPPING_MODE, "INVALID_PROPERTY" ); + + getValue = actor.GetProperty( Actor::Property::CLIPPING_MODE ); + getValueResult = getValue.Get( value ); + DALI_TEST_CHECK( getValueResult ); + + if( getValueResult ) + { + DALI_TEST_EQUALS( value, ClippingMode::DISABLED, TEST_LOCATION ); + } + + END_TEST; +} + +int UtcDaliActorPropertyClippingActor(void) +{ + // This test checks that an actor is correctly setup for clipping. + tet_infoline( "Testing Actor::Property::CLIPPING_MODE actor" ); + TestApplication application; + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace(); + TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace(); + size_t startIndex = 0u; + + // Create a clipping actor. + Actor actorDepth1Clip = CreateActorWithContent(); + actorDepth1Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + Stage::GetCurrent().Add( actorDepth1Clip ); + + // Gather the call trace. + GenerateTrace( application, enabledDisableTrace, stencilTrace ); + + // Check we are writing to the color buffer. + CheckColorMask( glAbstraction, true ); + + // Check the stencil buffer was enabled. + DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "2960" ) ); // 2960 is GL_STENCIL_TEST + + // Check the stencil buffer was cleared. + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "ClearStencil", "0", startIndex ) ); + + // Check the correct setup was done to write to the first bit-plane (only) of the stencil buffer. + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 1, 0", startIndex ) ); // 514 is GL_EQUAL, But testing no bit-planes for the first clipping node. + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilMask", "1", startIndex ) ); + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7681, 7681", startIndex ) ); // GL_KEEP, GL_REPLACE, GL_REPLACE + + END_TEST; +} + +int UtcDaliActorPropertyClippingNestedChildren(void) +{ + // This test checks that a hierarchy of actors are clipped correctly by + // writing to and reading from the correct bit-planes of the stencil buffer. + tet_infoline( "Testing Actor::Property::CLIPPING_MODE nested children" ); + TestApplication application; + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace(); + TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace(); + + // Create a clipping actor. + Actor actorDepth1Clip = CreateActorWithContent(); + actorDepth1Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + Stage::GetCurrent().Add( actorDepth1Clip ); + + // Create a child actor. + Actor childDepth2 = CreateActorWithContent(); + actorDepth1Clip.Add( childDepth2 ); + + // Create another clipping actor. + Actor childDepth2Clip = CreateActorWithContent(); + childDepth2Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + childDepth2.Add( childDepth2Clip ); + + // Create another 2 child actors. We do this so 2 nodes will have the same clipping ID. + // This tests the sort algorithm. + Actor childDepth3 = CreateActorWithContent(); + childDepth2Clip.Add( childDepth3 ); + Actor childDepth4 = CreateActorWithContent(); + childDepth3.Add( childDepth4 ); + + // Gather the call trace. + GenerateTrace( application, enabledDisableTrace, stencilTrace ); + + // Check we are writing to the color buffer. + CheckColorMask( glAbstraction, true ); + + // Check the stencil buffer was enabled. + DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "2960" ) ); // 2960 is GL_STENCIL_TEST + + // Perform the test twice, once for 2D layer, and once for 3D. + for( unsigned int i = 0u ; i < 2u; ++i ) + { + size_t startIndex = 0u; + + // Check the stencil buffer was cleared. + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "ClearStencil", "0", startIndex ) ); + + // Check the correct setup was done to write to the first bit-plane (only) of the stencil buffer. + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 1, 0", startIndex ) ); // 514 is GL_EQUAL, But testing no bit-planes for the first clipping node. + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilMask", "1", startIndex ) ); // Write to the first bit-plane + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7681, 7681", startIndex ) ); // GL_KEEP, GL_REPLACE, GL_REPLACE + + // Check the correct setup was done to test against first bit-plane (only) of the stencil buffer. + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 1, 255", startIndex ) ); // 514 is GL_EQUAL + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7680, 7680", startIndex ) ); // GL_KEEP, GL_KEEP, GL_KEEP + + // Check we are set up to write to the second bitplane of the stencil buffer (only). + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 3, 1", startIndex ) ); // 514 is GL_EQUAL, Test both bit-planes 1 & 2 + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilMask", "3", startIndex ) ); // Write to second (and previous) bit-planes + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7681, 7681", startIndex ) ); // GL_KEEP, GL_REPLACE, GL_REPLACE + + // Check we are set up to test against both the first and second bit-planes of the stencil buffer. + // (Both must be set to pass the check). + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilFunc", "514, 3, 255", startIndex ) ); // 514 is GL_EQUAL, Test both bit-planes 1 & 2 + DALI_TEST_CHECK( stencilTrace.FindMethodAndParamsFromStartIndex( "StencilOp", "7680, 7680, 7680", startIndex ) ); // GL_KEEP, GL_KEEP, GL_KEEP + + // If we are on the first loop, set the layer to 3D and loop to perform the test again. + if( i == 0u ) + { + Stage::GetCurrent().GetRootLayer().SetBehavior( Layer::LAYER_3D ); + GenerateTrace( application, enabledDisableTrace, stencilTrace ); + } + } + + END_TEST; +} + +int UtcDaliActorPropertyClippingActorWithRendererOverride(void) +{ + // This test checks that an actor with clipping will be ignored if overridden by the Renderer properties. + tet_infoline( "Testing Actor::Property::CLIPPING_MODE actor with renderer override" ); + TestApplication application; + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace(); + TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace(); + + // Create a clipping actor. + Actor actorDepth1Clip = CreateActorWithContent(); + actorDepth1Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + Stage::GetCurrent().Add( actorDepth1Clip ); + + // Turn the RenderMode to just "COLOR" at the Renderer level to ignore the clippingMode. + actorDepth1Clip.GetRendererAt( 0 ).SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR ); + + // Gather the call trace. + GenerateTrace( application, enabledDisableTrace, stencilTrace ); + + // Check we are writing to the color buffer. + CheckColorMask( glAbstraction, true ); + + // Check the stencil buffer was not enabled. + DALI_TEST_CHECK( !enabledDisableTrace.FindMethodAndParams( "Enable", "2960" ) ); // 2960 is GL_STENCIL_TEST + + // Check stencil functions are not called. + DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilFunc" ) ); + DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilMask" ) ); + DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilOp" ) ); + + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-Handle.cpp b/automated-tests/src/dali/utc-Dali-Handle.cpp index 4595d31..387676b 100644 --- a/automated-tests/src/dali/utc-Dali-Handle.cpp +++ b/automated-tests/src/dali/utc-Dali-Handle.cpp @@ -592,7 +592,7 @@ int UtcDaliHandleSetProperty02(void) END_TEST; } -int UtcDaliHandleRegisterProperty(void) +int UtcDaliHandleRegisterProperty01(void) { tet_infoline("Positive Test Dali::Handle::RegisterProperty()"); TestApplication application; @@ -629,6 +629,108 @@ int UtcDaliHandleRegisterProperty(void) END_TEST; } +int UtcDaliHandleRegisterProperty02(void) +{ + tet_infoline("Positive Test Dali::Handle::RegisterProperty() int key"); + TestApplication application; + + Stage stage = Stage::GetCurrent(); + + Actor actor = Actor::New(); + stage.Add( actor ); + + const unsigned int defaultPropertyCount = actor.GetPropertyCount(); + + application.SendNotification(); + application.Render(); + + Property::Index key1 = CORE_PROPERTY_MAX_INDEX+1; + Property::Index key2 = CORE_PROPERTY_MAX_INDEX+2; + + const Vector4 testColor(0.5f, 0.2f, 0.9f, 1.0f); + const float withFlake(99.f); + + Property::Index index1 = actor.RegisterProperty( "MyPropertyOne", Vector3::ONE ); + Property::Index index2 = actor.RegisterProperty( key1, "sideColor", testColor); + Property::Index index3 = actor.RegisterProperty( key2, "iceCream", withFlake ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( actor.GetPropertyCount(), defaultPropertyCount + 3, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( index1 ), Vector3::ONE, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< Vector4 >( index2 ), testColor, TEST_LOCATION ); + DALI_TEST_EQUALS( actor.GetProperty< float >( index3 ), withFlake, TEST_LOCATION ); + + // No new property should be registered when we call the below functions + Property::Index testIndex2 = actor.RegisterProperty( "iceCream", 2200.f ); + Property::Index testIndex1 = actor.RegisterProperty( "sideColor", Color::BLACK ); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( index2, testIndex1, TEST_LOCATION ); // We should have the same index as per the first registration + DALI_TEST_EQUALS( index3, testIndex2, TEST_LOCATION ); // We should have the same index as per the first registration + DALI_TEST_EQUALS( actor.GetPropertyCount(), defaultPropertyCount + 3, TEST_LOCATION ); // Property count should be the same + DALI_TEST_EQUALS( actor.GetProperty< Vector4 >( index2 ), Color::BLACK, TEST_LOCATION ); // Value should be what we sent on second RegisterProperty call + DALI_TEST_EQUALS( actor.GetProperty< float >( index3 ), 2200.f, TEST_LOCATION ); + + END_TEST; +} + + +int UtcDaliHandleGetPropertyIndex02(void) +{ + tet_infoline("Positive Test Dali::Handle::GetPropertyIndex() int key"); + TestApplication application; + + Stage stage = Stage::GetCurrent(); + + Actor actor = Actor::New(); + stage.Add( actor ); + + const unsigned int defaultPropertyCount = actor.GetPropertyCount(); + + application.SendNotification(); + application.Render(); + + Property::Index key1 = CORE_PROPERTY_MAX_INDEX+1; + Property::Index key2 = CORE_PROPERTY_MAX_INDEX+2; + + const Vector4 testColor(0.5f, 0.2f, 0.9f, 1.0f); + const float withFlake(99.f); + + Property::Index index1 = actor.RegisterProperty( "MyPropertyOne", Vector3::ONE ); + Property::Index index2 = actor.RegisterProperty( key1, "sideColor", testColor); + Property::Index index3 = actor.RegisterProperty( "MyPropertyTwo", Vector3::ONE ); + Property::Index index4 = actor.RegisterProperty( key2, "iceCream", withFlake ); + Property::Index index5 = actor.RegisterProperty( "MyPropertyThree", Vector3::ONE ); + + application.SendNotification(); + application.Render(); + + // Test that we can get the property index from the integer key + Property::Index testIndex1 = actor.GetPropertyIndex( key1 ); + Property::Index testIndex2 = actor.GetPropertyIndex( key2 ); + + DALI_TEST_EQUALS( index2, testIndex1, TEST_LOCATION ); + DALI_TEST_EQUALS( index4, testIndex2, TEST_LOCATION ); + + // Test that we keep the same indices on the named properties + Property::Index testIndex = actor.GetPropertyIndex("MyPropertyOne"); + DALI_TEST_EQUALS(testIndex, index1, TEST_LOCATION); + testIndex = actor.GetPropertyIndex("MyPropertyTwo"); + DALI_TEST_EQUALS(testIndex, index3, TEST_LOCATION); + testIndex = actor.GetPropertyIndex("MyPropertyThree"); + DALI_TEST_EQUALS(testIndex, index5, TEST_LOCATION); + testIndex = actor.GetPropertyIndex("sideColor"); + DALI_TEST_EQUALS(testIndex, index2, TEST_LOCATION); + testIndex = actor.GetPropertyIndex("iceCream"); + DALI_TEST_EQUALS(testIndex, index4, TEST_LOCATION); + + DALI_TEST_EQUALS(defaultPropertyCount+5, actor.GetPropertyCount(), TEST_LOCATION); + END_TEST; +} + int UtcDaliHandleGetProperty(void) { tet_infoline("Positive Test Dali::Handle::GetProperty()"); @@ -692,8 +794,27 @@ int UtcDaliHandleGetPropertyIndices(void) // Actor Actor actor = Actor::New(); actor.GetPropertyIndices( indices ); - DALI_TEST_CHECK( indices.Size() ); - DALI_TEST_EQUALS( indices.Size(), actor.GetPropertyCount(), TEST_LOCATION ); + int numDefaultProperties = indices.Size(); + DALI_TEST_CHECK( numDefaultProperties > 0 ); + DALI_TEST_EQUALS( numDefaultProperties, actor.GetPropertyCount(), TEST_LOCATION ); + + const Vector4 testColor(0.5f, 0.2f, 0.9f, 1.0f); + const float withFlake(99.f); + + Property::Index key1 = CORE_PROPERTY_MAX_INDEX+1; + Property::Index key2 = CORE_PROPERTY_MAX_INDEX+2; + + actor.RegisterProperty( "MyPropertyOne", Vector3::ONE ); + actor.RegisterProperty( key1, "sideColor", testColor); + actor.RegisterProperty( "MyPropertyTwo", 1234 ); + Property::Index index4 = actor.RegisterProperty( key2, "iceCream", withFlake ); + actor.RegisterProperty( "MyPropertyThree", Vector2(.2f,.7f) ); + + actor.GetPropertyIndices( indices ); + + DALI_TEST_EQUALS( indices.Size(), numDefaultProperties + 5, TEST_LOCATION ); + DALI_TEST_EQUALS( indices[indices.Size()-2], index4, TEST_LOCATION ); + END_TEST; } @@ -785,4 +906,3 @@ int UtcDaliHandleWeightNew(void) END_TEST; } - diff --git a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp index 99d16c4..b4cd632 100644 --- a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp +++ b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp @@ -361,7 +361,7 @@ int UtcDaliHitTestAlgorithmOrtho02(void) END_TEST; } -int UtcDaliHitTestAlgorithmStencil(void) +int UtcDaliHitTestAlgorithmClippingActor(void) { TestApplication application; tet_infoline("Testing Dali::HitTestAlgorithm with a stencil"); @@ -377,42 +377,38 @@ int UtcDaliHitTestAlgorithmStencil(void) layer.SetName( "layer" ); stage.Add( layer ); - // Create a stencil and add that to the layer - Actor stencil = CreateRenderableActor(Dali::BufferImage::WHITE() ); - stencil.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - stencil.SetParentOrigin( ParentOrigin::TOP_LEFT ); - stencil.SetSize( 50.0f, 50.0f ); - stencil.SetDrawMode( DrawMode::STENCIL ); - stencil.SetName( "stencil" ); - layer.Add( stencil ); - - // Create a renderable actor and add that to the layer - Actor layerHitActor = CreateRenderableActor( Dali::BufferImage::WHITE() ); - layerHitActor.SetSize( 100.0f, 100.0f ); - layerHitActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - layerHitActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); - layerHitActor.SetName( "layerHitActor" ); - layer.Add( layerHitActor ); + // Create a clipping actor and add it to the layer. + Actor clippingActor = CreateRenderableActor( Dali::BufferImage::WHITE() ); + clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + clippingActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + clippingActor.SetSize( 50.0f, 50.0f ); + clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + clippingActor.SetName( "clippingActor" ); + layer.Add( clippingActor ); + + // Create a renderable actor and add it to the clipping actor. + Actor childActor = CreateRenderableActor( Dali::BufferImage::WHITE() ); + childActor.SetSize( 100.0f, 100.0f ); + childActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + childActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + childActor.SetName( "childActor" ); + clippingActor.Add( childActor ); // Render and notify application.SendNotification(); application.Render(); - // Hit within stencil and actor - { - HitTestAlgorithm::Results results; - HitTest(stage, Vector2( 10.0f, 10.0f ), results, &DefaultIsActorTouchableFunction); - DALI_TEST_CHECK( results.actor == layerHitActor ); - tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) ); - } + // Hit within clippingActor and childActor. + HitTestAlgorithm::Results results; + HitTest( stage, Vector2( 10.0f, 10.0f ), results, &DefaultIsActorTouchableFunction ); + DALI_TEST_CHECK( results.actor == childActor ); + tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) ); + + // Hit within childActor but outside of clippingActor, should hit the root-layer instead. + HitTest( stage, Vector2( 60.0f, 60.0f ), results, &DefaultIsActorTouchableFunction); + DALI_TEST_CHECK( results.actor == rootLayer ); + tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) ); - // Hit within actor but outside of stencil, should hit the root-layer - { - HitTestAlgorithm::Results results; - HitTest(stage, Vector2( 60.0f, 60.0f ), results, &DefaultIsActorTouchableFunction); - DALI_TEST_CHECK( results.actor == rootLayer ); - tet_printf( "Hit: %s\n", ( results.actor ? results.actor.GetName().c_str() : "NULL" ) ); - } END_TEST; } diff --git a/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp b/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp index 7dd76a6..fd4a7e5 100644 --- a/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-HoverProcessing.cpp @@ -1248,38 +1248,37 @@ int UtcDaliHoverLeaveActorReadded(void) END_TEST; } - -int UtcDaliHoverStencilNonRenderableActor(void) +int UtcDaliHoverClippingActor(void) { TestApplication application; Stage stage = Stage::GetCurrent(); Actor actor = Actor::New(); - actor.SetSize(100.0f, 100.0f); - actor.SetAnchorPoint(AnchorPoint::TOP_LEFT); - stage.Add(actor); + actor.SetSize( 100.0f, 100.0f ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + stage.Add( actor ); - Actor stencil = Actor::New(); - stencil.SetSize(50.0f, 50.0f); - stencil.SetAnchorPoint(AnchorPoint::TOP_LEFT); - stencil.SetDrawMode( DrawMode::STENCIL ); - stage.Add(stencil); + Actor clippingActor = Actor::New(); + clippingActor.SetSize( 50.0f, 50.0f ); + clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + stage.Add( clippingActor ); - // Render and notify + // Render and notify. application.SendNotification(); application.Render(); - // Connect to actor's hovered signal + // Connect to actor's hovered signal. SignalData data; HoverEventFunctor functor( data ); actor.HoveredSignal().Connect( &application, functor ); - // Emit an event within stencil area + // Emit an event within clipped area. application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, Vector2( 10.0f, 10.0f ) ) ); DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); data.Reset(); - // Emit an event outside the stencil area but within the actor area, we should have a hit! + // Emit an event outside the clipped area but within the actor area, we should have a hit. application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, Vector2( 60.0f, 60.0f ) ) ); DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); data.Reset(); diff --git a/automated-tests/src/dali/utc-Dali-Layer.cpp b/automated-tests/src/dali/utc-Dali-Layer.cpp index 34c5741..7b31004 100644 --- a/automated-tests/src/dali/utc-Dali-Layer.cpp +++ b/automated-tests/src/dali/utc-Dali-Layer.cpp @@ -583,3 +583,58 @@ int UtcDaliLayerBehaviour(void) DALI_TEST_EQUALS( layer.GetBehavior(), Dali::Layer::LAYER_3D, TEST_LOCATION ); END_TEST; } + +Actor CreateActor( bool withAlpha ) +{ + Dali::BufferImage bufferImage; + + if( withAlpha ) + { + bufferImage = Dali::BufferImage::WHITE(); + } + else + { + bufferImage = BufferImage::New( 1u, 1u, Pixel::RGB888, Dali::Image::NEVER ); + PixelBuffer* pBuffer = bufferImage.GetBuffer(); + if( pBuffer ) + { + pBuffer[0] = pBuffer[1] = pBuffer[2] = 0xFF; + } + } + + Actor actor = CreateRenderableActor( bufferImage ); + actor.SetParentOrigin( ParentOrigin::CENTER ); + actor.SetAnchorPoint( AnchorPoint::CENTER ); + + return actor; +} + +int UtcDaliLayer3DSort(void) +{ + tet_infoline( "Testing LAYER_3D sort coverage test" ); + TestApplication application; + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace(); + + Stage::GetCurrent().GetRootLayer().SetBehavior( Layer::LAYER_3D ); + + // Create an actor. + Actor actor = CreateActor( false ); + Stage::GetCurrent().Add( actor ); + + // Create child actors. + Actor child1 = CreateActor( true ); + actor.Add( child1 ); + Actor child2 = CreateActor( false ); + child1.Add( child2 ); + + enabledDisableTrace.Reset(); + enabledDisableTrace.Enable( true ); + application.SendNotification(); + application.Render(); + enabledDisableTrace.Enable( false ); + + DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "2929" ) ); // 2929 is GL_DEPTH_TEST + + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-Renderer.cpp b/automated-tests/src/dali/utc-Dali-Renderer.cpp index 3bfbacf..6591dd9 100644 --- a/automated-tests/src/dali/utc-Dali-Renderer.cpp +++ b/automated-tests/src/dali/utc-Dali-Renderer.cpp @@ -2090,7 +2090,7 @@ int UtcDaliRendererEnumProperties(void) CheckEnumerationProperty< DepthFunction::Type >( renderer, Renderer::Property::DEPTH_FUNCTION, DepthFunction::LESS, DepthFunction::ALWAYS, DepthFunction::GREATER, "GREATER" ); CheckEnumerationProperty< DepthTestMode::Type >( renderer, Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::AUTO, DepthTestMode::OFF, DepthTestMode::ON, "ON" ); CheckEnumerationProperty< StencilFunction::Type >( renderer, Renderer::Property::STENCIL_FUNCTION, StencilFunction::ALWAYS, StencilFunction::LESS, StencilFunction::EQUAL, "EQUAL" ); - CheckEnumerationProperty< StencilMode::Type >( renderer, Renderer::Property::STENCIL_MODE, StencilMode::AUTO, StencilMode::OFF, StencilMode::ON, "ON" ); + CheckEnumerationProperty< RenderMode::Type >( renderer, Renderer::Property::RENDER_MODE, RenderMode::AUTO, RenderMode::NONE, RenderMode::STENCIL, "STENCIL" ); CheckEnumerationProperty< StencilOperation::Type >( renderer, Renderer::Property::STENCIL_OPERATION_ON_FAIL, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" ); CheckEnumerationProperty< StencilOperation::Type >( renderer, Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" ); CheckEnumerationProperty< StencilOperation::Type >( renderer, Renderer::Property::STENCIL_OPERATION_ON_Z_PASS, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" ); @@ -2166,8 +2166,7 @@ int UtcDaliRendererSetDepthTestMode(void) // Check depth-test is disabled. DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Disable", GetDepthTestString() ) ); - // Turn the layer depth-test flag back on, and confirm that depth testing is *still* off. - // This is because our renderer has DepthTestMode::AUTO and our layer behavior is LAYER_2D. + // Turn the layer depth-test flag back on, and confirm that depth testing is now on. Stage::GetCurrent().GetRootLayer().SetDepthTestDisabled( false ); glEnableDisableStack.Reset(); @@ -2175,7 +2174,7 @@ int UtcDaliRendererSetDepthTestMode(void) application.Render(); // Check depth-test is *still* disabled. - DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Disable", GetDepthTestString() ) ); + DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetDepthTestString() ) ); END_TEST; } @@ -2252,10 +2251,10 @@ int UtcDaliRendererCheckStencilDefaults(void) END_TEST; } -int UtcDaliRendererSetStencilMode(void) +int UtcDaliRendererSetRenderModeToUseStencilBuffer(void) { TestApplication application; - tet_infoline("Test setting the StencilMode"); + tet_infoline("Test setting the RenderMode to use the stencil buffer"); Renderer renderer = RendererTestFixture( application ); TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); @@ -2264,24 +2263,80 @@ int UtcDaliRendererSetStencilMode(void) TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace(); TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace(); + // Set the StencilFunction to something other than the default, to confirm it is set as a property, + // but NO GL call has been made while the RenderMode is set to not use the stencil buffer. + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::NONE ); ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); - // Set the StencilFunction to something other than the default, to confirm it is set as a property, - // but NO GL call has been made while the StencilMode is set to OFF. renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION, StencilFunction::NEVER ); DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION ).Get() ), static_cast( StencilFunction::NEVER ), TEST_LOCATION ); - ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); + ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); std::string methodString( "StencilFunc" ); DALI_TEST_CHECK( !glStencilFunctionStack.FindMethod( methodString ) ); - // Now set the StencilMode to ON and check the StencilFunction has changed. - renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON ); + // Test the other RenderModes that will not enable the stencil buffer. + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::AUTO ); + ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); + DALI_TEST_CHECK( !glStencilFunctionStack.FindMethod( methodString ) ); + + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR ); + ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); + DALI_TEST_CHECK( !glStencilFunctionStack.FindMethod( methodString ) ); + + // Now set the RenderMode to modes that will use the stencil buffer, and check the StencilFunction has changed. + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL ); ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetStencilTestString() ) ); DALI_TEST_CHECK( glStencilFunctionStack.FindMethod( methodString ) ); + // Test the COLOR_STENCIL RenderMode as it also enables the stencil buffer. + // First set a mode to turn off the stencil buffer, so the enable is required. + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR ); + ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR_STENCIL ); + ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); + + DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetStencilTestString() ) ); + DALI_TEST_CHECK( glStencilFunctionStack.FindMethod( methodString ) ); + + END_TEST; +} + +// Helper function for the SetRenderModeToUseColorBuffer test. +void CheckRenderModeColorMask( TestApplication& application, Renderer& renderer, RenderMode::Type renderMode, bool expectedValue ) +{ + // Set the RenderMode property to a value that should not allow color buffer writes. + renderer.SetProperty( Renderer::Property::RENDER_MODE, renderMode ); + application.SendNotification(); + application.Render(); + + // Check if ColorMask has been called, and that the values are correct. + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + const TestGlAbstraction::ColorMaskParams& colorMaskParams( glAbstraction.GetColorMaskParams() ); + + DALI_TEST_EQUALS( colorMaskParams.red, expectedValue, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.green, expectedValue, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.blue, expectedValue, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.alpha, expectedValue, TEST_LOCATION ); +} + +int UtcDaliRendererSetRenderModeToUseColorBuffer(void) +{ + TestApplication application; + tet_infoline("Test setting the RenderMode to use the color buffer"); + + Renderer renderer = RendererTestFixture( application ); + + // Set the RenderMode property to a value that should not allow color buffer writes. + // Then check if ColorMask has been called, and that the values are correct. + CheckRenderModeColorMask( application, renderer, RenderMode::AUTO, true ); + CheckRenderModeColorMask( application, renderer, RenderMode::NONE, false ); + CheckRenderModeColorMask( application, renderer, RenderMode::COLOR, true ); + CheckRenderModeColorMask( application, renderer, RenderMode::STENCIL, false ); + CheckRenderModeColorMask( application, renderer, RenderMode::COLOR_STENCIL, true ); + END_TEST; } @@ -2297,8 +2352,8 @@ int UtcDaliRendererSetStencilFunction(void) TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace(); TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace(); - // StencilMode must be ON for StencilFunction to operate. - renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON ); + // RenderMode must use the stencil for StencilFunction to operate. + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL ); ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack ); /* @@ -2387,8 +2442,8 @@ int UtcDaliRendererSetStencilOperation(void) TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace(); TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace(); - // StencilMode must be ON for StencilOperation to operate. - renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON ); + // RenderMode must use the stencil for StencilOperation to operate. + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL ); /* * Lookup table for testing StencilOperation. @@ -2474,8 +2529,8 @@ int UtcDaliRendererSetStencilMask(void) TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace(); TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace(); - // StencilMode must be ON for StencilMask to operate. - renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON ); + // RenderMode must use the stencil for StencilMask to operate. + renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL ); // Set the StencilMask property to a value. renderer.SetProperty( Renderer::Property::STENCIL_MASK, 0x00 ); @@ -2506,48 +2561,3 @@ int UtcDaliRendererSetStencilMask(void) END_TEST; } - -int UtcDaliRendererSetWriteToColorBuffer(void) -{ - TestApplication application; - tet_infoline("Test setting the WriteToColorBuffer flag"); - - Renderer renderer = RendererTestFixture( application ); - TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); - - // Set the StencilMask property to a value. - renderer.SetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER, false ); - - // Check GetProperty returns the same value. - DALI_TEST_CHECK( !renderer.GetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER ).Get() ); - - application.SendNotification(); - application.Render(); - - // Check if ColorMask has been called, and that the values are correct. - const TestGlAbstraction::ColorMaskParams& colorMaskParams( glAbstraction.GetColorMaskParams() ); - - DALI_TEST_EQUALS( colorMaskParams.red, false, TEST_LOCATION ); - DALI_TEST_EQUALS( colorMaskParams.green, false, TEST_LOCATION ); - DALI_TEST_EQUALS( colorMaskParams.blue, false, TEST_LOCATION ); - DALI_TEST_EQUALS( colorMaskParams.alpha, false, TEST_LOCATION ); - - // Set the StencilMask property to true. - renderer.SetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER, true ); - - // Check GetProperty returns the same value. - DALI_TEST_CHECK( renderer.GetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER ).Get() ); - - application.SendNotification(); - application.Render(); - - // Check if ColorMask has been called, and that the values are correct. - const TestGlAbstraction::ColorMaskParams& colorMaskParamsChanged( glAbstraction.GetColorMaskParams() ); - - DALI_TEST_EQUALS( colorMaskParamsChanged.red, true, TEST_LOCATION ); - DALI_TEST_EQUALS( colorMaskParamsChanged.green, true, TEST_LOCATION ); - DALI_TEST_EQUALS( colorMaskParamsChanged.blue, true, TEST_LOCATION ); - DALI_TEST_EQUALS( colorMaskParamsChanged.alpha, true, TEST_LOCATION ); - - END_TEST; -} diff --git a/automated-tests/src/dali/utc-Dali-Scripting.cpp b/automated-tests/src/dali/utc-Dali-Scripting.cpp index e76ff62..12e50d0 100644 --- a/automated-tests/src/dali/utc-Dali-Scripting.cpp +++ b/automated-tests/src/dali/utc-Dali-Scripting.cpp @@ -49,8 +49,7 @@ const unsigned int POSITION_INHERITANCE_MODE_VALUES_COUNT = sizeof( POSITION_INH const StringEnum DRAW_MODE_VALUES[] = { { "NORMAL", DrawMode::NORMAL }, - { "OVERLAY_2D", DrawMode::OVERLAY_2D }, - { "STENCIL", DrawMode::STENCIL }, + { "OVERLAY_2D", DrawMode::OVERLAY_2D } }; const unsigned int DRAW_MODE_VALUES_COUNT = sizeof( DRAW_MODE_VALUES ) / sizeof( DRAW_MODE_VALUES[0] ); @@ -484,7 +483,7 @@ int UtcDaliScriptingNewActorProperties(void) map[ "sensitive" ] = false; map[ "leaveRequired" ] = true; map[ "positionInheritance" ] = "DONT_INHERIT_POSITION"; - map[ "drawMode" ] = "STENCIL"; + map[ "drawMode" ] = "OVERLAY_2D"; map[ "inheritOrientation" ] = false; map[ "inheritScale" ] = false; @@ -507,7 +506,7 @@ int UtcDaliScriptingNewActorProperties(void) DALI_TEST_EQUALS( handle.IsSensitive(), false, TEST_LOCATION ); DALI_TEST_EQUALS( handle.GetLeaveRequired(), true, TEST_LOCATION ); DALI_TEST_EQUALS( handle.GetPositionInheritanceMode(), DONT_INHERIT_POSITION, TEST_LOCATION ); - DALI_TEST_EQUALS( handle.GetDrawMode(), DrawMode::STENCIL, TEST_LOCATION ); + DALI_TEST_EQUALS( handle.GetDrawMode(), DrawMode::OVERLAY_2D, TEST_LOCATION ); DALI_TEST_EQUALS( handle.IsOrientationInherited(), false, TEST_LOCATION ); DALI_TEST_EQUALS( handle.IsScaleInherited(), false, TEST_LOCATION ); diff --git a/automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp b/automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp index 36e8488..9b519d3 100644 --- a/automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-TouchDataProcessing.cpp @@ -1526,37 +1526,37 @@ int UtcDaliTouchDataLeaveActorReadded(void) END_TEST; } -int UtcDaliTouchDataStencilNonRenderableActor(void) +int UtcDaliTouchDataClippedActor(void) { TestApplication application; Stage stage = Stage::GetCurrent(); Actor actor = Actor::New(); - actor.SetSize(100.0f, 100.0f); - actor.SetAnchorPoint(AnchorPoint::TOP_LEFT); - stage.Add(actor); + actor.SetSize( 100.0f, 100.0f ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + stage.Add( actor ); - Actor stencil = Actor::New(); - stencil.SetSize(50.0f, 50.0f); - stencil.SetAnchorPoint(AnchorPoint::TOP_LEFT); - stencil.SetDrawMode( DrawMode::STENCIL ); - stage.Add(stencil); + Actor clippingActor = Actor::New(); + clippingActor.SetSize( 50.0f, 50.0f ); + clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + stage.Add( clippingActor ); - // Render and notify + // Render and notify. application.SendNotification(); application.Render(); - // Connect to actor's touched signal + // Connect to actor's touch signal. SignalData data; TouchDataFunctor functor( data ); actor.TouchSignal().Connect( &application, functor ); - // Emit an event within stencil area + // Emit an event within clipped area. application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 10.0f, 10.0f ) ) ); DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); data.Reset(); - // Emit an event outside the stencil area but within the actor area, we should have a hit! + // Emit an event outside the clipped area but within the actor area, we should have a hit. application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 60.0f, 60.0f ) ) ); DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); data.Reset(); diff --git a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp index 998b8ec..82d514b 100644 --- a/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp +++ b/automated-tests/src/dali/utc-Dali-TouchProcessing.cpp @@ -1300,37 +1300,37 @@ int UtcDaliTouchLeaveActorReadded(void) END_TEST; } -int UtcDaliTouchStencilNonRenderableActor(void) +int UtcDaliTouchClippingActor(void) { TestApplication application; Stage stage = Stage::GetCurrent(); Actor actor = Actor::New(); - actor.SetSize(100.0f, 100.0f); - actor.SetAnchorPoint(AnchorPoint::TOP_LEFT); - stage.Add(actor); + actor.SetSize( 100.0f, 100.0f ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + stage.Add( actor ); - Actor stencil = Actor::New(); - stencil.SetSize(50.0f, 50.0f); - stencil.SetAnchorPoint(AnchorPoint::TOP_LEFT); - stencil.SetDrawMode( DrawMode::STENCIL ); - stage.Add(stencil); + Actor clippingActor = Actor::New(); + clippingActor.SetSize( 50.0f, 50.0f ); + clippingActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + clippingActor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + stage.Add( clippingActor ); - // Render and notify + // Render and notify. application.SendNotification(); application.Render(); - // Connect to actor's touched signal + // Connect to actor's touched signal. SignalData data; TouchEventFunctor functor( data ); actor.TouchedSignal().Connect( &application, functor ); - // Emit an event within stencil area + // Emit an event within clipped area. application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 10.0f, 10.0f ) ) ); DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); data.Reset(); - // Emit an event outside the stencil area but within the actor area, we should have a hit! + // Emit an event outside the clipped area but within the actor area, we should have a hit. application.ProcessEvent( GenerateSingleTouch( TouchPoint::Down, Vector2( 60.0f, 60.0f ) ) ); DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION ); data.Reset(); diff --git a/automated-tests/src/dali/utc-Dali-WeakHandle.cpp b/automated-tests/src/dali/utc-Dali-WeakHandle.cpp index fedb2e1..9fc86a5 100644 --- a/automated-tests/src/dali/utc-Dali-WeakHandle.cpp +++ b/automated-tests/src/dali/utc-Dali-WeakHandle.cpp @@ -356,6 +356,23 @@ int UtcDaliWeakHandleBaseGetBaseHandle(void) END_TEST; } +int UtcDaliWeakHandleBaseReset(void) +{ + TestApplication application; + tet_infoline( "Testing Daku::WeakHandleBase::Reset()" ); + + Actor actor = Actor::New(); + WeakHandleBase object(actor); + DALI_TEST_CHECK(object.GetBaseHandle() == actor); + + object.Reset(); + + DALI_TEST_CHECK(object == WeakHandleBase()); + DALI_TEST_CHECK(object.GetBaseHandle() == Handle()); + + END_TEST; +} + int UtcDaliWeakHandleGetHandle(void) { TestApplication application; diff --git a/dali/devel-api/object/weak-handle.cpp b/dali/devel-api/object/weak-handle.cpp index eeed348..cfe628b 100644 --- a/dali/devel-api/object/weak-handle.cpp +++ b/dali/devel-api/object/weak-handle.cpp @@ -49,9 +49,15 @@ struct WeakHandleBase::Impl : public Internal::Object::Observer // Destruction ~Impl() { + Reset(); + } + + void Reset() + { if( mObject ) { mObject->RemoveObserver( *this ); + mObject = NULL; } } @@ -134,8 +140,7 @@ Handle WeakHandleBase::GetBaseHandle() const void WeakHandleBase::Reset() { - delete mImpl; - mImpl = NULL; + mImpl->Reset(); } diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index f58d612..462196c 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -122,12 +123,9 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mGeometryBatcher = new SceneGraph::GeometryBatcher(); - mRenderManager = RenderManager::New( - glAbstraction, - glSyncAbstraction, - *mGeometryBatcher, - *mTextureUploadedQueue ); + mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor(); + mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mGeometryBatcher, *mTextureUploadedQueue ); mRenderManager->SetVrEngine( vrEngine ); RenderQueue& renderQueue = mRenderManager->GetRenderQueue(); @@ -160,7 +158,8 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, *mRenderManager, renderQueue, *mTextureCacheDispatcher, - *mGeometryBatcher ); + *mGeometryBatcher, + *mRenderTaskProcessor ); mRenderManager->SetShaderSaver( *mUpdateManager ); @@ -225,6 +224,7 @@ Core::~Core() delete mTextureCacheDispatcher; delete mUpdateManager; delete mRenderManager; + delete mRenderTaskProcessor; delete mGeometryBatcher; delete mTextureUploadedQueue; } diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h index b418514..f46f33e 100644 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_INTERNAL_CORE_H__ -#define __DALI_INTERNAL_CORE_H__ +#ifndef DALI_INTERNAL_CORE_H +#define DALI_INTERNAL_CORE_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -68,6 +68,7 @@ class RenderManager; class DiscardQueue; class TextureCacheDispatcher; class GeometryBatcher; +class RenderTaskProcessor; } /** @@ -298,6 +299,7 @@ private: ResourceManager* mResourceManager; ///< Asynchronous Resource Loading IntrusivePtr< RelayoutController > mRelayoutController; ///< Size negotiation relayout controller SceneGraph::GeometryBatcher* mGeometryBatcher; ///< Instance of the geometry batcher + SceneGraph::RenderTaskProcessor* mRenderTaskProcessor; ///< Handles the processing of render tasks bool mIsActive : 1; ///< Whether Core is active or suspended bool mProcessingEvent : 1; ///< True during ProcessEvents() @@ -309,4 +311,4 @@ private: } // namespace Dali -#endif // __DALI_INTERNAL_CORE_H__ +#endif // DALI_INTERNAL_CORE_H diff --git a/dali/internal/common/type-abstraction-enums.h b/dali/internal/common/type-abstraction-enums.h index b1d44ad..a788e60 100644 --- a/dali/internal/common/type-abstraction-enums.h +++ b/dali/internal/common/type-abstraction-enums.h @@ -33,7 +33,7 @@ template <> struct ParameterType< Dali::BlendMode::Type > : public BasicT template <> struct ParameterType< Dali::DepthWriteMode::Type > : public BasicType< Dali::DepthWriteMode::Type > {}; template <> struct ParameterType< Dali::DepthTestMode::Type > : public BasicType< Dali::DepthTestMode::Type > {}; template <> struct ParameterType< Dali::DepthFunction::Type > : public BasicType< Dali::DepthFunction::Type > {}; -template <> struct ParameterType< Dali::StencilMode::Type > : public BasicType< Dali::StencilMode::Type > {}; +template <> struct ParameterType< Dali::RenderMode::Type > : public BasicType< Dali::RenderMode::Type > {}; template <> struct ParameterType< Dali::StencilFunction::Type > : public BasicType< Dali::StencilFunction::Type > {}; template <> struct ParameterType< Dali::StencilOperation::Type > : public BasicType< Dali::StencilOperation::Type > {}; diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 7b19757..485ec51 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -24,7 +24,6 @@ #include // INTERNAL INCLUDES - #include #include #include @@ -32,9 +31,7 @@ #include #include #include - #include - #include #include #include @@ -144,63 +141,64 @@ namespace // unnamed namespace /** * We want to discourage the use of property strings (minimize string comparisons), * particularly for the default properties. - * Name Type writable animatable constraint-input enum for index-checking + * Name Type writable animatable constraint-input enum for index-checking */ DALI_PROPERTY_TABLE_BEGIN -DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN ) -DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X ) -DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y ) -DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z ) -DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT ) -DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X ) -DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y ) -DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z ) -DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE ) -DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH ) -DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT ) -DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH ) -DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION ) -DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X ) -DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y ) -DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z ) -DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION ) -DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X ) -DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y ) -DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z ) -DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION ) -DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION ) -DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE ) -DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X ) -DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y ) -DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z ) -DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE ) -DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE ) -DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR ) -DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED ) -DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN ) -DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE ) -DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA ) -DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR ) -DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX ) -DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME ) -DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE ) -DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED ) -DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION ) -DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE ) -DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE ) -DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE ) -DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE ) -DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR ) -DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY ) -DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY ) -DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY ) -DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT ) -DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH ) -DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING ) -DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE ) -DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE ) -DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION ) -DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::Actor::Property::BATCH_PARENT ) +DALI_PROPERTY( "parentOrigin", VECTOR3, true, false, true, Dali::Actor::Property::PARENT_ORIGIN ) +DALI_PROPERTY( "parentOriginX", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_X ) +DALI_PROPERTY( "parentOriginY", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Y ) +DALI_PROPERTY( "parentOriginZ", FLOAT, true, false, true, Dali::Actor::Property::PARENT_ORIGIN_Z ) +DALI_PROPERTY( "anchorPoint", VECTOR3, true, false, true, Dali::Actor::Property::ANCHOR_POINT ) +DALI_PROPERTY( "anchorPointX", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_X ) +DALI_PROPERTY( "anchorPointY", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Y ) +DALI_PROPERTY( "anchorPointZ", FLOAT, true, false, true, Dali::Actor::Property::ANCHOR_POINT_Z ) +DALI_PROPERTY( "size", VECTOR3, true, true, true, Dali::Actor::Property::SIZE ) +DALI_PROPERTY( "sizeWidth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_WIDTH ) +DALI_PROPERTY( "sizeHeight", FLOAT, true, true, true, Dali::Actor::Property::SIZE_HEIGHT ) +DALI_PROPERTY( "sizeDepth", FLOAT, true, true, true, Dali::Actor::Property::SIZE_DEPTH ) +DALI_PROPERTY( "position", VECTOR3, true, true, true, Dali::Actor::Property::POSITION ) +DALI_PROPERTY( "positionX", FLOAT, true, true, true, Dali::Actor::Property::POSITION_X ) +DALI_PROPERTY( "positionY", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Y ) +DALI_PROPERTY( "positionZ", FLOAT, true, true, true, Dali::Actor::Property::POSITION_Z ) +DALI_PROPERTY( "worldPosition", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_POSITION ) +DALI_PROPERTY( "worldPositionX", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_X ) +DALI_PROPERTY( "worldPositionY", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Y ) +DALI_PROPERTY( "worldPositionZ", FLOAT, false, false, true, Dali::Actor::Property::WORLD_POSITION_Z ) +DALI_PROPERTY( "orientation", ROTATION, true, true, true, Dali::Actor::Property::ORIENTATION ) +DALI_PROPERTY( "worldOrientation", ROTATION, false, false, true, Dali::Actor::Property::WORLD_ORIENTATION ) +DALI_PROPERTY( "scale", VECTOR3, true, true, true, Dali::Actor::Property::SCALE ) +DALI_PROPERTY( "scaleX", FLOAT, true, true, true, Dali::Actor::Property::SCALE_X ) +DALI_PROPERTY( "scaleY", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Y ) +DALI_PROPERTY( "scaleZ", FLOAT, true, true, true, Dali::Actor::Property::SCALE_Z ) +DALI_PROPERTY( "worldScale", VECTOR3, false, false, true, Dali::Actor::Property::WORLD_SCALE ) +DALI_PROPERTY( "visible", BOOLEAN, true, true, true, Dali::Actor::Property::VISIBLE ) +DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Actor::Property::COLOR ) +DALI_PROPERTY( "colorRed", FLOAT, true, true, true, Dali::Actor::Property::COLOR_RED ) +DALI_PROPERTY( "colorGreen", FLOAT, true, true, true, Dali::Actor::Property::COLOR_GREEN ) +DALI_PROPERTY( "colorBlue", FLOAT, true, true, true, Dali::Actor::Property::COLOR_BLUE ) +DALI_PROPERTY( "colorAlpha", FLOAT, true, true, true, Dali::Actor::Property::COLOR_ALPHA ) +DALI_PROPERTY( "worldColor", VECTOR4, false, false, true, Dali::Actor::Property::WORLD_COLOR ) +DALI_PROPERTY( "worldMatrix", MATRIX, false, false, true, Dali::Actor::Property::WORLD_MATRIX ) +DALI_PROPERTY( "name", STRING, true, false, false, Dali::Actor::Property::NAME ) +DALI_PROPERTY( "sensitive", BOOLEAN, true, false, false, Dali::Actor::Property::SENSITIVE ) +DALI_PROPERTY( "leaveRequired", BOOLEAN, true, false, false, Dali::Actor::Property::LEAVE_REQUIRED ) +DALI_PROPERTY( "inheritOrientation", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_ORIENTATION ) +DALI_PROPERTY( "inheritScale", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_SCALE ) +DALI_PROPERTY( "colorMode", STRING, true, false, false, Dali::Actor::Property::COLOR_MODE ) +DALI_PROPERTY( "positionInheritance", STRING, true, false, false, Dali::Actor::Property::POSITION_INHERITANCE ) +DALI_PROPERTY( "drawMode", STRING, true, false, false, Dali::Actor::Property::DRAW_MODE ) +DALI_PROPERTY( "sizeModeFactor", VECTOR3, true, false, false, Dali::Actor::Property::SIZE_MODE_FACTOR ) +DALI_PROPERTY( "widthResizePolicy", STRING, true, false, false, Dali::Actor::Property::WIDTH_RESIZE_POLICY ) +DALI_PROPERTY( "heightResizePolicy", STRING, true, false, false, Dali::Actor::Property::HEIGHT_RESIZE_POLICY ) +DALI_PROPERTY( "sizeScalePolicy", STRING, true, false, false, Dali::Actor::Property::SIZE_SCALE_POLICY ) +DALI_PROPERTY( "widthForHeight", BOOLEAN, true, false, false, Dali::Actor::Property::WIDTH_FOR_HEIGHT ) +DALI_PROPERTY( "heightForWidth", BOOLEAN, true, false, false, Dali::Actor::Property::HEIGHT_FOR_WIDTH ) +DALI_PROPERTY( "padding", VECTOR4, true, false, false, Dali::Actor::Property::PADDING ) +DALI_PROPERTY( "minimumSize", VECTOR2, true, false, false, Dali::Actor::Property::MINIMUM_SIZE ) +DALI_PROPERTY( "maximumSize", VECTOR2, true, false, false, Dali::Actor::Property::MAXIMUM_SIZE ) +DALI_PROPERTY( "inheritPosition", BOOLEAN, true, false, false, Dali::Actor::Property::INHERIT_POSITION ) +DALI_PROPERTY( "clippingMode", STRING, true, false, false, Dali::Actor::Property::CLIPPING_MODE ) +DALI_PROPERTY( "batchParent", BOOLEAN, true, false, false, Dali::Actor::Property::BATCH_PARENT ) DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX ) // Signals @@ -291,6 +289,12 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FIT_WITH_ASPECT_RATIO ) DALI_ENUM_TO_STRING_WITH_SCOPE( SizeScalePolicy, FILL_WITH_ASPECT_RATIO ) DALI_ENUM_TO_STRING_TABLE_END( SIZE_SCALE_POLICY ) +DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED ) +DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN ) +DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE ) + + bool GetAnchorPointConstant( const std::string& value, Vector3& anchor ) { for( unsigned int i = 0; i < ANCHOR_CONSTANT_TABLE_COUNT; ++i ) @@ -1001,6 +1005,11 @@ float Actor::GetCurrentOpacity() const return 1.0f; } +ClippingMode::Type Actor::GetClippingMode() const +{ + return mClippingMode; +} + const Vector4& Actor::GetCurrentWorldColor() const { if( NULL != mNode ) @@ -1505,7 +1514,7 @@ void Actor::SetDrawMode( DrawMode::Type drawMode ) { // this flag is not animatable so keep the value mDrawMode = drawMode; - if( NULL != mNode ) + if( ( NULL != mNode ) && ( drawMode != DrawMode::STENCIL ) ) { // mNode is being used in a separate thread; queue a message to set the value SetDrawModeMessage( GetEventThreadServices(), *mNode, drawMode ); @@ -1708,12 +1717,11 @@ bool Actor::RaySphereTest( const Vector4& rayOrigin, const Vector4& rayDir ) con return ( b2 * b2 - a * c ) >= 0.f; } -bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector4& hitPointLocal, float& distance ) const +bool Actor::RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, Vector2& hitPointLocal, float& distance ) const { bool hit = false; - if( OnStage() && - NULL != mNode ) + if( OnStage() && NULL != mNode ) { // Transforms the ray to the local reference system. // Calculate the inverse of Model matrix @@ -1976,6 +1984,7 @@ Actor::Actor( DerivedType derivedType ) mDrawMode( DrawMode::NORMAL ), mPositionInheritanceMode( Node::DEFAULT_POSITION_INHERITANCE_MODE ), mColorMode( Node::DEFAULT_COLOR_MODE ), + mClippingMode( ClippingMode::DISABLED ), mIsBatchParent( false ) { } @@ -2664,6 +2673,21 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr } break; } + + case Dali::Actor::Property::CLIPPING_MODE: + { + ClippingMode::Type convertedValue = mClippingMode; + if( Scripting::GetEnumerationProperty< ClippingMode::Type >( property, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, convertedValue ) ) + { + mClippingMode = convertedValue; + if( NULL != mNode ) + { + SetClippingModeMessage( GetEventThreadServices(), *mNode, mClippingMode ); + } + } + break; + } + default: { // this can happen in the case of a non-animatable default property so just do nothing @@ -3161,6 +3185,12 @@ Property::Value Actor::GetDefaultProperty( Property::Index index ) const break; } + case Dali::Actor::Property::CLIPPING_MODE: + { + value = mClippingMode; + break; + } + default: { DALI_ASSERT_ALWAYS( false && "Actor Property index invalid" ); // should not come here diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index d40bde1..2b3074f 100644 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -1,5 +1,5 @@ -#ifndef __DALI_INTERNAL_ACTOR_H__ -#define __DALI_INTERNAL_ACTOR_H__ +#ifndef DALI_INTERNAL_ACTOR_H +#define DALI_INTERNAL_ACTOR_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -636,6 +636,12 @@ public: float GetCurrentOpacity() const; /** + * Retrieve the actor's clipping mode. + * @return The actor's clipping mode (cached) + */ + ClippingMode::Type GetClippingMode() const; + + /** * Sets whether an actor should emit touch or hover signals; see SignalTouch() and SignalHover(). * An actor is sensitive by default, which means that as soon as an application connects to the SignalTouch(), * the touch event signal will be emitted, and as soon as an application connects to the SignalHover(), the @@ -1275,7 +1281,7 @@ public: */ bool RayActorTest( const Vector4& rayOrigin, const Vector4& rayDir, - Vector4& hitPointLocal, + Vector2& hitPointLocal, float& distance ) const; /** @@ -1827,6 +1833,7 @@ protected: DrawMode::Type mDrawMode : 2; ///< Cached: How the actor and its children should be drawn PositionInheritanceMode mPositionInheritanceMode : 2; ///< Cached: Determines how position is inherited ColorMode mColorMode : 2; ///< Cached: Determines whether mWorldColor is inherited + ClippingMode::Type mClippingMode : 2; ///< Cached: Determines which clipping mode (if any) to use. private: @@ -1861,4 +1868,4 @@ inline const Internal::Actor& GetImplementation( const Dali::Actor& actor ) } // namespace Dali -#endif // __DALI_INTERNAL_ACTOR_H__ +#endif // DALI_INTERNAL_ACTOR_H diff --git a/dali/internal/event/actors/layer-impl.h b/dali/internal/event/actors/layer-impl.h index 0e97f3a..d1ad93d 100644 --- a/dali/internal/event/actors/layer-impl.h +++ b/dali/internal/event/actors/layer-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_INTERNAL_LAYER_H__ -#define __DALI_INTERNAL_LAYER_H__ +#ifndef DALI_INTERNAL_LAYER_H +#define DALI_INTERNAL_LAYER_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -335,4 +335,4 @@ inline const Internal::Layer& GetImplementation(const Dali::Layer& layer) } // namespace Dali -#endif //__DALI_INTERNAL_LAYER_H__ +#endif // DALI_INTERNAL_LAYER_H diff --git a/dali/internal/event/common/object-impl.cpp b/dali/internal/event/common/object-impl.cpp index a9af750..14a5008 100644 --- a/dali/internal/event/common/object-impl.cpp +++ b/dali/internal/event/common/object-impl.cpp @@ -243,6 +243,36 @@ Property::Index Object::GetPropertyIndex(const std::string& name) const return index; } +Property::Index Object::GetPropertyIndex( Property::Index key ) const +{ + Property::Index index = Property::INVALID_INDEX; + + if( mCustomProperties.Count() > 0 ) + { + Property::Index count = PROPERTY_CUSTOM_START_INDEX; + const PropertyMetadataLookup::ConstIterator end = mCustomProperties.End(); + for( PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count ) + { + CustomPropertyMetadata* custom = static_cast(*iter); + if( custom->key == key ) + { + if( custom->childPropertyIndex != Property::INVALID_INDEX ) + { + // If it is a child property, return the child property index + index = custom->childPropertyIndex; + } + else + { + index = count; + } + break; + } + } + } + + return index; +} + bool Object::IsPropertyWritable( Property::Index index ) const { DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds"); @@ -567,7 +597,7 @@ void Object::GetPropertyIndices( Property::IndexContainer& indices ) const } } -Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const +Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index key, Property::Index index, const Property::Value& propertyValue) const { // Create a new property Dali::Internal::OwnerPointer newProperty; @@ -650,7 +680,7 @@ Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Prop { DALI_ASSERT_ALWAYS( index <= PROPERTY_CUSTOM_MAX_INDEX && "Too many custom properties have been registered" ); - mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) ); + mCustomProperties.PushBack( new CustomPropertyMetadata( name, key, propertyValue.GetType(), property ) ); } else { @@ -675,14 +705,33 @@ Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Prop Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue ) { - return RegisterProperty( name, propertyValue, Property::ANIMATABLE ); + return RegisterProperty( name, Property::INVALID_KEY, propertyValue, Property::ANIMATABLE ); +} + +Property::Index Object::RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue ) +{ + return RegisterProperty( name, key, propertyValue, Property::ANIMATABLE ); } Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode ) { - // If property with the required name already exists, then just set it. - Property::Index index = GetPropertyIndex( name ); - if( index != Property::INVALID_INDEX ) + return RegisterProperty( name, Property::INVALID_KEY, propertyValue, accessMode ); +} + +Property::Index Object::RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue, Property::AccessMode accessMode ) +{ + // If property with the required key already exists, then just set it. + Property::Index index = Property::INVALID_INDEX; + if( key != Property::INVALID_KEY ) // Try integer key first if it's valid + { + index = GetPropertyIndex( key ); + } + if( index == Property::INVALID_INDEX ) // If it wasn't valid, or doesn't exist, try name + { + index = GetPropertyIndex( name ); + } + + if( index != Property::INVALID_INDEX ) // If there was a valid index found by either key, set it. { SetProperty( index, propertyValue ); } @@ -690,9 +739,9 @@ Property::Index Object::RegisterProperty( const std::string& name, const Propert { // Otherwise register the property - if(Property::ANIMATABLE == accessMode) + if( Property::ANIMATABLE == accessMode ) { - index = RegisterSceneGraphProperty( name, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue ); + index = RegisterSceneGraphProperty( name, key, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue ); AddUniformMapping( index, name ); } else @@ -1329,28 +1378,29 @@ AnimatablePropertyMetadata* Object::RegisterAnimatableProperty(Property::Index i // check whether the animatable property is registered already, if not then register one. AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index ); - if(!animatableProperty) + if( !animatableProperty ) { const TypeInfo* typeInfo( GetTypeInfo() ); - if (typeInfo) + if( typeInfo ) { Property::Index basePropertyIndex = typeInfo->GetBasePropertyIndex(index); - if(basePropertyIndex == Property::INVALID_INDEX) + if( basePropertyIndex == Property::INVALID_INDEX ) { // If the property is not a component of a base property, register the whole property itself. const std::string& propertyName = typeInfo->GetPropertyName(index); - RegisterSceneGraphProperty(propertyName, index, typeInfo->GetPropertyDefaultValue(index)); + RegisterSceneGraphProperty(propertyName, Property::INVALID_KEY, index, typeInfo->GetPropertyDefaultValue(index)); AddUniformMapping( index, propertyName ); } else { - // Since the property is a component of a base property, check whether the base property is regsitered. + // Since the property is a component of a base property, check whether the base property is registered. animatableProperty = FindAnimatableProperty( basePropertyIndex ); - if(!animatableProperty) + if( !animatableProperty ) { // If the base property is not registered yet, register the base property first. const std::string& basePropertyName = typeInfo->GetPropertyName(basePropertyIndex); - if(Property::INVALID_INDEX != RegisterSceneGraphProperty(basePropertyName, basePropertyIndex, Property::Value(typeInfo->GetPropertyType(basePropertyIndex)))) + + if( Property::INVALID_INDEX != RegisterSceneGraphProperty( basePropertyName, Property::INVALID_KEY, basePropertyIndex, Property::Value(typeInfo->GetPropertyType( basePropertyIndex ) ) ) ) { animatableProperty = static_cast(mAnimatableProperties[mAnimatableProperties.Size()-1]); AddUniformMapping( basePropertyIndex, basePropertyName ); diff --git a/dali/internal/event/common/object-impl.h b/dali/internal/event/common/object-impl.h index b7e6836..b4fbc53 100644 --- a/dali/internal/event/common/object-impl.h +++ b/dali/internal/event/common/object-impl.h @@ -151,6 +151,11 @@ public: virtual Property::Index GetPropertyIndex( const std::string& name ) const; /** + * @copydoc Dali::Handle::GetPropertyIndex() + */ + virtual Property::Index GetPropertyIndex( Property::Index key ) const; + + /** * @copydoc Dali::Handle::IsPropertyWritable() */ virtual bool IsPropertyWritable( Property::Index index ) const; @@ -191,11 +196,21 @@ public: virtual Property::Index RegisterProperty( const std::string& name, const Property::Value& propertyValue ); /** + * @copydoc Dali::Handle::RegisterProperty() + */ + virtual Property::Index RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue ); + + /** * @copydoc Dali::Handle::RegisterProperty(std::string name, Property::Value propertyValue, Property::AccessMode accessMode) */ virtual Property::Index RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode ); /** + * @brief Implementing method for this override + */ + virtual Property::Index RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue, Property::AccessMode accessMode ); + + /** * @copydoc Dali::Handle::AddPropertyNotification() */ virtual Dali::PropertyNotification AddPropertyNotification( Property::Index index, @@ -352,11 +367,12 @@ protected: /** * Helper to register a scene-graph property * @param [in] name The name of the property. + * @param [in] key The key of the property * @param [in] index The index of the property * @param [in] value The value of the property. * @return The index of the registered property or Property::INVALID_INDEX if registration failed. */ - Property::Index RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const; + Property::Index RegisterSceneGraphProperty(const std::string& name, Property::Index key, Property::Index index, const Property::Value& propertyValue) const; /** * Check whether the animatable property is registered already, if not then register one. diff --git a/dali/internal/event/common/property-metadata.h b/dali/internal/event/common/property-metadata.h index 0900afe..b0af410 100644 --- a/dali/internal/event/common/property-metadata.h +++ b/dali/internal/event/common/property-metadata.h @@ -201,13 +201,16 @@ public: /** * Constructor for metadata of scene graph based properties * @param [in] newName The name of the custom property. + * @param [in] newKey The key of the custom property. * @param [in] newType The type ID of the custom property. * @param [in] newProperty A pointer to the scene-graph owned property. */ CustomPropertyMetadata( const std::string& newName, + Property::Index newKey, Property::Type newType, const SceneGraph::PropertyBase* newProperty) : name(newName), + key(newKey), childPropertyIndex(Property::INVALID_INDEX), mAccessMode(Property::ANIMATABLE) { @@ -226,6 +229,7 @@ public: Property::Value newValue, Property::AccessMode accessMode ) : name(newName), + key(Property::INVALID_KEY), childPropertyIndex(Property::INVALID_INDEX), mAccessMode(accessMode) { @@ -242,6 +246,7 @@ public: } std::string name; ///< The name of the property + Property::Index key; ///< The key of the property Property::Index childPropertyIndex; ///< The index as a child property private: diff --git a/dali/internal/event/events/gesture-processor.cpp b/dali/internal/event/events/gesture-processor.cpp index a196d1a..5ad06df 100644 --- a/dali/internal/event/events/gesture-processor.cpp +++ b/dali/internal/event/events/gesture-processor.cpp @@ -147,12 +147,12 @@ void GestureProcessor::ProcessAndEmit( HitTestAlgorithm::Results& hitTestResults // Ensure tap is within the actor's area if ( actor->RaySphereTest( hitTestResults.rayOrigin, hitTestResults.rayDirection ) ) // Quick check { - Vector4 hitPointLocal; + Vector2 hitPointLocal; float distance( 0.0f ); if( actor->RayActorTest( hitTestResults.rayOrigin, hitTestResults.rayDirection, hitPointLocal, distance ) ) { // One of the parents was the gestured actor so we can emit the signal for that actor. - EmitGestureSignal( actor, gestureDetectors, Vector2( hitPointLocal.x, hitPointLocal.y ) ); + EmitGestureSignal( actor, gestureDetectors, hitPointLocal ); break; // We have found AND emitted a signal on the gestured actor, break out. } } diff --git a/dali/internal/event/events/hit-test-algorithm-impl.cpp b/dali/internal/event/events/hit-test-algorithm-impl.cpp index 5c77ccc..5026b95 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.cpp +++ b/dali/internal/event/events/hit-test-algorithm-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -52,19 +52,15 @@ struct HitActor { HitActor() : actor( NULL ), - x( 0 ), - y( 0 ), distance( std::numeric_limits::max() ), depth( std::numeric_limits::min() ) { } - Actor *actor; ///< the actor hit. (if actor hit, then initialised) - float x; ///< x position of hit (only valid if actor valid) - float y; ///< y position of hit (only valid if actor valid) - float distance; ///< distance from ray origin to hit actor - int depth; ///< depth index of this actor - + Actor *actor; ///< The actor hit (if actor is hit, then this is initialised). + Vector2 hitPosition; ///< Position of hit (only valid if actor valid). + float distance; ///< Distance from ray origin to hit actor. + int depth; ///< Depth index of this actor. }; /** @@ -135,16 +131,13 @@ bool IsActorExclusiveToAnotherRenderTask( const Actor& actor, const Vector< RenderTaskList::Exclusive >& exclusives ) { - if ( exclusives.Size() ) + if( exclusives.Size() ) { - for ( Vector< RenderTaskList::Exclusive >::Iterator exclusiveIt = exclusives.Begin(); exclusives.End() != exclusiveIt; ++exclusiveIt ) + for( Vector< RenderTaskList::Exclusive >::Iterator exclusiveIt = exclusives.Begin(); exclusives.End() != exclusiveIt; ++exclusiveIt ) { - if ( exclusiveIt->renderTaskPtr != &renderTask ) + if( ( exclusiveIt->renderTaskPtr != &renderTask ) && ( exclusiveIt->actorPtr == &actor ) ) { - if ( exclusiveIt->actorPtr == &actor ) - { - return true; - } + return true; } } } @@ -168,37 +161,39 @@ HitActor HitTestWithinLayer( Actor& actor, float& nearClippingPlane, float& farClippingPlane, HitTestInterface& hitCheck, - bool& stencilOnLayer, - bool& stencilHit, bool& overlayHit, - bool parentIsStencil, - bool layerIs3d ) + bool layerIs3d, + unsigned int clippingDepth, + unsigned int clippingBitPlaneMask ) { HitActor hit; - if ( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) ) + if( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) ) { return hit; } - // Children should inherit the stencil draw mode - bool isStencil = parentIsStencil; - - if ( actor.GetDrawMode() == DrawMode::STENCIL && actor.IsVisible() ) + // For clipping, regardless of whether we have hit this actor or not, + // we increase the clipping depth if we have hit a clipping actor. + // This is used later to ensure all nested clipped children have hit + // all clipping actors also for them to be counted as hit. + unsigned int newClippingDepth = clippingDepth; + bool clippingActor = actor.GetClippingMode() != ClippingMode::DISABLED; + if( clippingActor ) { - isStencil = true; - stencilOnLayer = true; + ++newClippingDepth; } - // If we are a stencil or hittable... - if ( isStencil || hitCheck.IsActorHittable( &actor ) ) + // If we are a clipping actor or hittable... + if( clippingActor || hitCheck.IsActorHittable( &actor ) ) { Vector3 size( actor.GetCurrentSize() ); - if ( size.x > 0.0f && size.y > 0.0f && // Ensure the actor has a valid size. - actor.RaySphereTest( rayOrigin, rayDir ) ) // Perform quicker ray sphere test to see if our ray is close to the actor. + // Ensure the actor has a valid size. + // If so, perform a quick ray sphere test to see if our ray is close to the actor. + if( size.x > 0.0f && size.y > 0.0f && actor.RaySphereTest( rayOrigin, rayDir ) ) { - Vector4 hitPointLocal; + Vector2 hitPointLocal; float distance; // Finally, perform a more accurate ray test to see if our ray actually hits the actor. @@ -206,36 +201,61 @@ HitActor HitTestWithinLayer( Actor& actor, { if( distance >= nearClippingPlane && distance <= farClippingPlane ) { - // If the hit has happened on a stencil then register, but don't record as hit result - if ( isStencil ) + // If the hit has happened on a clipping actor, then add this clipping depth to the mask of hit clipping depths. + // This mask shows all the actors that have been hit at different clipping depths. + if( clippingActor ) { - stencilHit = true; + clippingBitPlaneMask |= 1u << clippingDepth; + } + + if( overlayHit && !actor.IsOverlay() ) + { + // If we have already hit an overlay and current actor is not an overlay ignore current actor. } else { - if( overlayHit && !actor.IsOverlay() ) + if( actor.IsOverlay() ) { - //If we have already hit an overlay and current actor is not an overlay - //ignore current actor + overlayHit = true; } - else + + // At this point we have hit an actor. + // Now perform checks for clipping. + // Assume we have hit the actor first as if it is not clipped this would be the case. + bool haveHitActor = true; + + // Check if we are performing clipping. IE. if any actors so far have clipping enabled - not necessarily this one. + // We can do this by checking the clipping depth has a value 1 or above. + if( newClippingDepth >= 1u ) { - if( actor.IsOverlay() ) + // Now for us to count this actor as hit, we must have also hit + // all CLIPPING actors up to this point in the hierarchy as well. + // This information is stored in the clippingBitPlaneMask we updated above. + // Here we calculate a comparison mask by setting all the bits up to the current depth value. + // EG. a depth of 4 (10000 binary) = a mask of 1111 binary. + // This allows us a fast way of comparing all bits are set up to this depth. + unsigned int clippingDepthMask = ( 1u << clippingDepth ) - 1u; + + // The two masks must be equal to be a hit, as we are already assuming a hit + // (for non-clipping mode) then they must be not-equal to disqualify the hit. + if( clippingBitPlaneMask != clippingDepthMask ) { - overlayHit = true; + haveHitActor = false; } + } + if( haveHitActor ) + { hit.actor = &actor; - hit.x = hitPointLocal.x; - hit.y = hitPointLocal.y; + hit.hitPosition = hitPointLocal; hit.distance = distance; hit.depth = actor.GetHierarchyDepth() * Dali::Layer::TREE_DEPTH_MULTIPLIER; - if ( actor.GetRendererCount() > 0 ) + if( actor.GetRendererCount() > 0 ) { //Get renderer with maximum depth int rendererMaxDepth(actor.GetRendererAt( 0 ).Get()->GetDepthIndex()); - for( unsigned int i(1); iGetDepthIndex(); if( depth > rendererMaxDepth ) @@ -252,12 +272,6 @@ HitActor HitTestWithinLayer( Actor& actor, } } - // If we are a stencil (or a child of a stencil) and we have already ascertained that the stencil has been hit then there is no need to hit-test the children of this stencil-actor - if ( isStencil && stencilHit ) - { - return hit; - } - // Find a child hit, until we run out of actors in the current layer. HitActor childHit; if( actor.GetChildCount() > 0 ) @@ -272,30 +286,29 @@ HitActor HitTestWithinLayer( Actor& actor, for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter ) { // Descend tree only if... - if ( !(*iter)->IsLayer() && // Child is NOT a layer, hit testing current layer only or Child is not a layer and we've inherited the stencil draw mode - ( isStencil || hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We are a stencil OR we can descend into child hierarchy + if ( !( *iter )->IsLayer() && // Child is NOT a layer, hit testing current layer only + ( hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We can descend into child hierarchy { - HitActor currentHit( HitTestWithinLayer( (*iter->Get()), - renderTask, - exclusives, - rayOrigin, - rayDir, - nearClippingPlane, - farClippingPlane, - hitCheck, - stencilOnLayer, - stencilHit, - overlayHit, - isStencil, - layerIs3d) ); + HitActor currentHit( HitTestWithinLayer( ( *iter->Get() ), + renderTask, + exclusives, + rayOrigin, + rayDir, + nearClippingPlane, + farClippingPlane, + hitCheck, + overlayHit, + layerIs3d, + newClippingDepth, + clippingBitPlaneMask ) ); bool updateChildHit = false; - if ( currentHit.distance >= 0.0f ) + if( currentHit.distance >= 0.0f ) { if( layerIs3d ) { updateChildHit = ( ( currentHit.depth > childHit.depth ) || - ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) ); + ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) ); } else { @@ -303,17 +316,18 @@ HitActor HitTestWithinLayer( Actor& actor, } } - if ( updateChildHit ) + if( updateChildHit ) { if( !parentIsRenderable || currentHit.depth > hit.depth || ( layerIs3d && ( currentHit.depth == hit.depth && currentHit.distance < hit.distance )) ) - { - childHit = currentHit; - } + { + childHit = currentHit; + } } } } } + return ( childHit.actor ) ? childHit : hit; } @@ -326,13 +340,11 @@ bool IsWithinSourceActors( const Actor& sourceActor, const Actor& actor ) { return true; } - else + + Actor* parent = actor.GetParent(); + if ( parent ) { - Actor* parent = actor.GetParent(); - if ( parent ) - { - return IsWithinSourceActors( sourceActor, *parent ); - } + return IsWithinSourceActors( sourceActor, *parent ); } // Not within source actors @@ -346,7 +358,7 @@ inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates, { bool hittable( true ); - if(layer.IsClipping()) + if( layer.IsClipping() ) { ClippingBox box = layer.GetClippingBox(); @@ -360,14 +372,14 @@ inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates, } } - if(hittable) + if( hittable ) { Actor* actor( &layer ); // Ensure that we can descend into the layer's (or any of its parent's) hierarchy. - while ( actor && hittable ) + while( actor && hittable ) { - if ( ! hitCheck.DescendActorHierarchy( actor ) ) + if( ! hitCheck.DescendActorHierarchy( actor ) ) { hittable = false; break; @@ -414,14 +426,14 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, } float nearClippingPlane, farClippingPlane; - GetCameraClippingPlane(renderTask, nearClippingPlane, farClippingPlane); + GetCameraClippingPlane( renderTask, nearClippingPlane, farClippingPlane ); // Determine the layer depth of the source actor Actor* sourceActor( renderTask.GetSourceActor() ); - if ( sourceActor ) + if( sourceActor ) { Dali::Layer layer( sourceActor->GetLayer() ); - if ( layer ) + if( layer ) { const unsigned int sourceActorDepth( layer.GetDepth() ); @@ -438,26 +450,20 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, // Hit test starting with the top layer, working towards the bottom layer. HitActor hit; - bool stencilOnLayer = false; - bool stencilHit = false; bool overlayHit = false; bool layerConsumesHit = false; - const Vector2& stageSize = stage.GetSize(); - for (int i=layers.GetLayerCount()-1; i>=0 && !(hit.actor); --i) + for( int i = layers.GetLayerCount() - 1; i >= 0 && !( hit.actor ); --i ) { - Layer* layer( layers.GetLayer(i) ); - HitActor previousHit = hit; - stencilOnLayer = false; - stencilHit = false; + Layer* layer( layers.GetLayer( i ) ); overlayHit = false; // Ensure layer is touchable (also checks whether ancestors are also touchable) - if ( IsActuallyHittable ( *layer, screenCoordinates, stageSize, hitCheck ) ) + if( IsActuallyHittable( *layer, screenCoordinates, stageSize, hitCheck ) ) { // Always hit-test the source actor; otherwise test whether the layer is below the source actor in the hierarchy - if ( sourceActorDepth == static_cast(i) ) + if( sourceActorDepth == static_cast( i ) ) { // Recursively hit test the source actor & children, without crossing into other layers. hit = HitTestWithinLayer( *sourceActor, @@ -468,13 +474,12 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, nearClippingPlane, farClippingPlane, hitCheck, - stencilOnLayer, - stencilHit, overlayHit, - false, - layer->GetBehavior() == Dali::Layer::LAYER_3D); + layer->GetBehavior() == Dali::Layer::LAYER_3D, + 0u, + 0u ); } - else if ( IsWithinSourceActors( *sourceActor, *layer ) ) + else if( IsWithinSourceActors( *sourceActor, *layer ) ) { // Recursively hit test all the actors, without crossing into other layers. hit = HitTestWithinLayer( *layer, @@ -485,37 +490,31 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, nearClippingPlane, farClippingPlane, hitCheck, - stencilOnLayer, - stencilHit, overlayHit, - false, - layer->GetBehavior() == Dali::Layer::LAYER_3D); - } - - // If a stencil on this layer hasn't been hit, then discard hit results for this layer if our current hit actor is renderable - if ( stencilOnLayer && !stencilHit && - hit.actor && hit.actor->IsRenderable() ) - { - hit = previousHit; + layer->GetBehavior() == Dali::Layer::LAYER_3D, + 0u, + 0u ); } // If this layer is set to consume the hit, then do not check any layers behind it - if ( hitCheck.DoesLayerConsumeHit( layer ) ) + if( hitCheck.DoesLayerConsumeHit( layer ) ) { layerConsumesHit = true; break; } } } - if ( hit.actor ) + + if( hit.actor ) { - results.renderTask = Dali::RenderTask(&renderTask); - results.actor = Dali::Actor(hit.actor); - results.actorCoordinates.x = hit.x; - results.actorCoordinates.y = hit.y; + results.renderTask = Dali::RenderTask( &renderTask ); + results.actor = Dali::Actor( hit.actor ); + results.actorCoordinates = hit.hitPosition; + return true; // Success } - else if ( layerConsumesHit ) + + if( layerConsumesHit ) { return true; // Also success if layer is consuming the hit } @@ -526,76 +525,86 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, } /** - * Iterate through RenderTaskList and perform hit test. + * Iterate through the RenderTaskList and perform hit testing. * - * @return true if we have a hit, false otherwise + * @param[in] stage The stage the tests will be performed in + * @param[in] layers The list of layers to test + * @param[in] taskList The list of render tasks + * @param[out] results Ray information calculated by the camera + * @param[in] hitCheck The hit testing interface object to use + * @param[in] onScreen True to test on-screen, false to test off-screen + * @return True if we have a hit, false otherwise */ -bool HitTestForEachRenderTask( Stage& stage, - LayerList& layers, - RenderTaskList& taskList, - const Vector2& screenCoordinates, - Results& results, - HitTestInterface& hitCheck ) +bool HitTestRenderTaskList( Stage& stage, + LayerList& layers, + RenderTaskList& taskList, + const Vector2& screenCoordinates, + Results& results, + HitTestInterface& hitCheck, + bool onScreen ) { RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks(); RenderTaskList::RenderTaskContainer::reverse_iterator endIter = tasks.rend(); - const Vector< RenderTaskList::Exclusive >& exclusives = taskList.GetExclusivesList(); - // Check onscreen tasks before offscreen ones, hit test order should be reverse of draw order (see ProcessRenderTasks() where offscreen tasks are drawn first). - - // on screen - for ( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter ) + for( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter ) { RenderTask& renderTask = GetImplementation( *iter ); Dali::FrameBufferImage frameBufferImage = renderTask.GetTargetFrameBuffer(); // Note that if frameBufferImage is NULL we are using the default (on screen) render target - if(frameBufferImage) + if( frameBufferImage ) { - ResourceId id = GetImplementation(frameBufferImage).GetResourceId(); + ResourceId id = GetImplementation( frameBufferImage ).GetResourceId(); - // on screen only - if(0 != id) + // Change comparison depending on if on-screen or off-screen. + if( onScreen ? ( 0 != id ) : ( 0 == id ) ) { // Skip to next task continue; } } - if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) ) + if( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) ) { // Return true when an actor is hit (or layer in our render-task consumes the hit) return true; // don't bother checking off screen tasks } } - // off screen - for ( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter ) - { - RenderTask& renderTask = GetImplementation( *iter ); - Dali::FrameBufferImage frameBufferImage = renderTask.GetTargetFrameBuffer(); - - // Note that if frameBufferImage is NULL we are using the default (on screen) render target - if(frameBufferImage) - { - ResourceId id = GetImplementation(frameBufferImage).GetResourceId(); + return false; +} - // off screen only - if(0 == id) - { - // Skip to next task - continue; - } +/** + * Iterate through the RenderTaskList and perform hit testing for both on-screen and off-screen. + * + * @param[in] stage The stage the tests will be performed in + * @param[in] layers The list of layers to test + * @param[in] taskList The list of render tasks + * @param[out] results Ray information calculated by the camera + * @param[in] hitCheck The hit testing interface object to use + * @param[in] onScreen True to test on-screen, false to test off-screen + * @return True if we have a hit, false otherwise + */ +bool HitTestForEachRenderTask( Stage& stage, + LayerList& layers, + RenderTaskList& taskList, + const Vector2& screenCoordinates, + Results& results, + HitTestInterface& hitCheck ) +{ + bool result = false; - if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) ) - { - // Return true when an actor is hit (or a layer in our render-task consumes the hit) - return true; - } - } + // Check on-screen tasks before off-screen ones. + // Hit test order should be reverse of draw order (see ProcessRenderTasks() where off-screen tasks are drawn first). + if( HitTestRenderTaskList( stage, layers, taskList, screenCoordinates, results, hitCheck, true ) || + HitTestRenderTaskList( stage, layers, taskList, screenCoordinates, results, hitCheck, false ) ) + { + // Found hit. + result = true; } - return false; + + return result; } } // unnamed namespace @@ -609,7 +618,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgor Results hitTestResults; HitTestFunctionWrapper hitTestFunctionWrapper( func ); - if ( HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) ) + if( HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) ) { results.actor = hitTestResults.actor; results.actorCoordinates = hitTestResults.actorCoordinates; @@ -625,7 +634,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results, // Hit-test the system-overlay actors first SystemOverlay* systemOverlay = stage.GetSystemOverlayInternal(); - if ( systemOverlay ) + if( systemOverlay ) { RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks(); LayerList& overlayLayerList = systemOverlay->GetLayerList(); @@ -634,7 +643,7 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results, } // Hit-test the regular on-stage actors - if ( !wasHit ) + if( !wasHit ) { RenderTaskList& taskList = stage.GetRenderTaskList(); LayerList& layerList = stage.GetLayerList(); @@ -658,7 +667,7 @@ bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordin const Vector< RenderTaskList::Exclusive >& exclusives = stage.GetRenderTaskList().GetExclusivesList(); HitTestFunctionWrapper hitTestFunctionWrapper( func ); - if ( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) ) + if( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) ) { results.actor = hitTestResults.actor; results.actorCoordinates = hitTestResults.actorCoordinates; @@ -667,6 +676,7 @@ bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordin return wasHit; } + } // namespace HitTestAlgorithm } // namespace Internal diff --git a/dali/internal/event/events/hit-test-algorithm-impl.h b/dali/internal/event/events/hit-test-algorithm-impl.h index 07b2291..c0b68e3 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.h +++ b/dali/internal/event/events/hit-test-algorithm-impl.h @@ -1,8 +1,8 @@ -#ifndef __DALI_INTERNAL_HIT_TEST_ALGORITHM_H__ -#define __DALI_INTERNAL_HIT_TEST_ALGORITHM_H__ +#ifndef DALI_INTERNAL_HIT_TEST_ALGORITHM_H +#define DALI_INTERNAL_HIT_TEST_ALGORITHM_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -138,10 +138,11 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results ) bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordinates, Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func ); + } // namespace HitTestAlgorithm } // namespace Internal } // namespace Dali -#endif // __DALI_INTERNAL_HIT_TEST_ALGORITHM_H__ +#endif // DALI_INTERNAL_HIT_TEST_ALGORITHM_H diff --git a/dali/internal/event/rendering/renderer-impl.cpp b/dali/internal/event/rendering/renderer-impl.cpp index 0b89b26..d9f30a1 100644 --- a/dali/internal/event/rendering/renderer-impl.cpp +++ b/dali/internal/event/rendering/renderer-impl.cpp @@ -56,15 +56,14 @@ DALI_PROPERTY( "indexRangeCount", INTEGER, true, false, false DALI_PROPERTY( "depthWriteMode", INTEGER, true, false, false, Dali::Renderer::Property::DEPTH_WRITE_MODE ) DALI_PROPERTY( "depthFunction", INTEGER, true, false, false, Dali::Renderer::Property::DEPTH_FUNCTION ) DALI_PROPERTY( "depthTestMode", INTEGER, true, false, false, Dali::Renderer::Property::DEPTH_TEST_MODE ) +DALI_PROPERTY( "renderMode", INTEGER, true, false, false, Dali::Renderer::Property::RENDER_MODE ) DALI_PROPERTY( "stencilFunction", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_FUNCTION ) DALI_PROPERTY( "stencilFunctionMask", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_FUNCTION_MASK ) DALI_PROPERTY( "stencilFunctionReference", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE ) DALI_PROPERTY( "stencilMask", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_MASK ) -DALI_PROPERTY( "stencilMode", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_MODE ) DALI_PROPERTY( "stencilOperationOnFail", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL ) DALI_PROPERTY( "stencilOperationOnZFail", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL ) DALI_PROPERTY( "stencilOperationOnZPass", INTEGER, true, false, false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS ) -DALI_PROPERTY( "writeToColorBuffer", BOOLEAN, true, false, false, Dali::Renderer::Property::WRITE_TO_COLOR_BUFFER ) DALI_PROPERTY( "batchingEnabled", BOOLEAN, true, false, false, Dali::Renderer::Property::BATCHING_ENABLED ) DALI_PROPERTY_TABLE_END( DEFAULT_RENDERER_PROPERTY_START_INDEX ) @@ -141,11 +140,13 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, GREATER_EQUAL ) DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, ALWAYS ) DALI_ENUM_TO_STRING_TABLE_END( STENCIL_FUNCTION ) -DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_MODE ) -DALI_ENUM_TO_STRING_WITH_SCOPE( StencilMode, OFF ) -DALI_ENUM_TO_STRING_WITH_SCOPE( StencilMode, AUTO ) -DALI_ENUM_TO_STRING_WITH_SCOPE( StencilMode, ON ) -DALI_ENUM_TO_STRING_TABLE_END( STENCIL_MODE ) +DALI_ENUM_TO_STRING_TABLE_BEGIN( RENDER_MODE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, NONE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, AUTO ) +DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, COLOR ) +DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, STENCIL ) +DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, COLOR_STENCIL ) +DALI_ENUM_TO_STRING_TABLE_END( RENDER_MODE ) DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_OPERATION ) DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, ZERO ) @@ -561,13 +562,13 @@ void Renderer::SetDefaultProperty( Property::Index index, } break; } - case Dali::Renderer::Property::STENCIL_MODE: + case Dali::Renderer::Property::RENDER_MODE: { - StencilMode::Type convertedValue = mStencilParameters.stencilMode; - if( Scripting::GetEnumerationProperty< StencilMode::Type >( propertyValue, STENCIL_MODE_TABLE, STENCIL_MODE_TABLE_COUNT, convertedValue ) ) + RenderMode::Type convertedValue = mStencilParameters.renderMode; + if( Scripting::GetEnumerationProperty< RenderMode::Type >( propertyValue, RENDER_MODE_TABLE, RENDER_MODE_TABLE_COUNT, convertedValue ) ) { - mStencilParameters.stencilMode = convertedValue; - SetStencilModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue ); + mStencilParameters.renderMode = convertedValue; + SetRenderModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue ); } break; } @@ -650,19 +651,6 @@ void Renderer::SetDefaultProperty( Property::Index index, } break; } - case Dali::Renderer::Property::WRITE_TO_COLOR_BUFFER: - { - bool writeToColorBuffer; - if( propertyValue.Get( writeToColorBuffer ) ) - { - if( mWriteToColorBuffer != writeToColorBuffer ) - { - mWriteToColorBuffer = writeToColorBuffer; - SetWriteToColorBufferMessage( GetEventThreadServices(), *mSceneObject, writeToColorBuffer ); - } - } - break; - } case Dali::Renderer::Property::BATCHING_ENABLED: { bool enabled; @@ -824,9 +812,9 @@ Property::Value Renderer::GetDefaultProperty( Property::Index index ) const value = mStencilParameters.stencilMask; break; } - case Dali::Renderer::Property::STENCIL_MODE: + case Dali::Renderer::Property::RENDER_MODE: { - value = mStencilParameters.stencilMode; + value = mStencilParameters.renderMode; break; } case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL: @@ -844,11 +832,6 @@ Property::Value Renderer::GetDefaultProperty( Property::Index index ) const value = mStencilParameters.stencilOperationOnZPass; break; } - case Dali::Renderer::Property::WRITE_TO_COLOR_BUFFER: - { - value = mWriteToColorBuffer; - break; - } } return value; } @@ -926,20 +909,19 @@ void Renderer::Disconnect() } Renderer::Renderer() -: mSceneObject (NULL ), +: mSceneObject(NULL ), mBlendColor( NULL ), mDepthIndex( 0 ), mOnStageCount( 0 ), mIndexedDrawFirstElement( 0 ), mIndexedDrawElementCount( 0 ), - mStencilParameters( StencilMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ), + mStencilParameters( RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ), mBlendingOptions(), mDepthFunction( DepthFunction::LESS ), mFaceCullingMode( FaceCullingMode::NONE ), mBlendMode( BlendMode::AUTO ), mDepthWriteMode( DepthWriteMode::AUTO ), mDepthTestMode( DepthTestMode::AUTO ), - mWriteToColorBuffer( true ), mPremultipledAlphaEnabled( false ), mBatchingEnabled( false ) { diff --git a/dali/internal/event/rendering/renderer-impl.h b/dali/internal/event/rendering/renderer-impl.h index 14a2b79..dafa996 100644 --- a/dali/internal/event/rendering/renderer-impl.h +++ b/dali/internal/event/rendering/renderer-impl.h @@ -318,7 +318,6 @@ private: // data BlendMode::Type mBlendMode:2; ///< Local copy of the mode of blending DepthWriteMode::Type mDepthWriteMode:2; ///< Local copy of the depth write mode DepthTestMode::Type mDepthTestMode:2; ///< Local copy of the depth test mode - bool mWriteToColorBuffer:1; ///< Local copy of the write to color buffer flag bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required bool mBatchingEnabled : 1; ///< Flag indicating whether render is batchable or not }; diff --git a/dali/internal/file.list b/dali/internal/file.list index e90d723..6a02187 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -104,7 +104,6 @@ internal_src_files = \ $(internal_src_dir)/render/common/render-tracker.cpp \ $(internal_src_dir)/render/common/render-manager.cpp \ $(internal_src_dir)/render/data-providers/render-data-provider.cpp \ - $(internal_src_dir)/render/data-providers/uniform-name-cache.cpp \ $(internal_src_dir)/render/gl-resources/bitmap-texture.cpp \ $(internal_src_dir)/render/gl-resources/context.cpp \ $(internal_src_dir)/render/gl-resources/frame-buffer-state-cache.cpp \ @@ -146,9 +145,9 @@ internal_src_files = \ $(internal_src_dir)/update/gestures/pan-gesture-profiling.cpp \ $(internal_src_dir)/update/gestures/scene-graph-pan-gesture.cpp \ $(internal_src_dir)/update/queue/update-message-queue.cpp \ - $(internal_src_dir)/update/manager/prepare-render-instructions.cpp \ $(internal_src_dir)/update/manager/geometry-batcher.cpp \ - $(internal_src_dir)/update/manager/process-render-tasks.cpp \ + $(internal_src_dir)/update/manager/render-instruction-processor.cpp \ + $(internal_src_dir)/update/manager/render-task-processor.cpp \ $(internal_src_dir)/update/manager/transform-manager.cpp \ $(internal_src_dir)/update/manager/update-algorithms.cpp \ $(internal_src_dir)/update/manager/update-manager.cpp \ diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index d296903..c41465c 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -72,7 +72,7 @@ inline void SetScissorTest( const RenderList& renderList, Context& context ) context.SetScissorTest( true ); const Dali::ClippingBox& clip = renderList.GetClippingBox(); - context.Scissor(clip.x, clip.y, clip.width, clip.height); + context.Scissor( clip.x, clip.y, clip.width, clip.height ); } else { @@ -81,145 +81,257 @@ inline void SetScissorTest( const RenderList& renderList, Context& context ) } /** - * Sets the render flags for the stencil buffer and clears all required buffers (depth and stencil if required). - * @param[in] renderList The render list from which to get the render flags - * @param[in] context The context - * @param[in] depthTestEnabled True if depth test is enabled for the layer - * @param[in] isLayer3D True if the layer is a 3D layer + * @brief Set up the stencil and color buffer for automatic clipping (StencilMode::AUTO). + * @param[in] item The current RenderItem about to be rendered + * @param[in] context The context + * @param[in/out] lastStencilDepth The stencil depth of the last renderer drawn. + * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. */ -inline void SetRenderFlags( const RenderList& renderList, Context& context, bool depthTestEnabled, bool isLayer3D ) +inline void SetupClipping( const RenderItem& item, Context& context, uint32_t& lastStencilDepth, uint32_t& lastClippingId ) { - const unsigned int renderFlags = renderList.GetFlags(); - GLbitfield clearMask = 0u; - - // Stencil enabled, writing, and clearing... - const bool enableStencilBuffer( renderFlags & RenderList::STENCIL_BUFFER_ENABLED ); - const bool enableStencilWrite( renderFlags & RenderList::STENCIL_WRITE ); - context.EnableStencilBuffer( enableStencilBuffer ); - if( enableStencilBuffer ) - { - context.StencilFunc( ( enableStencilWrite ? GL_ALWAYS : GL_EQUAL ), 1, 0xFF ); - context.StencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE ); + const Dali::Internal::SceneGraph::Node* node = item.mNode; + const uint32_t clippingId = node->GetClippingId(); - // Write to stencil buffer or color buffer, but not both. - // These should only be set if the Actor::DrawMode is managing the stencil (and color) buffer. - context.StencilMask( enableStencilWrite ? 0xFF : 0x00 ); - context.ColorMask( !enableStencilWrite ); + // Turn the color buffer on as we always want to render this renderer, regardless of clipping hierarchy. + context.ColorMask( true ); - clearMask |= ( renderFlags & RenderList::STENCIL_CLEAR ) ? GL_STENCIL_BUFFER_BIT : 0u; + // If there is no clipping Id, then either we haven't reached a clipping Node yet, or there aren't any. + // Either way we can skip clipping setup for this renderer. + if( clippingId == 0u ) + { + // Exit immediately if there are no clipping actions to perform (EG. we have not yet hit a clipping node). + context.EnableStencilBuffer( false ); + return; } - // Enable and Clear the depth buffer if required. - // DepthTest must be enabled for the layer, else testing is turned off. - if( !depthTestEnabled ) + const ClippingMode::Type clippingMode( node->GetClippingMode() ); + const uint32_t currentStencilDepth( node->GetClippingDepth() ); + + context.EnableStencilBuffer( true ); + + // Pre-calculate a mask which has all bits set up to and including the current clipping depth. + // EG. If depth is 3, the mask would be "111" in binary. + const uint32_t currentDepthMask = ( 1u << currentStencilDepth ) - 1u; + + // If we have a clipping mode specified, we are writing to the stencil buffer. + if( clippingMode != ClippingMode::DISABLED ) { - context.EnableDepthBuffer( false ); + // We are writing to the stencil buffer. + // If clipping Id is 1, this is the first clipping renderer within this render-list. + if( clippingId == 1u ) + { + // We are enabling the stencil-buffer for the first time within this render list. + // Clear the buffer at this point. + context.StencilMask( 0xff ); + context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES ); + } + else if( ( currentStencilDepth < lastStencilDepth ) || ( clippingId != lastClippingId ) ) + { + // The above if() statement tests if we need to clear some (not all) stencil bit-planes. + // We need to do this if either of the following are true: + // 1) We traverse up the scene-graph to a previous stencil + // 2) We are at the same stencil depth but the clipping Id has changed. + // + // This calculation takes the new depth to move to, and creates an inverse-mask of that number of consecutive bits. + // This has the effect of clearing everything except the bit-planes up to (and including) our current depth. + const uint32_t stencilClearMask = ( currentDepthMask >> 1u ) ^ 0xff; + + context.StencilMask( stencilClearMask ); + context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES ); + } + + // We keep track of the last clipping Id and depth so we can determine when we are + // moving back up the scene graph and require some of the stencil bit-planes to be deleted. + lastStencilDepth = currentStencilDepth; + lastClippingId = clippingId; + + // We only ever write to bit-planes up to the current depth as we may need + // to erase individual bit-planes and revert to a previous clipping area. + // Our reference value for testing (in StencilFunc) is written to to the buffer, but we actually + // want to test a different value. IE. All the bit-planes up to but not including the current depth. + // So we use the Mask parameter of StencilFunc to mask off the top bit-plane when testing. + // Here we create our test mask to innore the top bit of the reference test value. + // As the mask is made up of contiguous "1" values, we can do this quickly with a bit-shift. + const uint32_t testMask = currentDepthMask >> 1u; + + context.StencilFunc( GL_EQUAL, currentDepthMask, testMask ); // Test against existing stencil bit-planes. All must match up to (but not including) this depth. + context.StencilMask( currentDepthMask ); // Write to the new stencil bit-plane (the other previous bit-planes are also written to). + context.StencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE ); } - else if( renderList.HasColorRenderItems() || isLayer3D ) // Also, within the context of this if(), depth test is enabled. + else { - - clearMask |= GL_DEPTH_BUFFER_BIT; - // We need to enable the depth buffer to clear it. - // Subsequently it is enabled and disabled on a per-RenderItem basis. - // If we do not have color renderers, this is only done for 3D layers. - context.EnableDepthBuffer( true ); + // We are reading from the stencil buffer. Set up the stencil accordingly + // This calculation sets all the bits up to the current depth bit. + // This has the effect of testing that the pixel being written to exists in every bit-plane up to the current depth. + context.StencilFunc( GL_EQUAL, currentDepthMask, 0xff ); + context.StencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); } - - // Clear Depth and/or stencil buffers as required. - // Note: The buffers will only be cleared if written to since a previous clear. - // TODOVR: if vr force - context.Clear( clearMask, Context::FORCE_CLEAR ); - //context.Clear( clearMask, Context::CHECK_CACHED_VALUES ); } /** - * @brief This method sets up the stencil and color buffer based on the current Renderers flags. + * @brief Set up the stencil and color buffer based on the current Renderers properties. * @param[in] item The current RenderItem about to be rendered * @param[in] context The context - * @param[in/out] usedStencilBuffer True if the stencil buffer has been used so far within this RenderList - * @param[in] stencilManagedByDrawMode True if the stencil and color buffer is being managed by DrawMode::STENCIL + * @param[in/out] usedStencilBuffer True if the stencil buffer has been used so far within this RenderList. Used by StencilMode::ON. + * @param[in/out] lastStencilDepth The stencil depth of the last renderer drawn. Used by the clipping feature. + * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. Used by the clipping feature. */ -inline void SetupPerRendererFlags( const RenderItem& item, Context& context, bool& usedStencilBuffer, bool stencilManagedByDrawMode ) +inline void SetupStencilBuffer( const RenderItem& item, Context& context, bool& usedStencilBuffer, uint32_t& lastStencilDepth, uint32_t& lastClippingId ) { - // DrawMode::STENCIL is deprecated, however to support it we must not set - // flags based on the renderer properties if it is in use. - if( stencilManagedByDrawMode ) + const Renderer *renderer = item.mRenderer; + + // Setup the stencil using either the automatic clipping feature, or, the manual per-renderer stencil API. + // Note: This switch is in order of most likely value first. + RenderMode::Type renderMode = renderer->GetRenderMode(); + switch( renderMode ) { - return; - } + case RenderMode::AUTO: + { + // The automatic clipping feature will manage the stencil functions and color buffer mask. + SetupClipping( item, context, lastStencilDepth, lastClippingId ); + break; + } - // Setup the color buffer based on the renderers properties. - Renderer *renderer = item.mRenderer; - context.ColorMask( renderer->GetWriteToColorBuffer() ); + case RenderMode::NONE: + case RenderMode::COLOR: + { + // The stencil buffer will not be used at all. + context.EnableStencilBuffer( false ); - // If the stencil buffer is disabled for this renderer, exit now to save unnecessary value setting. - if( renderer->GetStencilMode() != StencilMode::ON ) - { - // No per-renderer stencil setup, exit. - context.EnableStencilBuffer( false ); - return; - } + // Setup the color buffer based on the RenderMode. + context.ColorMask( renderMode == RenderMode::COLOR ); + return; + break; // Break statement for consistency (although return will be called instead). + } - // At this point, the stencil buffer is enabled. - context.EnableStencilBuffer( true ); + case RenderMode::STENCIL: + case RenderMode::COLOR_STENCIL: + { + // We are using the low-level Renderer Stencil API. + // The stencil buffer must be enabled for every renderer with stencil mode on, as renderers in between can disable it. + // Note: As the command state is cached, it is only sent when needed. + context.EnableStencilBuffer( true ); - // If this is the first use of the stencil buffer within this RenderList, clear it now. - // This avoids unnecessary clears. - if( !usedStencilBuffer ) - { - context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES ); - usedStencilBuffer = true; - } + // Setup the color buffer based on the RenderMode. + context.ColorMask( renderMode == RenderMode::COLOR_STENCIL ); - // Setup the stencil buffer based on the renderers properties. - context.StencilFunc( DaliStencilFunctionToGL[ renderer->GetStencilFunction() ], - renderer->GetStencilFunctionReference(), - renderer->GetStencilFunctionMask() ); - context.StencilOp( DaliStencilOperationToGL[ renderer->GetStencilOperationOnFail() ], - DaliStencilOperationToGL[ renderer->GetStencilOperationOnZFail() ], - DaliStencilOperationToGL[ renderer->GetStencilOperationOnZPass() ] ); - context.StencilMask( renderer->GetStencilMask() ); + // If this is the first use of the stencil buffer within this RenderList, clear it (this avoids unnecessary clears). + if( !usedStencilBuffer ) + { + context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES ); + usedStencilBuffer = true; + } + + // Setup the stencil buffer based on the renderers properties. + context.StencilFunc( DaliStencilFunctionToGL[ renderer->GetStencilFunction() ], + renderer->GetStencilFunctionReference(), + renderer->GetStencilFunctionMask() ); + context.StencilOp( DaliStencilOperationToGL[ renderer->GetStencilOperationOnFail() ], + DaliStencilOperationToGL[ renderer->GetStencilOperationOnZFail() ], + DaliStencilOperationToGL[ renderer->GetStencilOperationOnZPass() ] ); + context.StencilMask( renderer->GetStencilMask() ); + break; + } + } } /** - * Sets up the depth buffer for reading and writing based on the current render item. + * @brief Sets up the depth buffer for reading and writing based on the current render item. * The items read and write mode are used if specified. - * If AUTO is selected for reading, the decision will be based on the Layer Behavior. - * If AUTO is selected for writing, the decision will be based on the items opacity. - * @param item The RenderItem to set up the depth buffer for - * @param context The context used to execute GL commands. - * @param isLayer3D True if the layer behavior is set to LAYER_3D + * - If AUTO is selected for reading, the decision will be based on the Layer Behavior. + * - If AUTO is selected for writing, the decision will be based on the items opacity. + * @param[in] item The RenderItem to set up the depth buffer for. + * @param[in] context The context used to execute GL commands. + * @param[in] depthTestEnabled True if depth testing has been enabled. + * @param[in/out] firstDepthBufferUse Initialise to true on the first call, this method will set it to false afterwards. */ -inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool isLayer3D ) +inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool depthTestEnabled, bool& firstDepthBufferUse ) { // Set up whether or not to write to the depth buffer. const DepthWriteMode::Type depthWriteMode = item.mRenderer->GetDepthWriteMode(); // Most common mode (AUTO) is tested first. - bool enableDepthWrite = ( ( depthWriteMode == DepthWriteMode::AUTO ) && item.mIsOpaque ) || - ( depthWriteMode == DepthWriteMode::ON ); - context.DepthMask( enableDepthWrite ); + const bool enableDepthWrite = ( ( depthWriteMode == DepthWriteMode::AUTO ) && depthTestEnabled && item.mIsOpaque ) || + ( depthWriteMode == DepthWriteMode::ON ); // Set up whether or not to read from (test) the depth buffer. const DepthTestMode::Type depthTestMode = item.mRenderer->GetDepthTestMode(); // Most common mode (AUTO) is tested first. - bool enableDepthTest = ( ( depthTestMode == DepthTestMode::AUTO ) && isLayer3D ) || - ( depthTestMode == DepthTestMode::ON ); - // Look-up the GL depth function from the Dali::DepthFunction enum, and set it. - context.DepthFunc( DaliDepthToGLDepthTable[ item.mRenderer->GetDepthFunction() ] ); + const bool enableDepthTest = ( ( depthTestMode == DepthTestMode::AUTO ) && depthTestEnabled ) || + ( depthTestMode == DepthTestMode::ON ); - // The depth buffer must be enabled if either reading or writing. - context.EnableDepthBuffer( enableDepthWrite || enableDepthTest ); + // Is the depth buffer in use? + if( enableDepthWrite || enableDepthTest ) + { + // The depth buffer must be enabled if either reading or writing. + context.EnableDepthBuffer( true ); + + // Set up the depth mask based on our depth write setting. + context.DepthMask( enableDepthWrite ); + + // Look-up the GL depth function from the Dali::DepthFunction enum, and set it. + context.DepthFunc( DaliDepthToGLDepthTable[ item.mRenderer->GetDepthFunction() ] ); + + // If this is the first use of the depth buffer this RenderTask, perform a clear. + // Note: We could do this at the beginning of the RenderTask and rely on the + // context cache to ignore the clear if not required, but, we would have to enable + // the depth buffer to do so, which could be a redundant enable. + if( DALI_UNLIKELY( firstDepthBufferUse ) ) + { + // This is the first time the depth buffer is being written to or read. + firstDepthBufferUse = false; + + // Note: The buffer will only be cleared if written to since a previous clear. + // TODOVR: if vr force + //context.Clear( GL_DEPTH_BUFFER_BIT, Context::CHECK_CACHED_VALUES ); + context.Clear( GL_DEPTH_BUFFER_BIT, Context::FORCE_CLEAR ); + } + } + else + { + // The depth buffer is not being used by this renderer, so we must disable it to stop it being tested. + context.EnableDepthBuffer( false ); + } } /** - * Process a render-list. - * @param[in] renderList The render-list to process. - * @param[in] context The GL context. - * @param[in] defaultShader The default shader to use. - * @param[in] buffer The current render buffer index (previous update buffer) - * @param[in] viewMatrix The view matrix from the appropriate camera. + * @brief Setup Batching and calculate if we should perform or skip the upcoming render. + * + * Check if the node has a valid batch index value ( set previously by + * GeometryBatcher ). If so, then it queries the geometry object for this particular batch. + * If not, it still checks if the batch parent is set as it is possible, batching may + * fail (for example if vertex format or buffers are not set). In that case we need + * to skip rendering, otherwise unwanted GPU buffers will get uploaded. This is very rare case. + * @param[in] item The item to test / setup for batching + * @param[in] geometryBatcher The instance of the Geometry Batcher + * @return True if we should perform a render as normal. False if we should skip it due to batching. + */ +inline bool SetupBatching( const RenderItem& item, GeometryBatcher* geometryBatcher ) +{ + bool performRender( true ); + uint32_t batchIndex( item.mNode->mBatchIndex ); + + if( batchIndex != BATCH_NULL_HANDLE ) + { + item.mBatchRenderGeometry = geometryBatcher->GetGeometry( batchIndex ); + } + else + { + performRender = !( item.mNode->GetBatchParent() ); + item.mBatchRenderGeometry = NULL; + } + + return performRender; +} + +/** + * @brief Process a render-list. + * @param[in] renderList The render-list to process. + * @param[in] context The GL context. + * @param[in] defaultShader The default shader to use. + * @param[in] buffer The current render buffer index (previous update buffer) + * @param[in] viewMatrix The view matrix from the appropriate camera. * @param[in] projectionMatrix The projection matrix from the appropriate camera. - * @param[in] geometryBatcher The instance of the geometry batcher + * @param[in] geometryBatcher The instance of the geometry batcher */ inline void ProcessRenderList( const RenderList& renderList, @@ -233,64 +345,42 @@ inline void ProcessRenderList( { DALI_PRINT_RENDER_LIST( renderList ); - bool depthTestEnabled = !( renderList.GetSourceLayer()->IsDepthTestDisabled() ); - bool isLayer3D = renderList.GetSourceLayer()->GetBehavior() == Dali::Layer::LAYER_3D; - bool usedStencilBuffer = false; - bool stencilManagedByDrawMode = renderList.GetFlags() & RenderList::STENCIL_BUFFER_ENABLED; - SetScissorTest( renderList, context ); - SetRenderFlags( renderList, context, depthTestEnabled, isLayer3D ); - // The Layers depth enabled flag overrides the per-renderer depth flags. - // So if depth test is disabled at the layer level, we ignore per-render flags. - // Note: Overlay renderers will not read or write from the depth buffer. - if( DALI_LIKELY( !renderList.HasColorRenderItems() || !depthTestEnabled ) ) - { - size_t count = renderList.Count(); - bool skip( false ); - for ( size_t index = 0; index < count; ++index ) - { - const RenderItem& item = renderList.GetItem( index ); - DALI_PRINT_RENDER_ITEM( item ); - - SetupPerRendererFlags( item, context, usedStencilBuffer, stencilManagedByDrawMode ); - - // Check if the node has a valid batch index value ( set previously by - // GeometryBatcher ). If so, then it queries the geometry object for this particular batch. - // If not, it still checks if the batch parent is set as it is possible, batching may - // fail ( for example if vertex format or buffers are not set ). In that case we need - // to skip rendering, otherwise unwanted GPU buffers will get uploaded. This is very rare case. - uint32_t batchIndex = item.mNode->mBatchIndex; - if( batchIndex != BATCH_NULL_HANDLE ) - { - item.mBatchRenderGeometry = geometryBatcher->GetGeometry( batchIndex ); - } - else - { - skip = item.mNode->GetBatchParent(); - item.mBatchRenderGeometry = NULL; - } - if( !skip ) - { - item.mRenderer->Render( context, textureCache, bufferIndex, *item.mNode, defaultShader, - item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, item.mBatchRenderGeometry, !item.mIsOpaque ); - } - } - } - else + // Note: The depth buffer is enabled or disabled on a per-renderer basis. + // Here we pre-calculate the value to use if these modes are set to AUTO. + const bool autoDepthTestMode( !( renderList.GetSourceLayer()->IsDepthTestDisabled() ) && renderList.HasColorRenderItems() ); + const std::size_t count = renderList.Count(); + uint32_t lastStencilDepth( 0u ); + uint32_t lastClippingId( 0u ); + bool usedStencilBuffer( false ); + bool firstDepthBufferUse( true ); + + for( size_t index( 0u ); index < count; ++index ) { - size_t count = renderList.Count(); - for ( size_t index = 0; index < count; ++index ) - { - const RenderItem& item = renderList.GetItem( index ); - DALI_PRINT_RENDER_ITEM( item ); + const RenderItem& item = renderList.GetItem( index ); + DALI_PRINT_RENDER_ITEM( item ); + + // Set up the depth buffer based on per-renderer flags. + // If the per renderer flags are set to "ON" or "OFF", they will always override any Layer depth mode or + // draw-mode state, such as Overlays. + // If the flags are set to "AUTO", the behaviour then depends on the type of renderer. Overlay Renderers will always + // disable depth testing and writing. Color Renderers will enable them if the Layer does. + SetupDepthBuffer( item, context, autoDepthTestMode, firstDepthBufferUse ); - // Set up the depth buffer based on per-renderer flags. - SetupDepthBuffer( item, context, isLayer3D ); - SetupPerRendererFlags( item, context, usedStencilBuffer, stencilManagedByDrawMode ); + // Set up the stencil buffer based on both the Renderer and Actor APIs. + // The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used. + SetupStencilBuffer( item, context, usedStencilBuffer, lastStencilDepth, lastClippingId ); + // Setup Batching and calculate if we should perform or skip the upcoming render. + const bool performRender( SetupBatching( item, geometryBatcher ) ); + + // Render the item if it has not been skipped by batching. + if( DALI_LIKELY( performRender ) ) + { item.mRenderer->Render( context, textureCache, bufferIndex, *item.mNode, defaultShader, - item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, item.mBatchRenderGeometry, !item.mIsOpaque ); + item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, + item.mSize, item.mBatchRenderGeometry, !item.mIsOpaque ); } } } @@ -307,11 +397,10 @@ void ProcessRenderInstruction( const RenderInstruction& instruction, const Matrix* viewMatrix = instruction.GetViewMatrix( bufferIndex ); const Matrix* projectionMatrix = instruction.GetProjectionMatrix( bufferIndex ); - DALI_ASSERT_DEBUG( NULL != viewMatrix ); - DALI_ASSERT_DEBUG( NULL != projectionMatrix ); + DALI_ASSERT_DEBUG( viewMatrix ); + DALI_ASSERT_DEBUG( projectionMatrix ); - if( NULL != viewMatrix && - NULL != projectionMatrix ) + if( viewMatrix && projectionMatrix ) { const RenderListContainer::SizeType count = instruction.RenderListCount(); @@ -321,8 +410,7 @@ void ProcessRenderInstruction( const RenderInstruction& instruction, { const RenderList* renderList = instruction.GetRenderList( index ); - if( renderList && - !renderList->IsEmpty() ) + if( renderList && !renderList->IsEmpty() ) { ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, *viewMatrix, *projectionMatrix, &geometryBatcher ); } diff --git a/dali/internal/render/common/render-debug.cpp b/dali/internal/render/common/render-debug.cpp index d5f1165..e5e1d23 100644 --- a/dali/internal/render/common/render-debug.cpp +++ b/dali/internal/render/common/render-debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -26,7 +26,9 @@ #include #include #include +#include +using Dali::Internal::SceneGraph::Node; using Dali::Internal::SceneGraph::RenderList; namespace Dali @@ -38,6 +40,10 @@ namespace Internal namespace Render { +// These functions should only be defined if they are being used by the #define in the header. +// Otherwise they will contribute negatively to code coverage. +#ifdef DALI_PRINT_RENDER_INFO + void PrintFrameStart( BufferIndex bufferIndex ) { DALI_LOG_RENDER_INFO( "RENDER START - bufferIndex: %d\n", bufferIndex ); @@ -71,35 +77,9 @@ void PrintRenderInstruction( const SceneGraph::RenderInstruction& instruction, B void PrintRenderList( const RenderList& list ) { - unsigned int flags = list.GetFlags(); - std::stringstream debugStream; debugStream << "Rendering items"; - if( flags ) - { - debugStream << " with:"; - - if( flags & RenderList::STENCIL_BUFFER_ENABLED ) - { - debugStream << " STENCIL_TEST"; - } - - if( flags & RenderList::STENCIL_WRITE ) - { - debugStream << " STENCIL_WRITE"; - } - - if( flags & RenderList::STENCIL_CLEAR ) - { - debugStream << " STENCIL_CLEAR"; - } - } - else - { - debugStream << " without any STENCIL settings"; - } - if( list.IsClipping() ) { debugStream << ", ClippingBox: " << list.GetClippingBox().x << "," << list.GetClippingBox().y << " " << list.GetClippingBox().width << "x" << list.GetClippingBox().height; @@ -126,6 +106,8 @@ void PrintRendererCount( unsigned int frameCount, unsigned int rendererCount ) } } +#endif + } // Render } // Internal diff --git a/dali/internal/render/common/render-debug.h b/dali/internal/render/common/render-debug.h index 8d5176e..5cb25be 100644 --- a/dali/internal/render/common/render-debug.h +++ b/dali/internal/render/common/render-debug.h @@ -64,6 +64,7 @@ class PropertyInputImpl; namespace SceneGraph { +class Node; class RenderInstruction; struct RenderList; struct RenderItem; @@ -109,6 +110,13 @@ void PrintRenderItem( const SceneGraph::RenderItem& item ); */ void PrintRendererCount( unsigned int frameCount, unsigned int rendererCount ); +/** + * Recursively dumps a Node tree. + * @param[in] node The starting node to dump from + * @param[in] indent Optional. Leave unset for default indent (used internally while recursing) + */ +void DumpNode( const SceneGraph::Node* node, unsigned int indent = 0 ); + } // Render } // Internal diff --git a/dali/internal/render/common/render-item.cpp b/dali/internal/render/common/render-item.cpp index d7fd016..f8855f3 100644 --- a/dali/internal/render/common/render-item.cpp +++ b/dali/internal/render/common/render-item.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. diff --git a/dali/internal/render/common/render-item.h b/dali/internal/render/common/render-item.h index bd37bda..425d8a3 100644 --- a/dali/internal/render/common/render-item.h +++ b/dali/internal/render/common/render-item.h @@ -1,8 +1,8 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H__ +#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H +#define DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -46,6 +46,7 @@ struct RenderItem { /** * Construct a new RenderItem + * @return A pointer to a new RenderItem. */ static RenderItem* New(); @@ -57,6 +58,7 @@ struct RenderItem /** * Overriden delete operator. * Deletes the RenderItem from its global memory pool + * @param[in] A pointer to the RenderItem to delete. */ void operator delete( void* ptr ); @@ -72,7 +74,6 @@ struct RenderItem bool mIsOpaque:1; bool mBatched:1; - private: /** @@ -83,6 +84,7 @@ private: // RenderItems should not be copied as they are heavy RenderItem( const RenderItem& item ); RenderItem& operator = ( const RenderItem& item ); + }; } // namespace SceneGraph @@ -91,4 +93,4 @@ private: } // namespace Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H__ +#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H diff --git a/dali/internal/render/common/render-list.h b/dali/internal/render/common/render-list.h index 734ad0f..1aef561 100644 --- a/dali/internal/render/common/render-list.h +++ b/dali/internal/render/common/render-list.h @@ -1,8 +1,8 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__ +#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H +#define DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -47,29 +47,17 @@ struct RenderList; typedef OwnerContainer< RenderList* > RenderListContainer; /** - * The RenderList structure provides the renderer with a list of renderers and - * a set of flags to tell it what depth buffering is required. + * The RenderList structure provides the renderer with a list of renderers. */ struct RenderList { public: /** - * The RenderFlags describe how the objects are rendered using the stencil buffer. - */ - enum RenderFlags - { - STENCIL_BUFFER_ENABLED = 1 << 0, ///< If stencil buffer should be used for writing / test operation - STENCIL_WRITE = 1 << 1, ///< If the stencil buffer is writable - STENCIL_CLEAR = 1 << 2, ///< If the stencil buffer should first be cleared - }; - - /** * Constructor */ RenderList() : mNextFree( 0 ), - mRenderFlags( 0u ), mClippingBox( NULL ), mSourceLayer( NULL ), mHasColorRenderItems( false ) @@ -81,44 +69,17 @@ public: */ ~RenderList() { - // pointer container deletes the render items + // Pointer container deletes the render items delete mClippingBox; } /** - * Clear the render flags - */ - void ClearFlags() - { - mRenderFlags = 0u; - } - - /** - * Set particular render flags - * @param[in] flags The set of flags to bitwise or with existing flags - */ - void SetFlags( unsigned int flags ) - { - mRenderFlags |= flags; - } - - /** - * Retrieve the render flags. - * @return the render flags. - */ - unsigned int GetFlags() const - { - return mRenderFlags; - } - - /** * Reset the render list for next frame */ void Reset() { - // we dont want to delete and re-create the render items every frame + // We don't want to delete and re-create the render items every frame mNextFree = 0; - mRenderFlags = 0u; delete mClippingBox; mClippingBox = NULL; @@ -207,7 +168,7 @@ public: */ bool IsEmpty() const { - return (mNextFree == 0); + return ( mNextFree == 0 ); } /** @@ -219,9 +180,8 @@ public: { if( clipping ) { - ClippingBox* newBox = new ClippingBox( box ); delete mClippingBox; - mClippingBox = newBox; + mClippingBox = new ClippingBox( box );; } } @@ -230,7 +190,7 @@ public: */ bool IsClipping() const { - return (NULL != mClippingBox); + return ( NULL != mClippingBox ); } /** @@ -306,17 +266,17 @@ private: RenderItemContainer mItems; ///< Each item is a renderer and matrix pair RenderItemContainer::SizeType mNextFree; ///< index for the next free item to use - unsigned int mRenderFlags; ///< The render flags - ClippingBox* mClippingBox; ///< The clipping box, in window coordinates, when clipping is enabled Layer* mSourceLayer; ///< The originating layer where the renderers are from bool mHasColorRenderItems : 1; ///< True if list contains color render items + }; + } // namespace SceneGraph } // namespace Internal } // namespace Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__ +#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 19e4e8d..626c1f8 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -173,7 +172,6 @@ struct RenderManager::Impl Integration::GlSyncAbstraction& glSyncAbstraction; ///< GL sync abstraction RenderQueue renderQueue; ///< A message queue for receiving messages from the update-thread. TextureCache textureCache; ///< Cache for all GL textures - Render::UniformNameCache uniformNameCache; ///< Cache to provide unique indices for uniforms LockedResourceQueue& textureUploadedQueue; ///< A queue for requesting resource post processing in update thread // Render instructions describe what should be rendered during RenderManager::Render() @@ -303,7 +301,7 @@ void RenderManager::SetDefaultSurfaceRect(const Rect& rect) void RenderManager::AddRenderer( Render::Renderer* renderer ) { // Initialize the renderer as we are now in render thread - renderer->Initialize( mImpl->context, mImpl->textureCache, mImpl->uniformNameCache ); + renderer->Initialize( mImpl->context, mImpl->textureCache ); mImpl->rendererContainer.PushBack( renderer ); diff --git a/dali/internal/render/data-providers/uniform-name-cache.cpp b/dali/internal/render/data-providers/uniform-name-cache.cpp deleted file mode 100644 index a98c171..0000000 --- a/dali/internal/render/data-providers/uniform-name-cache.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2015 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. - */ - -// CLASS HEADER -#include - -// INTERNAL INCLUDES -#include - -namespace Dali -{ -namespace Internal -{ -namespace Render -{ - -UniformNameCache::UniformNameCache() -{} - -UniformNameCache::~UniformNameCache() -{ // OwnerContainer cleans up -} - -int32_t UniformNameCache::GetSamplerUniformUniqueIndex( const std::string& uniformName ) -{ - OwnerContainer< UniformEntry* >::SizeType index = 0; - const OwnerContainer< UniformEntry* >::SizeType end = mSamplerUniformCache.Size(); - - const std::size_t hash = Dali::CalculateHash( uniformName ); - - for( ;index < end; ++index ) - { - // check hash first - if( hash == mSamplerUniformCache[ index ]->nameHash ) - { - // check full name in case of collision - if( mSamplerUniformCache[ index ]->uniformName == uniformName ) - { - // match, return the index - return index; - } - } - } - // no match found, add new entry to cache - mSamplerUniformCache.PushBack( new UniformEntry( uniformName, hash ) ); - - return end; -} - -} // namespace Render - -} // namespace Internal - -} // namespace Dali diff --git a/dali/internal/render/data-providers/uniform-name-cache.h b/dali/internal/render/data-providers/uniform-name-cache.h deleted file mode 100644 index d251117..0000000 --- a/dali/internal/render/data-providers/uniform-name-cache.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef DALI_INTERNAL_UNIFORM_NAME_CACHE_H -#define DALI_INTERNAL_UNIFORM_NAME_CACHE_H - -/* - * Copyright (c) 2015 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. - */ - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Render -{ - -/** - * This class maps uniform names to unique indices that can be used to cache the GL uniform - * index values in programs and only do the costly string lookup once - */ -class UniformNameCache -{ -public: - - /** - * Constructor - */ - UniformNameCache(); - - /** - * Destructor - */ - ~UniformNameCache(); - - /** - * This method can be used to query a cache for the unique index for a sampler uniform - * @param uniformName to get the index for - * @return a unique index for this sampler uniform - */ - int32_t GetSamplerUniformUniqueIndex( const std::string& uniformName ); - -private: // Data - - struct UniformEntry - { - UniformEntry( const std::string& name, std::size_t hash ) - : uniformName( name ), - nameHash( hash ) - { } - std::string uniformName; - std::size_t nameHash; - }; - - OwnerContainer< UniformEntry* > mSamplerUniformCache; - -}; - -} // namespace Render - -} // namespace Internal - -} // namespace Dali - -#endif // DALI_INTERNAL_UNIFORM_NAME_CACHE_H diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index cfaa2be..c88bec2 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -118,12 +117,11 @@ Renderer* Renderer::New( SceneGraph::RenderDataProvider* dataProvider, DepthWriteMode::Type depthWriteMode, DepthTestMode::Type depthTestMode, DepthFunction::Type depthFunction, - StencilParameters& stencilParameters, - bool writeToColorBuffer ) + StencilParameters& stencilParameters ) { return new Renderer( dataProvider, geometry, blendingBitmask, blendColor, faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, - depthFunction, stencilParameters, writeToColorBuffer ); + depthFunction, stencilParameters ); } Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, @@ -135,12 +133,10 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, DepthWriteMode::Type depthWriteMode, DepthTestMode::Type depthTestMode, DepthFunction::Type depthFunction, - StencilParameters& stencilParameters, - bool writeToColorBuffer ) + StencilParameters& stencilParameters ) : mRenderDataProvider( dataProvider ), mContext( NULL), mTextureCache( NULL ), - mUniformNameCache( NULL ), mGeometry( geometry ), mUniformIndexMap(), mAttributesLocation(), @@ -152,7 +148,6 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, mFaceCullingMode( faceCullingMode ), mDepthWriteMode( depthWriteMode ), mDepthTestMode( depthTestMode ), - mWriteToColorBuffer( writeToColorBuffer ), mUpdateAttributesLocation( true ), mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ), mBatchingEnabled( false ) @@ -168,11 +163,10 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, } } -void Renderer::Initialize( Context& context, SceneGraph::TextureCache& textureCache, Render::UniformNameCache& uniformNameCache ) +void Renderer::Initialize( Context& context, SceneGraph::TextureCache& textureCache ) { mContext = &context; mTextureCache = &textureCache; - mUniformNameCache = &uniformNameCache; } Renderer::~Renderer() @@ -483,14 +477,14 @@ DepthFunction::Type Renderer::GetDepthFunction() const return mDepthFunction; } -void Renderer::SetStencilMode( StencilMode::Type stencilMode ) +void Renderer::SetRenderMode( RenderMode::Type renderMode ) { - mStencilParameters.stencilMode = stencilMode; + mStencilParameters.renderMode = renderMode; } -StencilMode::Type Renderer::GetStencilMode() const +RenderMode::Type Renderer::GetRenderMode() const { - return mStencilParameters.stencilMode; + return mStencilParameters.renderMode; } void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction ) @@ -563,16 +557,6 @@ StencilOperation::Type Renderer::GetStencilOperationOnZPass() const return mStencilParameters.stencilOperationOnZPass; } -void Renderer::SetWriteToColorBuffer( bool writeToColorBuffer ) -{ - mWriteToColorBuffer = writeToColorBuffer; -} - -bool Renderer::GetWriteToColorBuffer() const -{ - return mWriteToColorBuffer; -} - void Renderer::SetBatchingEnabled( bool batchingEnabled ) { mBatchingEnabled = batchingEnabled; @@ -649,7 +633,7 @@ void Renderer::Render( Context& context, } } -void Renderer::SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RendererWithSortAttributes& sortAttributes ) const +void Renderer::SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const { sortAttributes.shader = &( mRenderDataProvider->GetShader() ); const std::vector& textures( mRenderDataProvider->GetTextures() ); diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 8011c31..bbbbfa7 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include namespace Dali @@ -50,10 +50,8 @@ class TextureCache; class NodeDataProvider; } - namespace Render { -class UniformNameCache; /** * Renderers are used to render meshes @@ -69,28 +67,28 @@ public: */ struct StencilParameters { - StencilParameters( StencilMode::Type stencilMode, StencilFunction::Type stencilFunction, int stencilFunctionMask, + StencilParameters( RenderMode::Type renderMode, StencilFunction::Type stencilFunction, int stencilFunctionMask, int stencilFunctionReference, int stencilMask, StencilOperation::Type stencilOperationOnFail, StencilOperation::Type stencilOperationOnZFail, StencilOperation::Type stencilOperationOnZPass ) : stencilFunctionMask ( stencilFunctionMask ), stencilFunctionReference ( stencilFunctionReference ), stencilMask ( stencilMask ), + renderMode ( renderMode ), stencilFunction ( stencilFunction ), stencilOperationOnFail ( stencilOperationOnFail ), stencilOperationOnZFail ( stencilOperationOnZFail ), - stencilOperationOnZPass ( stencilOperationOnZPass ), - stencilMode ( stencilMode ) + stencilOperationOnZPass ( stencilOperationOnZPass ) { } int stencilFunctionMask; ///< The stencil function mask int stencilFunctionReference; ///< The stencil function reference int stencilMask; ///< The stencil mask - StencilFunction::Type stencilFunction:3; ///< The stencil function + RenderMode::Type renderMode:3; ///< The render mode + StencilFunction::Type stencilFunction:3; ///< The stencil function StencilOperation::Type stencilOperationOnFail:3; ///< The stencil operation for stencil test fail StencilOperation::Type stencilOperationOnZFail:3; ///< The stencil operation for depth test fail StencilOperation::Type stencilOperationOnZPass:3; ///< The stencil operation for depth test pass - StencilMode::Type stencilMode:2; ///< The stencil mode }; /** @@ -115,7 +113,6 @@ public: * @param[in] depthTestMode Depth buffer test mode * @param[in] depthFunction Depth function * @param[in] stencilParameters Struct containing all stencil related options - * @param[in] writeToColorBuffer Set to True to write to the color buffer */ static Renderer* New( SceneGraph::RenderDataProvider* dataProviders, Render::Geometry* geometry, @@ -126,8 +123,7 @@ public: DepthWriteMode::Type depthWriteMode, DepthTestMode::Type depthTestMode, DepthFunction::Type depthFunction, - StencilParameters& stencilParameters, - bool writeToColorBuffer ); + StencilParameters& stencilParameters ); /** * Constructor. @@ -141,7 +137,6 @@ public: * @param[in] depthTestMode Depth buffer test mode * @param[in] depthFunction Depth function * @param[in] stencilParameters Struct containing all stencil related options - * @param[in] writeToColorBuffer Set to True to write to the color buffer */ Renderer( SceneGraph::RenderDataProvider* dataProviders, Render::Geometry* geometry, @@ -152,8 +147,7 @@ public: DepthWriteMode::Type depthWriteMode, DepthTestMode::Type depthTestMode, DepthFunction::Type depthFunction, - StencilParameters& stencilParameters, - bool writeToColorBuffer ); + StencilParameters& stencilParameters ); /** * Change the data providers of the renderer @@ -181,9 +175,8 @@ public: * This is called when the renderer is inside render thread * @param[in] context Context used by the renderer * @param[in] textureCache The texture cache to use - * @param[in] uniformNameCache Cache of uniform names to use */ - void Initialize( Context& context, SceneGraph::TextureCache& textureCache, Render::UniformNameCache& uniformNameCache ); + void Initialize( Context& context, SceneGraph::TextureCache& textureCache ); /** * Destructor @@ -264,16 +257,16 @@ public: DepthFunction::Type GetDepthFunction() const; /** - * Sets the stencil mode - * @param[in] stencilMode The stencil function + * Sets the render mode + * @param[in] renderMode The render mode */ - void SetStencilMode( StencilMode::Type stencilMode ); + void SetRenderMode( RenderMode::Type mode ); /** - * Gets the stencil mode - * @return The stencil function + * Gets the render mode + * @return The render mode */ - StencilMode::Type GetStencilMode() const; + RenderMode::Type GetRenderMode() const; /** * Sets the stencil function @@ -360,18 +353,6 @@ public: StencilOperation::Type GetStencilOperationOnZPass() const; /** - * Sets whether or not to write to the color buffer - * @param[in] writeToColorBuffer True to write to the color buffer - */ - void SetWriteToColorBuffer( bool writeToColorBuffer ); - - /** - * Gets whether or not to write to the color buffer - * @return True to write to the color buffer - */ - bool GetWriteToColorBuffer() const; - - /** * Sets batching mode on the renderer * @param[in] batchingEnabled batching state */ @@ -410,7 +391,7 @@ public: * @param[in] bufferIndex The current update buffer index. * @param[out] sortAttributes */ - void SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RendererWithSortAttributes& sortAttributes ) const; + void SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const; private: @@ -461,16 +442,16 @@ private: Context* mContext; SceneGraph::TextureCache* mTextureCache; - Render::UniformNameCache* mUniformNameCache; Render::Geometry* mGeometry; struct UniformIndexMap { - unsigned int uniformIndex; ///< The index of the cached location in the Program + unsigned int uniformIndex; ///< The index of the cached location in the Program const PropertyInputImpl* propertyValue; }; typedef Dali::Vector< UniformIndexMap > UniformIndexMappings; + UniformIndexMappings mUniformIndexMap; Vector mAttributesLocation; @@ -485,10 +466,10 @@ private: BlendMode::Type mBlendMode:2; ///< The mode of blending DepthWriteMode::Type mDepthWriteMode:2; ///< The depth write mode DepthTestMode::Type mDepthTestMode:2; ///< The depth test mode - bool mWriteToColorBuffer:1; ///< True if we are writing to the color buffer bool mUpdateAttributesLocation:1; ///< Indicates attribute locations have changed bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required - bool mBatchingEnabled:1; ///< Flag indicating if the renderer is batchable + bool mBatchingEnabled:1; ///< Flag indicating if the renderer is batchable + }; } // namespace SceneGraph diff --git a/dali/internal/render/renderers/render-texture.cpp b/dali/internal/render/renderers/render-texture.cpp index 59c1206..8ca2647 100644 --- a/dali/internal/render/renderers/render-texture.cpp +++ b/dali/internal/render/renderers/render-texture.cpp @@ -625,6 +625,11 @@ void NewTexture::Destroy( Context& context ) if( mId ) { context.DeleteTextures( 1, &mId ); + + if( mNativeImage ) + { + mNativeImage->GlExtensionDestroy(); + } } } @@ -645,7 +650,12 @@ void NewTexture::Initialize(Context& context) context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT ); // platform specific implementation decides on what GL extension to use - mNativeImage->TargetTexture(); + if( mNativeImage->TargetTexture() != 0u ) + { + context.DeleteTextures( 1, &mId ); + mNativeImage->GlExtensionDestroy(); + mId = 0u; + } } } else @@ -803,6 +813,12 @@ bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampl ApplySampler( context, sampler ); + if( mNativeImage ) + { + //Allow implementation specific operations after binding the texture + mNativeImage->PrepareTexture(); + } + return true; } diff --git a/dali/internal/render/renderers/render-texture.h b/dali/internal/render/renderers/render-texture.h index 35efb2e..8e3dc3d 100644 --- a/dali/internal/render/renderers/render-texture.h +++ b/dali/internal/render/renderers/render-texture.h @@ -45,14 +45,6 @@ class Texture public: /** - * Enumeration to tell that this sampler does not have a unique index yet - */ - enum - { - NOT_INITIALIZED = -1 - }; - - /** * Constructor */ Texture() @@ -86,7 +78,6 @@ public: public: // called from RenderThread /** - * @param[in] buffer A vector wit * Get the texture ID * @return the id of the associated texture */ diff --git a/dali/internal/update/manager/prepare-render-instructions.cpp b/dali/internal/update/manager/prepare-render-instructions.cpp deleted file mode 100644 index 350d66e..0000000 --- a/dali/internal/update/manager/prepare-render-instructions.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (c) 2016 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. - * - */ - -// CLASS HEADER -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include // for the default sorting function -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace -{ -#if defined(DEBUG_ENABLED) -Debug::Filter* gRenderListLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_LISTS"); -#endif -} - -namespace Dali -{ - -namespace Internal -{ - -namespace SceneGraph -{ - -/** - * Add a renderer to the list - * @param updateBufferIndex to read the model matrix from - * @param renderList to add the item to - * @param renderable Node-Renderer pair - * @param viewMatrix used to calculate modelview matrix for the item - * @param camera The camera used to render - * @param geometryBatcher The instance of the geometry batcher - * @param isLayer3d Whether we are processing a 3D layer or not - * @param cull Whether frustum culling is enabled or not - */ -inline void AddRendererToRenderList( BufferIndex updateBufferIndex, - RenderList& renderList, - Renderable& renderable, - const Matrix& viewMatrix, - SceneGraph::Camera& camera, - GeometryBatcher& geometryBatcher, - bool isLayer3d, - bool cull ) -{ - // discard renderable early if it belongs to the batch which has been consumed in during frame - Node* renderableNode = renderable.mNode; - const bool batchingValid( renderable.mRenderer->IsBatchingEnabled() && renderableNode->mBatchIndex != BATCH_NULL_HANDLE ); - if( batchingValid && geometryBatcher.HasRendered( renderableNode->mBatchIndex ) ) - { - return; - } - - bool inside( true ); - const Node* batchParentNode = renderable.mNode->GetBatchParent(); - const Node* node = ( renderable.mRenderer->IsBatchingEnabled() && batchParentNode ) ? - batchParentNode : renderableNode; - - if ( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) ) - { - const Vector4& boundingSphere = node->GetBoundingSphere(); - inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) && - (camera.CheckSphereInFrustum( updateBufferIndex, Vector3(boundingSphere), boundingSphere.w ) ); - } - - if( inside ) - { - if( batchingValid ) - { - geometryBatcher.SetRendered( renderableNode->mBatchIndex ); - } - - Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode ); - if( opacity != Renderer::TRANSPARENT ) - { - // Get the next free RenderItem - RenderItem& item = renderList.GetNextFreeItem(); - item.mRenderer = &renderable.mRenderer->GetRenderer(); - item.mNode = renderable.mNode; - item.mIsOpaque = (opacity == Renderer::OPAQUE); - - if( isLayer3d ) - { - item.mDepthIndex = renderable.mRenderer->GetDepthIndex(); - } - else - { - item.mDepthIndex = renderable.mRenderer->GetDepthIndex() + static_cast( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER; - } - // save MV matrix onto the item - node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize ); - Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix ); - } - } -} - -/** - * Add all renderers to the list - * @param updateBufferIndex to read the model matrix from - * @param renderList to add the items to - * @param renderers to render - * NodeRendererContainer Node-Renderer pairs - * @param viewMatrix used to calculate modelview matrix for the items - * @param camera The camera used to render - * @param geometryBatcher The instance of the geometry batcher - * @param isLayer3d Whether we are processing a 3D layer or not - * @param cull Whether frustum culling is enabled or not - */ -inline void AddRenderersToRenderList( BufferIndex updateBufferIndex, - RenderList& renderList, - RenderableContainer& renderers, - const Matrix& viewMatrix, - SceneGraph::Camera& camera, - GeometryBatcher* geometryBatcher, - bool isLayer3d, - bool cull) -{ - DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n"); - - unsigned int rendererCount( renderers.Size() ); - for( unsigned int i(0); iGetRenderer(); - checkSumNew += size_t( &renderer ); - checkSumOld += size_t( &renderList.GetRenderer( index ) ); - } - if( checkSumNew == checkSumOld ) - { - // tell list to reuse its existing items - renderList.ReuseCachedItems(); - retValue = true; - } - } - return retValue; -} - -/** - * Function which sorts render items by depth index then by instance - * ptrs of shader/texture/geometry. - * @param lhs item - * @param rhs item - * @return true if left item is greater than right - */ -bool CompareItems( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs ) -{ - if( lhs.renderItem->mDepthIndex == rhs.renderItem->mDepthIndex ) - { - if( lhs.shader == rhs.shader ) - { - if( lhs.textureResourceId == rhs.textureResourceId ) - { - return lhs.geometry < rhs.geometry; - } - return lhs.textureResourceId < rhs.textureResourceId; - } - return lhs.shader < rhs.shader; - } - return lhs.renderItem->mDepthIndex < rhs.renderItem->mDepthIndex; -} -/** - * Function which sorts the render items by Z function, then - * by instance ptrs of shader/texture/geometry. - * @param lhs item - * @param rhs item - * @return true if left item is greater than right - */ -bool CompareItems3D( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs ) -{ - bool lhsIsOpaque = lhs.renderItem->mIsOpaque; - if( lhsIsOpaque == rhs.renderItem->mIsOpaque ) - { - if( lhsIsOpaque ) - { - //If both RenderItems are opaque, sort using shader, then texture then geometry - if( lhs.shader == rhs.shader ) - { - if( lhs.textureResourceId == rhs.textureResourceId ) - { - return lhs.geometry < rhs.geometry; - } - return lhs.textureResourceId < rhs.textureResourceId; - } - return lhs.shader < rhs.shader; - } - else - { - //If both RenderItems are transparent, sort using z,then shader, then texture, then geometry - if( Equals(lhs.zValue, rhs.zValue) ) - { - if( lhs.shader == rhs.shader ) - { - if( lhs.textureResourceId == rhs.textureResourceId ) - { - return lhs.geometry < rhs.geometry; - } - return lhs.textureResourceId < rhs.textureResourceId; - } - return lhs.shader < rhs.shader; - } - return lhs.zValue > rhs.zValue; - } - } - else - { - return lhsIsOpaque; - } -} - -/** - * Sort render items - * @param bufferIndex The buffer to read from - * @param renderList to sort - * @param layer where the renderers are from - * @param sortingHelper to use for sorting the renderitems (to avoid reallocating) - */ -inline void SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, RendererSortingHelper& sortingHelper ) -{ - const size_t renderableCount = renderList.Count(); - // reserve space if needed - const unsigned int oldcapacity = sortingHelper.size(); - if( oldcapacity < renderableCount ) - { - sortingHelper.reserve( renderableCount ); - // add real objects (reserve does not construct objects) - sortingHelper.insert( sortingHelper.begin() + oldcapacity, - (renderableCount - oldcapacity), - RendererWithSortAttributes() ); - } - else - { - // clear extra elements from helper, does not decrease capability - sortingHelper.resize( renderableCount ); - } - - // calculate the sorting value, once per item by calling the layers sort function - // Using an if and two for-loops rather than if inside for as its better for branch prediction - if( layer.UsesDefaultSortFunction() ) - { - for( size_t index = 0; index < renderableCount; ++index ) - { - RenderItem& item = renderList.GetItem( index ); - - item.mRenderer->SetSortAttributes( bufferIndex, sortingHelper[ index ] ); - - // the default sorting function should get inlined here - sortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; - - // keep the renderitem pointer in the helper so we can quickly reorder items after sort - sortingHelper[ index ].renderItem = &item; - } - } - else - { - const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction(); - for( size_t index = 0; index < renderableCount; ++index ) - { - RenderItem& item = renderList.GetItem( index ); - - item.mRenderer->SetSortAttributes( bufferIndex, sortingHelper[ index ] ); - sortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; - - // keep the renderitem pointer in the helper so we can quickly reorder items after sort - sortingHelper[ index ].renderItem = &item; - } - } - - if( layer.GetBehavior() == Dali::Layer::LAYER_3D) - { - // sort the renderers back to front, Z Axis point from near plane to far plane - std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems3D ); - } - else - { - // sort the renderers based on DepthIndex - std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems ); - } - - // reorder/repopulate the renderitems in renderlist to correct order based on sortinghelper - DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n"); - RenderItemContainer::Iterator renderListIter = renderList.GetContainer().Begin(); - for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter ) - { - *renderListIter = sortingHelper[ index ].renderItem; - DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, " sortedList[%d] = %p\n", index, sortingHelper[ index ].renderItem->mRenderer); - } -} - -/** - * Add color renderers from the layer onto the next free render list - * @param updateBufferIndex to use - * @param layer to get the renderers from - * @param viewmatrix for the camera from rendertask - * @param camera to use the view frustum - * @param stencilRenderablesExist is true if there are stencil renderers on this layer - * @param instruction to fill in - * @param sortingHelper to use for sorting the renderitems (to avoid reallocating) - * @param geometryBatcher the instance of the geometry batcher - * @param tryReuseRenderList whether to try to reuse the cached items from the instruction - * @param cull Whether frustum culling is enabled or not - */ -inline void AddColorRenderers( BufferIndex updateBufferIndex, - Layer& layer, - const Matrix& viewMatrix, - SceneGraph::Camera& camera, - bool stencilRenderablesExist, - RenderInstruction& instruction, - RendererSortingHelper& sortingHelper, - GeometryBatcher& geometryBatcher, - bool tryReuseRenderList, - bool cull) -{ - RenderList& renderList = instruction.GetNextFreeRenderList( layer.colorRenderables.Size() ); - renderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); - renderList.SetSourceLayer( &layer ); - renderList.SetHasColorRenderItems( true ); - - // try to reuse cached renderitems from last time around - if( tryReuseRenderList ) - { - if( TryReuseCachedRenderers( layer, renderList, layer.colorRenderables ) ) - { - return; - } - } - - AddRenderersToRenderList( updateBufferIndex, renderList, layer.colorRenderables, viewMatrix, camera, &geometryBatcher, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull ); - SortRenderItems( updateBufferIndex, renderList, layer, sortingHelper ); - - // Setup the render flags for stencil. - renderList.ClearFlags(); - if( stencilRenderablesExist ) - { - // Note: SetFlags does not overwrite, it ORs, so ClearFlags() is also required. - renderList.SetFlags( RenderList::STENCIL_BUFFER_ENABLED ); - } -} - -/** - * Add overlay renderers from the layer onto the next free render list - * @param updateBufferIndex to use - * @param layer to get the renderers from - * @param viewmatrix for the camera from rendertask - * @param camera to use - * @param stencilRenderablesExist is true if there are stencil renderers on this layer - * @param instruction to fill in - * @param tryReuseRenderList whether to try to reuse the cached items from the instruction - * @param cull Whether frustum culling is enabled or not - */ -inline void AddOverlayRenderers( BufferIndex updateBufferIndex, - Layer& layer, - const Matrix& viewMatrix, - SceneGraph::Camera& camera, - bool stencilRenderablesExist, - RenderInstruction& instruction, - RendererSortingHelper& sortingHelper, - bool tryReuseRenderList, - bool cull ) -{ - RenderList& overlayRenderList = instruction.GetNextFreeRenderList( layer.overlayRenderables.Size() ); - overlayRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); - overlayRenderList.SetSourceLayer( &layer ); - overlayRenderList.SetHasColorRenderItems( false ); - - //Set render flags - overlayRenderList.ClearFlags(); - if(stencilRenderablesExist) - { - overlayRenderList.SetFlags(RenderList::STENCIL_BUFFER_ENABLED); - } - - // try to reuse cached renderitems from last time around - if( tryReuseRenderList ) - { - if( TryReuseCachedRenderers( layer, overlayRenderList, layer.overlayRenderables ) ) - { - return; - } - } - AddRenderersToRenderList( updateBufferIndex, overlayRenderList, layer.overlayRenderables, viewMatrix, camera, NULL, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull ); - SortRenderItems( updateBufferIndex, overlayRenderList, layer, sortingHelper ); -} - -/** - * Add stencil renderers from the layer onto the next free render list - * @param updateBufferIndex to use - * @param layer to get the renderers from - * @param viewmatrix for the camera from rendertask - * @param camera to use - * @param instruction to fill in - * @param tryReuseRenderList whether to try to reuse the cached items from the instruction - * @param cull Whether frustum culling is enabled or not - */ -inline void AddStencilRenderers( BufferIndex updateBufferIndex, - Layer& layer, - const Matrix& viewMatrix, - SceneGraph::Camera& camera, - RenderInstruction& instruction, - bool tryReuseRenderList, - bool cull ) -{ - RenderList& stencilRenderList = instruction.GetNextFreeRenderList( layer.stencilRenderables.Size() ); - stencilRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); - stencilRenderList.SetSourceLayer( &layer ); - stencilRenderList.SetHasColorRenderItems( false ); - - //Set render flags - stencilRenderList.ClearFlags(); - stencilRenderList.SetFlags(RenderList::STENCIL_CLEAR | RenderList::STENCIL_WRITE | RenderList::STENCIL_BUFFER_ENABLED ); - - // try to reuse cached renderitems from last time around - if( tryReuseRenderList ) - { - if( TryReuseCachedRenderers( layer, stencilRenderList, layer.stencilRenderables ) ) - { - return; - } - } - AddRenderersToRenderList( updateBufferIndex, stencilRenderList, layer.stencilRenderables, viewMatrix, camera, NULL, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull ); -} - -void PrepareRenderInstruction( BufferIndex updateBufferIndex, - SortedLayerPointers& sortedLayers, - RenderTask& renderTask, - RendererSortingHelper& sortingHelper, - bool cull, - RenderInstructionContainer& instructions, - GeometryBatcher& geometryBatcher ) -{ - // Retrieve the RenderInstruction buffer from the RenderInstructionContainer - // then populate with instructions. - RenderInstruction& instruction = instructions.GetNextInstruction( updateBufferIndex ); - renderTask.PrepareRenderInstruction( instruction, updateBufferIndex ); - bool viewMatrixHasNotChanged = !renderTask.ViewMatrixUpdated(); - - const Matrix& viewMatrix = renderTask.GetViewMatrix( updateBufferIndex ); - SceneGraph::Camera& camera = renderTask.GetCamera(); - - const SortedLayersIter endIter = sortedLayers.end(); - for ( SortedLayersIter iter = sortedLayers.begin(); iter != endIter; ++iter ) - { - Layer& layer = **iter; - - const bool stencilRenderablesExist( !layer.stencilRenderables.Empty() ); - const bool colorRenderablesExist( !layer.colorRenderables.Empty() ); - const bool overlayRenderablesExist( !layer.overlayRenderables.Empty() ); - const bool tryReuseRenderList( viewMatrixHasNotChanged && layer.CanReuseRenderers( &renderTask.GetCamera() ) ); - - // Ignore stencils if there's nothing to test - if( stencilRenderablesExist && - ( colorRenderablesExist || overlayRenderablesExist ) ) - { - AddStencilRenderers( updateBufferIndex, layer, viewMatrix, camera, instruction, tryReuseRenderList, cull ); - } - - if ( colorRenderablesExist ) - { - AddColorRenderers( updateBufferIndex, - layer, - viewMatrix, - camera, - stencilRenderablesExist, - instruction, - sortingHelper, - geometryBatcher, - tryReuseRenderList, - cull ); - } - - if ( overlayRenderablesExist ) - { - AddOverlayRenderers( updateBufferIndex, layer, viewMatrix, camera, stencilRenderablesExist, - instruction, sortingHelper, tryReuseRenderList, cull ); - } - } - - // inform the render instruction that all renderers have been added and this frame is complete - instruction.UpdateCompleted(); -} - -} // SceneGraph - -} // Internal - -} // Dali diff --git a/dali/internal/update/manager/prepare-render-instructions.h b/dali/internal/update/manager/prepare-render-instructions.h deleted file mode 100644 index bd16804..0000000 --- a/dali/internal/update/manager/prepare-render-instructions.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_PREPARE_RENDER_INSTRUCTIONS_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_PREPARE_RENDER_INSTRUCTIONS_H__ - -/* - * Copyright (c) 2016 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. - * - */ - -// INTERNAL INCLUDES -#include -#include -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Render -{ -class Geometry; -} - -namespace SceneGraph -{ -class RenderTracker; -struct RenderItem; -class Shader; -class GeometryBatcher; - -/** - * Structure to store information for sorting the renderers. - * (Note, depthIndex is stored within the renderItem). - */ -struct RendererWithSortAttributes -{ - RendererWithSortAttributes() - : renderItem( NULL ), - shader(NULL), - textureResourceId( Integration::InvalidResourceId ), - geometry(NULL), - zValue(0.0f) - { - } - - RenderItem* renderItem; ///< The render item that is being sorted (includes depth index) - const Shader* shader; ///< The shader instance - Integration::ResourceId textureResourceId;///< The first texture resource ID of the texture set instance, is InvalidResourceId if the texture set doesn't have any textures - const Render::Geometry* geometry; ///< The geometry instance - float zValue; ///< The zValue of the given renderer (either distance from camera, or a custom calculated value) -}; - -typedef std::vector< RendererWithSortAttributes > RendererSortingHelper; - -class RenderTask; -class RenderInstructionContainer; - -/** - * Sorts and prepares the list of opaque/transparent renderers for each layer. - * Whilst iterating through each layer, update the renderitems ModelView matrices - * - * The opaque and transparent render lists are sorted first by depth - * index, then by Z (for transparent only), then by shader, texture - * and geometry. The render algorithm should then work through both - * lists simultaneously, working through opaque then transparent - * items at each depth index, resetting the flags appropriately. - * - * @param[in] updateBufferIndex The current update buffer index. - * @param[in] sortedLayers The layers containing lists of opaque/transparent renderables. - * @param[in] renderTask The rendering task information. - * @param[in] sortingHelper to avoid allocating containers for sorting every frame - * @param[in] cull Whether frustum culling is enabled or not - * @param[out] instructions The rendering instructions for the next frame. - */ -void PrepareRenderInstruction( BufferIndex updateBufferIndex, - SortedLayerPointers& sortedLayers, - RenderTask& renderTask, - RendererSortingHelper& sortingHelper, - bool cull, - RenderInstructionContainer& instructions, - GeometryBatcher& geometryBatcher ); - -} // namespace SceneGraph - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_SCENE_GRAPH_PREPARE_RENDER_INSTRUCTIONS_H__ diff --git a/dali/internal/update/manager/process-render-tasks.h b/dali/internal/update/manager/process-render-tasks.h deleted file mode 100644 index 3758b02..0000000 --- a/dali/internal/update/manager/process-render-tasks.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_PROCESS_RENDER_TASKS_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_PROCESS_RENDER_TASKS_H__ - -/* - * Copyright (c) 2016 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. - * - */ - -// INTERNAL INCLUDES -#include -#include - -namespace Dali -{ -namespace Internal -{ - -namespace SceneGraph -{ - -class RenderTaskList; - -/** - * Process the list of render-tasks; the output is a series of render instructions. - * @note When ProcessRenderTasks is called, the layers should already the transparent/opaque renderers which are ready to render. - * If there is only one default render-task, then no further processing is required. - * @param[in] updateBufferIndex The current update buffer index. - * @param[in] renderTasks The list of render-tasks. - * @param[in] rootNode The root node of the scene-graph. - * @param[in] sortedLayers The layers containing lists of opaque/transparent renderables. - * @param[in] sortingHelper Helper container for sorting transparent renderables. - * @param[in] geometryBatcher The instance of the geometry batcher - * @param[out] instructions The instructions for rendering the next frame. - */ -void ProcessRenderTasks( BufferIndex updateBufferIndex, - RenderTaskList& renderTasks, - Layer& rootNode, - SortedLayerPointers& sortedLayers, - RendererSortingHelper& sortingHelper, - GeometryBatcher& geometryBatcher, - RenderInstructionContainer& instructions ); - -} // namespace SceneGraph - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_SCENE_GRAPH_PROCESS_RENDER_TASKS_H__ diff --git a/dali/internal/update/manager/render-instruction-processor.cpp b/dali/internal/update/manager/render-instruction-processor.cpp new file mode 100644 index 0000000..7dfa417 --- /dev/null +++ b/dali/internal/update/manager/render-instruction-processor.cpp @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2016 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. + * + */ + +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include // for the default sorting function +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ +#if defined(DEBUG_ENABLED) +Debug::Filter* gRenderListLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_LISTS"); +#endif +} + +namespace Dali +{ + +namespace Internal +{ + +namespace SceneGraph +{ + +namespace +{ + +/** + * Function which sorts render items by depth index then by instance + * ptrs of shader/geometry/material. + * @param[in] lhs Left hand side item + * @param[in] rhs Right hand side item + * @return True if left item is greater than right + */ +bool CompareItems( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) +{ + // @todo Consider replacing all these sortAttributes with a single long int that + // encapsulates the same data (e.g. the middle-order bits of the ptrs). + if( lhs.renderItem->mDepthIndex == rhs.renderItem->mDepthIndex ) + { + if( lhs.shader == rhs.shader ) + { + if( lhs.textureResourceId == rhs.textureResourceId ) + { + return lhs.geometry < rhs.geometry; + } + return lhs.textureResourceId < rhs.textureResourceId; + } + return lhs.shader < rhs.shader; + } + return lhs.renderItem->mDepthIndex < rhs.renderItem->mDepthIndex; +} + +/** + * Function which sorts render items by clipping hierarchy, then depth index and instance + * ptrs of shader/geometry/material. + * @param[in] lhs Left hand side item + * @param[in] rhs Right hand side item + * @return True if left item is greater than right + */ +bool CompareItemsWithClipping( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) +{ + // Items must be sorted in order of clipping first, otherwise incorrect clipping regions could be used. + if( lhs.renderItem->mNode->mClippingSortModifier == rhs.renderItem->mNode->mClippingSortModifier ) + { + return CompareItems( lhs, rhs ); + } + + return lhs.renderItem->mNode->mClippingSortModifier < rhs.renderItem->mNode->mClippingSortModifier; +} + +/** + * Function which sorts the render items by Z function, then + * by instance ptrs of shader / geometry / material. + * @param[in] lhs Left hand side item + * @param[in] rhs Right hand side item + * @return True if left item is greater than right + */ +bool CompareItems3D( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) +{ + bool lhsIsOpaque = lhs.renderItem->mIsOpaque; + if( lhsIsOpaque == rhs.renderItem->mIsOpaque ) + { + if( lhsIsOpaque ) + { + // If both RenderItems are opaque, sort using shader, then material then geometry. + if( lhs.shader == rhs.shader ) + { + if( lhs.textureResourceId == rhs.textureResourceId ) + { + return lhs.geometry < rhs.geometry; + } + return lhs.textureResourceId < rhs.textureResourceId; + } + return lhs.shader < rhs.shader; + } + else + { + // If both RenderItems are transparent, sort using Z, then shader, then material, then geometry. + if( Equals( lhs.zValue, rhs.zValue ) ) + { + if( lhs.shader == rhs.shader ) + { + if( lhs.textureResourceId == rhs.textureResourceId ) + { + return lhs.geometry < rhs.geometry; + } + return lhs.textureResourceId < rhs.textureResourceId; + } + return lhs.shader < rhs.shader; + } + return lhs.zValue > rhs.zValue; + } + } + else + { + return lhsIsOpaque; + } +} + +/** + * Function which sorts render items by clipping hierarchy, then Z function and instance ptrs of shader / geometry / material. + * @param[in] lhs Left hand side item + * @param[in] rhs Right hand side item + * @return True if left item is greater than right + */ +bool CompareItems3DWithClipping( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) +{ + // Items must be sorted in order of clipping first, otherwise incorrect clipping regions could be used. + if( lhs.renderItem->mNode->mClippingSortModifier == rhs.renderItem->mNode->mClippingSortModifier ) + { + return CompareItems3D( lhs, rhs ); + } + + return lhs.renderItem->mNode->mClippingSortModifier < rhs.renderItem->mNode->mClippingSortModifier; +} + +/** + * Add a renderer to the list + * @param updateBufferIndex to read the model matrix from + * @param renderList to add the item to + * @param renderable Node-Renderer pair + * @param viewMatrix used to calculate modelview matrix for the item + * @param camera The camera used to render + * @param geometryBatcher The instance of the geometry batcher + * @param isLayer3d Whether we are processing a 3D layer or not + * @param cull Whether frustum culling is enabled or not + */ +inline void AddRendererToRenderList( BufferIndex updateBufferIndex, + RenderList& renderList, + Renderable& renderable, + const Matrix& viewMatrix, + SceneGraph::Camera& camera, + GeometryBatcher& geometryBatcher, + bool isLayer3d, + bool cull ) +{ + // Discard renderable early if it belongs to the batch which has been consumed in during frame. + Node* renderableNode = renderable.mNode; + const bool batchingValid( renderable.mRenderer->IsBatchingEnabled() && renderableNode->mBatchIndex != BATCH_NULL_HANDLE ); + if( batchingValid && geometryBatcher.HasRendered( renderableNode->mBatchIndex ) ) + { + return; + } + + bool inside( true ); + const Node* batchParentNode = renderable.mNode->GetBatchParent(); + const Node* node = ( renderable.mRenderer->IsBatchingEnabled() && batchParentNode ) ? + batchParentNode : renderableNode; + + if( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) ) + { + const Vector4& boundingSphere = node->GetBoundingSphere(); + inside = ( boundingSphere.w > Math::MACHINE_EPSILON_1000 ) && + ( camera.CheckSphereInFrustum( updateBufferIndex, Vector3( boundingSphere ), boundingSphere.w ) ); + } + + if( inside ) + { + if( batchingValid ) + { + geometryBatcher.SetRendered( renderableNode->mBatchIndex ); + } + + Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode ); + if( opacity != Renderer::TRANSPARENT ) + { + // Get the next free RenderItem. + RenderItem& item = renderList.GetNextFreeItem(); + item.mRenderer = &renderable.mRenderer->GetRenderer(); + item.mNode = renderable.mNode; + item.mIsOpaque = ( opacity == Renderer::OPAQUE ); + item.mDepthIndex = renderable.mRenderer->GetDepthIndex(); + + if( !isLayer3d ) + { + item.mDepthIndex += static_cast( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER; + } + + // Save ModelView matrix onto the item. + node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize ); + + Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix ); + } + } +} + +/** + * Add all renderers to the list + * @param updateBufferIndex to read the model matrix from + * @param renderList to add the items to + * @param renderers to render + * NodeRendererContainer Node-Renderer pairs + * @param viewMatrix used to calculate modelview matrix for the items + * @param camera The camera used to render + * @param geometryBatcher The instance of the geometry batcher + * @param isLayer3d Whether we are processing a 3D layer or not + * @param cull Whether frustum culling is enabled or not + */ +inline void AddRenderersToRenderList( BufferIndex updateBufferIndex, + RenderList& renderList, + RenderableContainer& renderers, + const Matrix& viewMatrix, + SceneGraph::Camera& camera, + GeometryBatcher* geometryBatcher, + bool isLayer3d, + bool cull ) +{ + DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n"); + + unsigned int rendererCount( renderers.Size() ); + for( unsigned int i(0); i < rendererCount; ++i ) + { + AddRendererToRenderList( updateBufferIndex, renderList, renderers[i], viewMatrix, camera, *geometryBatcher, isLayer3d, cull ); + } +} + +/** + * Try to reuse cached RenderItems from the RenderList + * This avoids recalculating the model view matrices in case this part of the scene was static + * An example case is a toolbar layer that rarely changes or a popup on top of the rest of the stage + * @param layer that is being processed + * @param renderList that is cached from frame N-1 + * @param renderables list of renderables + */ +inline bool TryReuseCachedRenderers( Layer& layer, + RenderList& renderList, + RenderableContainer& renderables ) +{ + bool retValue = false; + size_t renderableCount = renderables.Size(); + // Check that the cached list originates from this layer and that the counts match + if( ( renderList.GetSourceLayer() == &layer )&& + ( renderList.GetCachedItemCount() == renderableCount ) ) + { + // Check that all the same renderers are there. This gives us additional security in avoiding rendering the wrong things. + // Render list is sorted so at this stage renderers may be in different order. + // Therefore we check a combined sum of all renderer addresses. + size_t checkSumNew = 0; + size_t checkSumOld = 0; + for( size_t index = 0; index < renderableCount; ++index ) + { + const Render::Renderer& renderer = renderables[index].mRenderer->GetRenderer(); + checkSumNew += size_t( &renderer ); + checkSumOld += size_t( &renderList.GetRenderer( index ) ); + } + if( checkSumNew == checkSumOld ) + { + // tell list to reuse its existing items + renderList.ReuseCachedItems(); + retValue = true; + } + } + return retValue; +} + +inline bool SetupRenderList( RenderableContainer& renderables, + Layer& layer, + RenderInstruction& instruction, + bool tryReuseRenderList, + RenderList** renderList ) +{ + *renderList = &( instruction.GetNextFreeRenderList( renderables.Size() ) ); + ( *renderList )->SetClipping( layer.IsClipping(), layer.GetClippingBox() ); + ( *renderList )->SetSourceLayer( &layer ); + + // Try to reuse cached RenderItems from last time around. + return ( tryReuseRenderList && TryReuseCachedRenderers( layer, **renderList, renderables ) ); +} + +} // Anonymous namespace. + + +RenderInstructionProcessor::RenderInstructionProcessor() +: mSortingHelper() +{ + // Set up a container of comparators for fast run-time selection. + mSortComparitors.Reserve( 4u ); + + mSortComparitors.PushBack( CompareItems ); + mSortComparitors.PushBack( CompareItemsWithClipping ); + mSortComparitors.PushBack( CompareItems3D ); + mSortComparitors.PushBack( CompareItems3DWithClipping ); +} + +RenderInstructionProcessor::~RenderInstructionProcessor() +{ +} + +inline void RenderInstructionProcessor::SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, bool respectClippingOrder ) +{ + const size_t renderableCount = renderList.Count(); + // Reserve space if needed. + const unsigned int oldcapacity = mSortingHelper.size(); + if( oldcapacity < renderableCount ) + { + mSortingHelper.reserve( renderableCount ); + // Add real objects (reserve does not construct objects). + mSortingHelper.insert( mSortingHelper.begin() + oldcapacity, + (renderableCount - oldcapacity), + RenderInstructionProcessor::SortAttributes() ); + } + else + { + // Clear extra elements from helper, does not decrease capability. + mSortingHelper.resize( renderableCount ); + } + + // Calculate the sorting value, once per item by calling the layers sort function. + // Using an if and two for-loops rather than if inside for as its better for branch prediction. + if( layer.UsesDefaultSortFunction() ) + { + for( size_t index = 0; index < renderableCount; ++index ) + { + RenderItem& item = renderList.GetItem( index ); + + item.mRenderer->SetSortAttributes( bufferIndex, mSortingHelper[ index ] ); + + // The default sorting function should get inlined here. + mSortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; + + // Keep the renderitem pointer in the helper so we can quickly reorder items after sort. + mSortingHelper[ index ].renderItem = &item; + } + } + else + { + const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction(); + for( size_t index = 0; index < renderableCount; ++index ) + { + RenderItem& item = renderList.GetItem( index ); + + item.mRenderer->SetSortAttributes( bufferIndex, mSortingHelper[ index ] ); + mSortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; + + // Keep the RenderItem pointer in the helper so we can quickly reorder items after sort. + mSortingHelper[ index ].renderItem = &item; + } + } + + // Here we detemine which comparitor (of the 4) to use. + // The comparitors work like a bitmask. + // 1 << 0 is added to select a clipping comparitor. + // 1 << 1 is added for 3D comparitors. + const unsigned int comparitorIndex = ( respectClippingOrder ? ( 1u << 0u ) : 0u ) | + ( layer.GetBehavior() == Dali::Layer::LAYER_3D ? ( 1u << 1u ) : 0u ); + + std::stable_sort( mSortingHelper.begin(), mSortingHelper.end(), mSortComparitors[ comparitorIndex ] ); + + // Reorder / re-populate the RenderItems in the RenderList to correct order based on the sortinghelper. + DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n"); + RenderItemContainer::Iterator renderListIter = renderList.GetContainer().Begin(); + for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter ) + { + *renderListIter = mSortingHelper[ index ].renderItem; + DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, " sortedList[%d] = %p\n", index, mSortingHelper[ index ].renderItem->mRenderer); + } +} + +void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex, + SortedLayerPointers& sortedLayers, + RenderTask& renderTask, + bool cull, + GeometryBatcher& geometryBatcher, + bool hasClippingNodes, + RenderInstructionContainer& instructions ) +{ + // Retrieve the RenderInstruction buffer from the RenderInstructionContainer + // then populate with instructions. + RenderInstruction& instruction = instructions.GetNextInstruction( updateBufferIndex ); + renderTask.PrepareRenderInstruction( instruction, updateBufferIndex ); + bool viewMatrixHasNotChanged = !renderTask.ViewMatrixUpdated(); + + const Matrix& viewMatrix = renderTask.GetViewMatrix( updateBufferIndex ); + SceneGraph::Camera& camera = renderTask.GetCamera(); + + const SortedLayersIter endIter = sortedLayers.end(); + for( SortedLayersIter iter = sortedLayers.begin(); iter != endIter; ++iter ) + { + Layer& layer = **iter; + const bool tryReuseRenderList( viewMatrixHasNotChanged && layer.CanReuseRenderers( &renderTask.GetCamera() ) ); + const bool isLayer3D = layer.GetBehavior() == Dali::Layer::LAYER_3D; + RenderList* renderList = NULL; + + if( !layer.colorRenderables.Empty() ) + { + RenderableContainer& renderables = layer.colorRenderables; + + if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) ) + { + renderList->SetHasColorRenderItems( true ); + AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, &geometryBatcher, isLayer3D, cull ); + + // We only use the clipping version of the sort comparitor if any clipping nodes exist within the RenderList. + SortRenderItems( updateBufferIndex, *renderList, layer, hasClippingNodes ); + } + } + + if( !layer.overlayRenderables.Empty() ) + { + RenderableContainer& renderables = layer.overlayRenderables; + + if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) ) + { + renderList->SetHasColorRenderItems( false ); + AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, NULL, isLayer3D, cull ); + + // Clipping hierarchy is irrelevant when sorting overlay items, so we specify using the non-clipping version of the sort comparitor. + SortRenderItems( updateBufferIndex, *renderList, layer, false ); + } + } + } + + // Inform the render instruction that all renderers have been added and this frame is complete. + instruction.UpdateCompleted(); +} + + +} // SceneGraph + +} // Internal + +} // Dali diff --git a/dali/internal/update/manager/render-instruction-processor.h b/dali/internal/update/manager/render-instruction-processor.h new file mode 100644 index 0000000..d864b90 --- /dev/null +++ b/dali/internal/update/manager/render-instruction-processor.h @@ -0,0 +1,151 @@ +#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_PROCESSOR_H +#define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_PROCESSOR_H + +/* + * Copyright (c) 2016 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. + * + */ + +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Render +{ +class Geometry; +} + +namespace SceneGraph +{ + +class RenderTracker; +struct RenderItem; +class Shader; +class GeometryBatcher; +struct RenderList; +class RenderTask; +class RenderInstructionContainer; + + +/** + * @brief This class handles the sorting and preparation of Renderers for each layer. + */ +class RenderInstructionProcessor +{ +public: + + /** + * @brief Constructor. + */ + RenderInstructionProcessor(); + + /** + * @brief Destructor. + */ + ~RenderInstructionProcessor(); + + /** + * @brief Structure to store information for sorting the renderers. + * (Note, depthIndex is stored within the renderItem). + */ + struct SortAttributes + { + SortAttributes() + : renderItem( NULL ), + shader( NULL ), + textureResourceId( Integration::InvalidResourceId ), + geometry( NULL ), + zValue( 0.0f ) + { + } + + RenderItem* renderItem; ///< The render item that is being sorted (includes depth index) + const Shader* shader; ///< The shader instance + Integration::ResourceId textureResourceId; ///< The first texture resource ID of the texture set instance, is InvalidResourceId if the texture set doesn't have any textures + const Render::Geometry* geometry; ///< The geometry instance + float zValue; ///< The Z value of the given renderer (either distance from camera, or a custom calculated value) + }; + + + /** + * @brief Sorts and prepares the list of opaque/transparent Renderers for each layer. + * Whilst iterating through each layer, update the RenderItems ModelView matrices + * + * The opaque and transparent render lists are sorted first by depth + * index, then by Z (for transparent only), then by shader, texture + * and geometry. The render algorithm should then work through both + * lists simultaneously, working through opaque then transparent + * items at each depth index, resetting the flags appropriately. + * + * @param[in] updateBufferIndex The current update buffer index. + * @param[in] sortedLayers The layers containing lists of opaque/transparent renderables. + * @param[in] renderTask The rendering task information. + * @param[in] cull Whether frustum culling is enabled or not + * @param[in] geometryBatcher The instance of the geometry batcher + * @param[in] hasClippingNodes Whether any clipping nodes exist within this layer, to optimize sorting if not + * @param[out] instructions The rendering instructions for the next frame. + */ + void Prepare( BufferIndex updateBufferIndex, + SortedLayerPointers& sortedLayers, + RenderTask& renderTask, + bool cull, + GeometryBatcher& geometryBatcher, + bool hasClippingNodes, + RenderInstructionContainer& instructions ); + +private: + + /** + * Undefine copy and assignment operators. + */ + RenderInstructionProcessor( const RenderInstructionProcessor& renderInstructionProcessor ); ///< No definition + RenderInstructionProcessor& operator=( const RenderInstructionProcessor& renderInstructionProcessor ); ///< No definition + +private: + + /** + * @brief Sort render items + * @param bufferIndex The buffer to read from + * @param renderList to sort + * @param layer where the Renderers are from + * @param respectClippingOrder Sort with the correct clipping hierarchy. + */ + inline void SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, bool respectClippingOrder ); + + /// Sort comparitor function pointer type. + typedef bool ( *ComparitorPointer )( const SortAttributes& lhs, const SortAttributes& rhs ); + typedef std::vector< SortAttributes > SortingHelper; + + Dali::Vector< ComparitorPointer > mSortComparitors; ///< Contains all sort comparitors, used for quick look-up + RenderInstructionProcessor::SortingHelper mSortingHelper; ///< Helper used to sort Renderers + +}; + + +} // namespace SceneGraph + +} // namespace Internal + +} // namespace Dali + +#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_PROCESSOR_H diff --git a/dali/internal/update/manager/process-render-tasks.cpp b/dali/internal/update/manager/render-task-processor.cpp similarity index 51% rename from dali/internal/update/manager/process-render-tasks.cpp rename to dali/internal/update/manager/render-task-processor.cpp index b04a108..e620005 100644 --- a/dali/internal/update/manager/process-render-tasks.cpp +++ b/dali/internal/update/manager/render-task-processor.cpp @@ -16,10 +16,9 @@ */ // CLASS HEADER -#include +#include // INTERNAL INCLUDES -#include #include #include #include @@ -48,22 +47,13 @@ namespace SceneGraph namespace //Unnamed namespace { -// Return false if the node or it's parents are exclusive to another render-task +// Return false if the node or it's parents are exclusive to another render-task. bool CheckExclusivity( const Node& node, const RenderTask& task ) { const RenderTask* exclusiveTo = node.GetExclusiveRenderTask(); - if ( exclusiveTo ) + if( exclusiveTo ) { - if ( exclusiveTo == &task ) - { - // Exclusive to the same render-task - return true; - } - else - { - // Exclusive to another render-task - return false; - } + return ( exclusiveTo == &task ); } const Node* parent = node.GetParent(); @@ -72,17 +62,17 @@ bool CheckExclusivity( const Node& node, const RenderTask& task ) return CheckExclusivity( *parent, task ); } - // No exclusive flags set + // No exclusive flags set. return true; } Layer* FindLayer( Node& node ) { Node* currentNode( &node ); - Layer* layer(NULL); + Layer* layer( NULL ); while( currentNode ) { - if( (layer = currentNode->GetLayer()) != NULL ) + if( ( layer = currentNode->GetLayer() ) != NULL ) { return layer; } @@ -94,45 +84,66 @@ Layer* FindLayer( Node& node ) } /** - * Rebuild the Layer::colorRenderables, stencilRenderables and overlayRenderables members, + * Rebuild the Layer::colorRenderables and overlayRenderables members, * including only renderers which are included in the current render-task. * Returns true if all renderers have finished acquiring resources. + * + * @param[in] updateBufferIndex The current update buffer index. + * @param[in] node The current node of the scene-graph. + * @param[in] currentLayer The current layer containing lists of opaque/transparent renderables. + * @param[in] renderTask The current render-task. + * @param[in] inheritedDrawMode The draw mode of the parent + * @param[in] currentClippingId The current Clipping Id + * Note: ClippingId is passed by reference, so it is permanently modified when traversing back up the tree for uniqueness. + * @param[in] clippingDepth The current clipping depth */ bool AddRenderablesForTask( BufferIndex updateBufferIndex, Node& node, Layer& currentLayer, RenderTask& renderTask, - int inheritedDrawMode ) + int inheritedDrawMode, + uint32_t& currentClippingId, + uint32_t clippingDepth ) { bool resourcesFinished = true; // Short-circuit for invisible nodes - if ( !node.IsVisible( updateBufferIndex ) ) + if( !node.IsVisible( updateBufferIndex ) ) { return resourcesFinished; } // Check whether node is exclusive to a different render-task const RenderTask* exclusiveTo = node.GetExclusiveRenderTask(); - if ( exclusiveTo && - exclusiveTo != &renderTask ) + if( exclusiveTo && ( exclusiveTo != &renderTask ) ) { return resourcesFinished; } - Layer* layer = ¤tLayer; - Layer* nodeIsLayer( node.GetLayer() ); - if ( nodeIsLayer ) + // Assume all children go to this layer (if this node is a layer). + Layer* layer = node.GetLayer(); + if( layer ) { - // All children go to this layer - layer = nodeIsLayer; - // Layers do not inherit the DrawMode from their parents - inheritedDrawMode = DrawMode::NORMAL; + inheritedDrawMode = node.GetDrawMode(); + } + else + { + // This node is not a layer. + layer = ¤tLayer; + inheritedDrawMode |= node.GetDrawMode(); } + DALI_ASSERT_DEBUG( NULL != layer ); - inheritedDrawMode |= node.GetDrawMode(); + // Update the clipping Id and depth for this node (if clipping is enabled). + if( DALI_UNLIKELY( node.GetClippingMode() != ClippingMode::DISABLED ) ) + { + ++currentClippingId; // This modifies the reference passed in as well as the local value, causing the value to be global to the recursion. + ++clippingDepth; // This only modifies the local value (which is passed in when the method recurses). + } + // Set the information in the node. + node.SetClippingInformation( currentClippingId, clippingDepth ); const unsigned int count = node.GetRendererCount(); for( unsigned int i = 0; i < count; ++i ) @@ -142,52 +153,58 @@ bool AddRenderablesForTask( BufferIndex updateBufferIndex, bool complete = false; renderer->GetReadyAndComplete( ready, complete ); - DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready?"T":"F", complete?"T":"F"); + DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready ? "T" : "F", complete ? "T" : "F" ); resourcesFinished &= complete; - if( ready ) // i.e. should be rendered (all resources are available) + if( ready ) // IE. should be rendered (all resources are available) { - if( DrawMode::STENCIL == inheritedDrawMode ) - { - layer->stencilRenderables.PushBack( Renderable(&node, renderer ) ); - } - else if( DrawMode::OVERLAY_2D == inheritedDrawMode ) + // Normal is the more-likely draw mode to occur. + if( DALI_LIKELY( inheritedDrawMode == DrawMode::NORMAL ) ) { - layer->overlayRenderables.PushBack( Renderable(&node, renderer ) ); + layer->colorRenderables.PushBack( Renderable( &node, renderer ) ); } else { - layer->colorRenderables.PushBack( Renderable(&node, renderer ) ); + layer->overlayRenderables.PushBack( Renderable( &node, renderer ) ); } } } - // Recurse children + // Recurse children. NodeContainer& children = node.GetChildren(); const NodeIter endIter = children.End(); - for ( NodeIter iter = children.Begin(); iter != endIter; ++iter ) + for( NodeIter iter = children.Begin(); iter != endIter; ++iter ) { Node& child = **iter; - bool childResourcesComplete = AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode ); + bool childResourcesComplete = AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth ); resourcesFinished &= childResourcesComplete; } return resourcesFinished; } -} //Unnamed namespace - -void ProcessRenderTasks( BufferIndex updateBufferIndex, - RenderTaskList& renderTasks, - Layer& rootNode, - SortedLayerPointers& sortedLayers, - RendererSortingHelper& sortingHelper, - GeometryBatcher& geometryBatcher, - RenderInstructionContainer& instructions ) + +} // Anonymous namespace. + + +RenderTaskProcessor::RenderTaskProcessor() +{ +} + +RenderTaskProcessor::~RenderTaskProcessor() +{ +} + +void RenderTaskProcessor::Process( BufferIndex updateBufferIndex, + RenderTaskList& renderTasks, + Layer& rootNode, + SortedLayerPointers& sortedLayers, + GeometryBatcher& geometryBatcher, + RenderInstructionContainer& instructions ) { RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks(); - if ( taskContainer.IsEmpty() ) + if( taskContainer.IsEmpty() ) { // Early-exit if there are no tasks to process return; @@ -199,32 +216,30 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex, // 3) Traverse the scene-graph, filling the lists for the current render-task // 4) Prepare render-instructions - DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "ProcessRenderTasks() Offscreens first\n"); + DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Offscreens first\n" ); // First process off screen render tasks - we may need the results of these for the on screen renders + uint32_t clippingId = 0u; + bool hasClippingNodes = false; + RenderTaskList::RenderTaskContainer::ConstIterator endIter = taskContainer.End(); - for ( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter ) + for( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter ) { RenderTask& renderTask = **iter; - // off screen only - if(0 == renderTask.GetFrameBufferId() && renderTask.GetFrameBuffer() == 0 ) + // Off screen only. + if( ( ( 0 == renderTask.GetFrameBufferId() ) && ( renderTask.GetFrameBuffer() == 0 ) ) || + ( !renderTask.ReadyToRender( updateBufferIndex ) ) ) { - // Skip to next task - continue; - } - - if ( !renderTask.ReadyToRender( updateBufferIndex ) ) - { - // Skip to next task + // Skip to next task. continue; } Node* sourceNode = renderTask.GetSourceNode(); - DALI_ASSERT_DEBUG( NULL != sourceNode ); // otherwise Prepare() should return false + DALI_ASSERT_DEBUG( NULL != sourceNode ); // Otherwise Prepare() should return false - // Check that the source node is not exclusive to another task - if ( ! CheckExclusivity( *sourceNode, renderTask ) ) + // Check that the source node is not exclusive to another task. + if( ! CheckExclusivity( *sourceNode, renderTask ) ) { continue; } @@ -232,7 +247,7 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex, Layer* layer = FindLayer( *sourceNode ); if( !layer ) { - // Skip to next task as no layer + // Skip to next task as no layer. continue; } @@ -249,16 +264,22 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex, *sourceNode, *layer, renderTask, - sourceNode->GetDrawMode() ); + sourceNode->GetDrawMode(), + clippingId, + 0u ); renderTask.SetResourcesFinished( resourcesFinished ); - PrepareRenderInstruction( updateBufferIndex, - sortedLayers, - renderTask, - sortingHelper, - renderTask.GetCullMode(), - instructions, - geometryBatcher ); + + // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList. + hasClippingNodes = clippingId != 0u; + + mRenderInstructionProcessor.Prepare( updateBufferIndex, + sortedLayers, + renderTask, + renderTask.GetCullMode(), + geometryBatcher, + hasClippingNodes, + instructions ); } else { @@ -266,30 +287,29 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex, } } - DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "ProcessRenderTasks() Onscreen\n"); + DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Onscreen\n" ); - // Now that the off screen renders are done we can process on screen render tasks + // Now that the off screen renders are done we can process on screen render tasks. + // Reset the clipping Id for the OnScreen render tasks. + clippingId = 0u; for ( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter ) { RenderTask& renderTask = **iter; - // on screen only - if(0 != renderTask.GetFrameBufferId() || renderTask.GetFrameBuffer() != 0 ) + // On screen only. + if( ( 0 != renderTask.GetFrameBufferId() ) || + ( renderTask.GetFrameBuffer() != 0 ) || + ( !renderTask.ReadyToRender( updateBufferIndex ) ) ) { - // Skip to next task - continue; - } - if ( !renderTask.ReadyToRender( updateBufferIndex ) ) - { - // Skip to next task + // Skip to next task. continue; } Node* sourceNode = renderTask.GetSourceNode(); - DALI_ASSERT_DEBUG( NULL != sourceNode ); // otherwise Prepare() should return false + DALI_ASSERT_DEBUG( NULL != sourceNode ); // Otherwise Prepare() should return false. - // Check that the source node is not exclusive to another task - if ( ! CheckExclusivity( *sourceNode, renderTask ) ) + // Check that the source node is not exclusive to another task. + if( ! CheckExclusivity( *sourceNode, renderTask ) ) { continue; } @@ -297,7 +317,7 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex, Layer* layer = FindLayer( *sourceNode ); if( !layer ) { - // Skip to next task as no layer + // Skip to next task as no layer. continue; } @@ -305,7 +325,7 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex, if( renderTask.IsRenderRequired() ) { size_t layerCount( sortedLayers.size() ); - for( size_t i(0); iClearRenderables(); } @@ -314,15 +334,20 @@ void ProcessRenderTasks( BufferIndex updateBufferIndex, *sourceNode, *layer, renderTask, - sourceNode->GetDrawMode() ); - - PrepareRenderInstruction( updateBufferIndex, - sortedLayers, - renderTask, - sortingHelper, - renderTask.GetCullMode(), - instructions, - geometryBatcher ); + sourceNode->GetDrawMode(), + clippingId, + 0u ); + + // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList. + hasClippingNodes = clippingId != 0; + + mRenderInstructionProcessor.Prepare( updateBufferIndex, + sortedLayers, + renderTask, + renderTask.GetCullMode(), + geometryBatcher, + hasClippingNodes, + instructions ); } renderTask.SetResourcesFinished( resourcesFinished ); diff --git a/dali/internal/update/manager/render-task-processor.h b/dali/internal/update/manager/render-task-processor.h new file mode 100644 index 0000000..7715ab7 --- /dev/null +++ b/dali/internal/update/manager/render-task-processor.h @@ -0,0 +1,91 @@ +#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_PROCESSOR_H +#define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_PROCESSOR_H + +/* + * Copyright (c) 2016 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. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace SceneGraph +{ + +class RenderTaskList; + +/** + * @brief This class handles processing a given list of render tasks and generating render instructions from them. + */ +class RenderTaskProcessor +{ +public: + + /** + * @brief Constructor. + */ + RenderTaskProcessor(); + + /** + * @brief Destructor. + */ + ~RenderTaskProcessor(); + + /** + * Process the list of render-tasks; the output is a series of render instructions. + * @note When ProcessRenderTasks is called, the layers should already the transparent/opaque renderers which are ready to render. + * If there is only one default render-task, then no further processing is required. + * @param[in] updateBufferIndex The current update buffer index. + * @param[in] renderTasks The list of render-tasks. + * @param[in] rootNode The root node of the scene-graph. + * @param[in] sortedLayers The layers containing lists of opaque / transparent renderables. + * @param[in] geometryBatcher The instance of the geometry batcher + * @param[out] instructions The instructions for rendering the next frame. + */ + void Process( BufferIndex updateBufferIndex, + RenderTaskList& renderTasks, + Layer& rootNode, + SortedLayerPointers& sortedLayers, + GeometryBatcher& geometryBatcher, + RenderInstructionContainer& instructions ); + +private: + + /** + * Undefine copy and assignment operators. + */ + RenderTaskProcessor( const RenderTaskProcessor& renderTaskProcessor ); ///< No definition + RenderTaskProcessor& operator=( const RenderTaskProcessor& renderTaskProcessor ); ///< No definition + +private: + + RenderInstructionProcessor mRenderInstructionProcessor; ///< An instance of the RenderInstructionProcessor used to sort and handle the renderers for each layer. +}; + + +} // namespace SceneGraph + +} // namespace Internal + +} // namespace Dali + +#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_PROCESSOR_H diff --git a/dali/internal/update/manager/transform-manager.cpp b/dali/internal/update/manager/transform-manager.cpp index 5415778..b289bf4 100644 --- a/dali/internal/update/manager/transform-manager.cpp +++ b/dali/internal/update/manager/transform-manager.cpp @@ -312,6 +312,7 @@ void TransformManager::SwapComponents( unsigned int i, unsigned int j ) std::swap( mLocal[i], mLocal[j] ); std::swap( mComponentDirty[i], mComponentDirty[j] ); std::swap( mBoundingSpheres[i], mBoundingSpheres[j] ); + std::swap( mWorld[i], mWorld[j] ); mIds[ mComponentId[i] ] = i; mIds[ mComponentId[j] ] = j; @@ -335,10 +336,15 @@ void TransformManager::ReorderComponents() } } - std::sort( mOrderedComponents.Begin(), mOrderedComponents.End()); - for( size_t i(0); i #include +#ifdef DALI_PRINT_UPDATE_INFO + namespace Dali { @@ -48,7 +50,6 @@ static Debug::Filter* gNodeLogFilter = Debug::Filter::New(Debug::Verbose, false, */ void PrintNodes( const Node& node, BufferIndex updateBufferIndex, int level ) { -#if defined(DEBUG_ENABLED) const Vector3& position = node.GetPosition(updateBufferIndex); const Vector3& scale = node.GetScale(updateBufferIndex); const Vector3& fullPos = node.GetWorldPosition(updateBufferIndex); @@ -94,13 +95,10 @@ void PrintNodes( const Node& node, BufferIndex updateBufferIndex, int level ) { PrintNodes(**iter, updateBufferIndex, level); } -#endif // DEBUG_ENABLED } void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string indentation ) { -#if defined(DEBUG_ENABLED) - std::cout << "Node " << &node << " \"" << node.mDebugString << "\"" << " Origin: " << node.GetParentOrigin() @@ -135,8 +133,6 @@ void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string inden PrintNodeTree(**iter, bufferIndex, nextIndent); } - -#endif // DEBUG_ENABLED } } // SceneGraph @@ -144,3 +140,5 @@ void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string inden } // Internal } // Dali + +#endif diff --git a/dali/internal/update/manager/update-manager-debug.h b/dali/internal/update/manager/update-manager-debug.h index a5f98f4..122abc1 100644 --- a/dali/internal/update/manager/update-manager-debug.h +++ b/dali/internal/update/manager/update-manager-debug.h @@ -1,8 +1,8 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H__ +#ifndef DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H +#define DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -25,6 +25,11 @@ #include #include +// Define this to access debug functions for the update manager. +#undef DALI_PRINT_UPDATE_INFO + +#ifdef DALI_PRINT_UPDATE_INFO + namespace Dali { @@ -44,4 +49,6 @@ void PrintNodeTree( const Node& node, BufferIndex bufferIndex, std::string inden } // Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H__ +#endif + +#endif // DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_DEBUG_H diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 3b45ab6..08e12c4 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -133,7 +133,8 @@ struct UpdateManager::Impl RenderManager& renderManager, RenderQueue& renderQueue, SceneGraphBuffers& sceneGraphBuffers, - GeometryBatcher& geometryBatcher ) + GeometryBatcher& geometryBatcher, + RenderTaskProcessor& renderTaskProcessor ) : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ), notificationManager( notificationManager ), transformManager(), @@ -148,6 +149,7 @@ struct UpdateManager::Impl renderQueue( renderQueue ), renderInstructions( renderManager.GetRenderInstructionContainer() ), geometryBatcher( geometryBatcher ), + renderTaskProcessor( renderTaskProcessor ), backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ), taskList( renderMessageDispatcher, resourceManager ), systemLevelTaskList( renderMessageDispatcher, resourceManager ), @@ -161,7 +163,6 @@ struct UpdateManager::Impl nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update() previousUpdateScene( false ), frameCounter( 0 ), - renderSortingHelper(), renderTaskWaiting( false ) { sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue ); @@ -233,6 +234,7 @@ struct UpdateManager::Impl RenderQueue& renderQueue; ///< Used to queue messages for the next render RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher + RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. @@ -254,7 +256,7 @@ struct UpdateManager::Impl PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. ObjectOwnerContainer renderers; - TextureSetContainer textureSets; ///< A container of texture sets + TextureSetContainer textureSets; ///< A container of texture sets ShaderContainer shaders; ///< A container of owned shaders @@ -270,7 +272,6 @@ struct UpdateManager::Impl bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out) int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. - RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers GestureContainer gestures; ///< A container of owned gesture detectors bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered @@ -285,7 +286,8 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager, RenderManager& renderManager, RenderQueue& renderQueue, TextureCacheDispatcher& textureCacheDispatcher, - GeometryBatcher& geometryBatcher ) + GeometryBatcher& geometryBatcher, + RenderTaskProcessor& renderTaskProcessor ) : mImpl(NULL) { mImpl = new Impl( notificationManager, @@ -297,7 +299,8 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager, renderManager, renderQueue, mSceneGraphBuffers, - geometryBatcher ); + geometryBatcher, + renderTaskProcessor ); textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers ); mImpl->geometryBatcher.SetUpdateManager( this ); @@ -999,24 +1002,22 @@ unsigned int UpdateManager::Update( float elapsedSeconds, if ( NULL != mImpl->root ) { - ProcessRenderTasks( bufferIndex, - mImpl->taskList, - *mImpl->root, - mImpl->sortedLayers, - mImpl->renderSortingHelper, - mImpl->geometryBatcher, - mImpl->renderInstructions ); + mImpl->renderTaskProcessor.Process( bufferIndex, + mImpl->taskList, + *mImpl->root, + mImpl->sortedLayers, + mImpl->geometryBatcher, + mImpl->renderInstructions ); // Process the system-level RenderTasks last if ( NULL != mImpl->systemLevelRoot ) { - ProcessRenderTasks( bufferIndex, - mImpl->systemLevelTaskList, - *mImpl->systemLevelRoot, - mImpl->systemLevelSortedLayers, - mImpl->renderSortingHelper, - mImpl->geometryBatcher, - mImpl->renderInstructions ); + mImpl->renderTaskProcessor.Process( bufferIndex, + mImpl->systemLevelTaskList, + *mImpl->systemLevelRoot, + mImpl->systemLevelSortedLayers, + mImpl->geometryBatcher, + mImpl->renderInstructions ); } } } diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index ca1de09..6d2406a 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -1,5 +1,5 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H__ +#ifndef DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H +#define DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -74,6 +74,7 @@ class DiscardQueue; class PanGesture; class RenderManager; class RenderTaskList; +class RenderTaskProcessor; class RenderQueue; class TextureCacheDispatcher; class PropertyBuffer; @@ -104,6 +105,7 @@ public: * @param[in] renderQueue Used to queue messages for the next render. * @param[in] textureCacheDispatcher Used for sending messages to texture cache. * @param[in] geometryBatcher Used when geometry batching is enabled. + * @param[in] renderTaskProcessor Handles RenderTasks and RenderInstrucitons. */ UpdateManager( NotificationManager& notificationManager, CompleteNotificationInterface& animationFinishedNotifier, @@ -114,7 +116,8 @@ public: RenderManager& renderManager, RenderQueue& renderQueue, TextureCacheDispatcher& textureCacheDispatcher, - GeometryBatcher& geometryBatcher ); + GeometryBatcher& geometryBatcher, + RenderTaskProcessor& renderTaskProcessor ); /** * Destructor. @@ -1279,10 +1282,11 @@ inline void AttachColorTextureToFrameBuffer( UpdateManager& manager, Render::Fra new (slot) LocalType( &manager, &UpdateManager::AttachColorTextureToFrameBuffer, &frameBuffer, texture, mipmapLevel, layer ); } + } // namespace SceneGraph } // namespace Internal } // namespace Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H__ +#endif // DALI_INTERNAL_SCENE_GRAPH_UPDATE_MANAGER_H diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index 0a7dc5a..73b52ee 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -54,30 +54,33 @@ Node::Node() mTransformId( INVALID_TRANSFORM_ID ), mParentOrigin( TRANSFORM_PROPERTY_PARENT_ORIGIN ), mAnchorPoint( TRANSFORM_PROPERTY_ANCHOR_POINT ), - mSize(TRANSFORM_PROPERTY_SIZE), // zero initialized by default - mPosition(TRANSFORM_PROPERTY_POSITION), // zero initialized by default - mOrientation(), // initialized to identity by default + mSize( TRANSFORM_PROPERTY_SIZE ), // Zero initialized by default + mPosition( TRANSFORM_PROPERTY_POSITION ), // Zero initialized by default + mOrientation(), // Initialized to identity by default mScale( TRANSFORM_PROPERTY_SCALE ), mVisible( true ), mColor( Color::WHITE ), - mWorldPosition(TRANSFORM_PROPERTY_WORLD_POSITION, Vector3(0.0f,0.0f,0.0f)), // zero initialized by default - mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3(1.0f,1.0f,1.0f) ), - mWorldOrientation(), // initialized to identity by default + mWorldPosition( TRANSFORM_PROPERTY_WORLD_POSITION, Vector3( 0.0f,0.0f,0.0f ) ), // Zero initialized by default + mWorldScale( TRANSFORM_PROPERTY_WORLD_SCALE, Vector3( 1.0f,1.0f,1.0f ) ), + mWorldOrientation(), // Initialized to identity by default mWorldMatrix(), mWorldColor( Color::WHITE ), mGeometryBatcher( NULL ), mBatchIndex( BATCH_NULL_HANDLE ), + mClippingSortModifier( 0u ), mIsBatchParent( false ), mParent( NULL ), mBatchParent( NULL ), mExclusiveRenderTask( NULL ), mChildren(), + mClippingDepth( 0u ), mRegenerateUniformMap( 0 ), - mDepth(0u), - mDirtyFlags(AllFlags), - mIsRoot( false ), + mDepth( 0u ), + mDirtyFlags( AllFlags ), mDrawMode( DrawMode::NORMAL ), - mColorMode( DEFAULT_COLOR_MODE ) + mColorMode( DEFAULT_COLOR_MODE ), + mClippingMode( ClippingMode::DISABLED ), + mIsRoot( false ) { mUniformMapChanged[0] = 0u; mUniformMapChanged[1] = 0u; @@ -218,19 +221,19 @@ void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode ) void Node::AddRenderer( Renderer* renderer ) { - //Check that it has not been already added + // Check that it has not been already added. unsigned int rendererCount( mRenderer.Size() ); - for( unsigned int i(0); i struct ParameterType< ColorMode > : public BasicType< ColorMode > {}; template <> struct ParameterType< PositionInheritanceMode > : public BasicType< PositionInheritanceMode > {}; +template <> struct ParameterType< ClippingMode::Type > : public BasicType< ClippingMode::Type > {}; namespace SceneGraph { @@ -70,7 +71,7 @@ enum NodePropertyFlags SizeFlag = 0x008, OverlayFlag = 0x010, SortModifierFlag = 0x020, - ChildDeletedFlag = 0x040 + ChildDeletedFlag = 0x040, }; static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags @@ -143,6 +144,65 @@ public: } /** + * This method sets clipping information on the node based on its hierarchy in the scene-graph. + * A value is calculated that can be used during sorting to increase sort speed. + * @param[in] clippingId The Clipping ID of the node to set + * @param[in] clippingDepth The Clipping Depth of the node to set + */ + void SetClippingInformation( const uint32_t clippingId, const uint32_t clippingDepth ) + { + // We only set up the sort value if we have a clipping depth, IE. At least 1 clipping node has been hit. + // If not, if we traverse down a clipping tree and back up, and there is another + // node on the parent, this will have a non-zero clipping ID that must be ignored + if( DALI_LIKELY( clippingDepth > 0u ) ) + { + mClippingDepth = clippingDepth; + + // Calculate the sort value here on write, as when read (during sort) it may be accessed several times. + // The items must be sorted by Clipping ID first (so the ID is kept in the most-significant bits). + // For the same ID, the clipping nodes must be first, so we negate the + // clipping enabled flag and set it as the least significant bit. + mClippingSortModifier = ( clippingId << 1u ) | ( mClippingMode == ClippingMode::DISABLED ? 1u : 0u ); + } + } + + /** + * Gets the Clipping ID for this node. + * @return The Clipping ID for this node. + */ + uint32_t GetClippingId() const + { + return mClippingSortModifier >> 1u; + } + + /** + * Gets the Clipping Depth for this node. + * @return The Clipping Depth for this node. + */ + uint32_t GetClippingDepth() const + { + return mClippingDepth; + } + + /** + * Sets the clipping mode for this node. + * @param[in] clippingMode The ClippingMode to set + */ + void SetClippingMode( const ClippingMode::Type clippingMode ) + { + mClippingMode = clippingMode; + } + + /** + * Gets the Clipping Mode for this node. + * @return The ClippingMode of this node + */ + ClippingMode::Type GetClippingMode() const + { + return mClippingMode; + } + + /** * Add a renderer to the node * @param[in] renderer The renderer added to the node */ @@ -648,15 +708,11 @@ public: /** * Equality operator, checks for identity, not values. - * + * @param[in] */ bool operator==( const Node* rhs ) const { - if ( this == rhs ) - { - return true; - } - return false; + return ( this == rhs ); } unsigned short GetDepth() const @@ -792,52 +848,54 @@ private: public: // Default properties - TransformManager* mTransformManager; - TransformId mTransformId; - TransformManagerPropertyVector3 mParentOrigin; ///< Local transform; the position is relative to this. Sets the TransformFlag dirty when changed - TransformManagerPropertyVector3 mAnchorPoint; ///< Local transform; local center of rotation. Sets the TransformFlag dirty when changed - TransformManagerPropertyVector3 mSize; ///< Size is provided for layouting - TransformManagerPropertyVector3 mPosition; ///< Local transform; distance between parent-origin & anchor-point - TransformManagerPropertyQuaternion mOrientation; ///< Local transform; rotation relative to parent node - TransformManagerPropertyVector3 mScale; ///< Local transform; scale relative to parent node + TransformManager* mTransformManager; + TransformId mTransformId; + TransformManagerPropertyVector3 mParentOrigin; ///< Local transform; the position is relative to this. Sets the TransformFlag dirty when changed + TransformManagerPropertyVector3 mAnchorPoint; ///< Local transform; local center of rotation. Sets the TransformFlag dirty when changed + TransformManagerPropertyVector3 mSize; ///< Size is provided for layouting + TransformManagerPropertyVector3 mPosition; ///< Local transform; distance between parent-origin & anchor-point + TransformManagerPropertyQuaternion mOrientation; ///< Local transform; rotation relative to parent node + TransformManagerPropertyVector3 mScale; ///< Local transform; scale relative to parent node - AnimatableProperty mVisible; ///< Visibility can be inherited from the Node hierachy - AnimatableProperty mColor; ///< Color can be inherited from the Node hierarchy + AnimatableProperty mVisible; ///< Visibility can be inherited from the Node hierachy + AnimatableProperty mColor; ///< Color can be inherited from the Node hierarchy // Inherited properties; read-only from public API - TransformManagerVector3Input mWorldPosition; ///< Full inherited position - TransformManagerVector3Input mWorldScale; - TransformManagerQuaternionInput mWorldOrientation; ///< Full inherited orientation - TransformManagerMatrixInput mWorldMatrix; ///< Full inherited world matrix - InheritedColor mWorldColor; ///< Full inherited color + TransformManagerVector3Input mWorldPosition; ///< Full inherited position + TransformManagerVector3Input mWorldScale; + TransformManagerQuaternionInput mWorldOrientation; ///< Full inherited orientation + TransformManagerMatrixInput mWorldMatrix; ///< Full inherited world matrix + InheritedColor mWorldColor; ///< Full inherited color + + GeometryBatcher* mGeometryBatcher; ///< A pointer to an instance of geometry batcher + uint32_t mBatchIndex; ///< Batch 32bit handle, BATCH_NULL_HANDLE by default + uint32_t mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting - GeometryBatcher* mGeometryBatcher; ///< A pointer to an instance of geometry batcher - uint32_t mBatchIndex; ///< Batch 32bit handle, BATCH_NULL_HANDLE by default - bool mIsBatchParent:1; ///< Marks node as a batch parent + bool mIsBatchParent:1; ///< Marks node as a batch parent protected: - Node* mParent; ///< Pointer to parent node (a child is owned by its parent) - Node* mBatchParent; ///< Pointer to batch parent node - RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask + Node* mParent; ///< Pointer to parent node (a child is owned by its parent) + Node* mBatchParent; ///< Pointer to batch parent node + RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask - RendererContainer mRenderer; ///< Container of renderers; not owned + RendererContainer mRenderer; ///< Container of renderers; not owned - NodeContainer mChildren; ///< Container of children; not owned + NodeContainer mChildren; ///< Container of children; not owned - CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps of the node - unsigned int mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame - unsigned int mRegenerateUniformMap : 2; ///< Indicate if the uniform map has to be regenerated this frame + CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps of the node + unsigned int mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame + uint32_t mClippingDepth; ///< The number of clipping nodes deep this node is + unsigned int mRegenerateUniformMap:2; ///< Indicate if the uniform map has to be regenerated this frame // flags, compressed to bitfield - unsigned short mDepth: 12; ///< Depth in the hierarchy - int mDirtyFlags:8; ///< A composite set of flags for each of the Node properties - - bool mIsRoot:1; ///< True if the node cannot have a parent - - DrawMode::Type mDrawMode:2; ///< How the Node and its children should be drawn - ColorMode mColorMode:2; ///< Determines whether mWorldColor is inherited, 2 bits is enough + unsigned short mDepth:12; ///< Depth in the hierarchy + int mDirtyFlags:8; ///< A composite set of flags for each of the Node properties + DrawMode::Type mDrawMode:2; ///< How the Node and its children should be drawn + ColorMode mColorMode:2; ///< Determines whether mWorldColor is inherited, 2 bits is enough + ClippingMode::Type mClippingMode:2; ///< The clipping mode of this node + bool mIsRoot:1; ///< True if the node cannot have a parent // Changes scope, should be at end of class DALI_LOG_OBJECT_STRING_DECLARATION; @@ -955,6 +1013,17 @@ inline void SetIsBatchParentMessage( EventThreadServices& eventThreadServices, c new (slot) LocalType( &node, &Node::SetIsBatchParent, isBatchParent ); } +inline void SetClippingModeMessage( EventThreadServices& eventThreadServices, const Node& node, ClippingMode::Type clippingMode ) +{ + typedef MessageValue1< Node, ClippingMode::Type > LocalType; + + // Reserve some memory inside the message queue + unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &node, &Node::SetClippingMode, clippingMode ); +} + } // namespace SceneGraph @@ -962,4 +1031,4 @@ inline void SetIsBatchParentMessage( EventThreadServices& eventThreadServices, c } // namespace Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_NODE_H_ +#endif // DALI_INTERNAL_SCENE_GRAPH_NODE_H diff --git a/dali/internal/update/nodes/scene-graph-layer.cpp b/dali/internal/update/nodes/scene-graph-layer.cpp index 1d920be..573ccee 100644 --- a/dali/internal/update/nodes/scene-graph-layer.cpp +++ b/dali/internal/update/nodes/scene-graph-layer.cpp @@ -102,7 +102,6 @@ bool Layer::IsDepthTestDisabled() const void Layer::ClearRenderables() { - stencilRenderables.Clear(); colorRenderables.Clear(); overlayRenderables.Clear(); } diff --git a/dali/internal/update/nodes/scene-graph-layer.h b/dali/internal/update/nodes/scene-graph-layer.h index 89823a8..e036df1 100644 --- a/dali/internal/update/nodes/scene-graph-layer.h +++ b/dali/internal/update/nodes/scene-graph-layer.h @@ -1,5 +1,5 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_LAYER_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_LAYER_H__ +#ifndef DALI_INTERNAL_SCENE_GRAPH_LAYER_H +#define DALI_INTERNAL_SCENE_GRAPH_LAYER_H /* * Copyright (c) 2016 Samsung Electronics Co., Ltd. @@ -45,13 +45,13 @@ class Camera; struct Renderable { Renderable() - :mNode(0), - mRenderer(0) + : mNode( 0 ), + mRenderer( 0 ) {} Renderable( Node* node, Renderer* renderer ) - :mNode(node), - mRenderer(renderer) + : mNode( node ), + mRenderer( renderer ) {} Node* mNode; @@ -222,13 +222,12 @@ private: public: // For update-algorithms - RenderableContainer stencilRenderables; RenderableContainer colorRenderables; RenderableContainer overlayRenderables; private: - SortFunctionType mSortFunction; ///< Used to sort semi-transparent geometry + SortFunctionType mSortFunction; ///< Used to sort semi-transparent geometry ClippingBox mClippingBox; ///< The clipping box, in window coordinates Camera* mLastCamera; ///< Pointer to the last camera that has rendered the layer @@ -236,8 +235,8 @@ private: Dali::Layer::Behavior mBehavior; ///< The behavior of the layer bool mAllChildTransformsClean[ 2 ]; ///< True if all child nodes transforms are clean, - /// double buffered as we need two clean frames before we can reuse N-1 for N+1 - /// this allows us to cache render items when layer is "static" + /// double buffered as we need two clean frames before we can reuse N-1 for N+1 + /// this allows us to cache render items when layer is "static" bool mIsClipping:1; ///< True when clipping is enabled bool mDepthTestDisabled:1; ///< Whether depth test is disabled. bool mIsDefaultSortFunction:1; ///< whether the default depth sort function is used @@ -337,4 +336,4 @@ inline void SetDepthTestDisabledMessage( EventThreadServices& eventThreadService } // namespace Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_LAYER_H__ +#endif // DALI_INTERNAL_SCENE_GRAPH_LAYER_H diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index c28a236..e560f43 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -99,7 +99,7 @@ enum Flags RESEND_DEPTH_WRITE_MODE = 1 << 8, RESEND_DEPTH_TEST_MODE = 1 << 9, RESEND_DEPTH_FUNCTION = 1 << 10, - RESEND_STENCIL_MODE = 1 << 11, + RESEND_RENDER_MODE = 1 << 11, RESEND_STENCIL_FUNCTION = 1 << 12, RESEND_STENCIL_FUNCTION_MASK = 1 << 13, RESEND_STENCIL_FUNCTION_REFERENCE = 1 << 14, @@ -132,7 +132,7 @@ Renderer::Renderer() mGeometry( NULL ), mShader( NULL ), mBlendColor( NULL ), - mStencilParameters( StencilMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ), + mStencilParameters( RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ), mIndexedDrawFirstElement( 0u ), mIndexedDrawElementsCount( 0u ), mBlendBitmask( 0u ), @@ -143,7 +143,6 @@ Renderer::Renderer() mBlendMode( BlendMode::AUTO ), mDepthWriteMode( DepthWriteMode::AUTO ), mDepthTestMode( DepthTestMode::AUTO ), - mWriteToColorBuffer( true ), mResourcesReady( false ), mFinishedResourceAcquisition( false ), mPremultipledAlphaEnabled( false ), @@ -159,15 +158,15 @@ Renderer::Renderer() Renderer::~Renderer() { - if (mTextureSet) + if( mTextureSet ) { - mTextureSet->RemoveObserver(this); - mTextureSet=NULL; + mTextureSet->RemoveObserver( this ); + mTextureSet = NULL; } if( mShader ) { - mShader->RemoveConnectionObserver(*this); - mShader=NULL; + mShader->RemoveConnectionObserver( *this ); + mShader = NULL; } } @@ -315,11 +314,11 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction ); } - if( mResendFlag & RESEND_STENCIL_MODE ) + if( mResendFlag & RESEND_RENDER_MODE ) { - typedef MessageValue1< Render::Renderer, StencilMode::Type > DerivedType; + typedef MessageValue1< Render::Renderer, RenderMode::Type > DerivedType; unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilMode, mStencilParameters.stencilMode ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode ); } if( mResendFlag & RESEND_STENCIL_FUNCTION ) @@ -371,13 +370,6 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass ); } - if( mResendFlag & RESEND_WRITE_TO_COLOR_BUFFER ) - { - typedef MessageValue1< Render::Renderer, bool > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetWriteToColorBuffer, mWriteToColorBuffer ); - } - if( mResendFlag & RESEND_BATCHING_MODE ) { typedef MessageValue1< Render::Renderer, bool > DerivedType; @@ -505,10 +497,10 @@ void Renderer::SetDepthFunction( DepthFunction::Type depthFunction ) mResendFlag |= RESEND_DEPTH_FUNCTION; } -void Renderer::SetStencilMode( StencilMode::Type mode ) +void Renderer::SetRenderMode( RenderMode::Type mode ) { - mStencilParameters.stencilMode = mode; - mResendFlag |= RESEND_STENCIL_MODE; + mStencilParameters.renderMode = mode; + mResendFlag |= RESEND_RENDER_MODE; } void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction ) @@ -553,12 +545,6 @@ void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperati mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS; } -void Renderer::SetWriteToColorBuffer( bool writeToColorBuffer ) -{ - mWriteToColorBuffer = writeToColorBuffer; - mResendFlag |= RESEND_WRITE_TO_COLOR_BUFFER; -} - void Renderer::SetBatchingEnabled( bool batchingEnabled ) { mBatchingEnabled = batchingEnabled; @@ -573,7 +559,7 @@ void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferInde RenderDataProvider* dataProvider = NewRenderDataProvider(); mRenderer = Render::Renderer::New( dataProvider, mGeometry, mBlendBitmask, mBlendColor, static_cast< FaceCullingMode::Type >( mFaceCullingMode ), - mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters, mWriteToColorBuffer ); + mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters ); mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer ); } @@ -677,7 +663,6 @@ Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Nod } } - return opacity; } diff --git a/dali/internal/update/rendering/scene-graph-renderer.h b/dali/internal/update/rendering/scene-graph-renderer.h index 1a86cb9..b72a704 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.h +++ b/dali/internal/update/rendering/scene-graph-renderer.h @@ -30,6 +30,7 @@ namespace Dali { + namespace Internal { @@ -202,10 +203,10 @@ public: void SetDepthFunction( DepthFunction::Type depthFunction ); /** - * Sets the stencil mode - * @param[in] mode The stencil function + * Sets the render mode + * @param[in] mode The render mode */ - void SetStencilMode( StencilMode::Type mode ); + void SetRenderMode( RenderMode::Type mode ); /** * Sets the stencil function @@ -250,12 +251,6 @@ public: void SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass ); /** - * Sets whether or not to write to the color buffer - * @param[in] writeToColorBuffer True to write to the color buffer - */ - void SetWriteToColorBuffer( bool writeToColorBuffer ); - - /** * Turns on batching feature for the renderer * @param[in] batchingEnabled if true, enables the batching mode for the renderer */ @@ -400,7 +395,7 @@ private: Shader* mShader; ///< The shader this renderer uses. (Not owned) Vector4* mBlendColor; ///< The blend color for blending operation - Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options + Dali::Internal::Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options size_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw size_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw @@ -413,7 +408,6 @@ private: BlendMode::Type mBlendMode:2; ///< Local copy of the mode of blending DepthWriteMode::Type mDepthWriteMode:2; ///< Local copy of the depth write mode DepthTestMode::Type mDepthTestMode:2; ///< Local copy of the depth test mode - bool mWriteToColorBuffer:1; ///< Local copy of the write to color buffer flag bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame bool mResourcesReady; ///< Set during the Update algorithm; true if the renderer has resources ready for the current frame. @@ -422,7 +416,8 @@ private: public: - bool mBatchingEnabled : 1; ///< Flag indicating whether the render supports batching + bool mBatchingEnabled:1; ///< Flag indicating whether the render supports batching + int mDepthIndex; ///< Used only in PrepareRenderInstructions }; @@ -572,14 +567,14 @@ inline void SetDepthFunctionMessage( EventThreadServices& eventThreadServices, c new (slot) LocalType( &renderer, &Renderer::SetDepthFunction, depthFunction ); } -inline void SetStencilModeMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, StencilMode::Type mode ) +inline void SetRenderModeMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, RenderMode::Type mode ) { - typedef MessageValue1< Renderer, StencilMode::Type > LocalType; + typedef MessageValue1< Renderer, RenderMode::Type > LocalType; // Reserve some memory inside the message queue unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); - new (slot) LocalType( &renderer, &Renderer::SetStencilMode, mode ); + new (slot) LocalType( &renderer, &Renderer::SetRenderMode, mode ); } inline void SetStencilFunctionMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, StencilFunction::Type stencilFunction ) @@ -652,16 +647,6 @@ inline void SetStencilOperationOnZPassMessage( EventThreadServices& eventThreadS new (slot) LocalType( &renderer, &Renderer::SetStencilOperationOnZPass, stencilOperation ); } -inline void SetWriteToColorBufferMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, bool writeToColorBuffer ) -{ - typedef MessageValue1< Renderer, bool > LocalType; - - // Reserve some memory inside the message queue - unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); - - new (slot) LocalType( &renderer, &Renderer::SetWriteToColorBuffer, writeToColorBuffer ); -} - inline void SetBatchingEnabledMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, bool batchable ) { typedef MessageValue1< Renderer, bool > LocalType; diff --git a/dali/public-api/actors/actor-enumerations.h b/dali/public-api/actors/actor-enumerations.h index fea5c33..f82e8bd 100644 --- a/dali/public-api/actors/actor-enumerations.h +++ b/dali/public-api/actors/actor-enumerations.h @@ -1,8 +1,8 @@ -#ifndef __DALI_ACTOR_ENUMERATIONS_H__ -#define __DALI_ACTOR_ENUMERATIONS_H__ +#ifndef DALI_ACTOR_ENUMERATIONS_H +#define DALI_ACTOR_ENUMERATIONS_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -59,18 +59,18 @@ enum PositionInheritanceMode */ namespace Dimension { -enum Type -{ - WIDTH = 0x1, ///< Width dimension @SINCE_1_0.0 - HEIGHT = 0x2, ///< Height dimension @SINCE_1_0.0 + enum Type + { + WIDTH = 0x1, ///< Width dimension @SINCE_1_0.0 + HEIGHT = 0x2, ///< Height dimension @SINCE_1_0.0 - ALL_DIMENSIONS = 0x3 ///< Mask to cover all flags @SINCE_1_0.0 -}; + ALL_DIMENSIONS = 0x3 ///< Mask to cover all flags @SINCE_1_0.0 + }; -enum Meta -{ - DIMENSION_COUNT = 2 ///< Number of dimensions - update this if adding new dimension @SINCE_1_0.0 -}; + enum Meta + { + DIMENSION_COUNT = 2 ///< Number of dimensions - update this if adding new dimension @SINCE_1_0.0 + }; } /** @@ -79,18 +79,18 @@ enum Meta */ namespace ResizePolicy { -enum Type -{ - FIXED, ///< Size is fixed as set by SetSize @SINCE_1_0.0 - USE_NATURAL_SIZE, ///< Size is to use the actor's natural size @SINCE_1_0.0 - FILL_TO_PARENT, ///< Size is to fill up to the actor's parent's bounds. Aspect ratio is not maintained. @SINCE_1_0.0 - SIZE_RELATIVE_TO_PARENT, ///< The actors size will be ( ParentSize * SizeRelativeToParentFactor ). @SINCE_1_0.0 - SIZE_FIXED_OFFSET_FROM_PARENT, ///< The actors size will be ( ParentSize + SizeRelativeToParentFactor ). @SINCE_1_0.0 - FIT_TO_CHILDREN, ///< Size will adjust to wrap around all children @SINCE_1_0.0 - DIMENSION_DEPENDENCY, ///< One dimension is dependent on the other @SINCE_1_0.0 - USE_ASSIGNED_SIZE ///< The size will be assigned to the actor @SINCE_1_0.0 -}; -const Type DEFAULT = USE_NATURAL_SIZE; ///< Default resize policy + enum Type + { + FIXED, ///< Size is fixed as set by SetSize @SINCE_1_0.0 + USE_NATURAL_SIZE, ///< Size is to use the actor's natural size @SINCE_1_0.0 @see Actor::GetNaturalSize() + FILL_TO_PARENT, ///< Size is to fill up to the actor's parent's bounds. Aspect ratio is not maintained. @SINCE_1_0.0 + SIZE_RELATIVE_TO_PARENT, ///< The actors size will be ( ParentSize * SizeRelativeToParentFactor ). @SINCE_1_0.0 + SIZE_FIXED_OFFSET_FROM_PARENT, ///< The actors size will be ( ParentSize + SizeRelativeToParentFactor ). @SINCE_1_0.0 + FIT_TO_CHILDREN, ///< Size will adjust to wrap around all children @SINCE_1_0.0 + DIMENSION_DEPENDENCY, ///< One dimension is dependent on the other @SINCE_1_0.0 + USE_ASSIGNED_SIZE ///< The size will be assigned to the actor @SINCE_1_0.0 + }; + const Type DEFAULT = USE_NATURAL_SIZE; ///< Default resize policy } /** @@ -99,12 +99,12 @@ const Type DEFAULT = USE_NATURAL_SIZE; ///< Default resize policy */ namespace SizeScalePolicy { -enum Type -{ - USE_SIZE_SET, ///< Use the size that was set @SINCE_1_0.0 - FIT_WITH_ASPECT_RATIO, ///< Fit within the size set maintaining natural size aspect ratio @SINCE_1_0.0 - FILL_WITH_ASPECT_RATIO ///< Fill up the size set maintaining natural size aspect ratio. May exceed size bounds in one dimension. @SINCE_1_0.0 -}; + enum Type + { + USE_SIZE_SET, ///< Use the size that was set @SINCE_1_0.0 + FIT_WITH_ASPECT_RATIO, ///< Fit within the size set maintaining natural size aspect ratio @SINCE_1_0.0 + FILL_WITH_ASPECT_RATIO ///< Fill up the size set maintaining natural size aspect ratio. May exceed size bounds in one dimension. @SINCE_1_0.0 + }; } /** @@ -113,12 +113,12 @@ enum Type */ namespace HorizontalAlignment { -enum Type -{ - LEFT, ///< Align horizontally left @SINCE_1_0.0 - CENTER, ///< Align horizontally center @SINCE_1_0.0 - RIGHT ///< Align horiztonally right @SINCE_1_0.0 -}; + enum Type + { + LEFT, ///< Align horizontally left @SINCE_1_0.0 + CENTER, ///< Align horizontally center @SINCE_1_0.0 + RIGHT ///< Align horizontally right @SINCE_1_0.0 + }; } /** @@ -127,17 +127,31 @@ enum Type */ namespace VerticalAlignment { -enum Type + enum Type + { + TOP, ///< Align vertically top @SINCE_1_0.0 + CENTER, ///< Align vertically center @SINCE_1_0.0 + BOTTOM ///< Align vertically bottom @SINCE_1_0.0 + }; +} + +/** + * @brief The ClippingMode describes how this Actors children will be clipped against it. + * @SINCE_1_2_5 + */ +namespace ClippingMode { - TOP, ///< Align vertically top @SINCE_1_0.0 - CENTER, ///< Align vertically center @SINCE_1_0.0 - BOTTOM ///< Align vertically bottom @SINCE_1_0.0 -}; + enum Type + { + DISABLED, ///< This Actor will not clip its children. @SINCE_1_2_5 + CLIP_CHILDREN, ///< This Actor will clip all children to within its boundaries (the actor will also be visible itself). @SINCE_1_2_5 + }; } + /** * @} */ } // namespace Dali -#endif // __DALI_ACTOR_ENUMERATIONS_H__ +#endif // DALI_ACTOR_ENUMERATIONS_H diff --git a/dali/public-api/actors/actor.h b/dali/public-api/actors/actor.h index 78f19d7..79344e5 100644 --- a/dali/public-api/actors/actor.h +++ b/dali/public-api/actors/actor.h @@ -1,8 +1,8 @@ -#ifndef __DALI_ACTOR_H__ -#define __DALI_ACTOR_H__ +#ifndef DALI_ACTOR_H +#define DALI_ACTOR_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -28,6 +28,7 @@ #include #include #include + namespace Dali { /** @@ -147,13 +148,7 @@ typedef Rect Padding; ///< Padding definition @SINCE_1_0.0 * * Hit Priority of above Actor tree (all overlays): 1 - Lowest. 6 - Highest. * @endcode - * - Stencil Actors can be used to influence the result of hits on renderable actors within a layer. - * If a Stencil Actor exists on a layer and that Actor is marked visible then a successful - * hit on a renderable actor can only take place in the area that the stencil Actor marks as visible. - * The hit can be in any Stencil Actor in that layer, but must be in the region of one of them. - * Stencil Actor inheritance behaves as with rendering in that any child of a Stencil Actor will - * also be considered a Stencil Actor. - * Non-renderable actors can be hit regardless of whether a stencil actor is hit or not. + * For more information, see SetDrawMode(). * * Touch or hover Event Delivery: * @@ -255,60 +250,61 @@ public: { enum { - PARENT_ORIGIN = DEFAULT_ACTOR_PROPERTY_START_INDEX, ///< name "parentOrigin", type Vector3 (constraint-input) @SINCE_1_0.0 - PARENT_ORIGIN_X, ///< name "parentOriginX", type float (constraint-input) @SINCE_1_0.0 - PARENT_ORIGIN_Y, ///< name "parentOriginY", type float (constraint-input) @SINCE_1_0.0 - PARENT_ORIGIN_Z, ///< name "parentOriginZ", type float (constraint-input) @SINCE_1_0.0 - ANCHOR_POINT, ///< name "anchorPoint", type Vector3 (constraint-input) @SINCE_1_0.0 - ANCHOR_POINT_X, ///< name "anchorPointX", type float (constraint-input) @SINCE_1_0.0 - ANCHOR_POINT_Y, ///< name "anchorPointY", type float (constraint-input) @SINCE_1_0.0 - ANCHOR_POINT_Z, ///< name "anchorPointZ", type float (constraint-input) @SINCE_1_0.0 - SIZE, ///< name "size", type Vector3 (animatable / constraint-input) @SINCE_1_0.0 - SIZE_WIDTH, ///< name "sizeWidth", type float (animatable / constraint-input) @SINCE_1_0.0 - SIZE_HEIGHT, ///< name "sizeHeight", type float (animatable / constraint-input) @SINCE_1_0.0 - SIZE_DEPTH, ///< name "sizeDepth", type float (animatable / constraint-input) @SINCE_1_0.0 - POSITION, ///< name "position", type Vector3 (animatable / constraint-input) @SINCE_1_0.0 - POSITION_X, ///< name "positionX", type float (animatable / constraint-input) @SINCE_1_0.0 - POSITION_Y, ///< name "positionY", type float (animatable / constraint-input) @SINCE_1_0.0 - POSITION_Z, ///< name "positionZ", type float (animatable / constraint-input) @SINCE_1_0.0 - WORLD_POSITION, ///< name "worldPosition", type Vector3 (read-only / constraint-input) @SINCE_1_0.0 - WORLD_POSITION_X, ///< name "worldPositionX", type float (read-only / constraint-input) @SINCE_1_0.0 - WORLD_POSITION_Y, ///< name "worldPositionY", type float (read-only / constraint-input) @SINCE_1_0.0 - WORLD_POSITION_Z, ///< name "worldPositionZ", type float (read-only / constraint-input) @SINCE_1_0.0 - ORIENTATION, ///< name "orientation", type Quaternion (animatable / constraint-input) @SINCE_1_0.0 - WORLD_ORIENTATION, ///< name "worldOrientation", type Quaternion (read-only / constraint-input) @SINCE_1_0.0 - SCALE, ///< name "scale", type Vector3 (animatable / constraint-input) @SINCE_1_0.0 - SCALE_X, ///< name "scaleX", type float (animatable / constraint-input) @SINCE_1_0.0 - SCALE_Y, ///< name "scaleY", type float (animatable / constraint-input) @SINCE_1_0.0 - SCALE_Z, ///< name "scaleZ", type float (animatable / constraint-input) @SINCE_1_0.0 - WORLD_SCALE, ///< name "worldScale", type Vector3 (read-only / constraint-input) @SINCE_1_0.0 - VISIBLE, ///< name "visible", type bool (animatable / constraint-input) @SINCE_1_0.0 - COLOR, ///< name "color", type Vector4 (animatable / constraint-input) @SINCE_1_0.0 - COLOR_RED, ///< name "colorRed", type float (animatable / constraint-input) @SINCE_1_0.0 - COLOR_GREEN, ///< name "colorGreen", type float (animatable / constraint-input) @SINCE_1_0.0 - COLOR_BLUE, ///< name "colorBlue", type float (animatable / constraint-input) @SINCE_1_0.0 - COLOR_ALPHA, ///< name "colorAlpha", type float (animatable / constraint-input) @SINCE_1_0.0 - WORLD_COLOR, ///< name "worldColor", type Vector4 (read-only / constraint-input) @SINCE_1_0.0 - WORLD_MATRIX, ///< name "worldMatrix", type Matrix (read-only / constraint-input) @SINCE_1_0.0 + PARENT_ORIGIN = DEFAULT_ACTOR_PROPERTY_START_INDEX, ///< name "parentOrigin", type Vector3 (constraint-input) @SINCE_1_0.0 + PARENT_ORIGIN_X, ///< name "parentOriginX", type float (constraint-input) @SINCE_1_0.0 + PARENT_ORIGIN_Y, ///< name "parentOriginY", type float (constraint-input) @SINCE_1_0.0 + PARENT_ORIGIN_Z, ///< name "parentOriginZ", type float (constraint-input) @SINCE_1_0.0 + ANCHOR_POINT, ///< name "anchorPoint", type Vector3 (constraint-input) @SINCE_1_0.0 + ANCHOR_POINT_X, ///< name "anchorPointX", type float (constraint-input) @SINCE_1_0.0 + ANCHOR_POINT_Y, ///< name "anchorPointY", type float (constraint-input) @SINCE_1_0.0 + ANCHOR_POINT_Z, ///< name "anchorPointZ", type float (constraint-input) @SINCE_1_0.0 + SIZE, ///< name "size", type Vector3 (animatable / constraint-input) @SINCE_1_0.0 + SIZE_WIDTH, ///< name "sizeWidth", type float (animatable / constraint-input) @SINCE_1_0.0 + SIZE_HEIGHT, ///< name "sizeHeight", type float (animatable / constraint-input) @SINCE_1_0.0 + SIZE_DEPTH, ///< name "sizeDepth", type float (animatable / constraint-input) @SINCE_1_0.0 + POSITION, ///< name "position", type Vector3 (animatable / constraint-input) @SINCE_1_0.0 + POSITION_X, ///< name "positionX", type float (animatable / constraint-input) @SINCE_1_0.0 + POSITION_Y, ///< name "positionY", type float (animatable / constraint-input) @SINCE_1_0.0 + POSITION_Z, ///< name "positionZ", type float (animatable / constraint-input) @SINCE_1_0.0 + WORLD_POSITION, ///< name "worldPosition", type Vector3 (read-only / constraint-input) @SINCE_1_0.0 + WORLD_POSITION_X, ///< name "worldPositionX", type float (read-only / constraint-input) @SINCE_1_0.0 + WORLD_POSITION_Y, ///< name "worldPositionY", type float (read-only / constraint-input) @SINCE_1_0.0 + WORLD_POSITION_Z, ///< name "worldPositionZ", type float (read-only / constraint-input) @SINCE_1_0.0 + ORIENTATION, ///< name "orientation", type Quaternion (animatable / constraint-input) @SINCE_1_0.0 + WORLD_ORIENTATION, ///< name "worldOrientation", type Quaternion (read-only / constraint-input) @SINCE_1_0.0 + SCALE, ///< name "scale", type Vector3 (animatable / constraint-input) @SINCE_1_0.0 + SCALE_X, ///< name "scaleX", type float (animatable / constraint-input) @SINCE_1_0.0 + SCALE_Y, ///< name "scaleY", type float (animatable / constraint-input) @SINCE_1_0.0 + SCALE_Z, ///< name "scaleZ", type float (animatable / constraint-input) @SINCE_1_0.0 + WORLD_SCALE, ///< name "worldScale", type Vector3 (read-only / constraint-input) @SINCE_1_0.0 + VISIBLE, ///< name "visible", type bool (animatable / constraint-input) @SINCE_1_0.0 + COLOR, ///< name "color", type Vector4 (animatable / constraint-input) @SINCE_1_0.0 + COLOR_RED, ///< name "colorRed", type float (animatable / constraint-input) @SINCE_1_0.0 + COLOR_GREEN, ///< name "colorGreen", type float (animatable / constraint-input) @SINCE_1_0.0 + COLOR_BLUE, ///< name "colorBlue", type float (animatable / constraint-input) @SINCE_1_0.0 + COLOR_ALPHA, ///< name "colorAlpha", type float (animatable / constraint-input) @SINCE_1_0.0 + WORLD_COLOR, ///< name "worldColor", type Vector4 (read-only / constraint-input) @SINCE_1_0.0 + WORLD_MATRIX, ///< name "worldMatrix", type Matrix (read-only / constraint-input) @SINCE_1_0.0 NAME, ///< name "name", type std::string @SINCE_1_0.0 - SENSITIVE, ///< name "sensitive", type bool @SINCE_1_0.0 - LEAVE_REQUIRED, ///< name "leaveRequired", type bool @SINCE_1_0.0 - INHERIT_ORIENTATION, ///< name "inheritOrientation", type bool @SINCE_1_0.0 - INHERIT_SCALE, ///< name "inheritScale", type bool @SINCE_1_0.0 + SENSITIVE, ///< name "sensitive", type bool @SINCE_1_0.0 + LEAVE_REQUIRED, ///< name "leaveRequired", type bool @SINCE_1_0.0 + INHERIT_ORIENTATION, ///< name "inheritOrientation", type bool @SINCE_1_0.0 + INHERIT_SCALE, ///< name "inheritScale", type bool @SINCE_1_0.0 COLOR_MODE, ///< name "colorMode", type std::string @SINCE_1_0.0 POSITION_INHERITANCE, ///< name "positionInheritance", type std::string @DEPRECATED_1_1.24 Use INHERIT_POSITION instead DRAW_MODE, ///< name "drawMode", type std::string @SINCE_1_0.0 - SIZE_MODE_FACTOR, ///< name "sizeModeFactor", type Vector3 @SINCE_1_0.0 - WIDTH_RESIZE_POLICY, ///< name "widthResizePolicy", type String @SINCE_1_0.0 - HEIGHT_RESIZE_POLICY, ///< name "heightResizePolicy", type String @SINCE_1_0.0 - SIZE_SCALE_POLICY, ///< name "sizeScalePolicy", type String @SINCE_1_0.0 - WIDTH_FOR_HEIGHT, ///< name "widthForHeight", type Boolean @SINCE_1_0.0 - HEIGHT_FOR_WIDTH, ///< name "heightForWidth", type Boolean @SINCE_1_0.0 - PADDING, ///< name "padding", type Vector4 @SINCE_1_0.0 - MINIMUM_SIZE, ///< name "minimumSize", type Vector2 @SINCE_1_0.0 - MAXIMUM_SIZE, ///< name "maximumSize", type Vector2 @SINCE_1_0.0 - INHERIT_POSITION, ///< name "inheritPosition", type bool @SINCE_1_1.24 - BATCH_PARENT, ///< name "batchParent", type bool @SINCE_1_1.46 + SIZE_MODE_FACTOR, ///< name "sizeModeFactor", type Vector3 @SINCE_1_0.0 + WIDTH_RESIZE_POLICY, ///< name "widthResizePolicy", type String @SINCE_1_0.0 + HEIGHT_RESIZE_POLICY, ///< name "heightResizePolicy", type String @SINCE_1_0.0 + SIZE_SCALE_POLICY, ///< name "sizeScalePolicy", type String @SINCE_1_0.0 + WIDTH_FOR_HEIGHT, ///< name "widthForHeight", type bool @SINCE_1_0.0 + HEIGHT_FOR_WIDTH, ///< name "heightForWidth", type bool @SINCE_1_0.0 + PADDING, ///< name "padding", type Vector4 @SINCE_1_0.0 + MINIMUM_SIZE, ///< name "minimumSize", type Vector2 @SINCE_1_0.0 + MAXIMUM_SIZE, ///< name "maximumSize", type Vector2 @SINCE_1_0.0 + INHERIT_POSITION, ///< name "inheritPosition", type bool @SINCE_1_1.24 + CLIPPING_MODE, ///< name "clippingMode", type String @SINCE_1_2_5 + BATCH_PARENT, ///< name "batchParent", type bool @SINCE_1_2.0 }; }; @@ -1122,14 +1118,9 @@ public: * Overlay actors are drawn in a separate pass, after all non-overlay actors within the Layer. * For overlay actors, the drawing order is with respect to tree levels of Actors, * and depth-testing will not be used. - * - * If DrawMode::STENCIL is used, the actor and its children will be used to stencil-test other actors - * within the Layer. Stencil actors are therefore drawn into the stencil buffer before any other - * actors within the Layer. - * + * @SINCE_1_0.0 * @param[in] drawMode The new draw-mode to use. - * @note Setting STENCIL will override OVERLAY_2D, if that would otherwise have been inherited. * @note Layers do not inherit the DrawMode from their parents. */ void SetDrawMode( DrawMode::Type drawMode ); @@ -1559,6 +1550,7 @@ public: // Signals public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Actor::New() methods. * @@ -1566,6 +1558,7 @@ public: // Not intended for application developers * @param [in] actor A pointer to a newly allocated Dali resource */ explicit DALI_INTERNAL Actor(Internal::Actor* actor); + /// @endcond }; /** @@ -1590,4 +1583,4 @@ inline void UnparentAndReset( Actor& actor ) */ } // namespace Dali -#endif // __DALI_ACTOR_H__ +#endif // DALI_ACTOR_H diff --git a/dali/public-api/actors/camera-actor.h b/dali/public-api/actors/camera-actor.h index 5abe9c6..14a44b9 100644 --- a/dali/public-api/actors/camera-actor.h +++ b/dali/public-api/actors/camera-actor.h @@ -63,7 +63,7 @@ enum ProjectionMode } // namespace Camera /** - * @brief Controls a camera. + * @brief CameraActor controls a camera. * * Allows the developer to use actor semantics to control a camera. * @@ -360,6 +360,7 @@ public: void SetOrthographicProjection( float left, float right, float top, float bottom, float near, float far ); public: // Not intended for use by Application developers + /// @cond internal /** * @brief This constructor is used by CameraActor::New() methods. * @@ -367,6 +368,7 @@ public: // Not intended for use by Application developers * @param [in] actor A pointer to a newly allocated Dali resource */ explicit DALI_INTERNAL CameraActor(Internal::CameraActor* actor); + /// @endcond }; /** diff --git a/dali/public-api/actors/layer.h b/dali/public-api/actors/layer.h index 7615ecc..13d038d 100644 --- a/dali/public-api/actors/layer.h +++ b/dali/public-api/actors/layer.h @@ -1,8 +1,8 @@ -#ifndef __DALI_LAYER_H__ -#define __DALI_LAYER_H__ +#ifndef DALI_LAYER_H +#define DALI_LAYER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -360,7 +360,6 @@ public: * The contents of the layer will not be visible outside this box, when clipping is * enabled. The default clipping box is empty (0,0,0,0) which means everything is clipped. * You can only do rectangular clipping using this API in window coordinates. - * For other kinds of clipping, see Dali::Actor::SetDrawMode(). * @SINCE_1_0.0 * @param [in] x The X-coordinate of the top-left corner of the box * @param [in] y The Y-coordinate of the top-left corner of the box @@ -470,6 +469,7 @@ public: public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Layer::New() methods. * @@ -477,6 +477,7 @@ public: // Not intended for application developers * @param [in] Layer A pointer to a newly allocated Dali resource */ explicit DALI_INTERNAL Layer(Internal::Layer* Layer); + /// @endcond }; /** @@ -484,4 +485,4 @@ public: // Not intended for application developers */ } // namespace Dali -#endif //__DALI_LAYER_H__ +#endif // DALI_LAYER_H diff --git a/dali/public-api/animation/animation.h b/dali/public-api/animation/animation.h index 894398d..2d18da9 100644 --- a/dali/public-api/animation/animation.h +++ b/dali/public-api/animation/animation.h @@ -697,12 +697,14 @@ public: public: // Not intended for use by Application developers + /// @cond internal /** * @brief This constructor is used by Animation::New() methods * @SINCE_1_0.0 * @param [in] animation A pointer to a newly allocated Dali resource */ explicit DALI_INTERNAL Animation(Internal::Animation* animation); + /// @endcond }; diff --git a/dali/public-api/animation/constraint.h b/dali/public-api/animation/constraint.h index 1bf916a..1c336a1 100644 --- a/dali/public-api/animation/constraint.h +++ b/dali/public-api/animation/constraint.h @@ -515,15 +515,18 @@ public: public: // Not intended for use by Application developers + /// @cond internal /** * @brief This constructor is used by Constraint::New() methods * @SINCE_1_0.0 * @param [in] constraint A pointer to a newly allocated Dali resource */ explicit DALI_INTERNAL Constraint( Internal::ConstraintBase* constraint ); + /// @endcond private: // Not intended for use by Application developers + /// @cond internal /** * @brief Construct a new constraint which targets a property. * @@ -535,6 +538,7 @@ private: // Not intended for use by Application developers * @return The new constraint. */ static Constraint New( Handle handle, Property::Index targetIndex, Property::Type targetType, CallbackBase* function ); + /// @endcond }; /** diff --git a/dali/public-api/animation/key-frames.h b/dali/public-api/animation/key-frames.h index c688e05..462d819 100644 --- a/dali/public-api/animation/key-frames.h +++ b/dali/public-api/animation/key-frames.h @@ -133,6 +133,7 @@ public: public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by KeyFrames::New() methods. * @@ -140,6 +141,7 @@ public: // Not intended for application developers * @param[in] keyFrames A pointer to an internal KeyFrame resource */ explicit DALI_INTERNAL KeyFrames(Internal::KeyFrames* keyFrames); + /// @endcond }; /** diff --git a/dali/public-api/animation/linear-constrainer.h b/dali/public-api/animation/linear-constrainer.h index 173f839..a0aa186 100644 --- a/dali/public-api/animation/linear-constrainer.h +++ b/dali/public-api/animation/linear-constrainer.h @@ -144,6 +144,7 @@ public: void Remove( Dali::Handle& target ); public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by LinearConstrainer::New() methods. * @@ -151,6 +152,7 @@ public: // Not intended for application developers * @param[in] internal A pointer to an internal LinearConstrainer resource */ explicit DALI_INTERNAL LinearConstrainer(Internal::LinearConstrainer* internal); + /// @endcond }; /** diff --git a/dali/public-api/animation/path.h b/dali/public-api/animation/path.h index 1646acb..6827d65 100644 --- a/dali/public-api/animation/path.h +++ b/dali/public-api/animation/path.h @@ -184,6 +184,7 @@ public: size_t GetPointCount() const; public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Path::New() methods. * @@ -191,6 +192,7 @@ public: // Not intended for application developers * @param[in] path A pointer to an internal path resource */ explicit DALI_INTERNAL Path(Internal::Path* path); + /// @endcond }; /** diff --git a/dali/public-api/common/stage.h b/dali/public-api/common/stage.h index 625d5f7..09a5edf 100644 --- a/dali/public-api/common/stage.h +++ b/dali/public-api/common/stage.h @@ -359,6 +359,7 @@ public: public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Stage::GetCurrent() methods. * @@ -366,6 +367,7 @@ public: // Not intended for application developers * @param [in] stage A pointer to a Dali resource */ explicit DALI_INTERNAL Stage(Internal::Stage* stage); + /// @endcond }; /** diff --git a/dali/public-api/dali-core-version.cpp b/dali/public-api/dali-core-version.cpp index 4b18845..42e7e4f 100644 --- a/dali/public-api/dali-core-version.cpp +++ b/dali/public-api/dali-core-version.cpp @@ -27,8 +27,8 @@ namespace Dali { const unsigned int CORE_MAJOR_VERSION = 1; -const unsigned int CORE_MINOR_VERSION = 1; -const unsigned int CORE_MICRO_VERSION = 45; +const unsigned int CORE_MINOR_VERSION = 2; +const unsigned int CORE_MICRO_VERSION = 5; const char * const CORE_BUILD_DATE = __DATE__ " " __TIME__; #ifndef EMSCRIPTEN diff --git a/dali/public-api/events/gesture-detector.h b/dali/public-api/events/gesture-detector.h index c6cc8fd..8c9356d 100644 --- a/dali/public-api/events/gesture-detector.h +++ b/dali/public-api/events/gesture-detector.h @@ -151,6 +151,7 @@ public: // Actor related protected: + /// @cond internal /** * @brief This constructor is used by New() methods of derived classes (For example, PanGestureDetector::New()). * @@ -158,6 +159,7 @@ protected: * @param [in] internal A pointer to a newly allocated Dali resource. */ explicit DALI_INTERNAL GestureDetector(Internal::GestureDetector* internal); + /// @endcond }; /** diff --git a/dali/public-api/events/long-press-gesture-detector.h b/dali/public-api/events/long-press-gesture-detector.h index 4a9c849..a0502c5 100644 --- a/dali/public-api/events/long-press-gesture-detector.h +++ b/dali/public-api/events/long-press-gesture-detector.h @@ -39,7 +39,6 @@ struct LongPressGesture; /** * @brief This class emits a signals when a long press gesture occurs that meets the requirements set by the application. * @SINCE_1_0.0 - * @see LongPressGestureDetector::SetTouchesRequired. * * For any valid long press, two signals will be emitted: * - First identifying the beginning (state = Started) i.e. when fingers held down for the required time. @@ -210,6 +209,7 @@ public: // Signals public: // Not intended for Application developers + /// @cond internal /** * @brief This constructor is used by LongPressGestureDetector::New() methods. * @@ -217,6 +217,7 @@ public: // Not intended for Application developers * @param [in] internal A pointer to a newly allocated Dali resource. */ explicit DALI_INTERNAL LongPressGestureDetector(Internal::LongPressGestureDetector* internal); + /// @endcond }; diff --git a/dali/public-api/events/pan-gesture-detector.h b/dali/public-api/events/pan-gesture-detector.h index 72f688e..2d3500b 100644 --- a/dali/public-api/events/pan-gesture-detector.h +++ b/dali/public-api/events/pan-gesture-detector.h @@ -335,6 +335,7 @@ public: // Pan Properties Setters public: // Not intended for Application developers + /// @cond internal /** * @brief This constructor is used by PanGestureDetector::New() methods. * @@ -342,6 +343,7 @@ public: // Not intended for Application developers * @param [in] internal A pointer to a newly allocated Dali resource. */ explicit DALI_INTERNAL PanGestureDetector(Internal::PanGestureDetector* internal); + /// @endcond }; diff --git a/dali/public-api/events/pinch-gesture-detector.h b/dali/public-api/events/pinch-gesture-detector.h index 37eb16a..a3b2df5 100644 --- a/dali/public-api/events/pinch-gesture-detector.h +++ b/dali/public-api/events/pinch-gesture-detector.h @@ -139,6 +139,7 @@ public: // Signals public: // Not intended for Application developers + /// @cond internal /** * @brief This constructor is used by PinchGestureDetector::New() methods. * @@ -146,6 +147,7 @@ public: // Not intended for Application developers * @param [in] internal A pointer to a newly allocated Dali resource. */ explicit DALI_INTERNAL PinchGestureDetector(Internal::PinchGestureDetector* internal); + /// @endcond }; diff --git a/dali/public-api/events/tap-gesture-detector.h b/dali/public-api/events/tap-gesture-detector.h index 020558e..aa1bfc2 100644 --- a/dali/public-api/events/tap-gesture-detector.h +++ b/dali/public-api/events/tap-gesture-detector.h @@ -54,7 +54,8 @@ struct TapGesture; * @endcode * * @SINCE_1_0.0 - * @note Multi-touch taps are not currently supported. However, multiple taps (double & triple tap etc.) are supported. + * @note Multi-touch taps (two or more points of contact with the surface) are not currently + * supported. However, multiple taps (double & triple tap etc.) are supported. * * Signals * | %Signal Name | Method | @@ -198,6 +199,7 @@ public: // Signals public: // Not intended for Application developers + /// @cond internal /** * @brief This constructor is used by TapGestureDetector::New() methods. * @@ -205,6 +207,7 @@ public: // Not intended for Application developers * @param [in] internal A pointer to a newly allocated Dali resource. */ explicit DALI_INTERNAL TapGestureDetector(Internal::TapGestureDetector* internal); + /// @endcond }; /** diff --git a/dali/public-api/events/touch-data.h b/dali/public-api/events/touch-data.h index be302a2..9eedd3b 100644 --- a/dali/public-api/events/touch-data.h +++ b/dali/public-api/events/touch-data.h @@ -217,6 +217,7 @@ public: public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used internally to Create an initialized TouchData handle. * @@ -224,6 +225,7 @@ public: // Not intended for application developers * @param [in] touchData A pointer to a newly allocated Dali resource */ explicit DALI_INTERNAL TouchData( Internal::TouchData* touchData ); + /// @endcond }; /** diff --git a/dali/public-api/images/resource-image.h b/dali/public-api/images/resource-image.h index c4af9ce..d354a26 100644 --- a/dali/public-api/images/resource-image.h +++ b/dali/public-api/images/resource-image.h @@ -143,6 +143,7 @@ public: * * @sa Dali::FittingMode::Type Dali::SamplingMode::Type * @SINCE_1_0.0 + * @REMARK_INTERNET * @param [in] url The URL of the image file to use. * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header. * @return A handle to a newly allocated object @@ -155,6 +156,7 @@ public: * @brief Create an initialised ResourceImage object. * * @SINCE_1_0.0 + * @REMARK_INTERNET * @param [in] url The URL of the image file to use. * @param [in] loadPol The LoadPolicy to apply when loading the image resource. * @param [in] releasePol The ReleasePolicy to apply to Image. @@ -167,6 +169,7 @@ public: * @brief Create an initialised ResourceImage object. * * @SINCE_1_0.0 + * @REMARK_INTERNET * @param [in] url The URL of the image file to use. * @param [in] size The width and height to fit the loaded image to. * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter. @@ -186,6 +189,7 @@ public: * @brief Create an initialised ResourceImage object. * * @SINCE_1_0.0 + * @REMARK_INTERNET * @param [in] url The URL of the image file to use. * @param [in] loadPol The LoadPolicy to apply when loading the image resource. * @param [in] releasePol The ReleasePolicy to apply to Image. diff --git a/dali/public-api/math/quaternion.h b/dali/public-api/math/quaternion.h index af25592..21c83a3 100644 --- a/dali/public-api/math/quaternion.h +++ b/dali/public-api/math/quaternion.h @@ -455,6 +455,7 @@ public: private: + /// @cond internal /** * @brief Set the quaternion from 3 orthonormal axes. * @@ -464,6 +465,7 @@ private: * @param[in] zAxis The Z axis */ DALI_INTERNAL void SetFromAxes( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis ); + /// @endcond public: diff --git a/dali/public-api/object/base-handle.h b/dali/public-api/object/base-handle.h index 1cafbc1..087e7ba 100644 --- a/dali/public-api/object/base-handle.h +++ b/dali/public-api/object/base-handle.h @@ -129,6 +129,13 @@ public: /** * @brief Perform action on this object with the given action name and attributes. * + * Usage example: - + * @code + * BaseHandle handle = SomeClass::New(); // Initialized with New() method + * + * Property::Map attributes; // Type is Property Map + * handle.DoAction("show", attributes); + * @endcode * @SINCE_1_0.0 * @param [in] actionName The command for the action. * @param [in] attributes The list of attributes for the action. @@ -248,6 +255,8 @@ protected: /** * @brief Used by the safe bool idiom. * + * The safe bool idiom basically provides a Boolean test for classes. It validates objects + * in a boolean context without the usual harmful side effects. * @SINCE_1_0.0 */ void ThisIsSaferThanReturningVoidStar() const {} diff --git a/dali/public-api/object/handle.cpp b/dali/public-api/object/handle.cpp index 80da558..ea5ddd9 100644 --- a/dali/public-api/object/handle.cpp +++ b/dali/public-api/object/handle.cpp @@ -90,6 +90,11 @@ Property::Index Handle::GetPropertyIndex( const std::string& name ) const return GetImplementation(*this).GetPropertyIndex( name ); } +Property::Index Handle::GetPropertyIndex( Property::Index key ) const +{ + return GetImplementation(*this).GetPropertyIndex( key ); +} + bool Handle::IsPropertyWritable( Property::Index index ) const { return GetImplementation(*this).IsPropertyWritable( index ); @@ -120,6 +125,11 @@ Property::Index Handle::RegisterProperty( const std::string& name, const Propert return GetImplementation(*this).RegisterProperty( name, propertyValue ); } +Property::Index Handle::RegisterProperty( Property::Index key, const std::string& name, const Property::Value& propertyValue ) +{ + return GetImplementation(*this).RegisterProperty( name, key, propertyValue ); +} + Property::Index Handle::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode ) { return GetImplementation(*this).RegisterProperty( name, propertyValue, accessMode ); diff --git a/dali/public-api/object/handle.h b/dali/public-api/object/handle.h index 7d0e5a0..b0f7f6b 100644 --- a/dali/public-api/object/handle.h +++ b/dali/public-api/object/handle.h @@ -178,6 +178,23 @@ public: Property::Index GetPropertyIndex( const std::string& name ) const; /** + * @brief Query the index of a custom property matching the given key. + * + * Returns the first custom property that matches the given integer key. This is + * useful for other classes that know the key but not the name. Requires the property + * to have been registered with the associated key. + * + * @note This key is not the same as the Property enum found in + * objects such as Actor (which is a preset index). + * + * @SINCE_1_2.1 + * @param [in] key The integer key of the property + * @return The index of the property, or Property::INVALID_INDEX if no property exists with the given key. + * @note The key is not the same as the returned index, though it has the same type. + */ + Property::Index GetPropertyIndex( Property::Index key ) const; + + /** * @brief Query whether a property can be set using SetProperty(). * * @SINCE_1_0.0 @@ -252,6 +269,40 @@ public: Property::Index RegisterProperty( const std::string& name, const Property::Value& propertyValue ); /** + * @brief Register a new animatable property with an integer key. + * + * @SINCE_1_2.1 + * @param [in] key The integer key of the property. + * @param [in] name The text key of the property. + * @param [in] propertyValue The new value of the property. + * @return The index of the property or Property::INVALID_INDEX if registration failed + * @pre The object supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true. + * Property names and keys are expected to be unique, but this is not enforced. + * Property indices are unique to each registered custom property in a given object. + * @note Returns Property::INVALID_INDEX if registration failed. This can happen if you try to register + * animatable property on an object that does not have scene graph object. + * @note The returned property index is not the same as the integer key (though it shares a type) + * + * This version of RegisterProperty associates both an integer key + * and the text key with the property, allowing for lookup of the + * property index by either key or name ( which is useful when other + * classes know the key but not the name ) + * + * @note Only the following types can be animated: + * - Property::BOOLEAN + * - Property::FLOAT + * - Property::INTEGER + * - Property::VECTOR2 + * - Property::VECTOR3 + * - Property::VECTOR4 + * - Property::MATRIX3 + * - Property::MATRIX + * - Property::ROTATION + * @note If a property with the desired name already exists, then the value given is just set. + */ + Property::Index RegisterProperty( Property::Index key, const std::string& name, const Property::Value& propertyValue ); + + /** * @brief Register a new property. * * Properties can be set as non animatable using property attributes. diff --git a/dali/public-api/object/object-registry.h b/dali/public-api/object/object-registry.h index 38950b2..ff3205d 100644 --- a/dali/public-api/object/object-registry.h +++ b/dali/public-api/object/object-registry.h @@ -149,6 +149,7 @@ public: // Signals public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Dali Get() method. * @@ -156,6 +157,7 @@ public: // Not intended for application developers * @param [in] objectRegistry A pointer to a Dali resource */ explicit DALI_INTERNAL ObjectRegistry(Internal::ObjectRegistry* objectRegistry); + /// @endcond }; /** diff --git a/dali/public-api/object/property-notification.h b/dali/public-api/object/property-notification.h index 49bd291..caa799b 100644 --- a/dali/public-api/object/property-notification.h +++ b/dali/public-api/object/property-notification.h @@ -175,6 +175,7 @@ public: public: // Not intended for use by Application developers + /// @cond internal /** * @brief This constructor is used by Dali New() methods. * @@ -182,6 +183,7 @@ public: // Not intended for use by Application developers * @param [in] propertyNotification A pointer to a newly allocated Dali resource */ explicit DALI_INTERNAL PropertyNotification(Internal::PropertyNotification* propertyNotification); + /// @endcond }; /** diff --git a/dali/public-api/object/property.cpp b/dali/public-api/object/property.cpp index cc2386a..ba6cf7d 100644 --- a/dali/public-api/object/property.cpp +++ b/dali/public-api/object/property.cpp @@ -24,7 +24,8 @@ namespace Dali { -const int Property::INVALID_INDEX = -1; +const int Property::INVALID_INDEX = -1; +const int Property::INVALID_KEY = -1; const int Property::INVALID_COMPONENT_INDEX = -1; Property::Property(Handle& obj, Property::Index propIndex) diff --git a/dali/public-api/object/property.h b/dali/public-api/object/property.h index 03c40e0..b280269 100644 --- a/dali/public-api/object/property.h +++ b/dali/public-api/object/property.h @@ -48,6 +48,7 @@ struct DALI_IMPORT_API Property typedef int Index; static const int INVALID_INDEX; ///< -1 is not a valid property index + static const int INVALID_KEY; ///< -1 is not a valid property key static const int INVALID_COMPONENT_INDEX; ///< -1 is not a valid property index typedef Dali::Vector< Index > IndexContainer; ///< A vector of property indices @SINCE_1_0.0 diff --git a/dali/public-api/object/type-info.h b/dali/public-api/object/type-info.h index fbdcfab..ba9c6ff 100644 --- a/dali/public-api/object/type-info.h +++ b/dali/public-api/object/type-info.h @@ -217,6 +217,7 @@ public: public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Dali Get() method. * @@ -224,6 +225,7 @@ public: // Not intended for application developers * @param [in] typeInfo A pointer to a Dali resource */ explicit DALI_INTERNAL TypeInfo(Internal::TypeInfo* typeInfo); + /// @endcond }; diff --git a/dali/public-api/object/type-registry.h b/dali/public-api/object/type-registry.h index 2842213..8a17be5 100644 --- a/dali/public-api/object/type-registry.h +++ b/dali/public-api/object/type-registry.h @@ -169,6 +169,7 @@ public: public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Dali Get() method. * @@ -176,6 +177,7 @@ public: // Not intended for application developers * @param [in] typeRegistry A pointer to a Dali resource */ explicit DALI_INTERNAL TypeRegistry(Internal::TypeRegistry*typeRegistry); + /// @endcond }; /** diff --git a/dali/public-api/render-tasks/render-task-list.h b/dali/public-api/render-tasks/render-task-list.h index 8a36810..3992cc0 100644 --- a/dali/public-api/render-tasks/render-task-list.h +++ b/dali/public-api/render-tasks/render-task-list.h @@ -127,12 +127,15 @@ public: public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Dali New() methods + * * @SINCE_1_0.0 * @param [in] renderTask A pointer to a newly allocated render-task */ explicit DALI_INTERNAL RenderTaskList( Internal::RenderTaskList* renderTask ); + /// @endcond }; /** diff --git a/dali/public-api/render-tasks/render-task.h b/dali/public-api/render-tasks/render-task.h index 959c38d..ba86792 100644 --- a/dali/public-api/render-tasks/render-task.h +++ b/dali/public-api/render-tasks/render-task.h @@ -514,12 +514,14 @@ public: // Signals public: // Not intended for application developers + /// @cond internal /** * @brief This constructor is used by Dali New() methods. * @SINCE_1_0.0 * @param [in] renderTask A pointer to a newly allocated render-task */ explicit DALI_INTERNAL RenderTask( Internal::RenderTask* renderTask ); + /// @endcond }; /** diff --git a/dali/public-api/rendering/renderer.h b/dali/public-api/rendering/renderer.h index 353dd28..ad4cc74 100644 --- a/dali/public-api/rendering/renderer.h +++ b/dali/public-api/rendering/renderer.h @@ -162,6 +162,24 @@ enum Type } // namespace DepthFunction +namespace RenderMode +{ + +/** + * @brief Controls how this renderer uses its stencil properties and writes to the color buffer. + * @SINCE_1_2_5 + */ +enum Type +{ + NONE, ///< Don’t write to either color or stencil buffer (But will potentially render to depth buffer). @SINCE_1_2_5 + AUTO, ///< Managed by the Actor Clipping API. This is the default. @SINCE_1_2_5 + COLOR, ///< Ingore stencil properties. Write to the color buffer. @SINCE_1_2_5 + STENCIL, ///< Use the stencil properties. Do not write to the color buffer. @SINCE_1_2_5 + COLOR_STENCIL ///< Use the stencil properties AND Write to the color buffer. @SINCE_1_2_5 +}; + +} // namespace RenderMode + namespace StencilFunction { @@ -183,22 +201,6 @@ enum Type } // namespace StencilFunction -namespace StencilMode -{ - -/** - * @brief How the stencil buffer will be managed. - * @SINCE_1_1.43 - */ -enum Type -{ - OFF, ///< Off for this renderer @SINCE_1_1.43 - AUTO, ///< Managed by the Actor clipping API. This is the default @SINCE_1_1.43 - ON ///< On for this renderer. Select this to use the Renderer stencil properties to manage behavior. Note that Actor clipping management is bypassed for this renderer @SINCE_1_1.43 -}; - -} // namespace StencilMode - namespace StencilOperation { @@ -353,6 +355,14 @@ public: DEPTH_TEST_MODE, /** + * @brief name "renderMode", type INTEGER + * @see RenderMode + * @note The default value is RenderMode::AUTO + * @SINCE_1_2_5 + */ + RENDER_MODE, + + /** * @brief name "stencilFunction", type INTEGER * @see StencilFunction * @note The default value is StencilFunction::ALWAYS @@ -382,14 +392,6 @@ public: STENCIL_MASK, /** - * @brief name "stencilMode", type INTEGER - * @see StencilMode - * @note The default value is StencilMode::AUTO - * @SINCE_1_1.43 - */ - STENCIL_MODE, - - /** * @brief name "stencilOperationOnFail", type INTEGER * @see StencilOperation * @note The default value is StencilOperation::KEEP @@ -414,16 +416,8 @@ public: STENCIL_OPERATION_ON_Z_PASS, /** - * @brief name "writeToColorBuffer", type BOOLEAN - * This allows per-renderer control of writing to the color buffer. - * For example: This can be turned off to write to the stencil or depth buffers only. - * @note The default value is True - * @SINCE_1_1.43 - */ - WRITE_TO_COLOR_BUFFER, - - /** * @brief name "batchingEnabled", type BOOLEAN + * @SINCE_1_2.0 * @see Batching * @note The default value is 'false' */ diff --git a/dali/public-api/shader-effects/shader-effect.h b/dali/public-api/shader-effects/shader-effect.h index dffed8b..faea062 100644 --- a/dali/public-api/shader-effects/shader-effect.h +++ b/dali/public-api/shader-effects/shader-effect.h @@ -368,6 +368,7 @@ public: public: // Not intended for application developers + /// @cond internal /** * @DEPRECATED_1_0.47 * @brief This constructor is used by Dali New() methods. @@ -375,6 +376,7 @@ public: // Not intended for application developers * @param [in] effect A pointer to a newly allocated Dali resource. */ explicit DALI_INTERNAL ShaderEffect(Internal::ShaderEffect* effect); + /// @endcond }; /** diff --git a/doc/dali-core-doc.h b/doc/dali-core-doc.h index 561c847..788d16f 100644 --- a/doc/dali-core-doc.h +++ b/doc/dali-core-doc.h @@ -40,7 +40,7 @@ * * * @ref dali_core_animation - * Animation allows your objects to move around / change their properties for a specified duration. + * Classes for animation which allows your objects to move around / change their properties for a specified duration. * * * @ref dali_core_common @@ -48,7 +48,7 @@ * * * @ref dali_core_events - * Input events and gestures supported by DALi. + * Classes for input events and gestures supported by DALi. * * * @ref dali_core_images @@ -56,7 +56,7 @@ * * * @ref dali_core_math - * Basic math classes. + * Classes for basic math. * * * @ref dali_core_object @@ -64,7 +64,7 @@ * * * @ref dali_core_rendering_effects - * Render task and shader effect classes. + * Classes for render task and shader effect. * * * @ref dali_core_signals @@ -94,25 +94,25 @@ * @brief Actor is the primary object for interaction in DALi applications. * @defgroup dali_core_animation Animation - * @brief Animation allows your objects to move around / change their properties for a specified duration. + * @brief Classes for animation which allows your objects to move around / change their properties for a specified duration. * @defgroup dali_core_common Common * @brief Common classes for using DALi. * @defgroup dali_core_events Events - * @brief Input events and gestures supported by DALi. + * @brief Classes for input events and gestures supported by DALi. * @defgroup dali_core_images Images * @brief Classes for handling resource images. * @defgroup dali_core_math Math - * @brief Basic math classes. + * @brief Classes for basic math. * @defgroup dali_core_object Object * @brief Classes for the handle/body pattern and property system. * @defgroup dali_core_rendering_effects Rendering & Effect - * @brief Render task and shader effect classes. + * @brief Classes for render task and shader effect. * @defgroup dali_core_signals Signal * @brief Classes for the signal and slot structure. diff --git a/packaging/dali.spec b/packaging/dali.spec index 4a3d940..650c2e8 100644 --- a/packaging/dali.spec +++ b/packaging/dali.spec @@ -1,6 +1,6 @@ Name: dali Summary: The OpenGLES Canvas Core Library -Version: 1.1.45 +Version: 1.2.5 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-2-Clause and MIT -- 2.7.4