Harlequin RIP SDK

Implementation of a asynchronous raster output. More...

#include "hhrsdk.h"
#include "skintest.h"
#include "hvdreport.h"
#include "libtiffrast.h"
#include "asynctiffrast.h"
#include "eventerrors.h"

Data Structures

struct  bandentry_t
 
struct  write_queue_t
 Queue structure for work passed to the write-behind thread. More...
 

Macros

#define ASYNC_TIFF_FILEFORMAT   "%f-%p%?-N%?-S%?-T.async.tif"
 The default filename format for files produced by this example code. More...
 

Typedefs

typedef struct write_queue_t write_queue_t
 Queue structure for work passed to the write-behind thread.
 

Functions

static void BandTableRelease (HqBool continuing)
 Release the band table.
 
static sw_event_result ASYNC_TIFF_bands_handled (void *context, sw_event *event)
 Event handler for releasing bands back to RIP.
 
static void BandTableReset (void)
 Mark bands in the band table as unused, but do not free them.
 
static HqBool BandTableAcquire (RasterDescription *rd, uint32 minimum_bands)
 Allocate the band table. More...
 
static void * writer_fn (void *args)
 Write-behind function.
 
static async_writer_t * async_writer_create (void *pJobContext)
 Allocate memory for the raster handle structure. More...
 
static RASTER_result ASYNC_TIFF_RASTER_start (void *pJobContext, RasterDescription *pRD, RASTER_handle *pHandle)
 This function is called once at the start of each sheet in each job. More...
 
static RASTER_result ASYNC_TIFF_RASTER_write_data (void *pJobContext, RASTER_handle rh, RasterDescription *pRD, void *data, int32 topline, int32 lines, int32 bytesperline, int32 channel)
 For each page, multiple calls are made to this function, each delivering raster data for the page. More...
 
static RASTER_result ASYNC_TIFF_RASTER_finish (void *pJobContext, RASTER_handle *pHandle, RasterDescription *pRasterDescription, RASTER_result result)
 This function is called once at the end of each sheet in each job. More...
 
static RASTER_result ASYNC_TIFF_RASTER_job_end (void *pJobContext, RASTER_handle *pHandle)
 This function is called after the last sheet has been closed. More...
 
static RASTER_result ASYNC_TIFF_RasterRequirements (void *pJobContext, RASTER_REQUIREMENTS *pRasterRequirements, RasterDescription *pRD)
 This function gives the raster backend the details of the raster it's about to be handed. More...
 
static RASTER_result ASYNC_TIFF_RasterDestination (void *pJobContext, RASTER_DESTINATION *pRasterDestination, int32 separationIndex)
 This function allows the raster backend to provide a memory address range into which to render. More...
 
static HVD_result async_tiff_hvd_output_page (HVD_page_output *page)
 Callback function for libHVD to output an HVD page. More...
 

Variables

static size_t band_memory = 10 * 1024 * 1024
 
static uint32 guBandTableCount = 0
 
static size_t guBandTableSize = 0
 
static uint32 guBandHeight = 0
 
static uint32 guFrameHeight = 0
 
static uint32 guBandsPerPlane = 0
 

Detailed Description

Implementation of a asynchronous raster output.

There are two purposes to this example:

1) To illustrate asynchronous raster output. If the raster back-end performs significant processing on the band data, it may be advantageous to queue the output bands for a separate thread to process and output, and to return immediately to the RIP so that it can proceed with rendering. This backend illustrates how to do this, by creating a processing thread on the first raster start, queuing bands to it in from the write data calls, and asynchronously returning the bands to the RIP after processing using the SWEVT_BANDS_HANDLED event.

The processing thread in this example is simple, it just piggybacks on the simple LIBTIFF file implementation, so that output can be easily viewed.

In an operating system with extensive file cacheing, asynchronous writing of the raster to disk without much processing may not result in noticeable performance changes, because all that is saved is a copy to the operating system's file cache buffers. Using asynchronous output may still be an advantage even in such systems if there is raster processing integrated into the output that requires data crossing band boundaries, such as anti-alias filtering, error diffusion screening, or some compression algorithms.

2) To illustrate skin-controlled band allocation. This backend maintains its own table of bands, which the RIP will use to render data into. This is useful if the bands must be placed in particular areas of memory, for example in memory accessable by a hardware accelerator, or in shared memory for access by another process. The skin can control the amount of memory used to store bands, but must allocate at least the minimum number required by the RIP.

Skin-allocated bands are used during partial painting and two-pass compositing as well as for final output, so care may need to be taken if placing bands not used for the final output in restricted memory locations.

To make asynchronous raster output back-end useful, the RIP must be instructed to allocate more bands resources than there are rendering threads. This requires setting the DynamicBands pagedevice key and system parameter to true in the configuration, and also set the number of dynamic bands allowed, thus:

<< /DynamicBands true /DynamicBandLimit 0 % Allocate as many extra bands as possible

