(ColorVisual) Don't render if transparent alpha by default 31/164731/7
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 20 Dec 2017 14:56:24 +0000 (14:56 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 22 Dec 2017 13:26:41 +0000 (13:26 +0000)
Added a property to force rendering if required. This was needed for the CLIP_CHILDREN use case.

Change-Id: Id5beaf92ed38b2beb30439c7ab760c8a762f1d9f

automated-tests/src/dali-toolkit/utc-Dali-Control.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/visuals/color-visual-properties-devel.h [new file with mode: 0644]
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.h
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h
dali-toolkit/public-api/controls/control-impl.cpp

index 0a4dad2..df48a7d 100755 (executable)
@@ -75,6 +75,18 @@ static void TestKeyInputFocusCallback( Control control )
 const char* TEST_LARGE_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR "/tbcol.png";
 const char* TEST_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR "/gallery-small-1.jpg";
 
+Vector4 GetControlBackgroundColor( Control& control )
+{
+  Property::Value propValue = control.GetProperty( Control::Property::BACKGROUND );
+  Property::Map* resultMap = propValue.GetMap();
+  DALI_TEST_CHECK( resultMap->Find( ColorVisual::Property::MIX_COLOR ) );
+
+  Vector4 color;
+  resultMap->Find( ColorVisual::Property::MIX_COLOR )->Get( color );
+
+  return color;
+}
+
 } // namespace
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -458,6 +470,80 @@ int UtcDaliControlBackgroundColor(void)
   END_TEST;
 }
 
+int UtcDaliControlBackgroundColorRendererCount(void)
+{
+  tet_infoline( "Test ensures we only create renderers when non-transparent color is requested or if we our clipping-mode is set to CLIP_CHILDREN" );
+
+  ToolkitTestApplication application;
+  Control control = Control::New();
+  Stage::GetCurrent().Add( control );
+
+  tet_infoline( "Set transparent, no renderers should be created" );
+  control.SetBackgroundColor( Color::TRANSPARENT );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
+
+  tet_infoline( "Set transparent alpha with positive RGB values, no renderers should be created, but returned color should reflect what we set" );
+  const Vector4 alphaZero( 1.0f, 0.5f, 0.25f, 0.0f );
+  control.SetBackgroundColor( alphaZero );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
+  DALI_TEST_EQUALS( GetControlBackgroundColor( control ), alphaZero, TEST_LOCATION );
+
+  tet_infoline( "Set semi transparent alpha with positive RGB values, 1 renderer should be created, but returned color should reflect what we set" );
+  const Vector4 semiTransparent( 1.0f, 0.75f, 0.5f, 0.5f );
+  control.SetBackgroundColor( semiTransparent );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( GetControlBackgroundColor( control ), semiTransparent, TEST_LOCATION );
+
+  tet_infoline( "Set transparent, ensure no renderers are created" );
+  control.SetBackgroundColor( Color::TRANSPARENT );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
+  DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
+
+  tet_infoline( "Set control to clip its children, a renderer should be created which will be transparent" );
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
+
+  tet_infoline( "Set a color, only 1 renderer should exist" );
+  control.SetBackgroundColor( Color::RED );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::RED, TEST_LOCATION );
+
+  tet_infoline( "Clear the background, no renderers" );
+  control.ClearBackground();
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
+
+  tet_infoline( "Set control to clip its children again, a renderer should be created which will be transparent" );
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
+
+  tet_infoline( "Disable clipping, no renderers" );
+  control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::DISABLED );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( control.GetRendererCount(), 0u, TEST_LOCATION );
+  DALI_TEST_EQUALS( GetControlBackgroundColor( control ), Color::TRANSPARENT, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliControlBackgroundImage(void)
 {
   ToolkitTestApplication application;
index ab45fc0..bf54997 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/transition-data.h>
+#include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/text-visual-properties-devel.h>
@@ -3392,3 +3393,53 @@ int UtcDaliRegisterVisualWithDepthIndex(void)
 
   END_TEST;
 }
+
+int UtcDaliColorVisualRenderIfTransparentProperty(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "Test the renderIfTransparent property of ColorVisual" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert( Visual::Property::TYPE,  Visual::COLOR );
+  propertyMap.Insert( ColorVisual::Property::MIX_COLOR, Color::BLUE );
+
+  tet_infoline( "Check default value" );
+  {
+    Visual::Base testVisual = factory.CreateVisual( propertyMap );
+    Property::Map returnedMap;
+    testVisual.CreatePropertyMap( returnedMap );
+
+    Property::Value* renderIfTransparentProperty = returnedMap.Find( DevelColorVisual::Property::RENDER_IF_TRANSPARENT );
+    DALI_TEST_CHECK( renderIfTransparentProperty );
+    DALI_TEST_EQUALS( renderIfTransparentProperty->Get< bool >(), false, TEST_LOCATION );
+  }
+
+  propertyMap.Insert( DevelColorVisual::Property::RENDER_IF_TRANSPARENT, true );
+
+  tet_infoline( "Ensure set to value required" );
+  {
+    Visual::Base testVisual = factory.CreateVisual( propertyMap );
+    Property::Map returnedMap;
+    testVisual.CreatePropertyMap( returnedMap );
+
+    Property::Value* renderIfTransparentProperty = returnedMap.Find( DevelColorVisual::Property::RENDER_IF_TRANSPARENT );
+    DALI_TEST_CHECK( renderIfTransparentProperty );
+    DALI_TEST_EQUALS( renderIfTransparentProperty->Get< bool >(), true, TEST_LOCATION );
+  }
+
+  propertyMap[ DevelColorVisual::Property::RENDER_IF_TRANSPARENT ] = Color::BLUE;
+
+  tet_infoline( "Ensure it returns default value if set to wrong type" );
+  {
+    Visual::Base testVisual = factory.CreateVisual( propertyMap );
+    Property::Map returnedMap;
+    testVisual.CreatePropertyMap( returnedMap );
+
+    Property::Value* renderIfTransparentProperty = returnedMap.Find( DevelColorVisual::Property::RENDER_IF_TRANSPARENT );
+    DALI_TEST_CHECK( renderIfTransparentProperty );
+    DALI_TEST_EQUALS( renderIfTransparentProperty->Get< bool >(), false, TEST_LOCATION );
+  }
+
+  END_TEST;
+}
index 0bfd7d4..812668b 100644 (file)
@@ -91,9 +91,10 @@ devel_api_visual_factory_header_files = \
   $(devel_api_src_dir)/visual-factory/visual-base.h
 
 devel_api_visuals_header_files = \
+  $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \
+  $(devel_api_src_dir)/visuals/color-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-actions-devel.h \
-  $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/text-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/visual-properties-devel.h
 
diff --git a/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/color-visual-properties-devel.h
new file mode 100644 (file)
index 0000000..4eb8b3a
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H
+#define DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H
+
+/*
+ * Copyright (c) 2017 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 <dali-toolkit/public-api/visuals/color-visual-properties.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+
+namespace DevelColorVisual
+{
+
+/**
+ * @brief Additional ColorVisual Properties.
+ */
+namespace Property
+{
+
+/**
+ * @brief Enumeration for the instance of additional properties belonging to the ColorVisual.
+ */
+enum
+{
+  MIX_COLOR = Toolkit::ColorVisual::Property::MIX_COLOR,
+
+  /**
+   * @brief Whether to render if the MIX_COLOR is transparent.
+   * @details Name "renderIfTransparent", type Property::BOOLEAN.
+   * @note Optional.
+   * @note By default it's false, i.e. ColorVisual will not render if the MIX_COLOR is transparent.
+   */
+  RENDER_IF_TRANSPARENT = MIX_COLOR + 1,
+};
+
+} // namespace Property
+
+} // namespace ColorVisual
+
+/**
+ * @}
+ */
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_COLOR_VISUAL_PROPERTIES_DEVEL_H
index 2d8008f..2058e1b 100644 (file)
@@ -25,6 +25,7 @@
 //INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -88,7 +89,8 @@ ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache, const Propert
 }
 
 ColorVisual::ColorVisual( VisualFactoryCache& factoryCache )
