Add BlendMode::ON_WITHOUT_CULL to keep rendering even Transparent. 69/263369/5
authorEunki Hong <eunkiki.hong@samsung.com>
Wed, 1 Sep 2021 07:35:59 +0000 (00:35 -0700)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 8 Sep 2021 09:56:55 +0000 (18:56 +0900)
Previously, DevelRenderer always merged into uColor.a value.
This situation usally have no problem.

But when we want to use both MIX_COLOR and BORDERLINE_COLOR
there was no way to split Actor's opacity and MIX_COLOR's opacity.
So BORDERLINE_COLOR.a is always pre-multiplired by MIX_COLOR.a.
And also, when MIX_COLOR.a is zero, There is no way to render BORDERLINE only.

This patch try to fix this issue.

First, Add some flag keep-rendering logic.
Second, Turn on that flag only if borderline required (dali-toolkit)
Third, Add new custom uniform which have same value with actor's color (dali-toolkit)

Change-Id: I7115ecfa252eaaa862e4115b7fb41f208ca7026f
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/utc-Dali-Renderer.cpp
dali/devel-api/rendering/renderer-devel.h
dali/internal/event/rendering/renderer-impl.cpp
dali/internal/update/manager/render-instruction-processor.cpp
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/public-api/rendering/renderer.h

index 5bd95d2..3a94cce 100644 (file)
@@ -814,7 +814,7 @@ int UtcDaliRendererSetBlendMode01(void)
   Renderer renderer = Renderer::New(geometry, shader);
 
   Actor actor = Actor::New();
-  actor.SetProperty(Actor::Property::OPACITY, 0.98f);
+  actor.SetProperty(Actor::Property::OPACITY, 1.0f);
   actor.AddRenderer(renderer);
   actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
   application.GetScene().Add(actor);
@@ -1203,6 +1203,71 @@ int UtcDaliRendererSetBlendMode08b(void)
   END_TEST;
 }
 
+int UtcDaliRendererSetBlendMode09(void)
+{
+  TestApplication application;
+
+  tet_infoline("Test setting the blend mode to on_without_cull with an opaque color renders with blending enabled");
+
+  Geometry geometry = CreateQuadGeometry();
+  Shader   shader   = CreateShader();
+  Renderer renderer = Renderer::New(geometry, shader);
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::OPACITY, 1.0f);
+  actor.AddRenderer(renderer);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+  application.GetScene().Add(actor);
+
+  renderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON_WITHOUT_CULL);
+
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace(true);
+
+  application.SendNotification();
+  application.Render();
+
+  TraceCallStack&             glEnableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack::NamedParams params;
+  params["cap"] << std::hex << GL_BLEND;
+  DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", params));
+
+  END_TEST;
+}
+
+int UtcDaliRendererSetBlendMode09b(void)
+{
+  TestApplication application;
+
+  tet_infoline("Test setting the blend mode to on_without_cull with an transparent color renders with blending enabled");
+
+  Geometry geometry = CreateQuadGeometry();
+  Shader   shader   = CreateShader();
+  Renderer renderer = Renderer::New(geometry, shader);
+
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::OPACITY, 0.0f);
+  actor.AddRenderer(renderer);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+  application.GetScene().Add(actor);
+
+  renderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON_WITHOUT_CULL);
+
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace(true);
+  glAbstraction.EnableDrawCallTrace(true);
+
+  application.SendNotification();
+  application.Render();
+
+  TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace();
+  DALI_TEST_CHECK(glEnableStack.FindMethod("Enable"));
+
+  DALI_TEST_CHECK(glAbstraction.GetDrawTrace().FindMethod("DrawElements"));
+
+  END_TEST;
+}
+
 int UtcDaliRendererGetBlendMode(void)
 {
   TestApplication application;
@@ -1227,6 +1292,11 @@ int UtcDaliRendererGetBlendMode(void)
   mode = renderer.GetProperty<int>(Renderer::Property::BLEND_MODE);
   DALI_TEST_EQUALS(static_cast<BlendMode::Type>(mode), BlendMode::OFF, TEST_LOCATION);
 
+  // ON_WITHOUT_CULL
+  renderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON_WITHOUT_CULL);
+  mode = renderer.GetProperty<int>(Renderer::Property::BLEND_MODE);
+  DALI_TEST_EQUALS(static_cast<BlendMode::Type>(mode), BlendMode::ON_WITHOUT_CULL, TEST_LOCATION);
+
   END_TEST;
 }
 
index 6ffa32b..5cfc8fd 100644 (file)
@@ -144,7 +144,7 @@ enum Type
    * @brief name "blendEquation", type INTEGER
    * @note The default value is BlendEquation::ADD
    */
-  BLEND_EQUATION,
+  BLEND_EQUATION = STENCIL_OPERATION_ON_Z_PASS + 3,
 };
 } // namespace Property
 
index 01cb695..4342d90 100644 (file)
@@ -79,6 +79,7 @@ DALI_ENUM_TO_STRING_TABLE_BEGIN(BLEND_MODE)
   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, OFF)
   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, AUTO)
   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, ON)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, ON_WITHOUT_CULL)
 DALI_ENUM_TO_STRING_TABLE_END(BLEND_MODE)
 
 DALI_ENUM_TO_STRING_TABLE_BEGIN(BLEND_EQUATION)
index 64ba230..5488ab7 100644 (file)
@@ -167,7 +167,10 @@ inline void AddRendererToRenderList(BufferIndex         updateBufferIndex,
   if(inside)
   {
     Renderer::OpacityType opacityType = renderable.mRenderer ? renderable.mRenderer->GetOpacityType(updateBufferIndex, *renderable.mNode) : Renderer::OPAQUE;
-    if(opacityType != Renderer::TRANSPARENT || node->GetClippingMode() != ClippingMode::DISABLED)
+
+    // We can skip render when node is not clipping and transparent
+    const bool skipRender(opacityType == Renderer::TRANSPARENT && node->GetClippingMode() == ClippingMode::DISABLED);
+    if(!skipRender)
     {
       // Get the next free RenderItem.
       RenderItem& item = renderList.GetNextFreeItem();
index 55d4ec1..7be96da 100644 (file)
@@ -671,6 +671,11 @@ Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, co
 
   switch(mBlendMode)
   {
+    case BlendMode::ON_WITHOUT_CULL: // If the renderer should always be use blending and never want to be transparent by alpha.
+    {
+      opacityType = Renderer::TRANSLUCENT;
+      break;
+    }
     case BlendMode::ON: // If the renderer should always be use blending
     {
       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
index 6af1b32..d384918 100644 (file)
@@ -60,9 +60,10 @@ namespace BlendMode
  */
 enum Type
 {
-  OFF,  ///< Blending is disabled.                                                    @SINCE_1_1.43
-  AUTO, ///< Blending is enabled if there is alpha channel. This is the default mode. @SINCE_1_1.43
-  ON    ///< Blending is enabled.                                                     @SINCE_1_1.43
+  OFF,            ///< Blending is disabled.                                                    @SINCE_1_1.43
+  AUTO,           ///< Blending is enabled if there is alpha channel. This is the default mode. @SINCE_1_1.43
+  ON,             ///< Blending is enabled.                                                     @SINCE_1_1.43
+  ON_WITHOUT_CULL ///< Blending is enabled, and don't cull the renderer                         @SINCE_2_0.43
 };
 
 } // namespace BlendMode