[gs-cvs] rev 8426 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Fri Dec 7 15:39:07 PST 2007


Author: leonardo
Date: 2007-12-07 15:39:06 -0800 (Fri, 07 Dec 2007)
New Revision: 8426

Modified:
   trunk/gs/src/gdevdflt.c
   trunk/gs/src/gdevp14.c
   trunk/gs/src/gsalphac.c
   trunk/gs/src/gsovrc.c
   trunk/gs/src/gsropc.c
   trunk/gs/src/gstrans.h
   trunk/gs/src/gxcldev.h
   trunk/gs/src/gxclimag.c
   trunk/gs/src/gxclpath.c
   trunk/gs/src/gxclpath.h
   trunk/gs/src/gxclrast.c
   trunk/gs/src/gxclutil.c
   trunk/gs/src/gxcomp.h
   trunk/gs/src/lib.mak
Log:
Fix (clist interpreter) : Skip idle compositors, step 3.

DETAILS :

The clist writer writes the 'create compositor' operation to all bands,
including ones that are not covered by a transparency.
It does so because this operation changes the number of color components.

When rendering a specific band, it frequently happens that a compositor
is created and then immediately destroyed. Such thing happens outside 
the transparency bbox, and within the transparency bbox if
the band has no transparent objects. When compositor is created,
it allocates a big raster buffer and cleans it. 
Due to that we observe a significant CPU time expence
when running the test case of the bug 689155.

This patch is a preparation for further improvements.
This patch includes CTM into pdf14 compositor params
(see changes to c_pdf14trans_read, c_pdf14trans_write, clist_create_compositor).
The result should be same as the old code, but the algorithm is different.
The old code wrote CTM as a separate command before cmd_opv_ext_create_compositor.
The new code does not, and in many cases compositor commads 
immediately follow each another.

The last fact changes the behavior of the compositor queue :
before this patch it consisted of 1 element maximum,
but after it the queue becomes longer (up to 10 elements
with SoftMaskGroup.pdf). A bug is fixed in the queue logic 
in gxclrast.c ln 1355.

The queue is still immediately executed
when a non-compositor command appears in the input stream.
An annihilation of neighbour idle compositors will be a next step.

Minor changes:

- added a new method adjust_ctm to gs_composite_type_procs_t.
- added type checks with composite_*_proc macros to all compositor types.
- dependencies were broken for gdevp14.c in lib.mak .

EXPECTED DIFFERENCES :
      
None.


Modified: trunk/gs/src/gdevdflt.c
===================================================================
--- trunk/gs/src/gdevdflt.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gdevdflt.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -846,6 +846,14 @@
 }
 
 /*
+ * Default handler for adjusting a compositor's CTM. */
+int
+gx_default_composite_adjust_ctm(gs_composite_t *pcte, int x0, int y0, gs_imager_state *pis)
+{
+    return 0;
+}
+
+/*
  * Default handler for updating the clist device when reading a compositing
  * device.
  */

Modified: trunk/gs/src/gdevp14.c
===================================================================
--- trunk/gs/src/gdevp14.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gdevp14.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -39,6 +39,7 @@
 #include "gstrans.h"
 #include "gsutil.h"
 #include "gxcldev.h"
+#include "gxclpath.h"
 #include "gxdcconv.h"
 
 /*
@@ -2776,15 +2777,23 @@
     const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
     int need, avail = *psize;
 	/* Must be large enough for largest data struct */
