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

leonardo at ghostscript.com leonardo at ghostscript.com
Thu Nov 2 11:19:25 PST 2006


Author: leonardo
Date: 2006-11-02 11:19:23 -0800 (Thu, 02 Nov 2006)
New Revision: 7150

Added:
   trunk/gs/src/gximask.c
   trunk/gs/src/gximask.h
Modified:
   trunk/gs/src/gsimage.c
   trunk/gs/src/gxacpath.c
   trunk/gs/src/gxccache.c
   trunk/gs/src/gxclrast.c
   trunk/gs/src/gzcpath.h
   trunk/gs/src/int.mak
   trunk/gs/src/lib.mak
   trunk/gs/src/zfapi.c
Log:
Fix (imagemask) : An optimization for imagemask with a shading color, continued.

DETAILS :

This is a performance fix for 09-47D-3 .
It is a similar optimization as a recent one for imagemask, 
rather this one applies to different cases, which are not directly related to 
to Postscript operator imagemask. The cases are :
- filling a cached character with a shading color;
- filling a FAPI character with a shading color;
- rendering an imagemask while a clist playback (for future. 
  currently never happens with shadings).

This patch adds new modules gximask.c and gximask.h,
which factor out the common code for the mentioned cases.
The code is taken from the last patch for imagemask,
with minor restructurization.

The new function gx_image_fill_masked must be called
from the graphics librari instead a direct call
to the device virtual method fill_mask. 
It checks for the shading color and inserts the clipping device,
which represents the mask. 

Note that the clipping device always decompose a shading color,
so inserting the clipping device before it won't cause a problem.
However it needs some care when rendering to a high level device.

The clip accumulator device had no fill_mask virtual method.
This patch adds the default implementation 
for the proper work of gx_image_fill_masked.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gsimage.c
===================================================================
--- trunk/gs/src/gsimage.c	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/gsimage.c	2006-11-02 19:19:23 UTC (rev 7150)
@@ -24,10 +24,8 @@
 #include "gxdevice.h"
 #include "gxiparam.h"
 #include "gxpath.h"		/* for gx_effective_clip_path */
+#include "gximask.h"
 #include "gzstate.h"
-#include "gzacpath.h"
-#include "gzpath.h"
-#include "gzcpath.h"
 
 
 /*
@@ -175,23 +173,9 @@
 	gs_image_t *image = (gs_image_t *)pic;
 
 	if(image->ImageMask) {
-	    if (gx_dc_is_pattern2_color(pgs->dev_color)) {
-		if (!dev_proc(pgs->device, pattern_manage)(dev, gs_no_id, NULL, pattern_manage__can_accum)) {
-		    extern_st(st_device_cpath_accum);
-		    gs_memory_t *mem = pgs->memory;
-		    gx_device_cpath_accum *pcdev =  gs_alloc_struct(mem, 
-			    gx_device_cpath_accum, &st_device_cpath_accum, "gs_image_begin_typed");
-		    gs_fixed_rect cbox;
-
-		    if (pcdev == NULL)
-			return_error(gs_error_VMerror);
-		    gx_cpath_accum_begin(pcdev, mem);
-		    gx_cpath_outer_box(pcpath, &cbox);
-		    gx_cpath_accum_set_cbox(pcdev, &cbox);
-		    gx_device_retain((gx_device *)pcdev, true);
-		    dev2 = (gx_device *)pcdev;
-		}
-	    }
+	    code = gx_image_fill_masked_start(dev, pgs->dev_color, pcpath, pgs->memory, &dev2);
+	    if (code < 0)
+		return code;
 	}
     }
     return gx_device_begin_typed_image(dev2, (const gs_imager_state *)pgs,
@@ -595,27 +579,12 @@
 	if (dev_proc(penum->info->dev, pattern_manage)(penum->info->dev, 
 		    gs_no_id, NULL, pattern_manage__is_cpath_accum)) {
 	    /* Performing a conversion of imagemask into a clipping path. */
