Re: A preliminary patch for high level patterns
Henry Stiles <[email protected]> Mon, 16 Apr 2007 14:02:09 -0600
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
Igor V. Melichev wrote: > 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. > I see. >> 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. > I'll have a look. Thanks. > > Igor. > > > > ----- Original Message ----- From: "Henry Stiles" > <[email protected]> > To: "Igor V. Melichev" <[email protected]> > Cc: "gs-code-review" <[email protected]>; "tech" > <[email protected]> > 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" >>> <[email protected]> >>> To: "Igor V. Melichev" <[email protected]> >>> Cc: "gs-code-review" <[email protected]>; "tech" >>> <[email protected]> >>> 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 >>>>> [email protected] >>>>> http://www.ghostscript.com/mailman/listinfo/gs-code-review >>>>> >>>> >>> >>> >> > >