gdevprna.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Copyright (C) 1998 Aladdin Enterprises. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  4. distributor accepts any responsibility for the consequences of using it, or
  5. for whether it serves any particular purpose or works at all, unless he or
  6. she says so in writing. Refer to the Aladdin Free Public License (the
  7. "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. in a plain ASCII text file named PUBLIC. The License grants you the right
  10. to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. conditions described in the License. Among other things, the License
  12. requires that the copyright notice and this notice be preserved on all
  13. copies.
  14. */
  15. /*$Id: gdevprna.h,v 1.2 2000/09/19 19:00:21 lpd Exp $ */
  16. /* Generic asynchronous printer driver support */
  17. /* Initial version 2/1/1998 by John Desrosiers (soho@crl.com) */
  18. /* 7/28/98 ghost@aladdin.com - Updated to Ghostscript coding standards. */
  19. #ifndef gdevprna_INCLUDED
  20. # define gdevprna_INCLUDED
  21. # include "gdevprn.h"
  22. # include "gxsync.h"
  23. /*
  24. * General
  25. * -------
  26. * Async drivers actually create two separate instances of the device at
  27. * the same time. The first (the writer instance) is only used in the
  28. * interpretation operation; it feeds rendering commands into the command
  29. * lists. The second device instance is used only for rendering the
  30. * commands placed into the command list by the writer.
  31. * The writer builds a command list for an entire page; the command list
  32. * is only queued for rendering once a page's command list is completely
  33. * built. The only exception to this rule is when the interpreter runs
  34. * out of memory, or when no free command list memory is available. In
  35. * such cases, the interpreter queues a "partial page" consisting of all
  36. * command list data written so far, plus a command indicating that the
  37. * page description is not complete. After queuing the partial page, the
  38. * interpereter waits until the rendering process has freed enough
  39. * command list memory to enable the interpreter to proceed.
  40. * To avoid deadlocks when the system runs out of memory, special
  41. * memory allocation provisions are made on both the writer and
  42. * renderer sides. On the writer side, enough "reserve" bandlist
  43. * memory is set aside at startup time to cover the needs of queuing a
  44. * partial page to the renderer. The renderer operates out of a fixed
  45. * memory space; that way, it can always complete rendering pages with
  46. * the memory it has. To this end, the writer protects the renderer
  47. * from consuming unbounded amounts of memory by a) never putting
  48. * complex paths into the command list, b) pre-clipping any output
  49. * unless the clip path consists of a single rectangle, c) never putting
  50. * high-level images into the clip path unless the image in question
  51. * meets some very stringent requirements, such as only being rotated by
  52. * even multiples of 90 degrees and having source-image data rows which
  53. * fit into the command buffer in one piece. These restrictions are what
  54. * dictate the "restricted bandlist format."
  55. * Note that the renderer's instance of the device driver uses the
  56. * renderer's memory. That implies that it must also operate in a small,
  57. * fixed amount of memory, and must do all memory allocation using the
  58. * memory allocator pointed to by the render device's ->memory member.
  59. * Opening the Device
  60. * ------------------
  61. * The writer instance is opened first. This occurs when the system
  62. * calls the "standard" open procedure via the device's procedure
  63. * vector. The driver must implement the open function, but must call
  64. * down to gdev_prn_async_write_open instead of calling down to
  65. * gdev_prn_open. Before calling down to gdev_prn_async_write_open, the
  66. * driver must:
  67. * a - init several procedure vectors, to wit: start_render_thread,
  68. * buffer_page, print_page_copies,
  69. * b - init space_params.band.BandWidth, space_params.band.BandHeight,
  70. * space_params.BufferSpace (see extended comments in gdevasyn.c
  71. * for details on computing appropriate values).
  72. * c - if it implements those functions, the driver must init the
  73. * procedure vectors for: put_params, get_hardware_params,
  74. * output_page, open_render_device.
  75. * Notice that there are two procedure vectors: the usual std_procs, and
  76. * the printer-specific printer_procs.
  77. * Since partial page support imposes extra requirements on drivers,
  78. * such support can be disabled by zeroing out (in the async writer open
  79. * routine, after calling down to gdev_prn_async_write_open) the
  80. * free_up_bandlist_memory member of the driver structure. Doing so
  81. * will, of course, cause interpretation to fail if memory runs out.
  82. * Once the driver calls down to gdev_prn_async_write_open, the async
  83. * support logic will create a second instance of the driver for
  84. * rendering, but will not open it just yet. Instead, the async logic
  85. * will attempt to synchronize the two device instances.
  86. * Synchrnonizing the instances
  87. * ----------------------------
  88. * While still in the gdev_prn_async_write_open routine, the async logic
  89. * will call printer_procs.start_render_thread (which the driver is
  90. * required to implement). start_render_thread must somehow either start a new
  91. * thread or rendez-vous with an existing thread for use in rendering,
  92. * then return. start_render_thread must also have caused the render thread
  93. * to call gdev_prn_async_render_thread, passing it as an argument a magic
  94. * cookie passed to start_render_thread. start_render_thread will only
  95. * return once the device has been closed and all renering has been
  96. * completed.
  97. * The render device will be opened on the render device's thread, by
  98. * calling printer_procs.open_render_device.
  99. * Rendering Operation
  100. * -------------------
  101. * During rendering, the device will not see rendering operations -- the
  102. * first "rendering" operations the driver will see is when the renderer
  103. * instance's print_page_copies or buffer_page routines get called. In
  104. * both cases, the appropriate routine must then perform get_bits calls
  105. * on the async logic in order to retrieve rendered bits, then transmit
  106. * them to the appropriate device buffers.
  107. * The complication that is introduced is that which is related to partial
  108. * pages: A buffer_page call instructs the driver to grab the rendered bits,
  109. * but to keep the rendered bits available for later instead of marking on
  110. * media. This implies that a buffer_page call opens a context where
  111. * subsequent buffer_page's and print_page_copies' must first initialize the
  112. * rendering buffers with the previous rendering results before calling
  113. * get_bits. The first print_page_copies closes the context that was opened
  114. * by the initial buffer_page -- the driver must go back to normal rendering
  115. * until a new buffer_page comes along.
  116. */
  117. /* -------------- Type declarations --------------- */
  118. /* typedef is in gdevprn.h */
  119. /* typedef struct gdev_prn_start_render_params_s gdev_prn_start_render_params;*/
  120. struct gdev_prn_start_render_params_s {
  121. gx_device_printer *writer_device;/* writer dev that points to render dev */
  122. gx_semaphore_t *open_semaphore; /* signal this once open_code is set */
  123. int open_code; /* RETURNS status of open of reader device */
  124. };
  125. /* -------- Macros used to initialize render-specific structures ------ */
  126. #define init_async_render_procs(xpdev, xstart_render_thread,\
  127. xbuffer_page, xprint_page_copies)\
  128. BEGIN\
  129. (xpdev)->printer_procs.start_render_thread = (xstart_render_thread);\
  130. (xpdev)->printer_procs.buffer_page = (xbuffer_page);\
  131. (xpdev)->printer_procs.print_page_copies = (xprint_page_copies);\
  132. END
  133. /* -------------- Global procedure declarations --------- */
  134. /* Open this printer device in ASYNC (overlapped) mode.
  135. *
  136. * This routine is always called by the concrete device's xx_open routine
  137. * in lieu of gdev_prn_open.
  138. */
  139. int gdev_prn_async_write_open(P4(gx_device_printer *pdev, int max_raster,
  140. int min_band_height, int max_src_image_row));
  141. /* Open the render portion of a printer device in ASYNC (overlapped) mode.
  142. *
  143. * This routine is always called by concrete device's xx_open_render_device
  144. * in lieu of gdev_prn_open.
  145. */
  146. int gdev_prn_async_render_open(P1(gx_device_printer *prdev));
  147. /*
  148. * Must be called by async device driver implementation (see
  149. * gdevprna.h under "Synchronizing the Instances"). This is the
  150. * rendering loop, which requires its own thread for as long as
  151. * the device is open. This proc only returns after the device is closed.
  152. */
  153. int /* rets 0 ok, -ve error code */
  154. gdev_prn_async_render_thread(P1(gdev_prn_start_render_params *));
  155. #endif /* gdevprna_INCLUDED */