Implementation of a raster data sink. More...
#include "hhrsdk.h"
#include "skintest.h"
#include "rmreport.h"
#include "debugpage.h"
#include "nonerast.h"
#include <stdio.h>
Data Structures | |
struct | write_queue_t |
Queue structure for work passed to the write-behind thread. More... | |
struct | NONE_RASTER_handle |
Typedefs | |
typedef struct write_queue_t | write_queue_t |
Queue structure for work passed to the asynchronous output thread. | |
typedef struct NONE_RASTER_handle | NONE_RASTER_handle |
Functions | |
static void | microsleep (uint32 uS) |
static void * | NONE_writer (void *args) |
Write-behind simulation function. | |
HqBool | NONE_RegisterHandlers (void) |
Register the raster backend and event handlers. More... | |
Implementation of a raster data sink.
The raster data sink throws away all data written to it. It counts the amount of data written for testing and debugging purposes, supports debug output of raster data, asynchronous write-behind output, Scalable RIP Raster Manager integration, and also supports simulation of slow output devices. The raster data sink may be a good example to copy when creating your own raster backend.
The raster data sink supports the following parameters for configuration. These are specifed in a sub-dictionary of the setpagedevice call, keyed by the raster backend name (/None for the raster data sink). e.g.,
NONE_RasterBandSize() will be called during interpreter pagedevice creation. Settings made in this function will last the lifetime of the pagedevice, which may be multiple pages, or even multiple jobs if the pagedevice is set during RIP startup or by a PostScript startjob configuration.
NONE_RasterRequirements() will be called during interpretation when resource requirements change and when preparing to render a page; and during rendering when preparing a rendering pass or preparing to render a separation. This call is guaranteed to be called at least twice during interpretation (when setting up resources and when preparing to render), and at least twice during rendering (once for each pass and once for each separation in each pass). Any settings made in this call should be consistent for all calls.
NONE_BlankPage() will be called if there is nothing on a page, either because there is no content, or because all separations were omitted. It can set an action value determining whether the page should be rendered anyway, counted in the page counts but not rendered, or ignored. The Scalable RIP raster manager integration requires specific behavior of this function.
When rendering a separation, NONE_RASTER_start() will be called to open the output separation, NONE_RASTER_write_data() will be called for each band of data, and NONE_RASTER_finish() will be called at the end of the separation. A raster handle structure for each separation is created in NONE_RASTER_start(), and destroyed in NONE_RASTER_finish(). This raster handle structure is passed to NONE_RASTER_write_data() calls.
NONE_RASTER_finish() will be called again at the end of a job, with a NULL raster handle.
In normal operation, calls to NONE_RASTER_write_data() are made for each band. This function will accumulate the bytes written in the raster handle, wait enough time to simulate the output rate set for the PPM parameter, and return to the RIP. Nothing is read from the raster buffer supplied to the call.
When configured for asynchronous output, the NONE_RasterBandSize() call is used to tell the RIP to use dynamic bands, allowing the RIP to render ahead of slow output. The number of dynamic bands can be configured using the DynamicBandLimit systemparam, by default the RIP will try to allocate as many dynamic bands as it can use. The NONE_RasterRequirements() call is used to indicate that this raster backend will send the SWEVT_BANDS_HANDLED event after it has processed each band asynchronously. The raster backend must take responsibility for sending this event if it is to operate asynchronously, to indicate when the backend has stopped accessing the raster data and the RIP can safely use the band memory again.
A thread, mutex, and condition variable are created for each separation in NONE_RASTER_start(). The thread loops around, waiting for band information to be queued by NONE_RASTER_write_data(), then taking that band off the queue, waiting enough time to simulate the output rate for the PPM parameter, and then sending the SWEVT_BANDS_HANDLED event to signify that the band has been processed. The thread is joined in NONE_RASTER_finish() at the end of each separation. The RIP requires that all of the queued bands are handled at the end of the separation, so that it can reuse the band memory.
Creating and destroying the write-behind thread, mutex, and condition variable for every separation is not very efficient. This backend will be updated when more suitable lifecycle context calls are available, in the meantime backends that always use asynchronous output could use global variables, lazy creation, and destruction in the job end NONE_RASTER_finish() call.
Asynchronous output should only be used when the raster backend performs significant work on the output data, or expects to be delayed significantly (e.g., when writing data to disk or I/O via a non-buffered API call). There is no point in configuring the raster data sink to use asynchronous output unless also simulating a slow output device, because discarding the data takes no time.
typedef struct NONE_RASTER_handle NONE_RASTER_handle |
The raster sink handle. We keeps a count of the bytes written to the output, and fields to manage asynchronous write-behind (if enabled).
|
static |
A busy wait for a possibly small amount of time. We use a busy wait because there are no consistent platform-independent microsecond wait APIs, and scheduling quanta on different platforms are quite likely to be larger than the lower end of the times we want to wait for. The output thread we're simulating is likely to be performing work or doing I/O waits anyway, so it is reasonable to be using processor time for this.
HqBool NONE_RegisterHandlers | ( | void | ) |
Register the raster backend and event handlers.
TRUE | if successful; |
FALSE | otherwise. |