diff options
author | Igor Oliveira <igor.oliveira@openbossa.org> | 2010-06-10 09:21:30 -0400 |
---|---|---|
committer | Igor Oliveira <igor.oliveira@openbossa.org> | 2010-06-10 10:02:53 -0400 |
commit | 1228c6a89819dfe1052ad7accafe640271f6c36b (patch) | |
tree | d61b91d1e00699940160e4f873643613f4de3e39 | |
parent | 119d13f6f734b28a29e53c9832086043c401abf0 (diff) |
DRM/Gallium3D: implement fill method
Now it does not have support for antialiasing.
-rw-r--r-- | src/drm/cairo-drm-gallium-surface.c | 118 |
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 |