[gs-code-review] A preliminary patch for high level patterns
Henry Stiles
henry.stiles at artifex.com
Mon Apr 16 11:36:19 PDT 2007
Igor V. Melichev wrote:
> Henry,
>
>> Sorry, I am late to get around to this.
>
> A Russian proverb :
> "Late is better than never".
>
> 1. About file/memory clist :
>
> With BAND_LIST_STORAGE = memory,
> the new code generates a single memory-based clist code.
> It instantiates another clist device for each cached "large" pattern.
> Thus most old documents behave same as with the old code.
> Only exception is documents with large patterns :
> each large pattern will take 30-40K while cached.
> It is possible to release 30K buffer, but I did not
> schedule that optimization for the first release,
> which customers need urgently. It may be done later.
> I believe it is not critical because large patterns are rare.
>
> With BAND_LIST_STORAGE = file,
> the patch generates a code for memory-based clist
> *and* for a file-based clist.
> I believe it adds about 10K to the size of binaries.
> The "page" clist works as before,
> and the 'large pattern" clist takes 30-40K per
> cached pattern. Again, I'm delaying the related optimization.
>
My original question was why can't you use a file based clist for
patterns if the clist is file based and use a memory based clist for
patterns if the system is configured for memory based clist.
> 2. About non-gc_memory.
>
> There is nothing special for non-gc clients.
> I just don't like what the old code uses non-gc memory
> for the clist buffer for any client (either with gc or with no gc).
> I think I'll need to improve it later with moving it
> to "regular" memory. Otherwise the new code uses
> non-gc memory for large patterns - that's not good.
>
Ok.
>> Your code broke the async renderer and pcl with 7837. I can work around
>> this but it would be nice if you fixed it.
>
> Please explain better.
> I believe that I didn't change the old behavior.
> My insertions to clist code are wrapped with
>
> "if (fdev->procs.open_device != pattern_clist_open_device)",
>
> which is always false for the "page" clist.
>
There is a compilation error in gxpageq.c. Like I said, if you add the
bmpamono device to the default build you will see it. It also can be
seen by simply building pcl. I'd fix it but it is not clear what you
intended this code to do:
add bmpamono to the default build and compile:
../gs/src/gxpageq.c: In function 'gx_page_queue_add_page':
../gs/src/gxpageq.c:301: error: 'struct gx_device_clist_writer_s' has no
member named 'io_procs'
It would be best if you leave bmpamono in your makefile or check your
code by compiling pcl going forward.
Thanks
Henry
> Igor.
>
> ----- Original Message ----- From: "Henry Stiles"
> <henry.stiles at artifex.com>
> To: "Igor V. Melichev" <igor.melichev at artifex.com>
> Cc: "gs-code-review" <gs-code-review at ghostscript.com>; "tech"
> <tech at artifex.com>
> Sent: Monday, April 16, 2007 10:46 AM
> Subject: Re: [gs-code-review] A preliminary patch for high level patterns
> xefitra
>
>
>> 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