Convert SpicePath.segments to a pointer array

This commit is contained in:
Alexander Larsson 2010-07-05 20:45:13 +02:00
parent 6dcf43912e
commit f39d64f40b
8 changed files with 58 additions and 61 deletions

View File

@ -3062,7 +3062,6 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
stroke_fill_spans,
stroke_fill_rects
};
SpicePathSeg *seg;
StrokeLines lines;
unsigned int i;
int dashed;
@ -3165,24 +3164,22 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
CANVAS_ERROR("invalid brush type");
}
seg = (SpicePathSeg*)stroke->path->segments;
stroke_lines_init(&lines);
for (i = 0; i < stroke->path->num_segments; i++) {
uint32_t flags = seg->flags;
SpicePointFix* point = seg->points;
SpicePointFix* end_point = point + seg->count;
ASSERT(point < end_point);
seg = (SpicePathSeg*)end_point;
SpicePathSeg *seg = stroke->path->segments[i];
SpicePointFix* point, *end_point;
if (flags & SPICE_PATH_BEGIN) {
point = seg->points;
end_point = point + seg->count;
if (seg->flags & SPICE_PATH_BEGIN) {
stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
stroke_lines_append_fix(&lines, point);
point++;
}
if (flags & SPICE_PATH_BEZIER) {
if (seg->flags & SPICE_PATH_BEZIER) {
ASSERT((point - end_point) % 3 == 0);
for (; point + 2 < end_point; point += 3) {
stroke_lines_append_bezier(&lines,
@ -3196,8 +3193,8 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
stroke_lines_append_fix(&lines, point);
}
}
if (flags & SPICE_PATH_END) {
if (flags & SPICE_PATH_CLOSE) {
if (seg->flags & SPICE_PATH_END) {
if (seg->flags & SPICE_PATH_CLOSE) {
stroke_lines_append(&lines,
lines.points[0].x, lines.points[0].y);
}

View File

@ -310,17 +310,14 @@ uint32_t raster_ops[] = {
static void set_path(GdiCanvas *canvas, SpicePath *s)
{
SpicePathSeg* seg = (SpicePathSeg*)s->segments;
unsigned int i;
for (i = 0; i < s->num_segments; i++) {
uint32_t flags = seg->flags;
SpicePathSeg* seg = s->segments[0];
SpicePointFix* point = seg->points;
SpicePointFix* end_point = point + seg->count;
ASSERT(point < end_point);
seg = (SpicePathSeg*)end_point;
if (flags & SPICE_PATH_BEGIN) {
if (seg->flags & SPICE_PATH_BEGIN) {
BeginPath(canvas->dc);
if (!MoveToEx(canvas->dc, (int)fix_to_double(point->x), (int)fix_to_double(point->y),
NULL)) {
@ -330,7 +327,7 @@ static void set_path(GdiCanvas *canvas, SpicePath *s)
point++;
}
if (flags & SPICE_PATH_BEZIER) {
if (seg->flags & SPICE_PATH_BEZIER) {
ASSERT((point - end_point) % 3 == 0);
for (; point + 2 < end_point; point += 3) {
POINT points[3];
@ -355,9 +352,9 @@ static void set_path(GdiCanvas *canvas, SpicePath *s)
}
}
if (flags & SPICE_PATH_END) {
if (seg->flags & SPICE_PATH_END) {
if (flags & SPICE_PATH_CLOSE) {
if (seg->flags & SPICE_PATH_CLOSE) {
if (!CloseFigure(canvas->dc)) {
CANVAS_ERROR("CloseFigure failed");
}

View File

@ -115,20 +115,18 @@ static GLCPath get_path(GLCanvas *canvas, SpicePath *s)
{
GLCPath path = glc_path_create(canvas->glc);
int i;
SpicePathSeg* seg = (SpicePathSeg*)s->segments;
for (i = 0; i < s->num_segments; i++) {
uint32_t flags = seg->flags;
SpicePathSeg* seg = s->segments[i];
SpicePointFix* point = seg->points;
SpicePointFix* end_point = point + seg->count;
seg = (SpicePathSeg*)end_point;
if (flags & SPICE_PATH_BEGIN) {
if (seg->flags & SPICE_PATH_BEGIN) {
glc_path_move_to(path, fix_to_double(point->x), fix_to_double(point->y));
point++;
}
if (flags & SPICE_PATH_BEZIER) {
if (seg->flags & SPICE_PATH_BEZIER) {
ASSERT((point - end_point) % 3 == 0);
for (; point + 2 < end_point; point += 3) {
glc_path_curve_to(path,
@ -141,8 +139,8 @@ static GLCPath get_path(GLCanvas *canvas, SpicePath *s)
glc_path_line_to(path, fix_to_double(point->x), fix_to_double(point->y));
}
}
if (flags & SPICE_PATH_END) {
if (flags & SPICE_PATH_CLOSE) {
if (seg->flags & SPICE_PATH_END) {
if (seg->flags & SPICE_PATH_CLOSE) {
glc_path_close(path);
}
}

View File

@ -47,13 +47,16 @@ def write_parser_helpers(writer):
swap = "SPICE_BYTESWAP%d" % size
if size == 8:
writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" % type)
writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr) = val" % (type))
else:
writer.macro("read_%s" % type, "ptr", "((%s_t)%s(*((%s_t *)(ptr)))" % (type, swap, utype))
writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr) = %s((%s_t)val)" % (utype, swap, utype))
writer.writeln("#else")
for size in [8, 16, 32, 64]:
for sign in ["", "u"]:
type = "%sint%d" % (sign, size)
writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" % type)
writer.macro("write_%s" % type, "ptr, val", "(*((%s_t *)(ptr))) = val" % type)
writer.writeln("#endif")
for size in [8, 16, 32, 64]:
@ -96,6 +99,15 @@ def write_read_primitive(writer, start, container, name, scope):
writer.assign(var, "read_%s(pos)" % (m.member_type.primitive_type()))
return var
def write_write_primitive(writer, start, container, name, val):
m = container.lookup_member(name)
assert(m.is_primitive())
writer.assign("pos", start + " + " + container.get_nw_offset(m, "", "__nw_size"))
var = "%s__value" % (name)
writer.statement("write_%s(pos, %s)" % (m.member_type.primitive_type(), val))
return var
def write_read_primitive_item(writer, item, scope):
assert(item.type.is_primitive())
writer.assign("pos", item.get_position())
@ -280,6 +292,9 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
element_type = array.element_type
if array.is_bytes_length():
nelements = "%s__nbytes" %(item.prefix)
real_nelements = "%s__nelements" %(item.prefix)
if not parent_scope.variable_defined(real_nelements):
parent_scope.variable_def("uint32_t", real_nelements)
else:
nelements = "%s__nelements" %(item.prefix)
if not parent_scope.variable_defined(nelements):
@ -315,6 +330,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
is_byte_size = True
v = write_read_primitive(writer, start, container, array.size[1], scope)
writer.assign(nelements, v)
writer.assign(real_nelements, 0)
elif array.is_cstring_length():
writer.todo("cstring array size type not handled yet")
else:
@ -389,6 +405,8 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
with writer.index(no_block = is_byte_size) as index:
with writer.while_loop("%s < %s" % (start2, start2_end) ) if is_byte_size else writer.for_loop(index, nelements) as scope:
if is_byte_size:
writer.increment(real_nelements, 1)
write_validate_item(writer, container, element_item, scope, parent_scope, start2,
want_element_nw_size, want_mem_size, want_extra_size)
@ -405,6 +423,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
writer.increment(start2, start_increment)
if is_byte_size:
writer.error_check("%s != %s" % (start2, start2_end))
write_write_primitive(writer, start, container, array.size[1], real_nelements)
def write_validate_struct_item(writer, container, item, scope, parent_scope, start,
want_nw_size, want_mem_size, want_extra_size):
@ -613,11 +632,9 @@ class SubDemarshallingDestination(DemarshallingDestination):
def get_ref(self, member):
return self.parent_dest.get_ref(self.member) + "." + member
def read_array_len(writer, prefix, array, dest, scope, handles_bytes = False):
if array.is_bytes_length():
nelements = "%s__nbytes" % prefix
else:
nelements = "%s__nelements" % prefix
# Note: during parsing, byte_size types have been converted to count during validation
def read_array_len(writer, prefix, array, dest, scope):
nelements = "%s__nelements" % prefix
if dest.is_toplevel():
return nelements # Already there for toplevel, need not recalculate
element_type = array.element_type
@ -645,9 +662,7 @@ def read_array_len(writer, prefix, array, dest, scope, handles_bytes = False):
else:
writer.assign(nelements, "((%s * %s + 7) / 8 ) * %s" % (bpp, width_v, rows_v))
elif array.is_bytes_length():
if not handles_bytes:
raise NotImplementedError("handling of bytes() not supported here yet")
writer.assign(nelements, array.size[1])
writer.assign(nelements, dest.get_ref(array.size[2]))
else:
raise NotImplementedError("TODO array size type not handled yet")
return nelements
@ -758,24 +773,16 @@ def write_array_parser(writer, nelements, array, dest, scope):
writer.increment("in", nelements)
writer.increment("end", nelements)
else:
if is_byte_size:
real_nelements = nelements[:-len("nbytes")] + "nelements"
scope.variable_def("uint8_t *", "array_end")
scope.variable_def("uint32_t", real_nelements)
writer.assign("array_end", "end + %s" % nelements)
writer.assign(real_nelements, 0)
if array.has_attr("ptr_array"):
scope.variable_def("void **", "ptr_array")
scope.variable_def("int", "ptr_array_index")
writer.assign("ptr_array_index", 0)
writer.assign("ptr_array", "(void **)end")
writer.increment("end", "sizeof(void *) * %s" % nelements)
with writer.index(no_block = is_byte_size) as index:
with writer.while_loop("end < array_end") if is_byte_size else writer.for_loop(index, nelements) as array_scope:
with writer.index() as index:
with writer.for_loop(index, nelements) as array_scope:
if array.has_attr("ptr_array"):
writer.statement("ptr_array[ptr_array_index++] = end")
if is_byte_size:
writer.increment(real_nelements, 1)
if element_type.is_primitive():
writer.statement("*(%s *)end = consume_%s(&in)" % (element_type.c_type(), element_type.primitive_type()))
writer.increment("end", element_type.sizeof())
@ -786,8 +793,6 @@ def write_array_parser(writer, nelements, array, dest, scope):
if array.has_attr("ptr_array"):
writer.comment("Align ptr_array element to 4 bytes").newline()
writer.assign("end", "(uint8_t *)SPICE_ALIGN((size_t)end, 4)")
if is_byte_size:
writer.assign(dest.get_ref(array.size[2]), real_nelements)
def write_parse_pointer(writer, t, at_end, dest, member_name, scope):
as_c_ptr = t.has_attr("c_ptr")
@ -831,14 +836,14 @@ def write_member_parser(writer, container, member, dest, scope):
writer.increment("end", t.sizeof())
else:
if member.has_attr("bytes_count"):
scope.variable_def("uint32_t", member.name);
dest_var = member.name
print member.attributes["bytes_count"]
dest_var = dest.get_ref(member.attributes["bytes_count"][0])
else:
dest_var = dest.get_ref(member.name)
writer.assign(dest_var, "consume_%s(&in)" % (t.primitive_type()))
#TODO validate e.g. flags and enums
elif t.is_array():
nelements = read_array_len(writer, member.name, t, dest, scope, handles_bytes = True)
nelements = read_array_len(writer, member.name, t, dest, scope)
if member.has_attr("as_ptr") and t.element_type.is_fixed_nw_size():
writer.comment("use array as pointer").newline()
writer.assign(dest.get_ref(member.name), "(%s *)in" % t.element_type.c_type())

View File

@ -153,7 +153,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
bool free_data;
QXLPath *qxl;
SpicePath *red;
size_t size, mem_size, mem_size2, dsize;
size_t size, mem_size, mem_size2, dsize, segment_size;
int n_segments;
int i;
uint32_t count;
@ -173,7 +173,8 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
while (start < end) {
n_segments++;
count = start->count;
mem_size += sizeof(SpicePathSeg) + count * sizeof(SpicePointFix);
segment_size = sizeof(SpicePathSeg) + count * sizeof(SpicePointFix);
mem_size += sizeof(SpicePathSeg *) + SPICE_ALIGN(segment_size, 4);
start = (QXLPathSeg*)(&start->points[count]);
}
@ -182,11 +183,11 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
start = (QXLPathSeg*)data;
end = (QXLPathSeg*)(data + size);
seg = (SpicePathSeg*)red->segments;
seg = (SpicePathSeg*)&red->segments[n_segments];
n_segments = 0;
mem_size2 = sizeof(*red);
while (start < end) {
n_segments++;
red->segments[n_segments++] = seg;
count = start->count;
/* Protect against overflow in size calculations before

View File

@ -2296,9 +2296,10 @@ static int is_equal_path(RedWorker *worker, SpicePath *path1, SpicePath *path2)
if (path1->num_segments != path2->num_segments)
return FALSE;
seg1 = (SpicePathSeg*)&path1->segments[0];
seg2 = (SpicePathSeg*)&path2->segments[0];
for (i = 0; i < path1->num_segments; i++) {
seg1 = path1->segments[i];
seg2 = path2->segments[i];
if (seg1->flags != seg2->flags ||
seg1->count != seg2->count) {
return FALSE;
@ -2309,8 +2310,6 @@ static int is_equal_path(RedWorker *worker, SpicePath *path1, SpicePath *path2)
return FALSE;
}
}
seg1 = (SpicePathSeg*)(&seg1->points[seg1->count]);
seg2 = (SpicePathSeg*)(&seg2->points[seg2->count]);
}
return TRUE;

View File

@ -393,7 +393,7 @@ struct PathSegment {
struct Path {
uint32 num_segments;
PathSegment segments[num_segments] @end;
PathSegment segments[num_segments] @ptr_array;
};
struct Clip {

View File

@ -374,8 +374,8 @@ struct PathSegment {
} @ctype(SpicePathSeg);
struct Path {
uint32 segments_size @bytes_count;
PathSegment segments[bytes(segments_size, num_segments)] @end;
uint32 segments_size @bytes_count(num_segments);
PathSegment segments[bytes(segments_size, num_segments)] @ptr_array;
};
struct Clip {