summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-07-21 08:23:50 -0400
committerIgor Oliveira <igor.oliveira@openbossa.org>2010-07-21 08:23:50 -0400
commit67262f2f88a96cf9d063a27bc6314b218f24c02c (patch)
tree89b4e42085a2347ab39f5fcbff7b6252e1e1ffb0
parent2eaf9bc5892d537413e962f423c6c7ed248fcf87 (diff)
DRM/Gallium3d: initial implementation of blend operations,
uses src and dst factors
-rw-r--r--src/drm/cairo-drm-gallium-surface.c105
1 files changed, 95 insertions, 10 deletions
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c
index cb2fdbdb..a67edd38 100644
--- a/src/drm/cairo-drm-gallium-surface.c
+++ b/src/drm/cairo-drm-gallium-surface.c
@@ -572,6 +572,94 @@ _gallium_set_states(void *abstract_surface)
cso_set_viewport (device->cso, &device->viewport);
}
+static void
+_gallium_blend_mode(gallium_surface_t *surface,
+ cairo_operator_t mode)
+{
+ struct pipe_blend_state *blend = &surface->blend;
+
+ blend->rt[0].blend_enable = 1;
+ blend->rt[0].colormask = PIPE_MASK_RGBA;
+
+ switch (mode) {
+ case CAIRO_OPERATOR_CLEAR:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ break;
+ case CAIRO_OPERATOR_SOURCE:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ break;
+ case CAIRO_OPERATOR_OVER:
+ 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;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ break;
+ case CAIRO_OPERATOR_IN:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ break;
+ case CAIRO_OPERATOR_OUT:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ break;
+ case CAIRO_OPERATOR_ATOP:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ break;
+ case CAIRO_OPERATOR_DEST:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ break;
+ case CAIRO_OPERATOR_DEST_OVER:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ break;
+ case CAIRO_OPERATOR_DEST_IN:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ break;
+ case CAIRO_OPERATOR_DEST_OUT:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ break;
+ case CAIRO_OPERATOR_DEST_ATOP:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ break;
+ case CAIRO_OPERATOR_XOR:
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ break;
+ case CAIRO_OPERATOR_ADD:
+ case CAIRO_OPERATOR_SATURATE:
+ break;
+ }
+}
+
static cairo_status_t
gallium_surface_flush (void *abstract_surface)
{
@@ -994,6 +1082,7 @@ _gallium_fill (void *abstract_surface,
struct pipe_depth_stencil_alpha_state st;
struct pipe_stencil_ref sr;
+
struct pipe_surface *zsurface;
struct pipe_resource *resource;
{
@@ -1237,11 +1326,6 @@ gallium_surface_paint (void *abstract_surface,
gallium_shader_t *shader = gallium_device(surface)->shader;
cairo_status_t status;
- if (surface->fallback == NULL) {
- /* XXX insert magic */
- surface->fallback = gallium_surface_map_to_image (surface);
- }
-
status = _gallium_surface_clip (surface, clip);
if (unlikely (status))
return status;
@@ -1329,6 +1413,8 @@ gallium_surface_stroke (void *abstract_surface,
add_convex_quad,
gallium_stroke);
+ _gallium_blend_mode(surface, op);
+
{
struct list_head *head, *next;
@@ -1344,7 +1430,6 @@ gallium_surface_stroke (void *abstract_surface,
gallium_surface_flush(abstract_surface);
-
return CAIRO_STATUS_SUCCESS;
}
@@ -1374,14 +1459,14 @@ gallium_surface_fill (void *abstract_surface,
}
_gallium_set_states(abstract_surface);
-
gallium_stroke = _gallium_init_stroke();
gallium_stroke->gallium_ctm = &surface->gallium_ctm;
_gallium_path_from_cairo(gallium_stroke, path);
- _gallium_fill(abstract_surface, gallium_stroke, fill_rule);
+ _gallium_blend_mode(surface, op);
+ status = _gallium_fill(abstract_surface, gallium_stroke, fill_rule);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
static cairo_int_status_t
@@ -1792,7 +1877,7 @@ _cairo_drm_gallium_device_create (int fd, dev_t dev, int vendor_id, int chip_id)
//device->drm.surface.flink = gallium_surface_flink;
device->drm.surface.flink = NULL;
- device->drm.device.flush = gallium_surface_flush;
+ device->drm.device.flush = NULL;
device->drm.device.throttle = NULL;
device->drm.device.destroy = gallium_device_destroy;