summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <itrindade.oliveira@gmail.com>2010-06-13 08:44:25 -0400
committerIgor Oliveira <igor.oliveira@openbossa.org>2010-06-19 09:34:13 -0400
commitbd11c8f410f702f80a9add7137b82522554c4c07 (patch)
tree2d16cb47fd48a57d19620cfb9360cced23e74ff5
parent1228c6a89819dfe1052ad7accafe640271f6c36b (diff)
DRM/Gallium3D: implement clip method.
The clip method is done using depth buffer test.
-rw-r--r--src/drm/cairo-drm-gallium-surface.c179
1 files changed, 115 insertions, 64 deletions
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c
index c15a2c62..7597b9f3 100644
--- a/src/drm/cairo-drm-gallium-surface.c
+++ b/src/drm/cairo-drm-gallium-surface.c
@@ -600,63 +600,6 @@ gallium_surface_flush (void *abstract_surface)
return status;
}
-static void
-_gallium_surface_paint_solid(gallium_surface_t *surface, const cairo_pattern_t *pattern)
-{
- cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
-
- surface->paint.solid_color[0] = solid->color.red;
- surface->paint.solid_color[1] = solid->color.green;
- surface->paint.solid_color[2] = solid->color.blue;
- surface->paint.solid_color[3] = solid->color.alpha;
-}
-
-static cairo_int_status_t
-gallium_surface_paint (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_clip_t *clip)
-{
- gallium_surface_t *surface = 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);
- }
-
- if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
- _gallium_surface_paint_solid(surface, source);
- setup_constant_buffer(shader, &surface->paint.solid_color[0], 4*sizeof(float));
- setup_shader(shader, SOLID_FILL);
- status = CAIRO_STATUS_SUCCESS;
- } else {
- status = _cairo_surface_paint (surface->fallback, op, source, clip);
- }
-
- return status;
-}
-
-static cairo_int_status_t
-gallium_surface_mask (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- const cairo_pattern_t *mask,
- cairo_clip_t *clip)
-{
- gallium_surface_t *surface = abstract_surface;
-
- if (surface->fallback == NULL) {
- /* XXX insert magic */
- surface->fallback = gallium_surface_map_to_image (surface);
- }
-
- return _cairo_surface_mask (surface->fallback,
- op, source, mask,
- clip);
-}
-
#define MIN_POINTS 10
typedef struct _gallium_path {
@@ -772,13 +715,14 @@ draw_path (gallium_device_t *device,
rasterizer.line_width = path->width;
- cso_save_rasterizer(device->cso);
- cso_set_rasterizer(device->cso, &rasterizer);
+ //FIXME: we need surface
+// cso_save_rasterizer(device->cso);
+// cso_set_rasterizer(device->cso, &rasterizer);
ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLE_FAN,
0, path->count);
- cso_restore_rasterizer(device->cso);
+// cso_restore_rasterizer(device->cso);
}
static void
@@ -903,6 +847,102 @@ _gallium_path_from_cairo (gallium_path_t *gallium_path, const cairo_path_fixed_t
assert (status == CAIRO_STATUS_SUCCESS);
}
+static cairo_status_t
+_gallium_surface_clip (gallium_surface_t *abstract_surface,
+ cairo_clip_t *clip)
+{
+ if (clip != NULL) {
+ 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;
+ struct pipe_scissor_state scissor;
+
+ _gallium_init_path(gallium_path);
+ _gallium_path_from_cairo(gallium_path, &clip->path->path);
+
+ st.depth.writemask = 1;
+ st.depth.func = PIPE_FUNC_ALWAYS;
+ st.depth.enabled = 1;
+ cso_set_depth_stencil_alpha(device->cso, &st);
+ device->pipe->clear(device->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0);
+
+ surface->rasterizer.gl_rasterization_rules = 1;
+ surface->rasterizer.scissor = 1;
+
+ scissor.minx = gallium_path->minx;
+ scissor.miny = gallium_path->miny;
+ scissor.maxx = gallium_path->maxx;
+ scissor.maxy = gallium_path->maxy;
+
+ _gallium_finish_path(gallium_path);
+ _gallium_draw_quad(device->pipe, scissor.minx, scissor.miny, scissor.maxx, scissor.maxy);
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_gallium_surface_paint_solid(gallium_surface_t *surface, const cairo_pattern_t *pattern)
+{
+ cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
+
+ surface->paint.solid_color[0] = solid->color.red;
+ surface->paint.solid_color[1] = solid->color.green;
+ surface->paint.solid_color[2] = solid->color.blue;
+ surface->paint.solid_color[3] = solid->color.alpha;
+}
+
+static cairo_int_status_t
+gallium_surface_paint (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_clip_t *clip)
+{
+ gallium_surface_t *surface = 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;
+
+ if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
+ _gallium_surface_paint_solid(surface, source);
+ setup_constant_buffer(shader, &surface->paint.solid_color[0], 4*sizeof(float));
+ setup_shader(shader, SOLID_FILL);
+ status = CAIRO_STATUS_SUCCESS;
+ } else {
+ status = _cairo_surface_paint (surface->fallback, op, source, clip);
+ }
+
+ return status;
+}
+
+static cairo_int_status_t
+gallium_surface_mask (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask,
+ cairo_clip_t *clip)
+{
+ gallium_surface_t *surface = abstract_surface;
+
+ if (surface->fallback == NULL) {
+ /* XXX insert magic */
+ surface->fallback = gallium_surface_map_to_image (surface);
+ }
+
+ return _cairo_surface_mask (surface->fallback,
+ op, source, mask,
+ clip);
+}
+
static cairo_int_status_t
gallium_surface_stroke (void *abstract_surface,
cairo_operator_t op,
@@ -918,6 +958,11 @@ gallium_surface_stroke (void *abstract_surface,
gallium_surface_t *surface = abstract_surface;
gallium_path_t *gallium_path;
gallium_device_t *device = gallium_device(surface);
+ cairo_status_t status;
+
+ status = _gallium_surface_clip (surface, clip);
+ if (unlikely (status))
+ return status;
_gallium_init_path(gallium_path);
@@ -930,23 +975,29 @@ gallium_surface_stroke (void *abstract_surface,
draw_path(device, gallium_path);
_gallium_finish_path(gallium_path);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
+// implement clip
static cairo_int_status_t
gallium_surface_fill (void *abstract_surface,
- cairo_operator_t op,
+ cairo_operator_t op,
const cairo_pattern_t *source,
cairo_path_fixed_t *path,
- cairo_fill_rule_t fill_rule,
+ cairo_fill_rule_t fill_rule,
double tolerance,
- cairo_antialias_t antialias,
+ 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;
+ cairo_status_t status;
+
+ status = _gallium_surface_clip (surface, clip);
+ if (unlikely (status))
+ return status;
_gallium_init_path(gallium_path);
_gallium_path_from_cairo(gallium_path, path);