-    byte buf[21 + sizeof(pparams->Background)
+    byte buf[25 /* See sput_matrix. */ +
+	     21 + sizeof(pparams->Background)
 		+ sizeof(pparams->GrayBackground) + sizeof(pparams->bbox)];
     byte * pbuf = buf;
     int opcode = pparams->pdf14_op;
     int mask_size = 0;
+    int len, code;
 
     /* Write PDF 1.4 compositor data into the clist */
 
     *pbuf++ = opcode;			/* 1 byte */
+    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
+    pbuf--; /* For cmd_write_ctm. */
+    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
+    if (code < 0)
+	return code;
+    pbuf += len + 1;
     switch (opcode) {
 	default:			/* Should not occur. */
 	    break;
@@ -2861,7 +2870,7 @@
 }
 
 /* Function prototypes */
-int gs_create_pdf14trans( gs_composite_t ** ppct,
+static int gs_create_pdf14trans( gs_composite_t ** ppct,
 		const gs_pdf14trans_params_t * pparams,
 		gs_memory_t * mem );
 
@@ -2888,6 +2897,7 @@
     params.pdf14_op = *data++;
     if_debug2('v', "[v] c_pdf14trans_read: opcode = %s  avail = %d",
 				pdf14_opcode_names[params.pdf14_op], size);
+    data = cmd_read_matrix(&params.ctm, data);
     switch (params.pdf14_op) {
 	default:			/* Should not occur. */
 	    break;
@@ -2975,6 +2985,24 @@
 }
 
 /*
+ * Adjust the compositor's CTM.
+ */
+static int
+c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_imager_state *pis)
+{
+    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
+
+    gs_matrix mat = pct->params.ctm;
+    if_debug6('L', " [%g %g %g %g %g %g]\n",
+	      mat.xx, mat.xy, mat.yx, mat.yy,
+	      mat.tx, mat.ty);
+    mat.tx -= x0;
+    mat.ty -= y0;
+    gs_imager_setmatrix(pis, &mat);
+    return 0;
+}
+
+/*
  * Create a PDF 1.4 transparency compositor.
  *
  * Note that this routine will be called only if the device is not already
@@ -3006,9 +3034,15 @@
     return code;
 }
 
+static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
+static composite_equal_proc(c_pdf14trans_equal);
+static composite_write_proc(c_pdf14trans_write);
+static composite_read_proc(c_pdf14trans_read);
+static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
 static	composite_clist_write_update(c_pdf14trans_clist_write_update);
 static	composite_clist_read_update(c_pdf14trans_clist_read_update);
 
+
 /*
  * Methods for the PDF 1.4 transparency compositor
  *
@@ -3024,6 +3058,7 @@
 	c_pdf14trans_equal,                      /* procs.equal */
 	c_pdf14trans_write,                      /* procs.write */
 	c_pdf14trans_read,                       /* procs.read */
+	c_pdf14trans_adjust_ctm,		 /* procs.adjust_ctm */
 		/* Create a PDF 1.4 clist write device */
 	c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
 	c_pdf14trans_clist_read_update	   /* procs.composite_clist_reade_update */
@@ -3037,6 +3072,7 @@
 	c_pdf14trans_equal,                      /* procs.equal */
 	c_pdf14trans_write,                      /* procs.write */
 	c_pdf14trans_read,                       /* procs.read */
+	c_pdf14trans_adjust_ctm,		 /* procs.adjust_ctm */
 		/* The PDF 1.4 clist writer already exists, Do not create it. */
 	gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
 	c_pdf14trans_clist_read_update	   /* procs.composite_clist_reade_update */
@@ -3056,7 +3092,7 @@
 /*
  * Create a PDF 1.4 transparency compositor data structure.
  */
-int
+static int
 gs_create_pdf14trans(
     gs_composite_t **               ppct,
     const gs_pdf14trans_params_t *  pparams,
@@ -3087,6 +3123,7 @@
     gs_composite_t * pct = NULL;
     int code;
 
+    pparams->ctm = ctm_only(pis);
     code = gs_create_pdf14trans(&pct, pparams, mem);
     if (code < 0)
 	return code;
@@ -4162,6 +4199,12 @@
     pdf14_clist_device * p14dev;
     int code = 0;
 
+    {	gx_device_clist_writer * const cdev =
+			&((gx_device_clist *)dev)->writer;
+
+	state_update(ctm); /* See c_pdf14trans_write. */
+    }
+
     /* We only handle the push/pop operations */
     switch (pdf14pct->params.pdf14_op) {
 	case PDF14_PUSH_DEVICE:

Modified: trunk/gs/src/gsalphac.c
===================================================================
--- trunk/gs/src/gsalphac.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gsalphac.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -100,6 +100,7 @@
 	c_alpha_equal,
 	c_alpha_write,
 	c_alpha_read,
+	gx_default_composite_adjust_ctm,
 	gx_default_composite_clist_write_update,
 	gx_default_composite_clist_read_update
     }

Modified: trunk/gs/src/gsovrc.c
===================================================================
--- trunk/gs/src/gsovrc.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gsovrc.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -200,6 +200,11 @@
 
 
 static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
+static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
+static composite_equal_proc(c_overprint_equal);
+static composite_write_proc(c_overprint_write);
+static composite_read_proc(c_overprint_read);
+static composite_adjust_ctm_proc(c_overprint_adjust_ctm);
 
 /* methods for the overprint compositor */
 const gs_composite_type_t   gs_composite_overprint_type = {
@@ -209,6 +214,7 @@
         c_overprint_equal,                      /* procs.equal */
         c_overprint_write,                      /* procs.write */
         c_overprint_read,                       /* procs.read */
+	gx_default_composite_adjust_ctm,
 	gx_default_composite_clist_write_update,/* procs.composite_clist_write_update */
 	gx_default_composite_clist_read_update	/* procs.composite_clist_reade_update */
     }                                           /* procs */

Modified: trunk/gs/src/gsropc.c
===================================================================
--- trunk/gs/src/gsropc.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gsropc.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -35,6 +35,7 @@
 	c_rop_equal,
 	c_rop_write,
 	c_rop_read,
+	gx_default_composite_adjust_ctm,
 	gx_default_composite_clist_write_update,
 	gx_default_composite_clist_read_update
     }

Modified: trunk/gs/src/gstrans.h
===================================================================
--- trunk/gs/src/gstrans.h	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gstrans.h	2007-12-07 23:39:06 UTC (rev 8426)
@@ -19,6 +19,7 @@
 
 #include "gstparam.h"
 #include "gxcomp.h"
+#include "gsmatrix.h"
 
 /*
  * Define the operations for the PDF 1.4 transparency compositor.
@@ -89,6 +90,7 @@
     gs_transparency_source_t opacity;
     gs_transparency_source_t shape;
     bool mask_is_image;
+    gs_matrix ctm;
 };
 
 #ifndef gs_pdf14trans_params_DEFINED

Modified: trunk/gs/src/gxcldev.h
===================================================================
--- trunk/gs/src/gxcldev.h	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gxcldev.h	2007-12-07 23:39:06 UTC (rev 8426)
@@ -605,6 +605,10 @@
 #define RECT_RECOVER(codevar) (codevar < 0 && (codevar = clist_VMerror_recover(cdev, codevar)) >= 0)
 #define SET_BAND_CODE(codevar) (re.band_code = codevar)
 
+/* Read a transformation matrix. */
+const byte *cmd_read_matrix(gs_matrix * pmat, const byte * cbp);
+
+
 /* ------ Exported by gxclrect.c ------ */
 
 /* Put out a fill or tile rectangle command. */

Modified: trunk/gs/src/gxclimag.c
===================================================================
--- trunk/gs/src/gxclimag.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gxclimag.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -868,6 +868,7 @@
     if (code < 0)
         return code;
 
+#if 0 /* Disabled sinse c_pdf14trans_write includes CTM into the pdf14 compositor parameters. */
     if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
 	gx_device_clist_writer * const cdev =
 			&((gx_device_clist *)dev)->writer;
@@ -883,6 +884,7 @@
 	    return code;
 	state_update(ctm);
     }
