summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-06-10 09:21:30 -0400
committerIgor Oliveira <igor.oliveira@openbossa.org>2010-06-10 10:02:53 -0400
commit1228c6a89819dfe1052ad7accafe640271f6c36b (patch)
treed61b91d1e00699940160e4f873643613f4de3e39
parent119d13f6f734b28a29e53c9832086043c401abf0 (diff)
DRM/Gallium3D: implement fill method
Now it does not have support for antialiasing.
-rw-r--r--src/drm/cairo-drm-gallium-surface.c118
1 files changed, 98 insertions, 20 deletions
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c
index 0fc395ed..c15a2c62 100644
--- a/src/drm/cairo-drm-gallium-surface.c
+++ b/src/drm/cairo-drm-gallium-surface.c
@@ -664,6 +664,13 @@ typedef struct _gallium_path {
double *points;
int count;
+ float minx;
+ float miny;
+ float maxx;
+ float maxy;
+
+ float width;
+
struct pipe_resource *buf;
} gallium_path_t;
@@ -685,6 +692,8 @@ _gallium_init_path (gallium_path_t *path)
}
path->count = 0;
+ path->minx = path->miny = path->maxx = path->maxy = 0;
+
CLEAN:
return status;
}
@@ -720,14 +729,19 @@ _gallium_append_point (gallium_path_t *path, const cairo_point_t *point)
path->count += 2;
+ path->minx = MIN2(path->points[path->count], path->minx);
+ path->maxx = MAX2(path->points[path->count], path->maxx);
+
+ path->miny = MIN2(path->points[path->count + 1], path->miny);
+ path->maxy = MAX2(path->points[path->count + 1], path->maxy);
+
CLEAN:
return status;
}
static void
draw_path (gallium_device_t *device,
- gallium_path_t *path,
- const cairo_stroke_style_t *style)
+ gallium_path_t *path)
{
const int components = 2;
struct pipe_context *ctx = device->pipe;
@@ -756,7 +770,7 @@ draw_path (gallium_device_t *device,
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
cso_set_vertex_elements(device->cso, 1, &velement);
- rasterizer.line_width = style->line_width;
+ rasterizer.line_width = path->width;
cso_save_rasterizer(device->cso);
cso_set_rasterizer(device->cso, &rasterizer);
@@ -767,6 +781,49 @@ draw_path (gallium_device_t *device,
cso_restore_rasterizer(device->cso);
}
+static void
+_gallium_draw_quad(gallium_surface_t *surface,
+ float x0, float y0,
+ float x1, float y1)
+{
+ gallium_device_t *device = gallium_device(surface);
+ struct pipe_resource *buf;
+
+ float vertices[4][2][4] = {
+ {
+ { x0, y0, 0.0f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 1.0f }
+ },
+ {
+ { x0, y1, 0.0f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 1.0f }
+ },
+ {
+ { x1, y1, 0.0f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 1.0f }
+ },
+ {
+ { x0, 0.0f, 0.0f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 1.0f }
+ }
+ };
+
+ buf = pipe_user_buffer_create (device->pipe->screen,
+ vertices,
+ sizeof(vertices),
+ PIPE_BIND_VERTEX_BUFFER);
+
+ if (buf != NULL) {
+ cso_set_vertex_elements (device->cso, 2, surface->velem);
+ util_draw_vertex_buffer (device->pipe, buf, 0,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4,
+ 2);
+
+ pipe_resource_reference (&buf, NULL);
+ }
+}
+
static cairo_status_t
_gallium_move_to_line_to (void *closure, const cairo_point_t *point)
{
@@ -867,7 +924,10 @@ gallium_surface_stroke (void *abstract_surface,
gallium_path->ctm_inverse = ctm_inverse;
_gallium_path_from_cairo(gallium_path, path);
- draw_path(device, gallium_path, style);
+
+ gallium_path->width = style->line_width;
+
+ draw_path(device, gallium_path);
_gallium_finish_path(gallium_path);
return CAIRO_STATUS_SUCCESS;
@@ -875,26 +935,44 @@ gallium_surface_stroke (void *abstract_surface,
static cairo_int_status_t
gallium_surface_fill (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_fill_rule_t fill_rule,
- double tolerance,
- cairo_antialias_t antialias,
- cairo_clip_t *clip)
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_clip_t *clip)
{
gallium_surface_t *surface = abstract_surface;
+ gallium_path_t *gallium_path;
+ gallium_device_t *device = gallium_device(surface);
+ struct pipe_depth_stencil_alpha_state st;
- if (surface->fallback == NULL) {
- /* XXX insert magic */
- surface->fallback = gallium_surface_map_to_image (surface);
- }
+ _gallium_init_path(gallium_path);
+ _gallium_path_from_cairo(gallium_path, path);
- return _cairo_surface_fill (surface->fallback,
- op, source,
- path, fill_rule,
- tolerance, antialias,
- clip);
+ // initialize stencil
+ st.stencil[0].enabled = 1;
+ st.stencil[0].func = PIPE_FUNC_ALWAYS;
+ st.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
+ st.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
+ st.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
+ st.stencil[0].valuemask = 1;
+ cso_set_depth_stencil_alpha(device->cso, &st);
+ draw_path(device, gallium_path);
+
+ st.stencil[0].func = PIPE_FUNC_EQUAL;
+ st.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
+ st.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
+ st.stencil[0].zpass_op = PIPE_STENCIL_OP_KEEP;
+ st.stencil[0].valuemask = 1;
+ cso_set_depth_stencil_alpha(device->cso, &st);
+
+ _gallium_draw_quad(surface,
+ gallium_path->minx, gallium_path->miny,
+ gallium_path->maxx, gallium_path->maxy);
+ _gallium_finish_path(gallium_path);
+ cso_restore_depth_stencil_alpha(device->cso);
}
static cairo_int_status_t