Skip calculate corner radius opacity if possible at shader 73/317373/4
authorEunki Hong <eunkiki.hong@samsung.com>
Mon, 9 Sep 2024 14:08:01 +0000 (23:08 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Fri, 13 Sep 2024 02:22:20 +0000 (02:22 +0000)
Let we seperate potential calculation more detail, and
let we use only cheap operation as much as we can.

This feature have effort only if we use corner radius.
If we use cutout / borderline / blur radius, no effects.

Change-Id: I9742c6feab1e1ac161a76d1658fb6b51f647669b
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
dali-toolkit/internal/graphics/shaders/color-visual-shader.frag
dali-toolkit/internal/graphics/shaders/gradient-visual-shader.frag
dali-toolkit/internal/graphics/shaders/image-visual-shader.frag

index e4fae386d31a66a5d29a84d6ebe4a3fe15589414..5b917c6b5825d597b5c0304006ce26db4082b58a 100644 (file)
@@ -49,8 +49,11 @@ highp float gPotential = 0.0;
 highp float gPotentialRange = 0.0;
 highp float gMaxOutlinePotential = 0.0;
 highp float gMinOutlinePotential = 0.0;
+#ifdef IS_REQUIRED_BLUR
+#elif defined(IS_REQUIRED_BORDERLINE)
 highp float gMaxInlinePotential = 0.0;
 highp float gMinInlinePotential = 0.0;
+#endif
 
 void calculateCornerRadius(highp vec4 cornerRadius, highp vec2 position)
 {
@@ -63,10 +66,13 @@ void calculateCornerRadius(highp vec4 cornerRadius, highp vec2 position)
   );
 #endif
 }
-
-void calculatePosition(highp vec2 position, highp vec2 halfSizeOfRect, highp float currentBorderlineWidth)
+void calculateFragmentPosition(highp vec2 position, highp vec2 halfSizeOfRect)
 {
   gFragmentPosition = abs(position) - halfSizeOfRect;
+}
+
+void calculatePosition(highp float currentBorderlineWidth)
+{
   gCenterPosition = -gRadius;
 #ifdef IS_REQUIRED_BLUR
 #elif defined(IS_REQUIRED_BORDERLINE)
@@ -88,27 +94,24 @@ void setupMinMaxPotential(highp float currentBorderlineWidth)
   gMinOutlinePotential = gRadius - gPotentialRange;
 
 #ifdef IS_REQUIRED_BLUR
-  gMaxInlinePotential = gMaxOutlinePotential;
-  gMinInlinePotential = gMinOutlinePotential;
 #elif defined(IS_REQUIRED_BORDERLINE)
   gMaxInlinePotential = gMaxOutlinePotential - currentBorderlineWidth;
   gMinInlinePotential = gMinOutlinePotential - currentBorderlineWidth;
 #else
-  gMaxInlinePotential = gMaxOutlinePotential;
-  gMinInlinePotential = gMinOutlinePotential;
 #endif
 
   // reduce defect near edge of rounded corner.
-  gMaxOutlinePotential += clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, 1.0);
-  gMinOutlinePotential += clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, 1.0);
+  highp float heuristicEdgeCasePotential = clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, gPotentialRange);
+  gMaxOutlinePotential += heuristicEdgeCasePotential;
+  gMinOutlinePotential += heuristicEdgeCasePotential;
 }
 
 void PreprocessPotential(highp vec4 cornerRadius, highp vec2 position, highp vec2 halfSizeOfRect, highp float currentBorderlineWidth)
 {
   calculateCornerRadius(cornerRadius, position);
-  calculatePosition(position, halfSizeOfRect, currentBorderlineWidth);
+  calculateFragmentPosition(position, halfSizeOfRect);
+  calculatePosition(currentBorderlineWidth);
   calculatePotential();
-
   setupMinMaxPotential(currentBorderlineWidth);
 }
 #endif
@@ -333,25 +336,50 @@ void main()
 #ifdef IS_REQUIRED_ROUNDED_CORNER
     tempCornerRadius = vCornerRadius;
 #endif
-#ifdef IS_REQUIRED_BLUR
-#elif defined(IS_REQUIRED_BORDERLINE)
-    tempBorderlineWidth = borderlineWidth;
-#endif
-    PreprocessPotential(tempCornerRadius, vPosition, vRectSize, tempBorderlineWidth);
+    calculateCornerRadius(tempCornerRadius, vPosition);
+    calculateFragmentPosition(vPosition, vRectSize);
 #endif
 
 #ifdef IS_REQUIRED_BLUR
-#elif defined(IS_REQUIRED_BORDERLINE)
-    targetColor = convertBorderlineColor(targetColor);
-#endif
+    calculatePosition(tempBorderlineWidth);
+    calculatePotential();
+    setupMinMaxPotential(tempBorderlineWidth);
+
     OUT_COLOR = targetColor;
 
