[gs-code-review] A preliminary patch for high level patterns

Henry Stiles henry.stiles at artifex.com
Sun Apr 15 23:46:39 PDT 2007


Igor V. Melichev wrote:
> This is a preparation for fixing the bug 688396, step 4.
> This patch is not ready for commitment.
> I publicize it just to account useful ideas from reviewers.
>
> The patch implements patterns with clist.
> The choice between the old and the new implementation
> is being controlled with MAX_BITMAP_PATTERN_SIZE macro.
> It's value is chosen temporary for debug purpose only.
> When the tile size is bigger, it writes the pattern
> command stream into a clist object, which then
> is stored into the pattern cache.
> The pattern instantiation is done with the clist playback.
>
> This code is not complete :
> 1. It does not perform the tiling. Just renders a single instance of 
> the pattern cell.
> 2. The memory cleanup is not done when the pattern cache entry purges.
>
> However it paints something with a simple test (attached).
> I'd like to get ideas from reviewers at this state.
> Particularly I don't like 2 things :
> 1. my clist device initialization code;
Sorry, I am late to get around to this.  This is complicated because now 
there are now two clist devices (file and memory).  Is the only reason 
patterns must be done in memory performance?  Am I missing something or 
would it be possible to go back to the old separate compilation units 
for clist file and memory and have the new clist pattern object be file 
based if that is what is set for the current build.
> 2. what happens with non_gc_memory .
If you mean how this new code works with the non gc clients... I'd like 
to be able to build and run pcl (that will get you a better answer).  
Your code broke the async renderer and pcl with 7837.  I can work around 
this but it would be nice if you fixed it.

You can see this by adding the bmpamono.dev to gs or build pcl.

I think we are going to get rid of the asyncronous renderer but unless 
you have a strong need to deprecate it now I'd like to keep it compiling 
and running.

Thanks

Henry