+#endif
 
     /* overprint applies to all bands */
     /* fixme: optimize: the pdf14 compositor could be applied 

Modified: trunk/gs/src/gxclpath.c
===================================================================
--- trunk/gs/src/gxclpath.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gxclpath.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -301,6 +301,18 @@
     return (uint)stell(&s);
 }
 
+/* Compute the written CTM length. */
+int
+cmd_write_ctm_return_length_nodevice(const gs_matrix *m)
+{
+    stream s;
+
+    s_init(&s, NULL);
+    swrite_position_only(&s);
+    sput_matrix(&s, m);
+    return (uint)stell(&s);
+}
+
 /* Write out CTM. */
 int
 cmd_write_ctm(const gs_matrix *m, byte *dp, int len)

Modified: trunk/gs/src/gxclpath.h
===================================================================
--- trunk/gs/src/gxclpath.h	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gxclpath.h	2007-12-07 23:39:06 UTC (rev 8426)
@@ -246,6 +246,7 @@
 
 /* Compute the written CTM length. */
 int cmd_write_ctm_return_length(gx_device_clist_writer * cldev, const gs_matrix *m);
+int cmd_write_ctm_return_length_nodevice(const gs_matrix *m);
 /* Write out CTM. */
 int cmd_write_ctm(const gs_matrix *m, byte *dp, int len);
 

