The event interface for HVD defines how external and internal Harlequin VariData are driven by the Harlequin RIP PDF interpreter. More...
Files | |
file | rrevents.h |
This file defines the Event interface for HVD (aka Retained Raster). | |
Data Structures | |
struct | SWMSG_RR_CONNECT |
Message for SWEVT_RR_CONNECT: establishes a connection to an HVD cache instance. More... | |
struct | SWMSG_RR_DISCONNECT |
Message for SWEVT_RR_DISCONNECT: disconnects from a HVD cache instance. More... | |
struct | RR_PAGE_DEFINE_ELEMENT |
An element on a page in the External HVD interface Page Define message. More... | |
struct | RR_PAGE_DEFINE_PAGE |
A page or tile in the External HVD interface Page Define message. More... | |
struct | SWMSG_RR_PAGE_DEFINE |
An External HVD interface Page Define message, sent with the SWEVT_RR_PAGE_DEFINE event. More... | |
struct | SWMSG_RR_PAGE_REF |
External HVD interface Page reference: passed during SWEVT_RR_PAGE_READY and SWEVT_RR_PAGE_COMPLETE events. More... | |
struct | SWMSG_RR_ELEMENT_DEFINE |
HVD interface Page Element Define message. More... | |
struct | SWMSG_RR_ELEMENT_REF |
This is a message which identifies a particular raster element, and is used by two events: More... | |
struct | SWMSG_RR_ELEMENT_QUERY_LOCK |
HVD element query message, sent with the SWEVT_RR_ELEMENT_QUERY_LOCK event. More... | |
struct | SWMSG_RR_ELEMENT_UPDATE_RASTER |
Internal HVD element update message, sent with the SWEVT_RR_ELEMENT_UPDATE_RASTER event. More... | |
struct | SWMSG_RR_ELEMENT_UPDATE_HITS |
HVD element hit count message, sent with the SWEVT_RR_ELEMENT_UPDATE_HITS event. More... | |
Macros | |
#define | RR_CACHE_ID_LENGTH 256 |
Length of the string (including terminating zero byte) for External HVD cache IDs. | |
#define | RR_SETUP_ID_LENGTH 256 |
Length of the string (including terminating zero byte) for External HVD setup IDs. | |
#define | RR_ELEMENT_ID_LENGTH 16 |
Length of the id strings in External HVD elements. | |
Typedefs | |
typedef struct SWMSG_RR_CONNECT | SWMSG_RR_CONNECT |
Message for SWEVT_RR_CONNECT: establishes a connection to an HVD cache instance. | |
typedef struct SWMSG_RR_DISCONNECT | SWMSG_RR_DISCONNECT |
Message for SWEVT_RR_DISCONNECT: disconnects from a HVD cache instance. | |
typedef struct RR_PAGE_DEFINE_ELEMENT | RR_PAGE_DEFINE_ELEMENT |
An element on a page in the External HVD interface Page Define message. | |
typedef struct RR_PAGE_DEFINE_PAGE | RR_PAGE_DEFINE_PAGE |
A page or tile in the External HVD interface Page Define message. More... | |
typedef struct SWMSG_RR_PAGE_DEFINE | SWMSG_RR_PAGE_DEFINE |
An External HVD interface Page Define message, sent with the SWEVT_RR_PAGE_DEFINE event. More... | |
typedef struct SWMSG_RR_PAGE_REF | SWMSG_RR_PAGE_REF |
External HVD interface Page reference: passed during SWEVT_RR_PAGE_READY and SWEVT_RR_PAGE_COMPLETE events. | |
typedef struct SWMSG_RR_ELEMENT_DEFINE | SWMSG_RR_ELEMENT_DEFINE |
HVD interface Page Element Define message. More... | |
typedef struct SWMSG_RR_ELEMENT_REF | SWMSG_RR_ELEMENT_REF |
This is a message which identifies a particular raster element, and is used by two events: More... | |
typedef struct SWMSG_RR_ELEMENT_QUERY_LOCK | SWMSG_RR_ELEMENT_QUERY_LOCK |
HVD element query message, sent with the SWEVT_RR_ELEMENT_QUERY_LOCK event. More... | |
typedef struct SWMSG_RR_ELEMENT_UPDATE_RASTER | SWMSG_RR_ELEMENT_UPDATE_RASTER |
Internal HVD element update message, sent with the SWEVT_RR_ELEMENT_UPDATE_RASTER event. More... | |
typedef struct SWMSG_RR_ELEMENT_UPDATE_HITS | SWMSG_RR_ELEMENT_UPDATE_HITS |
HVD element hit count message, sent with the SWEVT_RR_ELEMENT_UPDATE_HITS event. More... | |
The event interface for HVD defines how external and internal Harlequin VariData are driven by the Harlequin RIP PDF interpreter.
Harlequin VariData automatically detects re-used objects, forms and elements in variable data PDF jobs, and can significantly improve performance by optimizing rendering of these jobs. The Harlequin VariData API defines an interface where the RIP can render the repeated parts and the non-repeated parts of the job separately, and a post-rendering application compositing process can re-combine the parts into a raster for output.
The HVD API is an event-driven asynchronous API, where the core library issues events to notify the application of the page structure and re-used elements, and the application responds with events to request raster data for the elements as it needs them. The application will usually cache rasters produced for elements, reducing the amount of rendering required for the job significantly. For details of the event API and how to discover RIP APIs in RDR (including the event API) see Events system and RIP Data Resource (RDR) System.
The re-used parts of the page for eHVD are referred to as elements. There are two types of eHVD output, they differ in how elements are sized and placed:
If the RIP is configured to produce separations, there will be more than one raster produced for each element.
The Harlequin core library issues HVD events while it is processing PDF jobs. The events inform a client about the structure of the PDF pages in the job, and how what elements each page is composed of. The client is expected to issue events in response, to indicate which elements the RIP should render. The RIP will render elements requested, delivering the rendered elements them through the normal raster output method. The client is sometimes referred to as the "HVD cache" in this documentation, because it is expected to cache raster elements and only request rasters for elements that it does not have cached. The client is responsible for composing the element rasters together to produce a complete raster for each PDF page.
The LibHVD library and Harlequin SDK support functions can simplify enabling eHVD in raster backends. However, if you have custom hardware that can support composition of raster elements, you may want to work directly with this API, or pick and choose the components of LibHVD that you use.
Because this API uses the event API, the client of the API must be in the same process as the RIP. When using a Scalable RIP, performance would be improved by sharing the cache across all Farm RIPs. The Harlequin RIP SDK does provide some support for caching element rasters in shared memory framebuffers, however this still uses cache structures local to each Farm RIP process. To share the cache across all Farm RIPs in a Scalable RIP, the HVD event handlers need to act as proxies, sending inter-process messages to the shared cache. Global Graphics intends to provide support for sharing an HVD cache across multiple Farm RIPs in a future release. Without a shared cache implementation, the use of eHVD with the Scalable RIP requires careful tuning of the memory allowed for each Farm RIP's cache, and the memory allocated to each Farm RIP, to ensure that performance is actually improved.
There may be multiple HVD-capable raster backends built into a RIP, including the internal HVD handlers. It is essential that clients of the HVD event API only respond to HVD API events when the client is selected.
The initial connection between the RIP and client code is established via the connect event SWEVT_RR_CONNECT. This event is issued with an associated SWMSG_RR_CONNECT message. The SWMSG_RR_CONNECT::cache_id field contains a string that each client should use to determine when it is selected. Each client is normally associated with a particular raster backend, which the RIP will deliver the element rasters to. When a connection is requested, the client should verify that the correct raster backend is selected, or it will not receive the raster elements that it expects. If using the libHVD library to simplify eHVD support, an HVD_connect_verify_fn verification function should be supplied to the event monitor to verify that the correct raster output backend is selected.
If the SWMSG_RR_CONNECT::cache_id field matches your client's name, and the correct raster backend is selected, the client's SWEVT_RR_CONNECT event handler is expected to set SWMSG_RR_CONNECT::connection to an opaque handle uniquely identifying this connection, and return SW_EVENT_HANDLED. Every subsequent eHVD event has a message whose first two fields are this opaque connection reference and the job timeline reference. They are omitted from the descriptions below for brevity. All subsequent handlers whose connection handle doesn't match the one created for SWEVT_RR_CONNECT should immediately return SW_EVENT_CONTINUE.
The remaining fields in the SWMSG_RR_CONNECT message are informational:
TRUE
. It is recommended that clients support position-independent eHVD, it reduces the size of element rasters considerably.TRUE
.The SWEVT_RR_CONNECT event is the only event handler that you need to register before processing HVD jobs. It is good practice to register the remaining HVD API event handlers after you have verified that your client is selected and that the correct raster backend is also selected to output elements. All HVD API event handlers registered in the SWEVT_RR_CONNECT handler should be de-registered upon receiving the SWEVT_RR_DISCONNECT message.
The connection between RIP and client code is destroyed on receipt of a matching SWEVT_RR_DISCONNECT event. The RIP does not issue such an event until the client code has indicated it is done with all pages in flight (see SWEVT_RR_PAGE_DEFINE and SWEVT_RR_PAGE_COMPLETE). The SWEVT_RR_DISCONNECT event has an associated SWMSG_RR_DISCONNECT message, containing just the job timeline and the opaque connection handle. The client's handler for this event should de-register all HVD API events except for SWEVT_RR_CONNECT, free any memory or resources allocated for the opaque handle, and return SW_EVENT_HANDLED.
The HVD API uses events to track and synchronize the sub-page raster elements cached by the OEM code, and to inform the OEM output code how pages are to be built up from sub-page raster elements.
The sequence of events and raster deliveries in HVD external mode is deliberately not fully defined to leave open the possibility of changing the order to improve performance. You are therefore strongly recommended not to rely on any specific undocumented ordering in their code. However, some generalities can be described that may help in understanding the intended use of the various events.
The SWEVT_RR_ELEMENT_DEFINE and SWEVT_RR_PAGE_DEFINE events are issued during the scanning process, as commonality in raster elements is identified. Currently, the whole of the page range requested is scanned before the first page define event is issued, although that situation is not guaranteed to continue in future versions and should not be assumed in OEM code. Client code can make a decision as to whether it has everything it needs to print a page by reviewing the page definitions in the SWMSG_RR_PAGE_DEFINE message (associated with the SWEVT_RR_PAGE_DEFINE event) and checking whether it holds raster data for all of the sub-raster elements required by that page. All of the remaining processing of HVD is defined by the response of the client to these events. At the least, the client must indicate that all pages in the SWMSG_RR_PAGE_DEFINE message are complete, by issuing a SWEVT_RR_PAGE_COMPLETE event for each page.
In general, event handlers should assume that any memory referenced by the messages, including the messages themselves, belongs to the module originating the event (i.e., the RIP, for messages sent to the client). No assumptions about the lifetime of such memory should be made beyond the scope of the event handler itself: if client code needs to reference such data, it must make a copy.
In order to make a real page from the pagebuffers it gets sent via the HVD external mode interface, a cache implementation (the client code), should play back each raster element in turn that is included for each page in the SWMSG_RR_PAGE_DEFINE message. The order is essential: the page should be initialized to zeros, or to the value of the pixel(s) in the RR_PAGE_DEFINE_PAGE::background_id element, and then the element pointed to by the zeroth entry in the RR_PAGE_DEFINE_PAGE::elements array of pointers should be played back first, followed by the element pointed to by the first array entry, and so on.
The HVD event sequence is as follows:
The RIP scans the requested page range of the PDF file. As it decides that collections of graphic objects can be re-used or are unique and should be grouped together, it issues SWEVT_RR_ELEMENT_DEFINE events with associated SWMSG_RR_ELEMENT_DEFINE messages. The element define message includes a bounding box for the element, in the SWMSG_RR_ELEMENT_DEFINE::x1, SWMSG_RR_ELEMENT_DEFINE::y1, SWMSG_RR_ELEMENT_DEFINE::x2 and SWMSG_RR_ELEMENT_DEFINE::y2 fields.
There may be elements which legitimately have degenerate bounding boxes (x1 >= x2 or y1 >= y2). These represent marking operators in the content stream which for some reason did not lead to a mark on the page. They may be clipped out, off the page, or otherwise empty. Caching an empty raster for these elements is still worthwhile because it means that the RIP can avoid interpreting the marking operators each time the page is played back.
When the RIP has finished scanning the requested page range of the PDF file, it issues a SWEVT_RR_PAGE_DEFINE event with an associated SWMSG_RR_PAGE_DEFINE message. The SWMSG_RR_PAGE_DEFINE::pages array contains an array of pointers to RR_PAGE_DEFINE_PAGE structures defining each page.
When tiling output, each tile appears as a separate RR_PAGE_DEFINE_PAGE entry in the pages array. Note that throughout the HVD external mode interface, SWMSG_RR_PAGE_REF::page_index values represent an ordinal within the page range (and, where appropriate, the tile range) requested by pdfexecid
. They should not be assumed to bear any relation to PDF page labels or page numbers (one logical page usually is made up of several pagebuffers given that it is split into raster elements). The original PDF page number of a page is available in the RR_PAGE_DEFINE_PAGE::pdf_page_number field of the page entry.
For each page in turn, for each raster element on the page, the RIP issues a SWEVT_RR_ELEMENT_QUERY_LOCK event with an associated SWMSG_RR_ELEMENT_QUERY_LOCK message. This message contains the element ID in SWMSG_RR_ELEMENT_QUERY_LOCK::id, and an element handle field. If the element rasters are cached for the connection's setup, the client's event handler should set the SWMSG_RR_ELEMENT_QUERY_LOCK::handle field, and should ensure the element is not purged from its cache before it has received the corresponding SWEVT_RR_ELEMENT_UNLOCK event. The event handler should return SW_EVENT_HANDLED if the element's rasters are cached, or SW_EVENT_CONTINUE if the element's rasters are not cached.
If the element's rasters are not cached, the RIP will issue a SWEVT_RR_ELEMENT_PENDING event with an associated SWMSG_RR_ELEMENT_REF message, which instructs the client code to remember the fact that the RIP has promised to render the element (but it may not yet have done so). Subsequent queries for this element should by answered by indicating that the element is in the cache.
The RIP will render the element at some point (but not necessarily immediately). When the rasters for the element are output, the RIP sets the OptimizedPDFId
and OptimizedPDFUsageCount
parameters for the raster backend. The raster output backend must detect that OptimizedPDFId
is not empty, and must capture the element's raster(s) into its cache. The same mechanism is used for elements intended to be cached and re-used multiple times as for those which are variable data and appear only once: the only difference is the usage count. After rendering all of the element's rasters, the RIP will re-issue the SWEVT_RR_ELEMENT_QUERY_LOCK event.
At this point, the cache has acknowledged that it has all of the rasters for an element, and they are all locked against purging.
OptimizedPDFId
element ID presented to the raster backend is represented as a hexadecimal string. The event messages in this API represent element IDs as a fixed length string of 16 binary bytes (RR_ELEMENT_ID_LENGTH). The raster output backend should convert the hexadecimal string to binary before comparing the element ID with IDs observed in HVD events.When all of the rasters for all elements of a page or tile have been locked or are pending, the RIP issues a SWEVT_RR_PAGE_READY event with an associated SWMSG_RR_PAGE_REF message. This indicates that the cache implementation can go ahead and compose the rasters together to complete the page or tile. Note that the SWEVT_RR_PAGE_READY event may be received before the final pending rasters for an element are output, so the client must be prepared to wait for any pending rasters before completing the page raster.
It is possible that element rasters for a page may become available before the SWEVT_RR_PAGE_READY event is issued for the page. For example, if a page happens to use the same elements as a previous page or pages in the job and these elements are cached, the client may choose to compose and store or output the page immediately. In this case, the client should remember that it has done this, so that it can respond appropriately when the SWEVT_RR_PAGE_READY event eventually does arrive for the page.
Throughout this process, the RIP may issue SWEVT_RR_ELEMENT_UPDATE_HITS events, with an associated SWMSG_RR_ELEMENT_UPDATE_HITS message. This message indicates whether to increase or decrease a hit count of the element. The hit count indicates how many times the element is referenced, and provides a useful hint when deciding whether an element should be purged from the cache.
A job can call pdfexec
or pdfexecid
multiple times while HVD is active, possibly with different PageRange
parameters. The entire sequence of events above will be repeated for each chunk of pages processed. HVD connections to a cache may remain open over multiple invocations of pdfexecid
in a job.
The SWEVT_RR_ELEMENT_UPDATE_RASTER event is only used in HVD internal mode and is not documented.
Raster elements are made known to the client code via the SWEVT_RR_ELEMENT_DEFINE event and SWMSG_RR_ELEMENT_DEFINE message. On receipt of this event, the client code should add an entry into its cache table or other structure, keyed on the unique ID. The bounds described by x1, y1, x2, and y2 are relative to the page raster containing the element when the RIP rasterizes the element.
When position independence is off, this page raster will be the same size as the page on which it appears, and typically all four coordinate values will be non-zero (that is, the salient part of the page raster is somewhere in the middle of the pagebuffer, surrounded by whitespace). The area outside of the bounds may be omitted when compositing output to create a full page raster.
When position independence is on, x1 and y1 bounds will be zero and x2 and y2 effectively become width and height of the element. The element rasters are sized to just contain the element and there is little or no surrounding whitespace.
The SWEVT_RR_ELEMENT_UPDATE_HITS event is used by the RIP to inform the client code about changes to the usage count of a particular element. An increment happens each time the HVD scanner finds another use of the element, and a decrement occurs when a page containing the element is completed. What the OEM code does with the hit count is private to the cache implementation, but the default might be to delete the raster straight away when the hit count reaches zero for a cache intended for single jobs. An OEM implementation may choose to ignore the hit count in the raster metadata maintained by the RIP.
A simple OEM implementation may choose to read the OptimizedPDFUsageCount
parameter when element rasters are output and treat those rasters with a value of 1 in that field as being variable and suitable for early purging.
The SWEVT_RR_PAGE_DEFINE event and SWMSG_RR_PAGE_DEFINE message give client code the information it needs to construct pages from their constituent raster elements. The SWMSG_RR_PAGE_DEFINE message includes an array of pointers to structures representing pages or tiles, and is generated by the RIP during the scanning process; this event informs the client code of the pages and their contents, in terms of raster element IDs.
The page definition provided by the RIP must be stored by the OEM code until it has been used, as it will not be re-sent by the RIP. There may be more than one SWEVT_RR_PAGE_DEFINE event for a page range. That means that the client code should append to its tables rather than overwrite them when a SWEVT_RR_PAGE_DEFINE event arrives. The page define structure defined by each SWMSG_RR_PAGE_DEFINE may need some explanation:
SWMSG_RR_PAGE_DEFINE::page_offset is the zero-based page number offset of the first page in this page define. This offset should be added to RR_PAGE_DEFINE_PAGE::relative_page_number, and adjusted by 1 to get the 1-based page index in the total sequence of pages output by the job. Note that this refers to the actual page number, not counting tiles as separate pages.
The page offset is adjusted to get page numbering correct when tiling, or running a job using multiple pdfexecid
chunks with /PageRange
to divide the job into chunks, or when using Harlequin Scalable RIP.
pdfexecid
page range, so you must keep track of how many pages have been defined previously.The RR_PAGE_DEFINE_PAGE structure describes each page or tile. If tiling, the RIP guarantees that all tiles of a page that are being output will appear in the same SWMSG_RR_PAGE_DEFINE message, with adjacent entries in the SWMSG_RR_PAGE_DEFINE::pages array. A couple of fields in this structure may need some extra explanation:
relative_page_number
.RR_PAGE_DEFINE_PAGE::background_id is an element ID of length RR_ELEMENT_ID_LENGTH, or NULL
. This is used to identify an element used to initialize the background of the page or tile when the erase color is not white. The page or tile background should be initialized to the color value of the pixel or pixels of the corresponding raster element(s). If the raster contains more than 1 pixel, all the pixels will have the same color value. A NULL
entry indicates that the page or tile background should be initialized to white.
Normally the page or tile rasters should be initialized to white, before composing in each of the raster elements in turn. However, if any of the pages or tiles need a non-white background, a non-NULL
RR_PAGE_DEFINE_PAGE::background_id will be supplied. In this case the raster element corresponding to the ID will be a very small raster if position independence is enabled, either 1 by 1 pixel or OptimizedPDFGridX
by OptimizedPDFGridY
(whichever is larger), and all of its pixels will be the required background color. If position independence is not enabled, the raster will be the full page size as usual, but only a very small bounding box will be indicated.
Each page or tile raster should be initialized to the required erase color by copying the value from one of the pixels in the background raster. After this, each of the element rasters corresponding to the RR_PAGE_DEFINE_PAGE::elements should be composed on the page raster as usual.
For more information on EraseColor see the Harlequin Extensions Manual.
PageRange
in the original pdfexec
or pdfexecid
.HVD cache implementations must take care not to allow purging of element definitions between the SWEVT_RR_ELEMENT_DEFINE event and the subsequent operation by the same client referring to that element (either SWEVT_RR_PAGE_DEFINE or SWEVT_RR_ELEMENT_UPDATE_HITS).
The SWEVT_RR_ELEMENT_QUERY_LOCK event is used by the RIP to ask the client code whether it already has a copy of the rasters for the element with the given ID. The client's event handler should return SW_EVENT_CONTINUE if it does not yet have, and is not expecting, a rasters for the element in question. The event handler should return SW_EVENT_HANDLED if it does have, or is expecting, rasters for the element.
The RIP may query the same element ID multiple times before the raster arrives in the cache. In part this is because the rasterization and delivery of the element by the RIP are asynchronous, but also the client code may impose further constraints. If the RIP sees that the event is unhandled, it will issue a SWEVT_RR_ELEMENT_PENDING event to signal that the element will be rendered and passed to the client. Once it has done so the client code should mark the element in its cache as "pending". That way the second and subsequent queries can return SW_EVENT_HANDLED to avoid having the RIP render the element repeatedly and redundantly.
In a Scalable RIP, another client may set the element to pending between the SWEVT_RR_ELEMENT_QUERY_LOCK and SWEVT_RR_ELEMENT_PENDING events issued by a RIP. If the SWEVT_RR_ELEMENT_PENDING event returns the error MON_INVALIDACCESS_LIBHVD_ALREADY_PENDING, the RIP will re-issue the SWEVT_RR_ELEMENT_QUERY_LOCK event. The client code may return SW_EVENT_HANDLED, indicating that the rasters are expected for the element.
Note that it is valid for the returned element handle to be NULL
: this either means that it exists in the cache but is degenerate, or it is pending as previously described. Also note that the value of the handle the client sets in the SWMSG_RR_ELEMENT_QUERY_LOCK message is not used by the RIP in external HVD mode, only in internal HVD.
The SWEVT_RR_ELEMENT_PENDING event uses the SWMSG_RR_ELEMENT_REF message to identify which element it concerns. This just contains the ID of the element that is now pending. Cache implementations must not purge element definitions or rasters between an SWEVT_RR_ELEMENT_PENDING event and the subsequent SWEVT_RR_ELEMENT_QUERY_LOCK event.
Once the cache implementation has responded to a SWEVT_RR_ELEMENT_QUERY_LOCK event with SW_EVENT_HANDLED, the element definition and rasters must not be purged before the corresponding SWEVT_RR_ELEMENT_UNLOCK event. This event uses the same SWMSG_RR_ELEMENT_REF message as SWEVT_RR_ELEMENT_PENDING above. Only one page's worth of elements (or in the case of tiling, one tile's worth of elements) will be locked at any given time by the RIP, and if the cache cannot contain all the necessary elements at once then this is an unrecoverable error. If implementing a shared cache across multiple processes, locking and unlocking should be treated as a lock count, and the element should not be purged from the cache unless the lock count is zero.
The SWEVT_RR_PAGE_READY event is a signal from the RIP to the client code that every element for the given page or tile is either present in the cache or will be supplied by the RIP soon (see SWEVT_RR_ELEMENT_PENDING). The RIP will then expect a SWEVT_RR_PAGE_COMPLETE event from the client code when, and only when, output is fully completed for the page or tile assembled by the client code from the constituent raster elements. At that point, the RIP will issue SWEVT_RR_ELEMENT_UNLOCK and SWEVT_RR_ELEMENT_UPDATE_HITS as appropriate. The message for both SWEVT_RR_PAGE_READY and SWEVT_RR_PAGE_COMPLETE is SWMSG_RR_PAGE_REF, which just contains a page index. This page index is cumulative over all page definitions for the HVD connection, it should be reduced by the page define's SWMSG_RR_PAGE_DEFINE::page_index_offset if you want to extract a page definition directly SWMSG_RR_PAGE_DEFINE::pages.
When using HVD external mode it is the responsibility of the client code to manage whatever caching of sub-page rasters is required. The cache implementation may choose to make use of the OptimizedPDFUsageCount
value from each raster delivered and/or the hit count managed through the SWEVT_RR_ELEMENT_UPDATE_HITS event. Alternatively, it may choose to follow some other strategy.
In general, element definitions should not be purged while they have a non-zero hit count, or between a SWEVT_RR_PAGE_DEFINE event and the SWEVT_RR_PAGE_COMPLETE events for all pages that refer to the element (this will be encapsulated by the element's hit count being non-zero). The RIP will re-issue an SWEVT_RR_ELEMENT_DEFINE event at the start of a scanning window if the hit count for an element required for a page definition cannot be updated, on the presumption that the element definition has been purged. (This is indicated by the SWEVT_RR_ELEMENT_UPDATE_HITS event returning the error MON_UNDEFINED_LIBHVD_ELEMENT.) Element rasters may be purged while the element is not pending and is not locked. Cache implementations used by multiple RIPs, or multiple threads within a single RIP, may attempt to purge elements to make space in the cache at any time, so care is required to handle simultaneous access to the cache.
To avoid stalling the RIP, the client code should copy element raster data from the raster output buffers to the cache as rapidly as possible. You may choose to use a band or framebuffer allocation strategy that lets the raster backend code allocate memory for the raster data directly from the cache, in which case copying may not be needed.
If the cache implementation deletes a cached raster before the next time the RIP queries for it, the RIP will regenerate the raster.
The client code should check its tables and deliver output upon receipt of a SWEVT_RR_PAGE_READY event. It is not generally safe to rely solely on checking for pages ready to be output on receipt of an element raster because if all element rasters for all pages in the current range are already cached, no such raster delivery will take place.
Element rasters must be replayed in turn by the client code in order to compose together the final page or tile. If the client code knows that all raster elements are already to hand, it can begin page output immediately.
When position independence is turned off, all rasters delivered will have nominally the full dimensions of the page, but a bounding box is supplied for each in the element SWMSG_RR_ELEMENT_DEFINE message. The size of this bounding box will match the size of the bounding box of the actual raster delivered to the back end when position independence is turned on; all rasters delivered when position independence is turned off are as large as the page and the bounding box in the event message tells you where to extract the relevant part from that raster from. Empty bands above and below the area actually marked in each raster may be suppressed with TrimPage
as usual. White space to the left and right of that marked area can be easily skipped in the cache implementation using the bounding box.
typedef struct RR_PAGE_DEFINE_PAGE RR_PAGE_DEFINE_PAGE |
A page or tile in the External HVD interface Page Define message.
The bounding box of the raster data can be used to determine if a whole page or a tile is represented. The relative page number can be used to determine if more than one tile of the same page is present. If tiling, the RIP guarantees that all tiles of a page that are being output will appear in the same SWEVT_RR_PAGE_DEFINE event, with adjacent entries in the SWMSG_RR_PAGE_DEFINE::pages array.
typedef struct SWMSG_RR_ELEMENT_DEFINE SWMSG_RR_ELEMENT_DEFINE |
HVD interface Page Element Define message.
This message is sent with a SWEVT_RR_ELEMENT_DEFINE event.
typedef struct SWMSG_RR_ELEMENT_QUERY_LOCK SWMSG_RR_ELEMENT_QUERY_LOCK |
HVD element query message, sent with the SWEVT_RR_ELEMENT_QUERY_LOCK event.
Looks for a raster element with the given id, and locks it against purging if found.
Returns SW_EVENT_CONTINUE if nothing found, in which case handle is undefined. Note that NULL
is a valid value for handle which means that the element is defined, but is degenerate.
If the element is found, it should not be purged from the cache instance until it receives a corresponding unlock event, or the connection ends. This controls the low water mark level of the cache such that the current page can be guaranteed to complete. Of course the cache implementation is free to store raster elements even after the unlock, and should be encouraged to do so. This locking mechanism simply defines the minimum requirement for successful output.
An element may be queried and locked multiple times in the same connection before receiving any unlock messages. This is a common case when Harlequin Parallel Pages is active. If there are no errors in processing a job, there will be an equal number of unlock messages to successful query/lock messages. All locks made during a connection should be removed when the connection is disconnected.
typedef struct SWMSG_RR_ELEMENT_REF SWMSG_RR_ELEMENT_REF |
This is a message which identifies a particular raster element, and is used by two events:
typedef struct SWMSG_RR_ELEMENT_UPDATE_HITS SWMSG_RR_ELEMENT_UPDATE_HITS |
HVD element hit count message, sent with the SWEVT_RR_ELEMENT_UPDATE_HITS event.
Increment or decrement the hit count for the element identified by id by the amount given in hits_delta - whether to add or subtract to the hit count is determined by the raise flag.
typedef struct SWMSG_RR_ELEMENT_UPDATE_RASTER SWMSG_RR_ELEMENT_UPDATE_RASTER |
Internal HVD element update message, sent with the SWEVT_RR_ELEMENT_UPDATE_RASTER event.
Update the raster element with the given values for raster and size. Only used in Internal HVD: not relevant for External HVD.
typedef struct SWMSG_RR_PAGE_DEFINE SWMSG_RR_PAGE_DEFINE |
An External HVD interface Page Define message, sent with the SWEVT_RR_PAGE_DEFINE event.
Note that the memory referred to in this structure should be treated as transient: if the code associated with a handler wishes to use any data contained in this event after the handler has returned, it should make a copy. When tiling output, each tile appears as a separate RR_PAGE_DEFINE_PAGE in the pages array.