-#ifdef IS_REQUIRED_BLUR
     mediump float opacity = calculateBlurOpacity();
     OUT_COLOR.a *= opacity;
-#elif defined(IS_REQUIRED_ROUNDED_CORNER)
-    mediump float opacity = calculateCornerOpacity();
-    OUT_COLOR.a *= opacity;
+#else
+#if defined(IS_REQUIRED_ROUNDED_CORNER) && !defined(IS_REQUIRED_BORDERLINE)
+    // skip rounded corner calculate for performance
+    if(gFragmentPosition.x + gFragmentPosition.y < -(gRadius + vAliasMargin) * 2.0)
+    {
+      // Do nothing.
+      OUT_COLOR = targetColor;
+    }
+    else
+#endif
+    {
+#if defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE)
+#ifdef IS_REQUIRED_BORDERLINE
+      tempBorderlineWidth = borderlineWidth;
+#endif
+      calculatePosition(tempBorderlineWidth);
+      calculatePotential();
+      setupMinMaxPotential(tempBorderlineWidth);
+
+#ifdef IS_REQUIRED_BORDERLINE
+      targetColor = convertBorderlineColor(targetColor);
+#endif
+#endif
+
+      OUT_COLOR = targetColor;
+
+#ifdef IS_REQUIRED_ROUNDED_CORNER
+      mediump float opacity = calculateCornerOpacity();
+      OUT_COLOR.a *= opacity;
+#endif
+    }
 #endif
 
 #if defined(IS_REQUIRED_BLUR) || defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE)
index 73d0a735401bfd25ce2636486ae1f46ae85be6f1..301a0a877de89310dabbd2c96c20f68bb58e07dc 100644 (file)
@@ -41,8 +41,10 @@ highp float gPotential = 0.0;
 highp float gPotentialRange = 0.0;
 highp float gMaxOutlinePotential = 0.0;
 highp float gMinOutlinePotential = 0.0;
+#ifdef IS_REQUIRED_BORDERLINE
 highp float gMaxInlinePotential = 0.0;
 highp float gMinInlinePotential = 0.0;
+#endif
 
 void calculateCornerRadius()
 {
@@ -56,9 +58,13 @@ void calculateCornerRadius()
 #endif
 }
 
-void calculatePosition()
+void calculateFragmentPosition()
 {
   gFragmentPosition = abs(vPosition) - vRectSize;
+}
+
+void calculatePosition()
+{
   gCenterPosition = -gRadius;
 #ifdef IS_REQUIRED_BORDERLINE
   gCenterPosition += borderlineWidth * (clamp(borderlineOffset, -1.0, 1.0) + 1.0) * 0.5;
@@ -81,24 +87,22 @@ void setupMinMaxPotential()
 #ifdef IS_REQUIRED_BORDERLINE
   gMaxInlinePotential = gMaxOutlinePotential - borderlineWidth;
   gMinInlinePotential = gMinOutlinePotential - borderlineWidth;
-#else
-  gMaxInlinePotential = gMaxOutlinePotential;
-  gMinInlinePotential = gMinOutlinePotential;
 #endif
 
   // reduce defect near edge of rounded corner.
-  gMaxOutlinePotential += clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, 1.0);
-  gMinOutlinePotential += clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, 1.0);
+  highp float heuristicEdgeCasePotential = clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, gPotentialRange);
+  gMaxOutlinePotential += heuristicEdgeCasePotential;
+  gMinOutlinePotential += heuristicEdgeCasePotential;
 }
 
-void PreprocessPotential()
-{
-  calculateCornerRadius();
-  calculatePosition();
-  calculatePotential();
-
-  setupMinMaxPotential();
-}
+//void PreprocessPotential()
+//{
+//  calculateCornerRadius();
+//  calculateFragmentPosition();
+//  calculatePosition();
+//  calculatePotential();
+//  setupMinMaxPotential();
+//}
 #endif
 
 
@@ -205,18 +209,36 @@ void main()
   }
   else
   {
-    PreprocessPotential();
+    calculateCornerRadius();
+    calculateFragmentPosition();
+#endif
+
+#if defined(IS_REQUIRED_ROUNDED_CORNER) && !defined(IS_REQUIRED_BORDERLINE)
+    // skip length and etc potential calculation for performance
+    if(gFragmentPosition.x + gFragmentPosition.y < -(gRadius + vAliasMargin) * 2.0)
+    {
+      // Do nothing.
+      OUT_COLOR = textureColor;
+    }
+    else
+#endif
+    {
+#if defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE)
+      calculatePosition();
+      calculatePotential();
+      setupMinMaxPotential();
 #endif
 
 #ifdef IS_REQUIRED_BORDERLINE
-    textureColor = convertBorderlineColor(textureColor);
+      textureColor = convertBorderlineColor(textureColor);
 #endif
-    OUT_COLOR = textureColor;
+      OUT_COLOR = textureColor;
 
 #ifdef IS_REQUIRED_ROUNDED_CORNER
-    mediump float opacity = calculateCornerOpacity();
-    OUT_COLOR *= opacity;
+      mediump float opacity = calculateCornerOpacity();
+      OUT_COLOR *= opacity;
 #endif
+    }
 
 #if defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE)
   }