>
> Igor.
> *** F:\SVN-GS\HEAD\gs\src\gxcldev.h    Fri Apr  6 09:52:30 2007
> --- files\gs\src\gxcldev.h    Sat Apr 14 00:37:24 2007
> ***************
> *** 737,739 ****
> --- 737,747 ----
>              int x0, int y0, gs_memory_t *mem);
>  
> + /* Playback the band file, taking the indicated action w/ its 
> contents. */
> + int clist_playback_file_bands(clist_playback_action action,
> +                       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);
> +  #endif /* gxcldev_INCLUDED */
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxclist.c    Tue Apr 10 10:54:58 2007
> --- files\gs\src\gxclist.c    Sat Apr 14 00:24:50 2007
> ***************
> *** 45,51 ****
>      case 1: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
>                   cdev->writer.color_space.space : 0));
>      default:
>      return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
> !               sizeof(gs_imager_state), index - 2);
>      }
>  ENUM_PTRS_END
> --- 45,52 ----
>      case 1: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
>                   cdev->writer.color_space.space : 0));
> +     case 2: return ENUM_OBJ(cdev->writer.pinst);
>      default:
>      return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
> !               sizeof(gs_imager_state), index - 3);
>      }
>  ENUM_PTRS_END
> ***************
> *** 60,63 ****
> --- 61,65 ----
>      RELOC_VAR(cdev->writer.color_space.space);
>      }
> +     RELOC_VAR(cdev->writer.pinst);
>      RELOC_USING(st_imager_state, &cdev->writer.imager_state,
>          sizeof(gs_imager_state));
> ***************
> *** 153,161 ****
>  {        if (in_memory || clist_io_procs_file_global == NULL)
> !     pclist_dev->common.page_info.io_procs = 
> pclist_dev->reader.page_info.io_procs = !         
> pclist_dev->writer.page_info.io_procs = clist_io_procs_memory_global;
>      else
> !     pclist_dev->common.page_info.io_procs = 
> pclist_dev->reader.page_info.io_procs = !         
> pclist_dev->writer.page_info.io_procs = clist_io_procs_file_global;
>  }
>  
> --- 155,161 ----
>  {        if (in_memory || clist_io_procs_file_global == NULL)
> !     pclist_dev->common.page_info.io_procs = 
> clist_io_procs_memory_global;
>      else
> !     pclist_dev->common.page_info.io_procs = clist_io_procs_file_global;
>  }
>  
> ***************
> *** 256,260 ****
> --- 256,267 ----
>      &((gx_device_clist *)dev)->writer;
>      int nbands;
> +     extern dev_proc_open_device(pattern_clist_open_device);
>  
> +     if (dev->procs.open_device == pattern_clist_open_device) {
> +     /* We don't need bands really. */
> +     cdev->page_band_height = dev->height;
> +     cdev->nbands = 1;
> +     return 0;
> +     }
>      if (gdev_mem_data_size(bdev, band_width, band_height) > data_size)
>      return_error(gs_error_rangecheck);
> ***************
> *** 599,605 ****
> --- 606,617 ----
>      gx_device_clist_writer * const cdev =
>      &((gx_device_clist *)dev)->writer;
> +     extern dev_proc_open_device(pattern_clist_open_device);
>  
>      if (cdev->do_not_open_or_close_bandfiles)
>      return 0;
> +     if (cdev->procs.open_device == pattern_clist_open_device) {
> +     gs_free_object(cdev->bandlist_memory, cdev->data, "clist_close");
> +     cdev->data = NULL;
> +     }
>      return clist_close_output_file(dev);
>  }
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxclist.h    Mon Apr  9 12:55:03 2007
> --- files\gs\src\gxclist.h    Sat Apr 14 00:37:24 2007
> ***************
> *** 57,60 ****
> --- 57,65 ----
>   */
>  
> + #ifndef gs_pattern1_instance_t_DEFINED
> + #  define gs_pattern1_instance_t_DEFINED
> + typedef struct gs_pattern1_instance_s gs_pattern1_instance_t;
> + #endif
> +  /* ---------------- Public structures ---------------- */
>  
> ***************
> *** 243,246 ****
> --- 248,252 ----
>      proc_free_up_bandlist_memory((*free_up_bandlist_memory)); /* if 
> nz, proc to free some bandlist memory */
>      int disable_mask;        /* mask of routines to disable 
> clist_disable_xxx */
> +     gs_pattern1_instance_t *pinst; /* Used when it is a pattern 
> clist. */
>  } gx_device_clist_writer;
>  
> ***************
> *** 265,273 ****
>  } gx_device_clist_reader;
>  
> ! typedef union gx_device_clist_s {
>      gx_device_clist_common common;
>      gx_device_clist_reader reader;
>      gx_device_clist_writer writer;
> ! } gx_device_clist;
>  
>  extern_st(st_device_clist);
> --- 271,284 ----
>  } gx_device_clist_reader;
>  
> ! union gx_device_clist_s {
>      gx_device_clist_common common;
>      gx_device_clist_reader reader;
>      gx_device_clist_writer writer;
> ! };
> ! ! #ifndef gx_device_clist_DEFINED
> ! #define gx_device_clist_DEFINED
> ! typedef union gx_device_clist_s gx_device_clist;
> ! #endif
>  
>  extern_st(st_device_clist);
> ***************
> *** 277,281 ****
>      gx_device_finalize)
>  #define st_device_clist_max_ptrs\
> !   (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 1)
>  
>  /* setup before opening clist device */
> --- 288,292 ----
>      gx_device_finalize)
>  #define st_device_clist_max_ptrs\
> !   (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 3)
>  
>  /* setup before opening clist device */
> ***************
> *** 292,295 ****
> --- 303,307 ----
>      (xclist)->writer.disable_mask = (xdisable);\
>      (xclist)->writer.page_uses_transparency = (pageusestransparency);\
> +     (xclist)->writer.pinst = NULL;\
>      END
>  
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxclmem.c    Tue Apr 10 10:54:58 2007
> --- files\gs\src\gxclmem.c    Wed Apr 11 22:13:39 2007
> ***************
> *** 1143,1147 ****
>  gs_gxclmem_init(gs_memory_t *mem)
>  {
> !     clist_io_procs_file_global = &clist_io_procs_memory;
>      return 0;
>  }
> --- 1143,1147 ----
>  gs_gxclmem_init(gs_memory_t *mem)
>  {
> !     clist_io_procs_memory_global = &clist_io_procs_memory;
>      return 0;
>  }
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxclmem.h    Mon Apr  9 12:55:03 2007
> --- files\gs\src\gxclmem.h    Thu Apr 12 10:22:48 2007
> ***************
> *** 62,66 ****
>  } LOG_MEMFILE_BLK;
>  
> ! typedef struct MEMFILE {
>      gs_memory_t *memory;    /* storage allocator */
>      gs_memory_t *data_memory;    /* storage allocator for data */
> --- 62,66 ----
>  } LOG_MEMFILE_BLK;
>  
> ! struct MEMFILE_s {
>      gs_memory_t *memory;    /* storage allocator */
>      gs_memory_t *data_memory;    /* storage allocator for data */
> ***************
> *** 103,107 ****
>      stream_state *compress_state;
>      stream_state *decompress_state;
> ! } MEMFILE;
>  
>  /*
> --- 103,111 ----
>      stream_state *compress_state;
>      stream_state *decompress_state;
> ! };
> ! #ifndef MEMFILE_DEFINED
> ! #define MEMFILE_DEFINED
> ! typedef struct MEMFILE_s MEMFILE;
> ! #endif
>  
>  /*
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxclread.c    Tue Apr 10 10:54:58 2007
> --- files\gs\src\gxclread.c    Fri Apr 13 23:14:57 2007
> ***************
> *** 143,152 ****
>  
>  private int clist_render_init(gx_device_clist *);
> - private int clist_playback_file_bands(clist_playback_action action,
> -                       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);
>  private int clist_rasterize_lines(gx_device *dev, int y, int lineCount,
>                    gx_device *bdev,
> --- 143,146 ----
> ***************
> *** 484,488 ****
>  
>  /* Playback the band file, taking the indicated action w/ its 
> contents. */
> ! private int
>  clist_playback_file_bands(clist_playback_action action, 
>                gx_device_clist_reader *crdev,
> --- 478,482 ----
>  
>  /* Playback the band file, taking the indicated action w/ its 
> contents. */
> ! int
>  clist_playback_file_bands(clist_playback_action action, 
>                gx_device_clist_reader *crdev,
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxp1fill.c    Wed Mar 15 15:05:08 2006
> --- files\gs\src\gxp1fill.c    Sat Apr 14 01:00:09 2007
> ***************
> *** 27,30 ****
> --- 27,31 ----
>  #include "gxpcolor.h"
>  #include "gxp1impl.h"
> + #include "gxcldev.h"
>  
>  /* Define the state for tile filling. */
> ***************
> *** 236,239 ****
> --- 237,250 ----
>      return code;
>  }
> + + private int + clist_fopen_dummy(char fname[gp_file_name_sizeof], 
> const char *fmode,
> +             clist_file_ptr * pcf,
> +             gs_memory_t * mem, gs_memory_t *data_mem,
> +             bool ok_to_compress)
> + {
> +     return 0;
> + }
> +  int
>  gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, 
> int y,
> ***************
> *** 253,256 ****
> --- 264,285 ----
>      if (rop_source == NULL)
>      set_rop_no_source(rop_source, no_source, dev);
> +     if (ptile->cdev != NULL) {
> +     gs_memory_t *mem = dev->memory;
> +     gx_device_clist *cdev = ptile->cdev;
> +     gx_device_clist_reader *crdev = (gx_device_clist_reader *)cdev;
> +     int x0 = 0, y0 = 0;
> +     gx_device_buf_procs_t buf_procs = {0};
> + +     crdev->yplane.depth = 0; /* Don't know what to set here. */
> +     crdev->yplane.shift = 0;
> +     crdev->yplane.index = -1;
> +     crdev->pages = NULL;
> +     crdev->num_pages = 1;
> +     crdev->page_info.io_procs->rewind(crdev->page_info.bfile, false, 
> NULL);
> +     crdev->page_info.io_procs->rewind(crdev->page_info.cfile, false, 
> NULL);
> +     code = clist_playback_file_bands(playback_action_render,
> +             crdev, &crdev->page_info, dev, 0, 0, x0, y0);
> +     return code;
> +    }
>      bits = &ptile->tbits;
>      code = tile_fill_init(&state, pdevc, dev, false);
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxpcmap.c    Tue Apr 10 21:14:03 2007
> --- files\gs\src\gxpcmap.c    Sat Apr 14 02:00:18 2007
> ***************
> *** 29,32 ****
> --- 29,33 ----
>  #include "gxpcolor.h"
>  #include "gxp1impl.h"
> + #include "gxclist.h"
>  #include "gzstate.h"
>  
> ***************
> *** 138,148 ****
>  };
>  
>  /* Allocate a pattern accumulator, with an initial refct of 0. */
> ! gx_device_pattern_accum *
> ! gx_pattern_accum_alloc(gs_memory_t * mem, gs_memory_t * 
> stoarge_memory,                 gs_pattern1_instance_t *pinst, 
> client_name_t cname)
>  {
> !     gx_device_pattern_accum *adev =
> !     gs_alloc_struct(mem, gx_device_pattern_accum,
>              &st_device_pattern_accum, cname);
>  
> --- 139,191 ----
>  };
>  
> + + private int + dummy_free_up_bandlist_memory(gx_device *cldev, bool b)
> + {
> +     return 0;
> + }
> + + int + pattern_clist_open_device(gx_device *dev)
> + {
> +     /* This function is defiled only for clist_init_bands. */
> +     return gs_clist_device_procs.open_device(dev);
> + }
> + + private dev_proc_create_buf_device(dummy_create_buf_device)
> + {
> +     gx_device_memory *mdev = (gx_device_memory *)*pbdev;
> + +     gs_make_mem_device(mdev, 
> gdev_mem_device_for_bits(target->color_info.depth),
> +         mem, 0, target);
> +     return 0;
> + }
> + private dev_proc_size_buf_device(dummy_size_buf_device)
> + {
> +     return 0;
> + }
> + private dev_proc_setup_buf_device(dummy_setup_buf_device)
> + {
> +     return 0;
> + }
> + private dev_proc_destroy_buf_device(dummy_destroy_buf_device)
> + {
> + }
> + + #define MAX_BITMAP_PATTERN_SIZE 10000
> +  /* Allocate a pattern accumulator, with an initial refct of 0. */
> ! gx_device_forward *
> ! gx_pattern_accum_alloc(gs_memory_t * mem, gs_memory_t * 
> storage_memory,                 gs_pattern1_instance_t *pinst, 
> client_name_t cname)
>  {
> !     gx_device *tdev = pinst->saved->device;
> !     int depth = (pinst->template.PaintType == 1 ? 1 : 
> tdev->color_info.depth);
> !     int raster = (pinst->size.x * depth + 7) / 8;
> !     int64_t size = (int64_t)raster * pinst->size.y;
> !     gx_device_forward *fdev;
> ! !     if (size < MAX_BITMAP_PATTERN_SIZE) {
> !     gx_device_pattern_accum *adev = gs_alloc_struct(mem, 
> gx_device_pattern_accum,
>              &st_device_pattern_accum, cname);
>  
> ***************
> *** 152,160 ****
>             (const gx_device *)&gs_pattern_accum_device,
>             mem, true);
> -     check_device_separable((gx_device *)adev);
> -     gx_device_forward_fill_in_procs((gx_device_forward *)adev);
>      adev->instance = pinst;
> !     adev->bitmap_memory = stoarge_memory;
> !     return adev;
>  }
>  
> --- 195,289 ----
>                 (const gx_device *)&gs_pattern_accum_device,
>                 mem, true);
>      adev->instance = pinst;
> !     adev->bitmap_memory = storage_memory;
> !     fdev = (gx_device_forward *)adev;
> !     } else {
> !     int code;
> !     int save_height = tdev->height;
> !     gx_device_buf_procs_t buf_procs = {dummy_create_buf_device,
> !     dummy_size_buf_device, dummy_setup_buf_device, 
> dummy_destroy_buf_device};
> !     gx_device_clist *cdev = gs_alloc_struct(mem, gx_device_clist,
> !             &st_device_clist, cname);
> !     gx_device_clist_writer *cwdev = (gx_device_clist_writer *)cdev;
> !     const int data_size = 1024*32;
> !     byte *data;
> ! !     if (cdev == 0)
> !         return 0;
> !     /* We're not shure how big area do we need here.
> !        Definitely we need 1 state in 'states'.
> !        Not sure whether we need to create tile_cache, etc..
> !        Note it is allocated in non-gc memory,
> !        because the garbager descriptor for
> !        gx_device_clist do not enumerate 'data'
> !        and its subfields, assuming they do not relocate.
> !        We place command list files to non-gc memory
> !        due to same reason.
> !      */
> !     data = gs_alloc_bytes(storage_memory->non_gc_memory, data_size, 
> cname);
> !     if (data == NULL) {
> !         gs_free_object(mem, cdev, cname);
> !         return 0;
> !     }
> !     memset(cdev, 0, sizeof(*cdev));
> !     cwdev->params_size = sizeof(gx_device_clist);
> !     cwdev->static_procs = NULL;
> !     cwdev->dname = "pattern-clist";
> !     cwdev->memory = mem;
> !     cwdev->stype = &st_device_clist;
> !     cwdev->stype_is_dynamic = false;
> !     cwdev->finalize = NULL;
> !     rc_init(cwdev, mem, 1);
> !     cwdev->retained = true;
> !     cwdev->is_open = false;
> !     cwdev->max_fill_band = 0;
> !     cwdev->color_info = tdev->color_info;
> !     cwdev->cached_colors = tdev->cached_colors;
> !     cwdev->width = pinst->size.x;
> !     cwdev->height = pinst->size.y;
> !         cwdev->LeadingEdge = tdev->LeadingEdge;
> !     /* Fields left zeroed :
> !     float MediaSize[2];
> !     float ImagingBBox[4];
> !     bool ImagingBBox_set;
> !     */
> !     cwdev->HWResolution[0] = tdev->HWResolution[0];
> !     cwdev->HWResolution[1] = tdev->HWResolution[1];
> !     /* Fields left zeroed :
> !     float MarginsHWResolution[2];
> !     float Margins[2];
> !     float HWMargins[4];
> !     long PageCount;
> !     long ShowpageCount;
> !     int NumCopies;
> !     bool NumCopies_set;
> !     bool IgnoreNumCopies;
> !     */
> !     cwdev->UseCIEColor = tdev->UseCIEColor;
> !     cwdev->LockSafetyParams = true;
> !     /* gx_page_device_procs page_procs; */
> !     cwdev->procs = gs_clist_device_procs;
> !     cwdev->procs.open_device = pattern_clist_open_device;
> !     gx_device_copy_color_params((gx_device *)cwdev, tdev);
> !     cwdev->target = tdev;
> !     clist_init_io_procs(cdev, true);
> !     cwdev->data = data;
> !     cwdev->data_size = data_size;
> !     cwdev->buf_procs = buf_procs ;
> !     cwdev->band_params.page_uses_transparency = false;
> !     cwdev->band_params.BandWidth = pinst->size.x;
> !     cwdev->band_params.BandHeight = pinst->size.x;
> !     cwdev->band_params.BandBufferSpace = max_long;
> !     cwdev->do_not_open_or_close_bandfiles = false;
> !     cwdev->bandlist_memory = storage_memory->non_gc_memory;
> !     cwdev->free_up_bandlist_memory = dummy_free_up_bandlist_memory;
> !     cwdev->disable_mask = 0;
> !     cwdev->page_uses_transparency = false;
> !     cwdev->pinst = pinst;
> !     fdev = (gx_device_forward *)cdev;
> !     }
> !     check_device_separable((gx_device *)fdev);
> !     gx_device_forward_fill_in_procs(fdev);
> !     return fdev;
>  }
>  
> ***************
> *** 409,412 ****
> --- 538,542 ----
>      tiles->tmask.data = 0;
>      tiles->index = i;
> +     tiles->cdev = NULL;
>      }
>      return pcache;
> ***************
> *** 486,503 ****
>  int
>  gx_pattern_cache_add_entry(gs_imager_state * pis,
> !            gx_device_pattern_accum * padev, gx_color_tile ** pctile)
>  {
> -     gx_device_memory *mbits = padev->bits;
> -     gx_device_memory *mmask = padev->mask;
> -     const gs_pattern1_instance_t *pinst = padev->instance;
>      gx_pattern_cache *pcache;
>      ulong used = 0;
> !     gx_bitmap_id id = pinst->id;
>      gx_color_tile *ctile;
>      int code = ensure_pattern_cache(pis);
>  
>      if (code < 0)
>      return code;
>      pcache = pis->pattern_cache;
>      /*
>       * Check whether the pattern completely fills its box.
> --- 616,638 ----
>  int
>  gx_pattern_cache_add_entry(gs_imager_state * pis,
> !            gx_device_forward * fdev, gx_color_tile ** pctile)
>  {
>      gx_pattern_cache *pcache;
> +     const gs_pattern1_instance_t *pinst;
>      ulong used = 0;
> !     gx_bitmap_id id;
>      gx_color_tile *ctile;
>      int code = ensure_pattern_cache(pis);
> +     extern dev_proc_open_device(pattern_clist_open_device);
>  
>      if (code < 0)
>      return code;
>      pcache = pis->pattern_cache;
> +     if (fdev->procs.open_device != pattern_clist_open_device) {
> +     gx_device_pattern_accum *padev = (gx_device_pattern_accum *)fdev;
> +     gx_device_memory *mbits = padev->bits;
> +     gx_device_memory *mmask = padev->mask;
> + +     pinst = padev->instance;
>      /*
>       * Check whether the pattern completely fills its box.
> ***************
> *** 526,529 ****
> --- 661,679 ----
>      if (mmask != 0)
>          used += gdev_mem_bitmap_size(mmask);
> +     } else {
> +     gx_device_clist *cdev = (gx_device_clist *)fdev;
> +     gx_device_clist_writer * cldev = (gx_device_clist_writer *)cdev;
> + +     code = clist_end_page(cldev);
> +     if (code < 0)
> +         return code;
> +     pinst = cdev->writer.pinst;
> +     /* HACK: we would like to copy the pattern clist stream into the 
> +        tile cache memory and properly account its size,
> +        but we have no time for this development now.
> +        Therefore the stream is stored outside the cache. */
> +     used = 0;
> +     }
> +     id = pinst->id;
>      ctile = &pcache->tiles[id % pcache->num_tiles];
>      gx_pattern_cache_free_entry(pcache, ctile);
> ***************
> *** 535,539 ****
>      }
>      ctile->id = id;
> !     ctile->depth = padev->color_info.depth;
>      ctile->uid = pinst->template.uid;
>      ctile->tiling_type = pinst->template.TilingType;
> --- 685,689 ----
>      }
>      ctile->id = id;
> !     ctile->depth = fdev->color_info.depth;
>      ctile->uid = pinst->template.uid;
>      ctile->tiling_type = pinst->template.TilingType;
> ***************
> *** 542,545 ****
> --- 692,700 ----
>      ctile->is_simple = pinst->is_simple;
>      ctile->is_dummy = false;
> +     if (fdev->procs.open_device != pattern_clist_open_device) {
> +     gx_device_pattern_accum *padev = (gx_device_pattern_accum *)fdev;
> +     gx_device_memory *mbits = padev->bits;
> +     gx_device_memory *mmask = padev->mask;
> +      if (mbits != 0) {
>          make_bitmap(&ctile->tbits, mbits, gs_next_ids(pis->memory, 1));
> ***************
> *** 552,556 ****
> --- 707,726 ----
>      } else
>          ctile->tmask.data = 0;
> +     ctile->cdev = NULL;
>      pcache->bits_used += used;
> +     } else {
> +     gx_device_clist *cdev = (gx_device_clist *)fdev;
> +     gx_device_clist_writer *cwdev = (gx_device_clist_writer *)fdev;
> + +     ctile->tbits.data = 0;
> +     ctile->tbits.size.x = 0;
> +     ctile->tbits.size.y = 0;
> +     ctile->tmask.data = 0;
> +     ctile->tmask.size.x = 0;
> +     ctile->tmask.size.y = 0;
> +     ctile->cdev = cdev;
> +     /* Prevent freeing files on pattern_paint_cleanup : */
> +     cwdev->do_not_open_or_close_bandfiles = true;
> +     }
>      pcache->tiles_used++;
>      *pctile = ctile;
> ***************
> *** 586,589 ****
> --- 756,760 ----
>      ctile->tbits.id = gs_no_bitmap_id;
>      memset(&ctile->tmask, 0 , sizeof(ctile->tmask));
> +     ctile->cdev = NULL;
>      pcache->tiles_used++;
>      return 0;
> ***************
> *** 624,628 ****
>          gx_device * dev, gs_color_select_t select)
>  {
> !     gx_device_pattern_accum *adev;
>      gs_pattern1_instance_t *pinst =
>      (gs_pattern1_instance_t *)pdc->ccolor.pattern;
> --- 795,799 ----
>          gx_device * dev, gs_color_select_t select)
>  {
> !     gx_device_forward *adev;
>      gs_pattern1_instance_t *pinst =
>      (gs_pattern1_instance_t *)pdc->ccolor.pattern;
> ***************
> *** 642,646 ****
>       * last reference to it from a graphics state is deleted.
>       */
> !     adev = gx_pattern_accum_alloc(mem, mem, pinst, "gx_pattern_load");
>      if (adev == 0)
>      return_error(gs_error_VMerror);
> --- 813,817 ----
>       * last reference to it from a graphics state is deleted.
>       */
> !     adev = gx_pattern_accum_alloc(mem, pis->pattern_cache->memory, 
> pinst, "gx_pattern_load");
>      if (adev == 0)
>      return_error(gs_error_VMerror);
> ***************
> *** 665,669 ****
>      }
>      /* We REALLY don't like the following cast.... */
> !     code = gx_pattern_cache_add_entry((gs_imager_state *)pis, adev, 
> &ctile);
>      if (code >= 0) {
>      if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) {
> --- 836,841 ----
>      }
>      /* We REALLY don't like the following cast.... */
> !     code = gx_pattern_cache_add_entry((gs_imager_state *)pis, 
> !         adev, &ctile);
>      if (code >= 0) {
>      if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) {
> ***************
> *** 673,684 ****
>      }
>  #ifdef DEBUG
> !     if (gs_debug_c('B')) {
> !         if (adev->mask)
> !         debug_dump_bitmap(adev->mask->base, adev->mask->raster,
> !                   adev->mask->height, "[B]Pattern mask");
> !     if (adev->bits)
> !         debug_dump_bitmap(((gx_device_memory *) adev->target)->base,
> !                   ((gx_device_memory *) adev->target)->raster,
> !                   adev->target->height, "[B]Pattern bits");
>      }
>  #endif
> --- 845,858 ----
>      }
>  #ifdef DEBUG
> !     if (gs_debug_c('B') && adev->procs.open_device == 
> pattern_accum_open) {
> !     gx_device_pattern_accum *pdev = (gx_device_pattern_accum *)adev;
> ! !         if (pdev->mask)
> !         debug_dump_bitmap(pdev->mask->base, pdev->mask->raster,
> !                   pdev->mask->height, "[B]Pattern mask");
> !     if (pdev->bits)
> !         debug_dump_bitmap(((gx_device_memory *) pdev->target)->base,
> !                   ((gx_device_memory *) pdev->target)->raster,
> !                   pdev->target->height, "[B]Pattern bits");
>      }
>  #endif
> ***************
> *** 690,693 ****
> --- 864,873 ----
>      return code;
>  fail:
> +     if (adev->procs.open_device == pattern_clist_open_device) {
> +     gx_device_clist *pdev = (gx_device_clist *)adev;
> + +     gs_free_object(mem, pdev->common.data, "gx_pattern_load");
> +     pdev->common.data = 0;
> +     }
>      gs_free_object(mem, adev, "gx_pattern_load");
>      return code;
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\gxpcolor.h    Tue Apr 10 21:14:03 2007
> --- files\gs\src\gxpcolor.h    Sat Apr 14 00:34:56 2007
> ***************
> *** 25,28 ****
> --- 25,33 ----
>  #include "gxpcache.h"
>  
> + #ifndef gx_device_clist_DEFINED
> + #define gx_device_clist_DEFINED
> + typedef union gx_device_clist_s gx_device_clist;
> + #endif
> +  /*
>   * Define the type of a Pattern, also used with Pattern instances.
> ***************
> *** 163,169 ****
>      gx_strip_bitmap tmask;    /* data = 0 if no mask */
>      /* (i.e., the mask is all 1's) */
> !     bool is_simple;        /* true if xstep/ystep = tile size */
> !     bool is_dummy;        /* if true, the device manages the 
> pattern,                                     and the content of the 
> tile is empty. */
>      /* The following is neither key nor value. */
>      uint index;            /* the index of the tile within */
> --- 168,176 ----
>      gx_strip_bitmap tmask;    /* data = 0 if no mask */
>      /* (i.e., the mask is all 1's) */
> !     gx_device_clist *cdev;    /* not NULL if the graphics is a 
> command list. */
> !     byte is_simple;        /* true if xstep/ystep = tile size */
> !     byte is_dummy;        /* if true, the device manages the 
> pattern,                                     and the content of the 
> tile is empty. */
> +     byte pad[2];        /* structure members alignment. */
>      /* The following is neither key nor value. */
>      uint index;            /* the index of the tile within */
> ***************
> *** 172,177 ****
>  
>  #define private_st_color_tile()    /* in gxpcmap.c */\
> !   gs_private_st_ptrs2(st_color_tile, gx_color_tile, "gx_color_tile",\
> !     color_tile_enum_ptrs, color_tile_reloc_ptrs, tbits.data, 
> tmask.data)
>  #define private_st_color_tile_element()    /* in gxpcmap.c */\
>    gs_private_st_element(st_color_tile_element, gx_color_tile,\
> --- 179,184 ----
>  
>  #define private_st_color_tile()    /* in gxpcmap.c */\
> !   gs_private_st_ptrs3(st_color_tile, gx_color_tile, "gx_color_tile",\
> !     color_tile_enum_ptrs, color_tile_reloc_ptrs, tbits.data, 
> tmask.data, cdev)
>  #define private_st_color_tile_element()    /* in gxpcmap.c */\
>    gs_private_st_element(st_color_tile_element, gx_color_tile,\
> ***************
> *** 216,220 ****
>  
>  /* Allocate a pattern accumulator. */
> ! gx_device_pattern_accum * gx_pattern_accum_alloc(gs_memory_t * mem, 
>                 gs_memory_t * stoarge_memory,                 
> gs_pattern1_instance_t *pinst, client_name_t cname);
> --- 223,227 ----
>  
>  /* Allocate a pattern accumulator. */
> ! gx_device_forward * gx_pattern_accum_alloc(gs_memory_t * mem, 
>                 gs_memory_t * stoarge_memory,                 
> gs_pattern1_instance_t *pinst, client_name_t cname);
> ***************
> *** 224,228 ****
>  /* device, but it may zero out the bitmap_memory pointers to prevent */
>  /* the accumulated bitmaps from being freed when the device is 
> closed. */
> ! int gx_pattern_cache_add_entry(gs_imager_state *, 
> gx_device_pattern_accum *,
>                     gx_color_tile **);
>  /* Add a dummy Pattern cache entry.  Stubs a pattern tile for 
> interpreter when
> --- 231,235 ----
>  /* device, but it may zero out the bitmap_memory pointers to prevent */
>  /* the accumulated bitmaps from being freed when the device is 
> closed. */
> ! int gx_pattern_cache_add_entry(gs_imager_state *, gx_device_forward *,
>                     gx_color_tile **);
>  /* Add a dummy Pattern cache entry.  Stubs a pattern tile for 
> interpreter when
>
>
>
> *** F:\SVN-GS\HEAD\gs\src\zpcolor.c    Tue Apr 10 21:14:03 2007
> --- files\gs\src\zpcolor.c    Thu Apr 12 10:22:15 2007
> ***************
> *** 236,240 ****
>      (gs_pattern1_instance_t *)gs_currentcolor(pgs)->pattern;
>      ref *pdict = &((int_pattern *) pinst->template.client_data)->dict;
> !     gx_device_pattern_accum *pdev = NULL;
>      gx_device *cdev = gs_currentdevice_inline(igs);
>      int code;
> --- 236,240 ----
>      (gs_pattern1_instance_t *)gs_currentcolor(pgs)->pattern;
>      ref *pdict = &((int_pattern *) pinst->template.client_data)->dict;
> !     gx_device_forward *pdev = NULL;
>      gx_device *cdev = gs_currentdevice_inline(igs);
>      int code;
> ***************
> *** 317,321 ****
>  {
>      int o_stack_adjust = ref_stack_count(&o_stack) - esp->value.intval;
> !     gx_device_pattern_accum *pdev = r_ptr(esp - 1, 
> gx_device_pattern_accum);
>  
>      if (pdev != NULL) {
> --- 317,321 ----
>  {
>      int o_stack_adjust = ref_stack_count(&o_stack) - esp->value.intval;
> !     gx_device_forward *pdev = r_ptr(esp - 1, gx_device_forward);
>  
>      if (pdev != NULL) {
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> gs-code-review mailing list
> gs-code-review at ghostscript.com
> http://www.ghostscript.com/mailman/listinfo/gs-code-review
>   



More information about the gs-code-review mailing list