Modified: trunk/gs/src/gxclrast.c
===================================================================
--- trunk/gs/src/gxclrast.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gxclrast.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -242,13 +242,13 @@
                             gs_memory_t *mem);
 static int read_create_compositor(command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp);
 static int apply_create_compositor(gx_device_clist_reader *cdev, gs_imager_state *pis, 
-				   gs_memory_t *mem, gs_composite_t *pcomp, gx_device **ptarget);
+				   gs_memory_t *mem, gs_composite_t *pcomp, 
+				   int x0, int y0, gx_device **ptarget);
 static int read_alloc_ht_buff(ht_buff_t *, uint, gs_memory_t *);
 static int read_ht_segment(ht_buff_t *, command_buf_t *, gs_imager_state *,
 			    gx_device *, gs_memory_t *);
 
 static const byte *cmd_read_rect(int, gx_cmd_rect *, const byte *);
-static const byte *cmd_read_matrix(gs_matrix *, const byte *);
 static const byte *cmd_read_short_bits(command_buf_t *pcb, byte *data,
                                         int width_bytes, int height,
                                         uint raster, const byte *cbp);
@@ -1352,11 +1352,14 @@
 					    pcomp_back = pcomp;
 					    pcomp = pcomp_ahead;
 					}
+					pcomp_back = pcomp_last;
+					pcomp_last = pcomp_first;
+					pcomp_first = pcomp_back;
 					/* Apply and clean the queue: */
 					while (pcomp_last != NULL) {
 					    pcomp = dequeue_last_compositor(&pcomp_first, &pcomp_last);
 					    code = apply_create_compositor(cdev, &imager_state, 
-						    mem, pcomp, &target); /* Releases the compositor. */
+						    mem, pcomp, x0, y0, &target); /* Releases the compositor. */
 					    if (code < 0)
 						goto out;
 					    tdev = target;
@@ -2385,11 +2388,15 @@
 }
 
 static int apply_create_compositor(gx_device_clist_reader *cdev, gs_imager_state *pis, 
-				   gs_memory_t *mem, gs_composite_t *pcomp, gx_device **ptarget)
+				   gs_memory_t *mem, gs_composite_t *pcomp, 
+				   int x0, int y0, gx_device **ptarget)
 {
     gx_device *tdev = *ptarget;
     int code;
 
+    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pis);
+    if (code < 0)
+        return code;
     /*
      * Apply the compositor to the target device; note that this may
      * change the target device.
@@ -2399,6 +2406,8 @@
         rc_increment(tdev);
         *ptarget = tdev;
     }
+    if (code < 0)
+        return code;
 
     /* Perform any updates for the clist device required */
     code = pcomp->type->procs.clist_compositor_read_update(pcomp,
@@ -2467,18 +2476,6 @@
     return cbp;
 }
 
-/* Read a transformation matrix. */
-static const byte *
-cmd_read_matrix(gs_matrix * pmat, const byte * cbp)
-{
-    stream s;
-
-    s_init(&s, NULL);
-    sread_string(&s, cbp, 1 + sizeof(*pmat));
-    sget_matrix(&s, pmat);
-    return cbp + stell(&s);
-}
-
 /*
  * Select a map for loading with data.
  *

Modified: trunk/gs/src/gxclutil.c
===================================================================
--- trunk/gs/src/gxclutil.c	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gxclutil.c	2007-12-07 23:39:06 UTC (rev 8426)
@@ -748,3 +748,16 @@
     s_RLD_set_defaults_inline(ss);
     s_RLD_init_inline(ss);
 }
+
+/* Read a transformation matrix. */
+const byte *
+cmd_read_matrix(gs_matrix * pmat, const byte * cbp)
+{
+    stream s;
+
+    s_init(&s, NULL);
+    sread_string(&s, cbp, 1 + sizeof(*pmat));
+    sget_matrix(&s, pmat);
+    return cbp + stell(&s);
+}
+