index 81d3e730c26ca0376b5a7a65d5a7337b15a03db7..9393692c531e5a2ccc93580e89c94fd97e09fb05 100644 (file)
@@ -78,8 +78,10 @@ highp float gPotential = 0.0;
 highp float gPotentialRange = 0.0;
 highp float gMaxOutlinePotential = 0.0;
 highp float gMinOutlinePotential = 0.0;
+#ifdef IS_REQUIRED_BORDERLINE
 highp float gMaxInlinePotential = 0.0;
 highp float gMinInlinePotential = 0.0;
+#endif
 
 void calculateCornerRadius()
 {
@@ -93,9 +95,13 @@ void calculateCornerRadius()
 #endif
 }
 
-void calculatePosition()
+void calculateFragmentPosition()
 {
   gFragmentPosition = abs(vPosition) - vRectSize;
+}
+
+void calculatePosition()
+{
   gCenterPosition = -gRadius;
 #ifdef IS_REQUIRED_BORDERLINE
   gCenterPosition += borderlineWidth * (clamp(borderlineOffset, -1.0, 1.0) + 1.0) * 0.5;
@@ -118,24 +124,22 @@ void setupMinMaxPotential()
 #ifdef IS_REQUIRED_BORDERLINE
   gMaxInlinePotential = gMaxOutlinePotential - borderlineWidth;
   gMinInlinePotential = gMinOutlinePotential - borderlineWidth;
-#else
-  gMaxInlinePotential = gMaxOutlinePotential;
-  gMinInlinePotential = gMinOutlinePotential;
 #endif
 
   // reduce defect near edge of rounded corner.
-  gMaxOutlinePotential += clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, 1.0);
-  gMinOutlinePotential += clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, 1.0);
+  highp float heuristicEdgeCasePotential = clamp(-min(gDiff.x, gDiff.y) / max(1.0, gRadius), 0.0, gPotentialRange);
+  gMaxOutlinePotential += heuristicEdgeCasePotential;
+  gMinOutlinePotential += heuristicEdgeCasePotential;
 }
 
-void PreprocessPotential()
-{
-  calculateCornerRadius();
-  calculatePosition();
-  calculatePotential();
-
-  setupMinMaxPotential();
-}
+//void PreprocessPotential()
+//{
+//  calculateCornerRadius();
+//  calculateFragmentPosition();
+//  calculatePosition();
+//  calculatePotential();
+//  setupMinMaxPotential();
+//}
 #endif
 
 #ifdef IS_REQUIRED_BORDERLINE
@@ -401,19 +405,37 @@ void main()
   else
 #endif
   {
-    PreprocessPotential();
+    calculateCornerRadius();
+    calculateFragmentPosition();
+#endif
+
+#if defined(IS_REQUIRED_ROUNDED_CORNER) && !defined(IS_REQUIRED_BORDERLINE) && !defined(IS_REQUIRED_DEBUG_VISUAL_SHADER)
+    // skip rounded corner calculate for performance
+    if(gFragmentPosition.x + gFragmentPosition.y < -(gRadius + vAliasMargin) * 2.0)
+    {
+      // Do nothing.
+      OUT_COLOR = textureColor;
+    }
+    else
+#endif
+    {
+#if defined(IS_REQUIRED_DEBUG_VISUAL_SHADER) || defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE)
+      calculatePosition();
+      calculatePotential();
+      setupMinMaxPotential();
 #endif
 
 #ifdef IS_REQUIRED_BORDERLINE
-    textureColor = convertBorderlineColor(textureColor);
+      textureColor = convertBorderlineColor(textureColor);
 #endif
-    OUT_COLOR = textureColor;
+      OUT_COLOR = textureColor;
 
 #ifdef IS_REQUIRED_ROUNDED_CORNER
-    mediump float opacity = calculateCornerOpacity();
-    OUT_COLOR.a *= opacity;
-    OUT_COLOR.rgb *= mix(1.0, opacity, preMultipliedAlpha);
+      mediump float opacity = calculateCornerOpacity();
+      OUT_COLOR.a *= opacity;
+      OUT_COLOR.rgb *= mix(1.0, opacity, preMultipliedAlpha);
 #endif
+    }
 
 #if defined(IS_REQUIRED_DEBUG_VISUAL_SHADER) || defined(IS_REQUIRED_ROUNDED_CORNER) || defined(IS_REQUIRED_BORDERLINE)
   }