Beispiel #1
0
int
gs_screen_order_init_memory(gx_ht_order * porder, const gs_state * pgs,
                            gs_screen_halftone * phsp, bool accurate,
                            gs_memory_t * mem)
{
    gs_matrix imat;
    ulong max_size = gx_ht_cache_default_bits_size();
    int code;
    gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);

    if (phsp->frequency < 0.1)
        return_error(gs_error_rangecheck);
    gs_deviceinitialmatrix(gs_currentdevice(pgs), &imat);
    code = pick_cell_size(phsp, &imat, max_size,
                          ctx->screen_min_screen_levels, accurate,
                          &porder->params);
    if (code < 0)
        return code;
    gx_compute_cell_values(&porder->params);
    porder->screen_params.matrix = imat;
    porder->screen_params.max_size = max_size;
    return gs_screen_order_alloc(porder, mem);
}
Beispiel #2
0
/*
 * Open this printer device in ASYNC (overlapped) mode.
 * This routine must always called by the concrete device's xx_open routine
 * in lieu of gdev_prn_open.
 */
int
gdev_prn_async_write_open(gx_device_printer * pwdev, int max_raster,
                          int min_band_height, int max_src_image_row)
{
    gx_device *const pdev = (gx_device *) pwdev;
    int code;
    bool writer_is_open = false;
    gx_device_clist_writer *const pcwdev =
        &((gx_device_clist *) pwdev)->writer;
    gx_device_clist_reader *pcrdev = 0;
    gx_device_printer *prdev = 0;
    gs_memory_t *render_memory = 0;	/* renderer's mem allocator */

    pwdev->page_queue = 0;
    pwdev->bandlist_memory = 0;
    pwdev->async_renderer = 0;

    /* allocate & init render memory */
    /* The big memory consumers are: */
    /* - the buffer used to read images from the command list */
    /* - buffer used by gx_real_default_strip_copy_rop() */
    /* - line pointer tables for memory devices used in plane extraction */
    /* - the halftone cache */
    /* - the band rendering buffer */
    /* The * 2's in the next statement are a ****** HACK ****** to deal with */
    /* sandbars in the memory manager. */
    if ((code = alloc_render_memory(&render_memory,
            pwdev->memory->non_gc_memory, RendererAllocationOverheadBytes + max_raster
                                    /* the first * 2 is not a hack */
                   + (max_raster + sizeof(void *) * 2) * min_band_height
                   + max_src_image_row + gx_ht_cache_default_bits_size() * 2)) < 0)
             goto open_err;

    /* Alloc & init bandlist allocators */
    /* Bandlist mem is threadsafe & common to rdr/wtr, so it's used */
    /* for page queue & cmd list buffers. */
    if ((code = alloc_bandlist_memory
         (&pwdev->bandlist_memory, pwdev->memory->non_gc_memory)) < 0)
        goto open_err;

    /* Dictate banding parameters for both renderer & writer */
    /* Protect from user change, since user changing these won't be */
    /* detected, ergo the necessary close/reallocate/open wouldn't happen. */
    pwdev->space_params.banding_type = BandingAlways;
    pwdev->space_params.params_are_read_only = true;

    /* Make a copy of device for use as rendering device b4 opening writer */
    code = gs_copydevice((gx_device **) & prdev, pdev, render_memory);
    pcrdev = &((gx_device_clist *) prdev)->reader;
    if (code < 0)
        goto open_err;

    /* -------------- Open cmd list WRITER instance of device ------- */
    /* --------------------------------------------------------------- */
    /* This is wrong, because it causes the same thing in the renderer */
    pwdev->OpenOutputFile = 0;	/* Don't open output file in writer */

    /* Hack: set this vector to tell gdev_prn_open to allocate for async rendering */
    pwdev->free_up_bandlist_memory = &gdev_prn_async_write_free_up_bandlist_memory;

    /* prevent clist writer from queuing path graphics & force it to split images */
    pwdev->clist_disable_mask |= clist_disable_fill_path |
        clist_disable_stroke_path | clist_disable_complex_clip |
        clist_disable_nonrect_hl_image | clist_disable_pass_thru_params;

    if ((code = gdev_prn_open(pdev)) >= 0) {
        writer_is_open = true;

        /* set up constant async-specific fields in device */
        reinit_printer_into_printera(pwdev);

        /* keep ptr to renderer device */
        pwdev->async_renderer = prdev;

        /* Allocate the page queue, then initialize it */
        /* Use bandlist memory since it's shared between rdr & wtr */
        if ((pwdev->page_queue = gx_page_queue_alloc(pwdev->bandlist_memory)) == 0)
            code = gs_note_error(gs_error_VMerror);
        else
            /* Allocate from clist allocator since it is thread-safe */
            code = gx_page_queue_init(pwdev->page_queue, pwdev->bandlist_memory);
    }
    /* ------------ Open cmd list RENDERER instance of device ------- */
    /* --------------------------------------------------------------- */
    if (code >= 0) {
        gx_semaphore_t *open_semaphore;

        /* Force writer's actual band params into reader's requested params */
        prdev->space_params.band = pcwdev->page_info.band_params;

        /* copydevice has already set up prdev->memory = render_memory */
        /* prdev->bandlist_memory = pwdev->bandlist_memory; */
        prdev->buffer_memory = prdev->memory;

        /* enable renderer to accept changes to params computed by writer */
        prdev->space_params.params_are_read_only = false;

        /* page queue is common to both devices */
        prdev->page_queue = pwdev->page_queue;

        /* Start renderer thread & wait for its successful open of device */
        if (!(open_semaphore = gx_semaphore_alloc(prdev->memory)))
            code = gs_note_error(gs_error_VMerror);
        else {
            gdev_prn_start_render_params thread_params;

            thread_params.writer_device = pwdev;
            thread_params.open_semaphore = open_semaphore;
            thread_params.open_code = 0;
            code = (*pwdev->printer_procs.start_render_thread)
                (&thread_params);
            if (code >= 0)
                gx_semaphore_wait(open_semaphore);
            code = thread_params.open_code;
            gx_semaphore_free(open_semaphore);
        }
    }
    /* ----- Set the recovery procedure for the mem allocator ----- */
    if (code >= 0) {
        gs_memory_retrying_set_recover(
                (gs_memory_retrying_t *)pwdev->memory->non_gc_memory,
                prna_mem_recover,
                (void *)pcwdev
            );
    }
    /* --------------------- Wrap up --------------------------------- */
    /* --------------------------------------------------------------- */
    if (code < 0) {
open_err:
        /* error mop-up */
        if (render_memory && !prdev)
            free_render_memory(render_memory);

        gdev_prn_dealloc(pwdev);
        if (writer_is_open) {
            gdev_prn_close(pdev);
            pwdev->free_up_bandlist_memory = 0;
        }
    }
    return code;
}