if (paintModes & VG_STROKE_PATH) {
ctx->state.vg.stroke_paint = handle_to_paint(paint);
}
+
+ ctx->state.dirty |= PAINT_DIRTY;
}
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);
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)
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;
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;
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));
+}
const struct matrix *mat,
void *buffer);
+VGboolean paint_is_opaque(struct vg_paint *paint);
#endif
#include "renderer.h"
#include "vg_context.h"
+#include "paint.h" /* for paint_is_opaque */
#include "pipe/p_context.h"
#include "pipe/p_state.h"
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;
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:
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,
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