summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-07-11 17:53:31 -0400
committerIgor Oliveira <igor.oliveira@openbossa.org>2010-07-11 22:18:25 -0400
commit5ba35782a0aa8cda1db3bc5f23c0133c5cb523bb (patch)
treeb746225d7d39b2c9586d61ecf5fb3f726bd55065
parentf9799a5ce4512accafb08de07b0f998b83027d2d (diff)
DRM/Gallium3D: implement stroke styles using to_shape helper from cairo, and
use cairo_matrix_* to convert the cairo coordinate system to gallium coordinate system
-rw-r--r--src/drm/cairo-drm-gallium-surface.c440
1 files changed, 260 insertions, 180 deletions
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c
index 415067ed..3b25b585 100644
--- a/src/drm/cairo-drm-gallium-surface.c
+++ b/src/drm/cairo-drm-gallium-surface.c
@@ -68,8 +68,6 @@
#define MAX_CONTANTS 20
-int draw_operation = 0;
-
typedef enum _shader_type shadertype_t;
typedef struct _gallium_paint gallium_paint_t;
@@ -120,6 +118,7 @@ struct _gallium_surface {
struct pipe_resource *texture;
struct pipe_transfer *map_transfer;
gallium_paint_t paint;
+ cairo_matrix_t gallium_ctm;
struct pipe_resource *vbuf;
struct pipe_vertex_element velem[2];
@@ -659,6 +658,8 @@ struct _gallium_stroke {
float maxx;
float maxy;
+ cairo_matrix_t *gallium_ctm;
+
float line_width;
};
@@ -679,13 +680,14 @@ _gallium_init_path ()
}
path->count = 0;
- path->minx = path->miny = path->maxx = path->maxy = 0;
+ path->minx = path->miny = 1.0;
+ path->maxx = path->maxy = 0.0;
CLEAN:
return path;
}
-static cairo_status_t
+static void
_gallium_finish_path (gallium_path_t *path)
{
if (path->count != 0)
@@ -709,7 +711,7 @@ _gallium_init_stroke()
}
static cairo_status_t
-_gallium_append_point (gallium_path_t *path, const cairo_point_t *point)
+_gallium_append_point (gallium_path_t *path, double x, double y)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
@@ -725,8 +727,8 @@ _gallium_append_point (gallium_path_t *path, const cairo_point_t *point)
path->points = new_points;
}
- path->points[path->count] = _cairo_fixed_to_double (point->x);
- path->points[path->count + 1] = _cairo_fixed_to_double (point->y);
+ path->points[path->count] = x;
+ path->points[path->count + 1] = y;
printf("%f %f", path->points[path->count], path->points[path->count +1]);
@@ -756,12 +758,15 @@ draw_path (gallium_surface_t *surface,
int vert_size = path->count * sizeof(float);
int num_vert = path->count * 0.5;
- if (path->buf == NULL) {
- path->buf = pipe_buffer_create(device->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, vert_size);
- pipe_buffer_write(device->pipe, path->buf, 0, vert_size, path->points);
- device->pipe->set_constant_buffer(device->pipe, PIPE_SHADER_VERTEX, 0, path->buf);
+ if (path->buf != NULL) {
+ pipe_resource_reference(&path->buf, NULL);
}
+ path->buf= pipe_user_buffer_create(device->pipe->screen,
+ path->points,
+ vert_size,
+ PIPE_BIND_VERTEX_BUFFER);
+
memset(&vbuffer, 0, sizeof(vbuffer));
vbuffer.buffer = path->buf;
// We just have x and y components
@@ -826,11 +831,15 @@ static cairo_status_t
_gallium_move_to (void *closure, const cairo_point_t *point)
{
gallium_stroke_t *stroke = closure;
- printf("move to\n");
+
+ const double x = _cairo_fixed_to_double(point->x);
+ const double y = _cairo_fixed_to_double(point->y);
//if (path->ctm_inverse)
// cairo_matrix_transform_point (path->ctm_inverse, point->x, point->y);
+ cairo_matrix_transform_point (stroke->gallium_ctm, &x, &y);
+
stroke->current_path = _gallium_init_path();
if ((stroke->list_head.next == NULL) &&
@@ -842,7 +851,7 @@ _gallium_move_to (void *closure, const cairo_point_t *point)
LIST_ADDTAIL(&stroke->current_path->list, &stroke->list_head);
}
- _gallium_append_point(stroke->current_path, point);
+ _gallium_append_point(stroke->current_path, x, y);
return CAIRO_STATUS_SUCCESS;
}
@@ -850,13 +859,16 @@ static cairo_status_t
_gallium_line_to (void *closure, const cairo_point_t *point)
{
gallium_stroke_t *stroker = closure;
- gallium_path_t *path = stroker->current_path;
- printf("line to\n");
+
+ const double x = _cairo_fixed_to_double(point->x);
+ const double y = _cairo_fixed_to_double(point->y);
//if (path->ctm_inverse)
// cairo_matrix_transform_point (path->ctm_inverse, point->x, point->y);
- _gallium_append_point(path, point);
+ cairo_matrix_transform_point (stroker->gallium_ctm, &x, &y);
+
+ _gallium_append_point(stroker->current_path, x, y);
return CAIRO_STATUS_SUCCESS;
}
@@ -869,11 +881,9 @@ _gallium_close_path (void *closure)
printf("close path\n");
if (stroker->current_path->count != 0) {
- cairo_point_t close_point_path;
- close_point_path.x = _cairo_fixed_from_double (stroker->current_path->points[0]);
- close_point_path.y = _cairo_fixed_from_double (stroker->current_path->points[1]);
-
- _gallium_append_point(stroker->current_path, &close_point_path);
+ _gallium_append_point(stroker->current_path,
+ stroker->current_path->points[0],
+ stroker->current_path->points[1]);
status = CAIRO_STATUS_SUCCESS;
}
@@ -931,187 +941,64 @@ _gallium_path_from_cairo (gallium_stroke_t *gallium_stroke, const cairo_path_fix
}
static cairo_status_t
-_gallium_surface_clip (gallium_surface_t *abstract_surface,
- cairo_clip_t *clip)
+add_triangle (void *closure, const cairo_point_t triangle[3])
{
- if (clip != NULL) {
- gallium_surface_t *surface = abstract_surface;
- gallium_stroke_t *gallium_stroke;
- gallium_device_t *device = gallium_device(surface);
- struct pipe_depth_stencil_alpha_state st;
- struct pipe_scissor_state scissor;
-
- gallium_stroke = _gallium_init_stroke();
- _gallium_path_from_cairo(gallium_stroke, &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_stroke->current_path->minx;
- scissor.miny = gallium_stroke->current_path->miny;
- scissor.maxx = gallium_stroke->current_path->maxx;
- scissor.maxy = gallium_stroke->current_path->maxy;
+ gallium_stroke_t *stroke = closure;
- //_gallium_finish_path(gallium_path);
- _gallium_draw_quad(device->pipe, scissor.minx, scissor.miny, scissor.maxx, scissor.maxy);
- }
+ _gallium_move_to(stroke, &triangle[0]);
+ _gallium_line_to(stroke, &triangle[1]);
+ _gallium_line_to(stroke, &triangle[2]);
return CAIRO_STATUS_SUCCESS;
}
-static cairo_int_status_t
-gallium_surface_paint (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_clip_t *clip)
+//XXX: fix triangle fan
+static cairo_status_t
+add_triangle_fan (void *closure,
+ const cairo_point_t *midpt,
+ const cairo_point_t *points,
+ int npoints)
{
- gallium_surface_t *surface = abstract_surface;
- gallium_device_t *device = gallium_device(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) {
- status = _gallium_surface_paint_solid(surface, source, shader);
- } else {
- status = _cairo_surface_paint (surface->fallback, op, source, clip);
- }
-
- _gallium_set_states(surface);
-
- cso_set_vertex_elements (device->cso, 2, surface->velem);
-
- util_draw_vertex_buffer (device->pipe,
- surface->vbuf, 0,
- PIPE_PRIM_QUADS,
- 4,
- 2);
-
- gallium_surface_flush(abstract_surface);
+ int i;
- 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;
- cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
+ gallium_stroke_t *stroke = closure;
+ printf("\n number points:%d\n", npoints);
- if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
- cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask;
- float alpha = surface->paint.solid_color[4];
+ for (i = 0; i < npoints; i++) {
+ if (i == 0)
+ _gallium_move_to(stroke, &points[i]);
- surface->paint.solid_color[4] = solid_mask->color.alpha;
- status = gallium_surface_paint(abstract_surface, op, source, clip);
- surface->paint.solid_color[4] = alpha;
+ _gallium_line_to(stroke, &points[i]);
}
- return status;
+ return CAIRO_STATUS_SUCCESS;
}
-static cairo_int_status_t
-gallium_surface_stroke (void *abstract_surface,
- cairo_operator_t op,
- const cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- const cairo_stroke_style_t *style,
- const cairo_matrix_t *ctm,
- const cairo_matrix_t *ctm_inverse,
- double tolerance,
- cairo_antialias_t antialias,
- cairo_clip_t *clip)
+static cairo_status_t
+add_convex_quad (void *closure, const cairo_point_t quad[4])
{
- gallium_surface_t *surface = abstract_surface;
- gallium_stroke_t *gallium_stroke;
- gallium_device_t *device = gallium_device(surface);
- gallium_shader_t *shader = device->shader;
- cairo_status_t status;
-
- status = _gallium_surface_clip (surface, clip);
- if (unlikely (status))
- return status;
-
- gallium_stroke = _gallium_init_stroke();
-
- //gallium_path->ctm_inverse = ctm_inverse;
-
- _gallium_path_from_cairo(gallium_stroke, path);
-
- gallium_stroke->line_width = style->line_width;
-
- if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
- _gallium_surface_paint_solid(abstract_surface, source, shader);
- }
+ gallium_stroke_t *stroke = closure;
- surface->rasterizer.line_width = gallium_stroke->line_width;
+ printf("\n convex quad\n");
- _gallium_set_states(abstract_surface);
- {
- struct list_head *head, *next;
+ _gallium_move_to(stroke, &quad[0]);
+ _gallium_line_to(stroke, &quad[1]);
+ _gallium_line_to(stroke, &quad[2]);
+ _gallium_line_to(stroke, &quad[3]);
- for (head = gallium_stroke->list_head.next; head != &gallium_stroke->list_head; head = next) {
- gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list);
-
- draw_path(abstract_surface, gallium_path, PIPE_PRIM_LINE_STRIP);
- _gallium_finish_path(gallium_path);
+ return CAIRO_STATUS_SUCCESS;
- gallium_surface_flush(abstract_surface);
- next = head->next;
- }
- }
- return status;
}
-// implement clip
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)
+_gallium_fill (void *abstract_surface,
+ gallium_stroke_t *gallium_stroke,
+ cairo_fill_rule_t fill_rule)
{
gallium_surface_t *surface = abstract_surface;
- gallium_stroke_t *gallium_stroke;
gallium_device_t *device = gallium_device(surface);
- gallium_shader_t *shader = device->shader;
struct pipe_depth_stencil_alpha_state st;
struct pipe_stencil_ref sr;
- cairo_status_t status;
-
- status = _gallium_surface_clip (surface, clip);
- if (unlikely (status))
- return status;
-
- if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
- _gallium_surface_paint_solid(abstract_surface, source, shader);
- }
-
- _gallium_set_states(abstract_surface);
-
- gallium_stroke = _gallium_init_stroke();
- _gallium_path_from_cairo(gallium_stroke, path);
struct pipe_surface *zsurface;
struct pipe_resource *resource;
@@ -1139,8 +1026,9 @@ gallium_surface_fill (void *abstract_surface,
_gallium_set_states(abstract_surface);
{
- cso_save_blend(device->cso);
struct pipe_blend_state blend;
+
+ cso_save_blend(device->cso);
memset(&blend, 0, sizeof(struct pipe_blend_state));
blend.rt[0].colormask = 0; /*disable colorwrites*/
@@ -1183,7 +1071,6 @@ gallium_surface_fill (void *abstract_surface,
gallium_stroke->miny = MIN2(gallium_stroke->miny, gallium_path->miny);
gallium_stroke->maxy = MAX2(gallium_stroke->maxy, gallium_path->maxy);
- gallium_surface_flush(abstract_surface);
next = head->next;
}
}
@@ -1220,7 +1107,6 @@ gallium_surface_fill (void *abstract_surface,
gallium_stroke->miny = MIN2(gallium_stroke->miny, gallium_path->miny);
gallium_stroke->maxy = MAX2(gallium_stroke->maxy, gallium_path->maxy);
- gallium_surface_flush(abstract_surface);
next = head->next;
}
}
@@ -1253,7 +1139,6 @@ gallium_surface_fill (void *abstract_surface,
gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list);
draw_path(abstract_surface, gallium_path, PIPE_PRIM_TRIANGLE_FAN);
- gallium_surface_flush(abstract_surface);
next = head->next;
}
@@ -1282,7 +1167,6 @@ gallium_surface_fill (void *abstract_surface,
gallium_stroke->miny = MIN2(gallium_stroke->miny, gallium_path->miny);
gallium_stroke->maxy = MAX2(gallium_stroke->maxy, gallium_path->maxy);
- gallium_surface_flush(abstract_surface);
next = head->next;
}
}
@@ -1310,10 +1194,204 @@ gallium_surface_fill (void *abstract_surface,
cso_restore_depth_stencil_alpha(device->cso);
printf("filling");
+ return 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_stroke_t *gallium_stroke;
+ gallium_device_t *device = gallium_device(surface);
+ struct pipe_depth_stencil_alpha_state st;
+ struct pipe_scissor_state scissor;
+
+ gallium_stroke = _gallium_init_stroke();
+ _gallium_path_from_cairo(gallium_stroke, &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_stroke->current_path->minx;
+ scissor.miny = gallium_stroke->current_path->miny;
+ scissor.maxx = gallium_stroke->current_path->maxx;
+ scissor.maxy = gallium_stroke->current_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 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_device_t *device = gallium_device(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) {
+ status = _gallium_surface_paint_solid(surface, source, shader);
+ } else {
+ status = _cairo_surface_paint (surface->fallback, op, source, clip);
+ }
+
+ _gallium_set_states(surface);
+
+ cso_set_vertex_elements (device->cso, 2, surface->velem);
+
+ util_draw_vertex_buffer (device->pipe,
+ surface->vbuf, 0,
+ PIPE_PRIM_QUADS,
+ 4,
+ 2);
+
+ gallium_surface_flush(abstract_surface);
+
+ 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;
+ cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
+ cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask;
+ float alpha = surface->paint.solid_color[4];
+
+ surface->paint.solid_color[4] = solid_mask->color.alpha;
+ status = gallium_surface_paint(abstract_surface, op, source, clip);
+ surface->paint.solid_color[4] = alpha;
+ }
+
return status;
}
static cairo_int_status_t
+gallium_surface_stroke (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ const cairo_stroke_style_t *style,
+ const cairo_matrix_t *ctm,
+ const cairo_matrix_t *ctm_inverse,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_clip_t *clip)
+{
+ gallium_surface_t *surface = abstract_surface;
+ gallium_stroke_t *gallium_stroke;
+ gallium_device_t *device = gallium_device(surface);
+ gallium_shader_t *shader = device->shader;
+ cairo_status_t status;
+
+ const cairo_fill_rule_t rule = CAIRO_FILL_RULE_WINDING;
+
+ status = _gallium_surface_clip (surface, clip);
+ if (unlikely (status))
+ return status;
+
+ if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
+ _gallium_surface_paint_solid(abstract_surface, source, shader);
+ }
+
+ _gallium_set_states(abstract_surface);
+
+ gallium_stroke = _gallium_init_stroke();
+ gallium_stroke->gallium_ctm = &surface->gallium_ctm;
+ _cairo_path_fixed_stroke_to_shaper(path,
+ style, ctm, ctm_inverse,
+ tolerance,
+ add_triangle,
+ add_triangle_fan,
+ add_convex_quad,
+ gallium_stroke);
+
+ {
+ struct list_head *head, *next;
+
+ for (head = gallium_stroke->list_head.next; head != &gallium_stroke->list_head; head = next) {
+ gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list);
+
+ draw_path(abstract_surface, gallium_path, PIPE_PRIM_TRIANGLE_FAN);
+ _gallium_finish_path(gallium_path);
+
+ next = head->next;
+ }
+ }
+
+ gallium_surface_flush(abstract_surface);
+
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+// implement clip
+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)
+{
+ gallium_surface_t *surface = abstract_surface;
+ gallium_stroke_t *gallium_stroke;
+ gallium_device_t *device = gallium_device(surface);
+ gallium_shader_t *shader = device->shader;
+ cairo_status_t status;
+
+ status = _gallium_surface_clip (surface, clip);
+ if (unlikely (status))
+ return status;
+
+ if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
+ _gallium_surface_paint_solid(abstract_surface, source, shader);
+ }
+
+ _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);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
gallium_surface_glyphs (void *abstract_surface,
cairo_operator_t op,
const cairo_pattern_t *source,
@@ -1533,6 +1611,8 @@ gallium_surface_create_internal (gallium_device_t *device,
device->shader = shader_create(device);
+ cairo_matrix_init_scale (&surface->gallium_ctm, 1.0/width, 1.0/height);
+
return &surface->drm.base;
}