Mesa (master): st/vega: Disable blending when the paint is opaque.

Chia-I Wu olv at kemper.freedesktop.org
Sun Jan 30 15:23:13 UTC 2011


Module: Mesa
Branch: master
Commit: 3f0a966807f03a364edea0272ddf45f08ab7ce4f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3f0a966807f03a364edea0272ddf45f08ab7ce4f

Author: Chia-I Wu <olv at lunarg.com>
Date:   Sun Jan 30 22:54:40 2011 +0800

st/vega: Disable blending when the paint is opaque.

When the paint is opaque (currently, solid color with alpha 1.0f), no
blending is needed for VG_BLEND_SRC_OVER.  This eliminates the serious
performance hit introduced by 859106f196ade77f59f8787b071739901cd1a843
for a common scenario.

---

 src/gallium/state_trackers/vega/api_paint.c  |   10 +++++++++-
 src/gallium/state_trackers/vega/api_params.c |    6 ++++++
 src/gallium/state_trackers/vega/paint.c      |    7 +++++++
 src/gallium/state_trackers/vega/paint.h      |    1 +
 src/gallium/state_trackers/vega/renderer.c   |    7 ++++++-
 src/gallium/state_trackers/vega/shader.c     |    2 ++
 src/gallium/state_trackers/vega/vg_context.c |    5 +++--
 src/gallium/state_trackers/vega/vg_context.h |    4 +++-
 8 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/gallium/state_trackers/vega/api_paint.c b/src/gallium/state_trackers/vega/api_paint.c
index 6a8ae9c..2610ebe 100644
--- a/src/gallium/state_trackers/vega/api_paint.c
+++ b/src/gallium/state_trackers/vega/api_paint.c
@@ -72,6 +72,8 @@ void vegaSetPaint(VGPaint paint, VGbitfield paintModes)
    if (paintModes & VG_STROKE_PATH) {
       ctx->state.vg.stroke_paint = handle_to_paint(paint);
    }
+
+   ctx->state.dirty |= PAINT_DIRTY;
 }
 
 VGPaint vegaGetPaint(VGPaintMode paintMode)
@@ -98,6 +100,7 @@ VGPaint vegaGetPaint(VGPaintMode paintMode)
 void vegaSetColor(VGPaint paint, VGuint rgba)
 {
    struct vg_context *ctx = vg_current_context();
+   struct vg_paint *p;
 
    if (paint == VG_INVALID_HANDLE) {
       vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
@@ -109,7 +112,12 @@ void vegaSetColor(VGPaint paint, VGuint rgba)
       return;
    }
 
-   paint_set_colori(handle_to_paint(paint), rgba);
+   p = handle_to_paint(paint);
+   paint_set_colori(p, rgba);
+
+   if (ctx->state.vg.fill_paint == p ||
+       ctx->state.vg.stroke_paint == p)
+      ctx->state.dirty |= PAINT_DIRTY;
 }
 
 VGuint vegaGetColor(VGPaint paint)
diff --git a/src/gallium/state_trackers/vega/api_params.c b/src/gallium/state_trackers/vega/api_params.c
index e5e5521..aa1e5dd 100644
--- a/src/gallium/state_trackers/vega/api_params.c
+++ b/src/gallium/state_trackers/vega/api_params.c
@@ -1135,6 +1135,9 @@ void vegaSetParameterfv(VGHandle object,
       else {
          struct vg_paint *paint = handle_to_paint(object);
          paint_set_color(paint, values);
+         if (ctx->state.vg.fill_paint == paint ||
+             ctx->state.vg.stroke_paint == paint)
+            ctx->state.dirty |= PAINT_DIRTY;
       }
    }
       break;
@@ -1248,6 +1251,9 @@ void vegaSetParameteriv(VGHandle object,
       else {
          struct vg_paint *paint = handle_to_paint(object);
          paint_set_coloriv(paint, values);
+         if (ctx->state.vg.fill_paint == paint ||
+             ctx->state.vg.stroke_paint == paint)
+            ctx->state.dirty |= PAINT_DIRTY;
       }
    }
       break;
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index 2db8cbc..6e5348a 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -748,3 +748,10 @@ void paint_fill_constant_buffer(struct vg_paint *paint,
       abort();
    }
 }
+
+VGboolean paint_is_opaque(struct vg_paint *paint)
+{
+   /* TODO add other paint types and make sure PAINT_DIRTY gets set */
+   return (paint->type == VG_PAINT_TYPE_COLOR &&
+           floatsEqual(paint->solid.color[3], 1.0f));
+}
diff --git a/src/gallium/state_trackers/vega/paint.h b/src/gallium/state_trackers/vega/paint.h
index 3de3bbe..e535776 100644
--- a/src/gallium/state_trackers/vega/paint.h
+++ b/src/gallium/state_trackers/vega/paint.h
@@ -118,5 +118,6 @@ void paint_fill_constant_buffer(struct vg_paint *paint,
                                 const struct matrix *mat,
                                 void *buffer);
 
+VGboolean paint_is_opaque(struct vg_paint *paint);
 
 #endif
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index e42bad7..936bf2e 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -28,6 +28,7 @@
 #include "renderer.h"
 
 #include "vg_context.h"
+#include "paint.h" /* for paint_is_opaque */
 
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
@@ -1289,7 +1290,11 @@ static void renderer_validate_blend(struct renderer *renderer,
       blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
       break;
    case VG_BLEND_SRC_OVER:
-      if (!util_format_has_alpha(fb_format)) {
+      if (paint_is_opaque(state->fill_paint) &&
+          paint_is_opaque(state->stroke_paint)) {
+         /* no blending */
+      }
+      else if (!util_format_has_alpha(fb_format)) {
          blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_SRC_ALPHA;
          blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
          blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index 2a6bae8..bee6d84 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -134,6 +134,8 @@ static VGboolean blend_use_shader(struct vg_context *ctx)
    switch (ctx->state.vg.blend_mode) {
    case VG_BLEND_SRC_OVER:
       advanced_blending =
+         (!paint_is_opaque(ctx->state.vg.fill_paint) ||
+          !paint_is_opaque(ctx->state.vg.stroke_paint)) &&
          util_format_has_alpha(ctx->draw_buffer->strb->format);
       break;
    case VG_BLEND_DST_OVER:
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index cd25183..83b4260 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -408,8 +408,9 @@ void vg_validate_state(struct vg_context *ctx)
    if (vg_context_update_depth_stencil_rb(ctx, stfb->width, stfb->height))
       ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
 
-   /* blend state depends on fb format */
-   if (ctx->state.dirty & FRAMEBUFFER_DIRTY)
+   /* blend state depends on fb format and paint color */
+   if ((ctx->state.dirty & FRAMEBUFFER_DIRTY) ||
+       (ctx->state.dirty & PAINT_DIRTY))
       ctx->state.dirty |= BLEND_DIRTY;
 
    renderer_validate(ctx->renderer, ctx->state.dirty,
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index 45e5985..71491a5 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -81,10 +81,12 @@ enum dirty_state {
    BLEND_DIRTY         = 1 << 0,
    FRAMEBUFFER_DIRTY   = 1 << 1,
    DEPTH_STENCIL_DIRTY = 1 << 2,
+   PAINT_DIRTY         = 1 << 3,
 
    ALL_DIRTY           = BLEND_DIRTY |
                          FRAMEBUFFER_DIRTY |
-                         DEPTH_STENCIL_DIRTY
+                         DEPTH_STENCIL_DIRTY |
+                         PAINT_DIRTY
 };
 
 struct vg_context




More information about the mesa-commit mailing list