-	    gx_device_cpath_accum *pcdev = (gx_device_cpath_accum *)penum->info->dev;
-	    gx_clip_path cpath;
-	    gx_device_clip cdev;
+	    gx_device *cdev = penum->info->dev;
 
 	    code = gx_image_end(penum->info, !penum->error); /* Releases penum->info . */
-	    gx_cpath_init_local(&cpath, pcdev->memory);
-	    code1 = gx_cpath_accum_end(pcdev, &cpath);
+	    code1 = gx_image_fill_masked_end(cdev, penum->dev, pgs->dev_color);
 	    if (code == 0)
 		code = code1;
-	    gx_make_clip_path_device(&cdev, &cpath);
-	    cdev.target = penum->dev;
-	    (*dev_proc(&cdev, open_device)) ((gx_device *) & cdev);
-	    code1 = gx_device_color_fill_rectangle(pgs->dev_color, 
-			pcdev->bbox.p.x, pcdev->bbox.p.y, 
-			pcdev->bbox.q.x - pcdev->bbox.p.x, 
-			pcdev->bbox.q.y - pcdev->bbox.p.y, 
-			(gx_device *)&cdev, lop_default, 0);
-	    if (code == 0)
-		code = code1;
-	    gx_device_retain((gx_device *)pcdev, false);
-	    gx_cpath_free(&cpath, "s_image_cleanup");
 	} else
 	    code = gx_image_end(penum->info, !penum->error);
     }

Modified: trunk/gs/src/gxacpath.c
===================================================================
--- trunk/gs/src/gxacpath.c	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/gxacpath.c	2006-11-02 19:19:23 UTC (rev 7150)
@@ -80,7 +80,7 @@
   NULL,
   gx_default_fill_path,
   gx_default_stroke_path,
-  NULL,
+  gx_default_fill_mask,
   gx_default_fill_trapezoid,
   gx_default_fill_parallelogram,
   gx_default_fill_triangle,

Modified: trunk/gs/src/gxccache.c
===================================================================
--- trunk/gs/src/gxccache.c	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/gxccache.c	2006-11-02 19:19:23 UTC (rev 7150)
@@ -30,6 +30,7 @@
 #include "gxfont.h"
 #include "gxfcache.h"
 #include "gxxfont.h"
+#include "gximask.h"
 #include "gscspace.h"		/* for gsimage.h */
 #include "gsimage.h"
 #include "gxhttile.h"
