From 3f0a966807f03a364edea0272ddf45f08ab7ce4f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sun, 30 Jan 2011 22:54:40 +0800 Subject: 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 6a8ae9c96c8..2610ebe0576 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 e5e55215b75..aa1e5dd280a 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 2db8cbcf7c8..6e5348a1ff2 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 3de3bbe12ed..e5357763b89 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 e42bad76492..936bf2e4e03 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 2a6bae8a630..bee6d84001d 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 cd251838e02..83b42609e03 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 45e5985c4bc..71491a5aa22 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 -- cgit v1.2.3