-: Visual::Base( factoryCache )
+: Visual::Base( factoryCache ),
+  mRenderIfTransparent( false )
 {
 }
 
@@ -122,13 +124,27 @@ void ColorVisual::DoSetProperties( const Property::Map& propertyMap )
       DALI_LOG_ERROR("ColorVisual: mixColor property has incorrect type\n");
     }
   }
+
+  Property::Value* renderIfTransparentValue = propertyMap.Find( Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT, RENDER_IF_TRANSPARENT_NAME );
+  if( renderIfTransparentValue )
+  {
+    if( ! renderIfTransparentValue->Get( mRenderIfTransparent ) )
+    {
+      DALI_LOG_ERROR( "ColorVisual: renderIfTransparent property has incorrect type: %d\n", renderIfTransparentValue->GetType() );
+    }
+  }
 }
 
 void ColorVisual::DoSetOnStage( Actor& actor )
 {
   InitializeRenderer();
 
-  actor.AddRenderer( mImpl->mRenderer );
+  // Only add the renderer if it's not fully transparent
+  // We cannot avoid creating a renderer as it's used in the base class
+  if( mRenderIfTransparent || mImpl->mMixColor.a > 0.0f )
+  {
+    actor.AddRenderer( mImpl->mRenderer );
+  }
 
   // Color Visual generated and ready to display
   ResourceReady( Toolkit::Visual::ResourceStatus::READY );
@@ -139,6 +155,7 @@ void ColorVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Clear();
   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR );
   map.Insert( Toolkit::ColorVisual::Property::MIX_COLOR, mImpl->mMixColor );
+  map.Insert( Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT, mRenderIfTransparent );
 }
 
 void ColorVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
