[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