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

leonardo at ghostscript.com leonardo at ghostscript.com
Mon Jan 28 00:45:22 PST 2008


Author: leonardo
Date: 2008-01-28 00:45:21 -0800 (Mon, 28 Jan 2008)
New Revision: 8506

Modified:
   trunk/gs/src/gxclrast.c
Log:
Fix (clist & transparency) : Improve the compositor queue logic.

DETAILS :

Bug 689492 "Ghostscript uses a large amount of memory", part 2.

This patch fixes the missed shadow of a text, which is mentioned 
in the Comment #8 of the bug report.

1. Added macros for configuring visual trace for easier debugging.
2. The idle transparency bufer allocation condition was wrong. 
   The patched code allocated ;esser buffers.
3. Found more cases when a mask needs to be released.
4. The old code immediately executes idle masks.
   It caused a wrong order for compositor execution
   with images that have a soft mask.
   With the test case the image's mask was executed before 
   the group that containing the image.
   It caused a premature releasing of a mask,
   which preceeeds the group and must noy be released.

   The new code delays the execution of idle masks
   after all containing groups are executed,
   so that the queue is now longer and stores all masks.
   We beleive that's not harmful, because
   transparency queue elements are pretty small and
   work for hos based applications only.

   The new function mark_as_idle works for the new logic.
   Few aother functions are enhanced with a smarter
   processing of the idle flag.
5. Improved comments for the compositor queue logic.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gxclrast.c
===================================================================
--- trunk/gs/src/gxclrast.c	2008-01-26 13:21:27 UTC (rev 8505)
+++ trunk/gs/src/gxclrast.c	2008-01-28 08:45:21 UTC (rev 8506)
@@ -366,7 +366,7 @@
 	code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
 	if (code < 0)
 	    return code;
-	pcomp->idle = idle;
+	pcomp->idle |= idle;
 	code = apply_create_compositor(cdev, pis, mem, pcomp, x0, y0, target); /* Releases the compositor. */
 	if (code < 0)
 	    return code;
@@ -375,6 +375,19 @@
     return 0;
 }
 
+static void
+mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
+{
+    gs_composite_t *pcomp = pcomp_start;
+
+    while (pcomp != NULL) {
+	pcomp->idle = true;
+	if (pcomp == pcomp_end)
+	    break;
+	pcomp = pcomp->next;
+    }
+}
+
 static inline void
 drop_compositor_queue(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, 
 		      gs_composite_t *pcomp_from, gs_memory_t *mem)
@@ -1412,6 +1425,10 @@
 					    -x0, -y0, gs_color_select_all);
 				cbp -= 2; /* Step back to simplify the cycle invariant below. */
 				for (;;) {
+				    /* This internal loop looks ahead for compositor commands and 
+				       copies them into a temporary queue. Compositors, which do not paint something,
+				       are marked as idle and later executed with a reduced functionality 
+				       for reducing time and memory expense. */
 				    int len;
 
 				    if (cbp >= cbuf.limit) {
@@ -1434,9 +1451,10 @@
 					if (code < 0)
 					    goto out;
 					else if (code == 0) {
+					    /* Enqueue. */
 					    enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
 					} else if (code == 1) {
-					    /* Annihilate the last compositors. */
+					    /* Execute idle. */
 					    enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
 					    code = execute_compositor_queue(cdev, &target, &tdev, 
 						&imager_state, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true);
@@ -1464,8 +1482,13 @@
 					    enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
 					    free_compositor(pcomp_opening, mem);
 					} else if (code == 5) {
+					    /* Annihilate the last compositors. */
 					    enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
 					    drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem);
+					} else if (code == 6) {
+					    /* Mark as idle. */
+					    enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
+					    mark_as_idle(pcomp_opening, pcomp);
 					} else {
 					    code = gs_note_error(gs_error_unregistered); /* Must not happen. */
 					    goto out;
@@ -1537,7 +1560,7 @@
 						goto out;
 					}
 				    } else {
-					/* A drawing command, execute the queue. */
+					/* A drawing command, execute entire queue. */
 					code = execute_compositor_queue(cdev, &target, &tdev, 
 					    &imager_state, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
   					if (code < 0)



More information about the gs-cvs mailing list