index 939d40e..4b6dca6 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_COLOR_VISUAL_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -112,6 +112,10 @@ private:
 
   // Undefined
   ColorVisual& operator=( const ColorVisual& colorRenderer );
+
+private:
+
+  bool mRenderIfTransparent; ///< Whether we should render even if the mix-color is transparent.
 };
 
 } // namespace Internal
index 9e889cb..079141d 100644 (file)
@@ -72,6 +72,9 @@ const char * const PREMULTIPLIED_ALPHA( "premultipliedAlpha" );
 const char * const MIX_COLOR( "mixColor" );
 const char * const OPACITY( "opacity" );
 
+// Color visual
+const char * const RENDER_IF_TRANSPARENT_NAME( "renderIfTransparent" );
+
 // Image visual
 const char * const IMAGE_URL_NAME( "url" );
 const char * const ATLAS_RECT_UNIFORM_NAME( "uAtlasRect" );
index eb0b617..1a73da9 100644 (file)
@@ -58,6 +58,9 @@ extern const char * const PREMULTIPLIED_ALPHA;
 extern const char * const MIX_COLOR;
 extern const char * const OPACITY;
 
+// Color visual
+extern const char * const RENDER_IF_TRANSPARENT_NAME;
+
 // Image visual
 extern const char * const IMAGE_URL_NAME;
 extern const char * const ATLAS_RECT_UNIFORM_NAME;
index 47a12b1..49064a8 100755 (executable)
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
+#include <dali-toolkit/public-api/align-enumerations.h>
 #include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
 #include <dali-toolkit/public-api/styling/style-manager.h>
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
-#include <dali-toolkit/public-api/visuals/visual-properties.h>
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
+#include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
-#include <dali-toolkit/public-api/align-enumerations.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 
 namespace Dali
@@ -61,6 +62,30 @@ Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CO
 #endif
 
 /**
+ * @brief Replace the background visual if it's a color visual with the renderIfTransparent property set as required.
+ * @param[in] controlImpl The control implementation
+ * @param[in] renderIfTransaparent Whether we should render if the color is transparent
+ */
+void ChangeBackgroundColorVisual( Control& controlImpl, bool renderIfTransparent )
+{
+  Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
+
+  Toolkit::Visual::Base backgroundVisual = controlDataImpl.GetVisual( Toolkit::Control::Property::BACKGROUND );
+  if( backgroundVisual )
+  {
+    Property::Map map;
+    backgroundVisual.CreatePropertyMap( map );
+    Property::Value* typeValue = map.Find( Toolkit::Visual::Property::TYPE );
+    if( typeValue && typeValue->Get< int >() == Toolkit::Visual::COLOR )
+    {
+      // Only change it if it's a color visual
+      map[ Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT ] = renderIfTransparent;
+      controlImpl.SetBackground( map );
+    }
+  }
+}
+
+/**
  * @brief Creates a clipping renderer if required.
  * (EG. If no renders exist and clipping is enabled).
  * @param[in] controlImpl The control implementation.
@@ -72,13 +97,34 @@ void CreateClippingRenderer( Control& controlImpl )
   int clippingMode = ClippingMode::DISABLED;
   if( self.GetProperty( Actor::Property::CLIPPING_MODE ).Get( clippingMode ) )
   {
-    Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
-
-    if( ( clippingMode == ClippingMode::CLIP_CHILDREN ) &&
-        controlDataImpl.mVisuals.Empty() &&
-        ( self.GetRendererCount() == 0u ) )
+    switch( clippingMode )
     {
-      controlImpl.SetBackgroundColor( Color::TRANSPARENT );
+      case ClippingMode::CLIP_CHILDREN:
+      {
+        if( self.GetRendererCount() == 0u )
+        {
+          Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
+          if( controlDataImpl.mVisuals.Empty() )
+          {
+            controlImpl.SetBackgroundColor( Color::TRANSPARENT );
+          }
+          else
+          {
+            // We have visuals, check if we've set the background and re-create it to
+            // render even if transparent (only if it's a color visual)
+            ChangeBackgroundColorVisual( controlImpl, true );
+          }
+        }
+        break;
+      }
+
+      case ClippingMode::DISABLED:
+      case ClippingMode::CLIP_TO_BOUNDING_BOX:
+      {
+        // If we have a background visual, check if it's a color visual and remove the render if transparent flag
+        ChangeBackgroundColorVisual( controlImpl, false );
+        break;
+      }
     }
   }
 }
@@ -168,6 +214,14 @@ void Control::SetBackgroundColor( const Vector4& color )
   map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
   map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
 
+  int clippingMode = ClippingMode::DISABLED;
+  if( ( Self().GetProperty( Actor::Property::CLIPPING_MODE ).Get( clippingMode ) ) &&
+      ( clippingMode == ClippingMode::CLIP_CHILDREN ) )
+  {
+    // If clipping-mode is set to CLIP_CHILDREN, then force visual to add the render even if transparent
+    map[ Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT ] = true;
+  }
+
   SetBackground( map );
 }