@@ -385,7 +386,7 @@
 
 	code = gx_effective_clip_path(pgs, &pcpath);
 	if (code >= 0) {
-	    code = (*dev_proc(orig_dev, fill_mask))
+	    code = gx_image_fill_masked
 		(orig_dev, bits, 0, cc_raster(cc), cc->id,
 		 x, y, w, h, pdevc, depth, pgs->log_op, pcpath);
 	    if (code >= 0)

Modified: trunk/gs/src/gxclrast.c
===================================================================
--- trunk/gs/src/gxclrast.c	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/gxclrast.c	2006-11-02 19:19:23 UTC (rev 7150)
@@ -38,6 +38,7 @@
 #include "gxpaint.h"		/* for gx_fill/stroke_params */
 #include "gxhttile.h"
 #include "gxiparam.h"
+#include "gximask.h"
 #include "gzpath.h"
 #include "gzcpath.h"
 #include "gzacpath.h"
@@ -1473,7 +1474,7 @@
 									 * This call of copy_mono originated as a call
 									 * of fill_mask.
 									 */
-		    code = (*dev_proc(tdev, fill_mask))
+		    code = gx_image_fill_masked
 			(tdev, source, data_x, raster, gx_no_bitmap_id,
 			 state.rect.x - x0, state.rect.y - y0,
 			 state.rect.width - data_x, state.rect.height,

Added: trunk/gs/src/gximask.c
===================================================================
--- trunk/gs/src/gximask.c	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/gximask.c	2006-11-02 19:19:23 UTC (rev 7150)
@@ -0,0 +1,99 @@
+/* Copyright (C) 2001-2006 artofcode LLC.
+   All Rights Reserved.
+  
+   This software is provided AS-IS with no warranty, either express or
+   implied.
+
+   This software is distributed under license and may not be copied, modified
+   or distributed except as expressly authorized under the terms of that
+   license.  Refer to licensing information at http://www.artifex.com/
+   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
+   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* $Id$ */
+/* Functions for masked fill optimization. */
+#include "gx.h"
+#include "memory_.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gxdcolor.h"
+#include "gxcpath.h"
+#include "gzacpath.h"
+#include "gzcpath.h"
+
+
+/* Functions for masked fill optimization. */
+/* Imagemask with a shading color would paint entire shading for each rectangle of the mask.
+   These functions convert the mask into a clipping path and then render entire shading
+   at once through it.
+*/
+
+int
+gx_image_fill_masked_start(gx_device *dev, const gx_device_color *pdevc, const gx_clip_path *pcpath, 
+			   gs_memory_t *mem, gx_device **cdev)
+{
+    if (gx_dc_is_pattern2_color(pdevc)) {
+	if (!dev_proc(dev, pattern_manage)(dev, gs_no_id, NULL, pattern_manage__can_accum)) {
+	    extern_st(st_device_cpath_accum);
+	    gx_device_cpath_accum *pcdev =  gs_alloc_struct(mem, 
+		    gx_device_cpath_accum, &st_device_cpath_accum, "gx_image_fill_masked_start");
+	    gs_fixed_rect cbox;
+
+	    if (pcdev == NULL)
+		return_error(gs_error_VMerror);
+	    gx_cpath_accum_begin(pcdev, mem);
+	    gx_cpath_outer_box(pcpath, &cbox);
+	    gx_cpath_accum_set_cbox(pcdev, &cbox);
+	    pcdev->rc.memory = mem;
+	    gx_device_retain((gx_device *)pcdev, true);
+	    *cdev = (gx_device *)pcdev;
+	}
+    } else
+	*cdev = dev;
+    return 0;
+}
+
+int 
+gx_image_fill_masked_end(gx_device *dev, gx_device *tdev, const gx_device_color *pdevc)
+{
+    gx_device_cpath_accum *pcdev = (gx_device_cpath_accum *)dev;
+    gx_clip_path cpath;
+    gx_device_clip cdev;
+    int code, code1;
+
+    gx_cpath_init_local(&cpath, pcdev->memory);
+    code = gx_cpath_accum_end(pcdev, &cpath);
+    gx_make_clip_path_device(&cdev, &cpath);
+    cdev.target = tdev;
+    (*dev_proc(&cdev, open_device)) ((gx_device *) & cdev);
+    code1 = gx_device_color_fill_rectangle(pdevc, 
+		pcdev->bbox.p.x, pcdev->bbox.p.y, 
+		pcdev->bbox.q.x - pcdev->bbox.p.x, 
+		pcdev->bbox.q.y - pcdev->bbox.p.y, 
+		(gx_device *)&cdev, lop_default, 0);
+    if (code == 0)
+	code = code1;
+    gx_device_retain((gx_device *)pcdev, false);
+    gx_cpath_free(&cpath, "s_image_cleanup");
+    return code;
+}
+
+int 
+gx_image_fill_masked(gx_device *dev,
+    const byte *data, int data_x, int raster, gx_bitmap_id id,
+    int x, int y, int width, int height,
+    const gx_device_color *pdc, int depth,
+    gs_logical_operation_t lop, const gx_clip_path *pcpath)
+{
+    gx_device *cdev;
+    int code;
+
+    code = gx_image_fill_masked_start(dev, pdc, pcpath, dev->memory, &cdev);
+    if (code >= 0)
+	code = (*dev_proc(cdev, fill_mask))(cdev, data, data_x, raster, id,
+			    x, y, width, height, pdc, depth, lop, pcpath);
+    if (code >= 0 && cdev != dev)
+	code = gx_image_fill_masked_end(cdev, dev, pdc);
+    return code;
+}


Property changes on: trunk/gs/src/gximask.c
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: trunk/gs/src/gximask.h
===================================================================
--- trunk/gs/src/gximask.h	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/gximask.h	2006-11-02 19:19:23 UTC (rev 7150)
@@ -0,0 +1,48 @@
+/* Copyright (C) 2001-2006 artofcode LLC.
+   All Rights Reserved.
+  
+   This software is provided AS-IS with no warranty, either express or
+   implied.
+
+   This software is distributed under license and may not be copied, modified
+   or distributed except as expressly authorized under the terms of that
+   license.  Refer to licensing information at http://www.artifex.com/
+   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
+   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* $Id$ */
+/* Functions for masked fill optimization. */
+
+#ifndef gximask_INCLUDED
+#  define gximask_INCLUDED
+
+#include "gxbitmap.h"
+#include "gsropt.h"
+
+#ifndef gx_device_DEFINED
+#  define gx_device_DEFINED
+typedef struct gx_device_s gx_device;
+#endif
+#ifndef gx_device_color_DEFINED
+#  define gx_device_color_DEFINED
+typedef struct gx_device_color_s gx_device_color;
+#endif
+#ifndef gx_clip_path_DEFINED
+#  define gx_clip_path_DEFINED
+typedef struct gx_clip_path_s gx_clip_path;
+#endif
+
+int gx_image_fill_masked_start(gx_device *dev, const gx_device_color *pdevc, const gx_clip_path *pcpath, 
+			   gs_memory_t *mem, gx_device **cdev);
+
+int gx_image_fill_masked_end(gx_device *dev, gx_device *tdev, const gx_device_color *pdevc);
+
+int gx_image_fill_masked(gx_device *dev,
+    const byte *data, int data_x, int raster, gx_bitmap_id id,
+    int x, int y, int width, int height,
+    const gx_device_color *pdcolor, int depth,
+    gs_logical_operation_t lop, const gx_clip_path *pcpath);
+
+
+#endif /* gximask_INCLUDED */


Property changes on: trunk/gs/src/gximask.h
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: trunk/gs/src/gzcpath.h
===================================================================
--- trunk/gs/src/gzcpath.h	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/gzcpath.h	2006-11-02 19:19:23 UTC (rev 7150)
@@ -19,6 +19,7 @@
 #  define gzcpath_INCLUDED
 
 #include "gxcpath.h"
+#include "gzpath.h"
 
 /*
  * The reference counting considerations for clip paths are the same as

Modified: trunk/gs/src/int.mak
===================================================================
--- trunk/gs/src/int.mak	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/int.mak	2006-11-02 19:19:23 UTC (rev 7150)
@@ -1888,7 +1888,7 @@
 
 $(PSOBJ)zfapi.$(OBJ) : $(PSSRC)zfapi.c $(OP) $(math__h) $(memory__h) $(string__h)\
  $(gp_h) $(gscoord_h) $(gscrypt1_h) $(gsfont_h) $(gspaint_h) $(gspath_h)\
- $(gxchar_h) $(gxchrout_h) $(gxdevice_h) $(gxfcache_h) $(gxfcid_h)\
+ $(gxchar_h) $(gxchrout_h) $(gximask_h) $(gxdevice_h) $(gxfcache_h) $(gxfcid_h)\
  $(gxfont_h) $(gxfont1_h) $(gxpath_h) $(gzstate_h) $(gdevpsf_h)\
  $(bfont_h) $(dstack_h) $(files_h) \
  $(ichar_h) $(idict_h) $(iddict_h) $(idparam_h) $(iname_h) $(ifont_h)\

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/lib.mak	2006-11-02 19:19:23 UTC (rev 7150)
@@ -417,6 +417,7 @@
  $(gsstype_h) $(gsuid_h)\
  $(gxftype_h)
 gxiparam_h=$(GLSRC)gxiparam.h $(gsstype_h) $(gxdevcli_h)
+gximask_h=$(GLSRC)gximask.h $(gxibitmap_h) $(gsropt_h)
 gscie_h=$(GLSRC)gscie.h $(gconfigv_h) $(gsrefct_h) $(gsstype_h) $(gstypes_h) $(gxctable_h)
 gsicc_h=$(GLSRC)gsicc.h $(gscie_h)
 gscrd_h=$(GLSRC)gscrd.h $(gscie_h)
@@ -448,7 +449,7 @@
  $(gscolor_h) $(gscpm_h) $(gscsel_h) $(gsdevice_h) $(gsht_h) $(gsline_h)
 
 gzacpath_h=$(GLSRC)gzacpath.h $(GLSRC)gxcpath.h
-gzcpath_h=$(GLSRC)gzcpath.h $(gxcpath_h)
+gzcpath_h=$(GLSRC)gzcpath.h $(gxcpath_h) $(gzpath_h)
 gzht_h=$(GLSRC)gzht.h $(gscsel_h)\
  $(gxdht_h) $(gxfmap_h) $(gxht_h) $(gxhttile_h)
 gzline_h=$(GLSRC)gzline.h $(gxline_h)
@@ -546,7 +547,7 @@
  $(gscencs_h) $(gxfixed_h) $(gxmatrix_h)\
  $(gzstate_h) $(gzpath_h) $(gxdevice_h) $(gxdevmem_h)\
  $(gzcpath_h) $(gxchar_h) $(gxfont_h) $(gxfcache_h)\
- $(gxxfont_h) $(gscspace_h) $(gsimage_h) $(gxhttile_h)
+ $(gxxfont_h) $(gximask_h) $(gscspace_h) $(gsimage_h) $(gxhttile_h)
 	$(GLCC) $(GLO_)gxccache.$(OBJ) $(C_) $(GLSRC)gxccache.c
 
 $(GLOBJ)gxccman.$(OBJ) : $(GLSRC)gxccman.c $(GXERR) $(memory__h) $(gpcheck_h)\
@@ -662,6 +663,11 @@
  $(gzht_h)
 	$(GLCC) $(GLO_)gximono.$(OBJ) $(C_) $(GLSRC)gximono.c
 
+$(GLOBJ)gximask.$(OBJ) : $(GLSRC)gximask.c $(GXERR) $(memory__h) $(gserrors_h)\
+ $(gxdevice_h) $(gxdcolor_h) $(gxcpath_h) $(gzacpath_h)\
+ $(gzcpath_h) 
+ 	$(GLCC) $(GLO_)gximask.$(OBJ) $(C_) $(GLSRC)gximask.c
+
 $(GLOBJ)gxipixel.$(OBJ) : $(GLSRC)gxipixel.c $(GXERR) $(math__h) $(memory__h)\
  $(gpcheck_h)\
  $(gsccolor_h) $(gscdefs_h) $(gspaint_h) $(gsstruct_h) $(gsutil_h)\
@@ -817,8 +823,7 @@
 
 $(GLOBJ)gsimage.$(OBJ) : $(GLSRC)gsimage.c $(GXERR) $(memory__h)\
  $(gscspace_h) $(gsimage_h) $(gsmatrix_h) $(gsstruct_h) $(gsptype2_h)\
- $(gxarith_h) $(gxdevice_h) $(gxiparam_h) $(gxpath_h) $(gzstate_h)\
- $(gzacpath_h) $(gzpath_h) $(gzcpath_h)
+ $(gxarith_h) $(gxdevice_h) $(gxiparam_h) $(gxpath_h) $(gximask_h) $(gzstate_h)
 	$(GLCC) $(GLO_)gsimage.$(OBJ) $(C_) $(GLSRC)gsimage.c
 
 $(GLOBJ)gsimpath.$(OBJ) : $(GLSRC)gsimpath.c $(GXERR)\
@@ -1091,7 +1096,7 @@
 LIB4x=$(GLOBJ)gxdcconv.$(OBJ) $(GLOBJ)gxdcolor.$(OBJ) $(GLOBJ)gxhldevc.$(OBJ)
 LIB5x=$(GLOBJ)gxfill.$(OBJ) $(GLOBJ)gxfdrop.$(OBJ) $(GLOBJ)gxht.$(OBJ) $(GLOBJ)gxhtbit.$(OBJ)
 LIB6x=$(GLOBJ)gxwts.$(OBJ) $(GLOBJ)gxidata.$(OBJ) $(GLOBJ)gxifast.$(OBJ) $(GLOBJ)gximage.$(OBJ)
-LIB7x=$(GLOBJ)gximage1.$(OBJ) $(GLOBJ)gximono.$(OBJ) $(GLOBJ)gxipixel.$(OBJ)
+LIB7x=$(GLOBJ)gximage1.$(OBJ) $(GLOBJ)gximono.$(OBJ) $(GLOBJ)gxipixel.$(OBJ) $(GLOBJ)gximask.$(OBJ)
 LIB8x=$(GLOBJ)gxpaint.$(OBJ) $(GLOBJ)gxpath.$(OBJ) $(GLOBJ)gxpath2.$(OBJ)
 LIB9x=$(GLOBJ)gxpcopy.$(OBJ) $(GLOBJ)gxpdash.$(OBJ) $(GLOBJ)gxpflat.$(OBJ)
 LIB10x=$(GLOBJ)gxsample.$(OBJ) $(GLOBJ)gxstroke.$(OBJ) $(GLOBJ)gxsync.$(OBJ) $(GLOBJ)vdtrace.$(OBJ)
@@ -1654,7 +1659,7 @@
  $(gsdevice_h) $(gsiparm4_h)\
  $(gxdevmem_h) $(gxcldev_h) $(gxclpath_h) $(gxcmap_h)\
  $(gxcolor2_h) $(gxcspace_h) $(gxdhtres_h) $(gxgetbit_h)\
- $(gxpaint_h) $(gxhttile_h) $(gxiparam_h)\
+ $(gxpaint_h) $(gxhttile_h) $(gxiparam_h) $(gximask_h)\
  $(gzpath_h) $(gxcpath_h) $(gzacpath_h)\
  $(stream_h) $(strimpl_h) $(gxcomp_h)\
  $(gsserial_h) $(gxdhtserial_h) $(gzht_h)

Modified: trunk/gs/src/zfapi.c
===================================================================
--- trunk/gs/src/zfapi.c	2006-11-01 21:18:41 UTC (rev 7149)
+++ trunk/gs/src/zfapi.c	2006-11-02 19:19:23 UTC (rev 7150)
@@ -27,6 +27,7 @@
 #include "gxpath.h"
 #include "gxfcache.h"
 #include "gxchrout.h"
+#include "gximask.h"
 #include "gscoord.h"
 #include "gspaint.h"
 #include "gsfont.h"
@@ -1208,7 +1209,7 @@
 	        const gx_clip_path * pcpath = i_ctx_p->pgs->clip_path; 
                 const gx_drawing_color * pdcolor = penum->pdcolor;
 
-		if ((code = dev_proc(dev, fill_mask)(dev, rast.p, 0, rast.line_step, 0,
+		if ((code = gx_image_fill_masked(dev, rast.p, 0, rast.line_step, 0,
 			          (int)(penum_s->pgs->ctm.tx + (double)rast_orig_x / (1 << frac_pixel_shift) + penum_s->fapi_glyph_shift.x + 0.5), 
 			          (int)(penum_s->pgs->ctm.ty + (double)rast_orig_y / (1 << frac_pixel_shift) + penum_s->fapi_glyph_shift.y + 0.5), 
 			          rast.width, rast.height,



More information about the gs-cvs mailing list