setsystemparams

<< /PageBufferType /ASYNCTIFF /DynamicBands true

setpagedevice

Note that the SDK functions that drives the raster callbacks normally calls the write data function one line at a time if the image width does not match the padded raster width. This is very inefficient for this example, because each line will be queued to the processing thread individually, and many SWEVT_BANDS_HANDLED events will be generated, which will slow down processing. To get around this, the raster start function (in this case, LIBTIFF_RASTER_start()) sets the RasterDescription::line_data_may_be_padded boolean to TRUE.

Macro Definition Documentation

◆ ASYNC_TIFF_FILEFORMAT

#define ASYNC_TIFF_FILEFORMAT   "%f-%p%?-N%?-S%?-T.async.tif"

The default filename format for files produced by this example code.

The additional "async" tag is used to distinguish between the output of this back-end and the output of the other TIFF back-ends.

Function Documentation

◆ async_tiff_hvd_output_page()

static HVD_result async_tiff_hvd_output_page ( HVD_page_output page)
static

Callback function for libHVD to output an HVD page.

Parameters
[in]pageThe output page description from libHVD.
Return values
HVD_SUCCESSThe page was output successfully
Returns
One of the HVD_ERROR_* error codes, or any other return value greater than MON_CLASS_ERROR is an error UID. HVD_ERROR_* codes should be translated to monitor UID errors using HVD_result_translate(). The error subclass, PS error type, and UID for the error can be deconstructed using the macros in monevent.h.

◆ ASYNC_TIFF_RASTER_finish()

static RASTER_result ASYNC_TIFF_RASTER_finish ( void *  pJobContext,
RASTER_handle pHandle,
RasterDescription pRasterDescription,
RASTER_result  result 
)
static

This function is called once at the end of each sheet in each job.

See RASTER_FINISH_EX in rasthand.h

◆ ASYNC_TIFF_RASTER_job_end()

static RASTER_result ASYNC_TIFF_RASTER_job_end ( void *  pJobContext,
RASTER_handle pHandle 
)
static

This function is called after the last sheet has been closed.

See RASTER_JOB_END_EX in rasthand.h

◆ ASYNC_TIFF_RASTER_start()

static RASTER_result ASYNC_TIFF_RASTER_start ( void *  pJobContext,
RasterDescription pRD,
RASTER_handle pHandle 
)
static

This function is called once at the start of each sheet in each job.

See RASTER_START_EX in rasthand.h

◆ ASYNC_TIFF_RASTER_write_data()

static RASTER_result ASYNC_TIFF_RASTER_write_data ( void *  pJobContext,
RASTER_handle  rh,
RasterDescription pRD,
void *  data,
int32  topline,
int32  lines,
int32  bytesperline,
int32  channel 
)
static

For each page, multiple calls are made to this function, each delivering raster data for the page.

See RASTER_WRITE_DATA_EX in rasthand.h

◆ ASYNC_TIFF_RasterDestination()

static RASTER_result ASYNC_TIFF_RasterDestination ( void *  pJobContext,
RASTER_DESTINATION pRasterDestination,
int32  separationIndex 
)
static

This function allows the raster backend to provide a memory address range into which to render.

See SwLeRASTERDESTINATION in skinkit.h

◆ ASYNC_TIFF_RasterRequirements()

static RASTER_result ASYNC_TIFF_RasterRequirements ( void *  pJobContext,
RASTER_REQUIREMENTS pRasterRequirements,
RasterDescription pRD 
)
static

This function gives the raster backend the details of the raster it's about to be handed.

The band table memory is allocated here once the page dimensions are known.

See SwLeRASTERREQUIREMENTS in skinkit.h

◆ async_writer_create()

static async_writer_t* async_writer_create ( void *  pJobContext)
static

Allocate memory for the raster handle structure.

Returns
A pointer to the data.

◆ BandTableAcquire()

static HqBool BandTableAcquire ( RasterDescription rd,
uint32  minimum_bands 
)
static

Allocate the band table.

Returns
TRUE if the band table can be obtained, FALSE if not

Variable Documentation

◆ band_memory

size_t band_memory = 10 * 1024 * 1024
static

How much band memory should we allocate to bands? We always allocate at least the minimum requested by the RIP, but if we can fit in extra bands for asynchronous writing into this amount, we will. If the amount is set to 0, we allow the RIP to allocate and manage all of the band memory, but will still perform asynchronous write-behind.

◆ guBandHeight

uint32 guBandHeight = 0
static

The height in lines of each RIP band

◆ guBandsPerPlane

uint32 guBandsPerPlane = 0
static

The number of RIP bands for each frame

◆ guBandTableCount

uint32 guBandTableCount = 0
static

The number of bands in the band table

◆ guBandTableSize

size_t guBandTableSize = 0
static

The size in bytes of the bands

◆ guFrameHeight

uint32 guFrameHeight = 0
static

The height in lines of each RIP frame