mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 20:28:02 +02:00
[path] Inline path ops during append_to_context()
By inlining the operations, and most significantly, precomputing the combined user-to-backend matrix, we can achieve a speed up of over 50%, which is a noticeable performance boost in swfdec - where append-to-path accounts for over 35% [inclusive] of the time for a h/w accelerated backend.
This commit is contained in:
parent
d295942b9d
commit
005436758c
1 changed files with 58 additions and 18 deletions
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-private.h"
|
||||
#include "cairo-path-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
|
|
@ -441,43 +442,82 @@ cairo_status_t
|
|||
_cairo_path_append_to_context (const cairo_path_t *path,
|
||||
cairo_t *cr)
|
||||
{
|
||||
int i;
|
||||
cairo_path_data_t *p;
|
||||
const cairo_path_data_t *p, *end;
|
||||
cairo_fixed_t x1_fixed, y1_fixed;
|
||||
cairo_fixed_t x2_fixed, y2_fixed;
|
||||
cairo_fixed_t x3_fixed, y3_fixed;
|
||||
cairo_matrix_t user_to_backend;
|
||||
cairo_status_t status;
|
||||
double x, y;
|
||||
|
||||
for (i=0; i < path->num_data; i += path->data[i].header.length) {
|
||||
p = &path->data[i];
|
||||
user_to_backend = cr->gstate->ctm;
|
||||
cairo_matrix_multiply (&user_to_backend,
|
||||
&cr->gstate->target->device_transform,
|
||||
&user_to_backend);
|
||||
|
||||
end = &path->data[path->num_data];
|
||||
for (p = &path->data[0]; p < end; p += p->header.length) {
|
||||
switch (p->header.type) {
|
||||
case CAIRO_PATH_MOVE_TO:
|
||||
if (p->header.length < 2)
|
||||
if (unlikely (p->header.length < 2))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_move_to (cr,
|
||||
p[1].point.x, p[1].point.y);
|
||||
|
||||
x = p[1].point.x, y = p[1].point.y;
|
||||
cairo_matrix_transform_point (&user_to_backend, &x, &y);
|
||||
x1_fixed = _cairo_fixed_from_double (x);
|
||||
y1_fixed = _cairo_fixed_from_double (y);
|
||||
|
||||
status = _cairo_path_fixed_move_to (cr->path, x1_fixed, y1_fixed);
|
||||
break;
|
||||
|
||||
case CAIRO_PATH_LINE_TO:
|
||||
if (p->header.length < 2)
|
||||
if (unlikely (p->header.length < 2))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_line_to (cr,
|
||||
p[1].point.x, p[1].point.y);
|
||||
|
||||
x = p[1].point.x, y = p[1].point.y;
|
||||
cairo_matrix_transform_point (&user_to_backend, &x, &y);
|
||||
x1_fixed = _cairo_fixed_from_double (x);
|
||||
y1_fixed = _cairo_fixed_from_double (y);
|
||||
|
||||
status = _cairo_path_fixed_line_to (cr->path, x1_fixed, y1_fixed);
|
||||
break;
|
||||
|
||||
case CAIRO_PATH_CURVE_TO:
|
||||
if (p->header.length < 4)
|
||||
if (unlikely (p->header.length < 4))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_curve_to (cr,
|
||||
p[1].point.x, p[1].point.y,
|
||||
p[2].point.x, p[2].point.y,
|
||||
p[3].point.x, p[3].point.y);
|
||||
|
||||
x = p[1].point.x, y = p[1].point.y;
|
||||
cairo_matrix_transform_point (&user_to_backend, &x, &y);
|
||||
x1_fixed = _cairo_fixed_from_double (x);
|
||||
y1_fixed = _cairo_fixed_from_double (y);
|
||||
|
||||
x = p[2].point.x, y = p[2].point.y;
|
||||
cairo_matrix_transform_point (&user_to_backend, &x, &y);
|
||||
x2_fixed = _cairo_fixed_from_double (x);
|
||||
y2_fixed = _cairo_fixed_from_double (y);
|
||||
|
||||
x = p[3].point.x, y = p[3].point.y;
|
||||
cairo_matrix_transform_point (&user_to_backend, &x, &y);
|
||||
x3_fixed = _cairo_fixed_from_double (x);
|
||||
y3_fixed = _cairo_fixed_from_double (y);
|
||||
|
||||
status = _cairo_path_fixed_curve_to (cr->path,
|
||||
x1_fixed, y1_fixed,
|
||||
x2_fixed, y2_fixed,
|
||||
x3_fixed, y3_fixed);
|
||||
break;
|
||||
|
||||
case CAIRO_PATH_CLOSE_PATH:
|
||||
if (p->header.length < 1)
|
||||
if (unlikely (p->header.length < 1))
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
cairo_close_path (cr);
|
||||
|
||||
status = _cairo_path_fixed_close_path (cr->path);
|
||||
break;
|
||||
|
||||
default:
|
||||
return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
|
||||
}
|
||||
|
||||
status = cairo_status (cr);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue