[gs-cvs] rev 8365 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Wed Nov 14 10:37:47 PST 2007
Author: leonardo
Date: 2007-11-14 10:37:45 -0800 (Wed, 14 Nov 2007)
New Revision: 8365
Modified:
trunk/gs/src/gxcldev.h
trunk/gs/src/gxclist.c
trunk/gs/src/gxclist.h
trunk/gs/src/gxclrast.c
trunk/gs/src/gxclread.c
trunk/gs/src/gxclutil.c
Log:
Fix (clist) : Providing clist instruction ids and offsets to debug trace.
DETAILS :
This change is algorithmically equivalent for release build.
In the debug build it only adds a new debug printing.
Let clist segment is consecutive instuctions buffered for same band.
1. gx_device_clist_writer::ins_count counts clist segments.
2. cmd_prefix_s::id is the number of clist segment that it belongs to.
3. stream_band_read_state_s::offset_map stores a table for mapping
clist segments' buffer offsets to clist file offsets.
4. s_band_read_init_offset_map, s_band_read_dnit_offset_map,
clist_file_offset, top_up_offset_map maintain the table.
5. Inserted a debug printing into gxclutil.c, gxclrast.c .
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gxcldev.h
===================================================================
--- trunk/gs/src/gxcldev.h 2007-11-14 18:09:02 UTC (rev 8364)
+++ trunk/gs/src/gxcldev.h 2007-11-14 18:37:45 UTC (rev 8365)
@@ -713,4 +713,9 @@
gx_device_clist_reader *crdev,
gx_band_page_info_t *page_info, gx_device *target,
int band_first, int band_last, int x0, int y0);
+#ifdef DEBUG
+int64_t clist_file_offset(const stream_state *st, uint buffer_offset);
+void top_up_offset_map(stream_state * st, const byte *buf, const byte *ptr, const byte *end);
+#endif
+
#endif /* gxcldev_INCLUDED */
Modified: trunk/gs/src/gxclist.c
===================================================================
--- trunk/gs/src/gxclist.c 2007-11-14 18:09:02 UTC (rev 8364)
+++ trunk/gs/src/gxclist.c 2007-11-14 18:37:45 UTC (rev 8365)
@@ -378,6 +378,7 @@
if (band_height == 0)
return_error(gs_error_rangecheck);
}
+ cdev->ins_count = 0;
code = clist_init_tile_cache(dev, data, bits_size);
if (code < 0)
return code;
Modified: trunk/gs/src/gxclist.h
===================================================================
--- trunk/gs/src/gxclist.h 2007-11-14 18:09:02 UTC (rev 8364)
+++ trunk/gs/src/gxclist.h 2007-11-14 18:37:45 UTC (rev 8365)
@@ -133,7 +133,7 @@
struct cmd_prefix_s {
cmd_prefix *next;
uint size;
- ulong id; /* Debug purpose only. */
+ ulong id; /* Debug purpose only. */
};
/* Define the pointers for managing a list of command runs in the buffer. */
@@ -251,7 +251,7 @@
gs_pattern1_instance_t *pinst; /* Used when it is a pattern clist. */
bool cropping_by_path;
int cropping_min, cropping_max;
- ulong ins_count; /* Debug purpose only. */
+ ulong ins_count;
} gx_device_clist_writer;
/* Bits for gx_device_clist_writer.disable_mask. Bit set disables behavior */
Modified: trunk/gs/src/gxclrast.c
===================================================================
--- trunk/gs/src/gxclrast.c 2007-11-14 18:09:02 UTC (rev 8364)
+++ trunk/gs/src/gxclrast.c 2007-11-14 18:37:45 UTC (rev 8365)
@@ -150,10 +150,13 @@
byte *cb_top = pcb->data + (pcb->end - cbp);
if (seofp(pcb->s)) {
- /* Return early because s_close did reset s->state. */
+ /* Can't use offset_map, because s_close resets s->state. Don't top up. */
pcb->end_status = pcb->s->end_status;
return cbp;
}
+# ifdef DEBUG
+ top_up_offset_map(pcb->s->state, pcb->data, cbp, pcb->end);
+# endif
memmove(pcb->data, cbp, pcb->end - cbp);
nread = pcb->end - cb_top;
pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
@@ -319,6 +322,7 @@
gx_device_clip clipper_dev;
bool clipper_dev_open;
patch_fill_state_t pfs;
+ stream_state *st = s->state; /* Save because s_close resets s->state. */
cbuf.data = (byte *)cbuf_storage;
cbuf.size = cbuf_size;
@@ -410,11 +414,13 @@
#ifdef DEBUG
if (gs_debug_c('L')) {
const char *const *sub = cmd_sub_op_names[op >> 4];
+ long offset = (long)clist_file_offset(st, cbp - 1 - cbuf.data);
if (sub)
- dlprintf1("[L]%s:", sub[op & 0xf]);
+ dlprintf1("[L]%s", sub[op & 0xf]);
else
- dlprintf2("[L]%s %d:", cmd_op_names[op >> 4], op & 0xf);
+ dlprintf2("[L]%s %d", cmd_op_names[op >> 4], op & 0xf);
+ dlprintf1("(offset=%ld):", offset);
}
#endif
switch (op >> 4) {
Modified: trunk/gs/src/gxclread.c
===================================================================
--- trunk/gs/src/gxclread.c 2007-11-14 18:09:02 UTC (rev 8364)
+++ trunk/gs/src/gxclread.c 2007-11-14 18:37:45 UTC (rev 8365)
@@ -43,6 +43,14 @@
/* ------ Band file reading stream ------ */
+#ifdef DEBUG
+/* An auxiliary table for mapping clist buffer offsets to cfile offsets. */
+typedef struct {
+ uint buffered;
+ int64_t file_offset;
+} cbuf_offset_map_elem;
+#endif
+
/*
* To separate banding per se from command list interpretation,
* we make the command list interpreter simply read from a stream.
@@ -56,6 +64,11 @@
int band_first, band_last;
uint left; /* amount of data left in this run */
cmd_block b_this;
+#ifdef DEBUG
+ cbuf_offset_map_elem *offset_map;
+ int offset_map_length;
+ int offset_map_max_length;
+#endif
} stream_band_read_state;
static int
@@ -72,7 +85,34 @@
return 0;
}
+#ifdef DEBUG
static int
+s_band_read_init_offset_map(stream_state * st, gs_memory_t *memory)
+{
+ stream_band_read_state *const ss = (stream_band_read_state *) st;
+ const clist_io_procs_t *io_procs = ss->page_info.io_procs;
+
+ ss->offset_map_length = 0;
+ ss->offset_map_max_length = cbuf_size + 1; /* fixme: Wanted a more accurate implementation. */
+ ss->offset_map = (cbuf_offset_map_elem *)gs_alloc_byte_array(memory,
+ ss->offset_map_max_length, sizeof(*ss->offset_map), "s_band_read_init_offset_map");
+ if (ss->offset_map == NULL)
+ return_error(gs_error_VMerror);
+ ss->offset_map[0].buffered = 0;
+ return 0;
+}
+
+static void
+s_band_read_dnit_offset_map(stream_state * st, gs_memory_t *memory)
+{
+ stream_band_read_state *const ss = (stream_band_read_state *) st;
+
+ gs_free_object(memory, ss->offset_map, "s_band_read_dnit_offset_map");
+}
+#endif
+
+
+static int
s_band_read_process(stream_state * st, stream_cursor_read * ignore_pr,
stream_cursor_write * pw, bool last)
{
@@ -90,6 +130,9 @@
if (left) { /* Read more data for the current run. */
if (count > left)
count = left;
+# ifdef DEBUG
+ ss->offset_map[ss->offset_map_length - 1].buffered += count;
+# endif
io_procs->fread_chars(q + 1, count, cfile);
if (io_procs->ferror_code(cfile) < 0) {
status = ERRC;
@@ -98,7 +141,7 @@
q += count;
left -= count;
process_interrupts(st->memory);
- continue;
+continue;
}
rb:
/*
@@ -119,6 +162,15 @@
if (!(ss->band_last >= bmin && ss->band_first <= bmax))
goto rb;
io_procs->fseek(cfile, pos, SEEK_SET, ss->page_cfname);
+# ifdef DEBUG
+ if (ss->offset_map_length >= ss->offset_map_max_length) {
+ gs_note_error(gs_error_unregistered); /* Must not happen. */
+ return ERRC;
+ }
+ ss->offset_map[ss->offset_map_length].file_offset = ss->b_this.pos;
+ ss->offset_map[ss->offset_map_length].buffered = 0;
+ ss->offset_map_length++;
+# endif
left = (uint) (ss->b_this.pos - pos);
if_debug7('l',
"[l]reading for bands (%d,%d) at bfile %ld, cfile %ld, length %u color %d rop %d\n",
@@ -129,7 +181,7 @@
}
}
pw->ptr = q;
- ss->left = left;
+ ss->left = left;
return status;
}
@@ -138,7 +190,59 @@
&st_stream_state, s_band_read_init, s_band_read_process, 1, cbuf_size
};
+#ifdef DEBUG
+int
+buffer_segment_index(const stream_band_read_state *ss, uint buffer_offset, uint *poffset0)
+{
+ uint i, offset0, offset = 0;
+ for (i = 0; i < ss->offset_map_length; i++) {
+ offset0 = offset;
+ offset += ss->offset_map[i].buffered;
+ if (buffer_offset < offset) {
+ *poffset0 = offset0;
+ return i;
+ }
+ }
+ gs_note_error(gs_error_unregistered); /* Must not happen. */
+ return -1;
+}
+
+int64_t
+clist_file_offset(const stream_state * st, uint buffer_offset)
+{
+ const stream_band_read_state *ss = (const stream_band_read_state *) st;
+ uint offset0;
+ int i = buffer_segment_index(ss, buffer_offset, &offset0);
+
+ if (i < 0)
+ return -1;
+ return ss->offset_map[i].file_offset + (uint)(buffer_offset - offset0);
+}
+
+
+void
+top_up_offset_map(stream_state * st, const byte *buf, const byte *ptr, const byte *end)
+{
+ stream_band_read_state *const ss = (stream_band_read_state *) st;
+
+ if (ptr == end)
+ ss->offset_map_length = 0;
+ else {
+ uint buffer_offset = ptr - buf;
+ uint offset0, consumed;
+ int i = buffer_segment_index(ss, buffer_offset, &offset0);
+
+ consumed = buffer_offset - offset0;
+ ss->offset_map[i].buffered -= consumed;
+ ss->offset_map[i].file_offset += consumed;
+ memmove(ss->offset_map, ss->offset_map + i,
+ (ss->offset_map_length - i) * sizeof(*ss->offset_map));
+ }
+}
+#endif /* DEBUG */
+
+
/* ------ Reading/rendering ------ */
/* Forward references */
@@ -542,13 +646,15 @@
};
s_band_read_init((stream_state *)&rs);
+# ifdef DEBUG
+ s_band_read_init_offset_map((stream_state *)&rs, crdev->memory);
+# endif
/* The stream doesn't need a memory, but we'll need to access s.memory->gs_lib_ctx. */
s_init(&s, mem);
s_std_init(&s, sbuf, cbuf_size, &no_procs, s_mode_read);
s.foreign = 1;
s.state = (stream_state *)&rs;
-
vd_get_dc('s');
vd_set_shift(0, 0);
vd_set_scale(0.01);
@@ -556,6 +662,9 @@
vd_erase(RGB(192, 192, 192));
code = clist_playback_band(action, crdev, &s, target, x0, y0, mem);
vd_release_dc;
+# ifdef DEBUG
+ s_band_read_dnit_offset_map((stream_state *)&rs, crdev->memory);
+# endif
}
/* Close the files if we just opened them. */
Modified: trunk/gs/src/gxclutil.c
===================================================================
--- trunk/gs/src/gxclutil.c 2007-11-14 18:09:02 UTC (rev 8364)
+++ trunk/gs/src/gxclutil.c 2007-11-14 18:37:45 UTC (rev 8365)
@@ -160,6 +160,8 @@
return_error(gs_error_Fatal);
}
#endif
+ if_debug2('L',"[L]Wrote cmd id=%ld at %ld\n", cp->id,
+ (long)cldev->page_info.io_procs->ftell(cfile));
cldev->page_info.io_procs->fwrite_chars(cp + 1, cp->size, cfile);
}
pcl->head = pcl->tail = 0;
@@ -268,6 +270,9 @@
pcl->tail = cp;
cldev->ccl = pcl;
cp->size = size;
+ cp->id = cldev->ins_count;
+ if_debug1('L', ", id=%ld ", cldev->ins_count);
+ cldev->ins_count++;
}
cldev->cnext = dp + size;
return dp;
More information about the gs-cvs
mailing list