diff options
Diffstat (limited to 'src/drm/cairo-drm-gallium-surface.c')
-rw-r--r-- | src/drm/cairo-drm-gallium-surface.c | 179 |
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); |