Modified: trunk/gs/src/gxcomp.h
===================================================================
--- trunk/gs/src/gxcomp.h	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/gxcomp.h	2007-12-07 23:39:06 UTC (rev 8426)
@@ -105,6 +105,15 @@
     composite_read_proc((*read));
 
     /*
+     * Convert the string representation of a function back to
+     * a structure, allocating the structure. Return the number of
+     * bytes read, or < 0 in the event of an error.
+     */
+#define composite_adjust_ctm_proc(proc)\
+  int proc(gs_composite_t *pcte, int x0, int y0, gs_imager_state *pis)
+    composite_adjust_ctm_proc((*adjust_ctm));
+
+    /*
      * Update the clist write device when a compositor device is created.
      */
 #define composite_clist_write_update(proc)\
@@ -134,6 +143,11 @@
 composite_clist_write_update(gx_default_composite_clist_write_update);
 
 /*
+ * Default handler for adjusting a compositor's CTM. */
+composite_adjust_ctm_proc(gx_default_composite_adjust_ctm);
+
+
+/*
  * Default implementation for adjusting the clist reader when a compositor
  * device is added.  The default does nothing.
  */

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2007-12-05 23:39:42 UTC (rev 8425)
+++ trunk/gs/src/lib.mak	2007-12-07 23:39:06 UTC (rev 8426)
@@ -2565,7 +2565,7 @@
 
 # ---------------- Transparency ---------------- #
 
-gstrans_h=$(GLSRC)gstrans.h $(gstparam_h) $(gxcomp_h)
+gstrans_h=$(GLSRC)gstrans.h $(gstparam_h) $(gxcomp_h) $(gsmatrix_h)
 gsipar3x_h=$(GLSRC)gsipar3x.h $(gsiparam_h) $(gsiparm3_h)
 gximag3x_h=$(GLSRC)gximag3x.h $(gsipar3x_h) $(gxiparam_h)
 gxblend_h=$(GLSRC)gxblend.h
@@ -2587,11 +2587,10 @@
 	$(GLCC) $(GLO_)gxblend.$(OBJ) $(C_) $(GLSRC)gxblend.c
 
 $(GLOBJ)gdevp14.$(OBJ) : $(GLSRC)gdevp14.c $(GXERR) $(math__h) $(memory__h)\
- $(gscdefs_h) $(gsdevice_h) $(gsdfilt_h) $(gsimage_h)\
- $(gsstruct_h) $(gstparam_h)\
- $(gxblend_h) $(gxdcolor_h) $(gxdevice_h) $(gxiparam_h) $(gxistate_h)\
- $(gxtext_h) $(gsrect_h) $(gstrans_h) $(gsutil_h) $(gxcldev_h)\
- $(gzstate_h) $(gdevp14_h) $(gsovrc_h) $(gxcmap_h) $(gscolor1_h)
+ $(gscdefs_h) $(gxdevice_h) $(gsdevice_h) $(gsstruct_h) $(gxistate_h) $(gxdcolor_h)\
+ $(gxiparam_h) $(gstparam_h) $(gxblend_h) $(gxtext_h) $(gsdfilt_h) $(gsimage_h)\
+ $(gsrect_h) $(gzstate_h) $(gdevdevn_h) $(gdevp14_h) $(gsovrc_h) $(gxcmap_h) $(gscolor1_h)\
+ $(gstrans_h) $(gsutil_h) $(gxcldev_h) $(gxclpath_h) $(gxdcconv_h)
 	$(GLCC) $(GLO_)gdevp14.$(OBJ) $(C_) $(GLSRC)gdevp14.c
 
 translib_=$(GLOBJ)gstrans.$(OBJ) $(GLOBJ)gximag3x.$(OBJ)\



More information about the gs-cvs mailing list