[gs-code-review] A preliminary patch for high level patterns
Igor V. Melichev
igor.melichev at artifex.com
Mon Apr 16 12:17:49 PDT 2007
Henry,
> My original question was why can't you use a file based clist for patterns
> if the clist is file based
I don't want to create 2 disk files for each pattern defined in a document.
Sharing "page" clist files would be too complicated.
> There is a compilation error in gxpageq.c.
I fixed one in rev 7855.
> but it is not clear what you intended this code to do
Just initialize io_procs against a crash in clist reader.
Now MSVC generates a harmful warning with gdevbmpa.c :
f:\afpl\gs-hd\src\gdevbmpa.c(456) : warning C4047: 'function' :
'gx_band_complexity_t *' differs in levels of indirection from 'int'
f:\afpl\gs-hd\src\gdevbmpa.c(456) : warning C4024: 'gdev_create_buf_device'
: different types for formal and actual parameter 6
The prototype defines arg 6 as gx_band_complexity_t * .
I guess we should replace 'true' with clist_get_band_complexity(dev,y).
Please take a look.
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:36 PM
Subject: Re: [gs-code-review] A preliminary patch for high level patterns
xefitra
> 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