diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-07-05 20:45:13 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-07-05 20:45:13 +0200 |
commit | f39d64f40bca094396d5002dcfcd38eaa281c9af (patch) | |
tree | 5e25c5d01bf1bd390f119ec3146f4f6b56dee2b4 | |
parent | 6dcf43912e752b8c61199017718ccfb067b45576 (diff) | |
download | spice-f39d64f40bca094396d5002dcfcd38eaa281c9af.tar.gz spice-f39d64f40bca094396d5002dcfcd38eaa281c9af.tar.xz spice-f39d64f40bca094396d5002dcfcd38eaa281c9af.zip |
Convert SpicePath.segments to a pointer array
-rw-r--r-- | common/canvas_base.c | 21 | ||||
-rw-r--r-- | common/gdi_canvas.c | 13 | ||||
-rw-r--r-- | common/gl_canvas.c | 12 | ||||
-rw-r--r-- | python_modules/demarshal.py | 51 | ||||
-rw-r--r-- | server/red_parse_qxl.c | 9 | ||||
-rw-r--r-- | server/red_worker.c | 7 | ||||
-rw-r--r-- | spice.proto | 2 | ||||
-rw-r--r-- | spice1.proto | 4 |
8 files changed, 58 insertions, 61 deletions
diff --git a/common/canvas_base.c b/common/canvas_base.c index 53d13f25..a0429a6a 100644 --- a/common/canvas_base.c +++ b/common/canvas_base.c @@ -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; + + point = seg->points; + end_point = point + seg->count; - if (flags & SPICE_PATH_BEGIN) { + 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); } diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c index e3489941..9c520024 100644 --- a/common/gdi_canvas.c +++ b/common/gdi_canvas.c @@ -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"); } diff --git a/common/gl_canvas.c b/common/gl_canvas.c index 3e02a25e..f0e10dd7 100644 --- a/common/gl_canvas.c +++ b/common/gl_canvas.c @@ -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); } } diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py index 606b926c..bd7660df 100644 --- a/python_modules/demarshal.py +++ b/python_modules/demarshal.py @@ -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()) diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c index d38cad7b..56f17dc8 100644 --- a/server/red_parse_qxl.c +++ b/server/red_parse_qxl.c @@ -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 diff --git a/server/red_worker.c b/server/red_worker.c index ff0a049e..255a46e7 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -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; diff --git a/spice.proto b/spice.proto index 8df12387..e4376300 100644 --- a/spice.proto +++ b/spice.proto @@ -393,7 +393,7 @@ struct PathSegment { struct Path { uint32 num_segments; - PathSegment segments[num_segments] @end; + PathSegment segments[num_segments] @ptr_array; }; struct Clip { diff --git a/spice1.proto b/spice1.proto index 982f6668..b49371ad 100644 --- a/spice1.proto +++ b/spice1.proto @@ -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 { |