| 1 | /*****************************************************************************/ |
| 2 | // Copyright 2006 Adobe Systems Incorporated |
| 3 | // All Rights Reserved. |
| 4 | // |
| 5 | // NOTICE: Adobe permits you to use, modify, and distribute this file in |
| 6 | // accordance with the terms of the Adobe license agreement accompanying it. |
| 7 | /*****************************************************************************/ |
| 8 | |
| 9 | /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_area_task.h#1 $ */ |
| 10 | /* $DateTime: 2012/05/30 13:28:51 $ */ |
| 11 | /* $Change: 832332 $ */ |
| 12 | /* $Author: tknoll $ */ |
| 13 | |
| 14 | /** \file |
| 15 | * Class to handle partitioning a rectangular image processing operation taking into account multiple processing resources and memory constraints. |
| 16 | */ |
| 17 | |
| 18 | /*****************************************************************************/ |
| 19 | |
| 20 | #ifndef __dng_area_task__ |
| 21 | #define __dng_area_task__ |
| 22 | |
| 23 | /*****************************************************************************/ |
| 24 | |
| 25 | #include "dng_classes.h" |
| 26 | #include "dng_point.h" |
| 27 | #include "dng_types.h" |
| 28 | |
| 29 | /*****************************************************************************/ |
| 30 | |
| 31 | /// \brief Abstract class for rectangular processing operations with support for partitioning across multiple processing resources and observing memory constraints. |
| 32 | |
| 33 | class dng_area_task |
| 34 | { |
| 35 | |
| 36 | protected: |
| 37 | |
| 38 | uint32 fMaxThreads; |
| 39 | |
| 40 | uint32 fMinTaskArea; |
| 41 | |
| 42 | dng_point fUnitCell; |
| 43 | |
| 44 | dng_point fMaxTileSize; |
| 45 | |
| 46 | public: |
| 47 | |
| 48 | dng_area_task (); |
| 49 | |
| 50 | virtual ~dng_area_task (); |
| 51 | |
| 52 | /// Getter for the maximum number of threads (resources) that can be used for processing |
| 53 | /// |
| 54 | /// \retval Number of threads, minimum of 1, that can be used for this task. |
| 55 | |
| 56 | virtual uint32 MaxThreads () const |
| 57 | { |
| 58 | return fMaxThreads; |
| 59 | } |
| 60 | |
| 61 | /// Getter for minimum area of a partitioned rectangle. |
| 62 | /// Often it is not profitable to use more resources if it requires partitioning the input into chunks that are too small, |
| 63 | /// as the overhead increases more than the speedup. This method can be ovreridden for a specific task to indicate the smallest |
| 64 | /// area for partitioning. Default is 256x256 pixels. |
| 65 | /// |
| 66 | /// \retval Minimum area for a partitoned tile in order to give performant operation. (Partitions can be smaller due to small inputs and edge cases.) |
| 67 | |
| 68 | virtual uint32 MinTaskArea () const |
| 69 | { |
| 70 | return fMinTaskArea; |
| 71 | } |
| 72 | |
| 73 | /// Getter for dimensions of which partitioned tiles should be a multiple. |
| 74 | /// Various methods of processing prefer certain alignments. The partitioning attempts to construct tiles such that the |
| 75 | /// sizes are a multiple of the dimensions of this point. |
| 76 | /// |
| 77 | /// \retval a point giving preferred alignment in x and y |
| 78 | |
| 79 | virtual dng_point UnitCell () const |
| 80 | { |
| 81 | return fUnitCell; |
| 82 | } |
| 83 | |
| 84 | /// Getter for maximum size of a tile for processing. |
| 85 | /// Often processing will need to allocate temporary buffers or use other resources that are either fixed or in limited supply. |
| 86 | /// The maximum tile size forces further partitioning if the tile is bigger than this size. |
| 87 | /// |
| 88 | /// \retval Maximum tile size allowed for this area task. |
| 89 | |
| 90 | virtual dng_point MaxTileSize () const |
| 91 | { |
| 92 | return fMaxTileSize; |
| 93 | } |
| 94 | |
| 95 | /// Getter for RepeatingTile1. |
| 96 | /// RepeatingTile1, RepeatingTile2, and RepeatingTile3 are used to establish a set of 0 to 3 tile patterns for which |
| 97 | /// the resulting partitions that the final Process method is called on will not cross tile boundaries in any of the |
| 98 | /// tile patterns. This can be used for a processing routine that needs to read from two tiles and write to a third |
| 99 | /// such that all the tiles are aligned and sized in a certain way. A RepeatingTile value is valid if it is non-empty. |
| 100 | /// Higher numbered RepeatingTile patterns are only used if all lower ones are non-empty. A RepeatingTile pattern must |
| 101 | /// be a multiple of UnitCell in size for all constraints of the partitionerr to be met. |
| 102 | |
| 103 | virtual dng_rect RepeatingTile1 () const; |
| 104 | |
| 105 | /// Getter for RepeatingTile2. |
| 106 | /// RepeatingTile1, RepeatingTile2, and RepeatingTile3 are used to establish a set of 0 to 3 tile patterns for which |
| 107 | /// the resulting partitions that the final Process method is called on will not cross tile boundaries in any of the |
| 108 | /// tile patterns. This can be used for a processing routine that needs to read from two tiles and write to a third |
| 109 | /// such that all the tiles are aligned and sized in a certain way. A RepeatingTile value is valid if it is non-empty. |
| 110 | /// Higher numbered RepeatingTile patterns are only used if all lower ones are non-empty. A RepeatingTile pattern must |
| 111 | /// be a multiple of UnitCell in size for all constraints of the partitionerr to be met. |
| 112 | |
| 113 | virtual dng_rect RepeatingTile2 () const; |
| 114 | |
| 115 | /// Getter for RepeatingTile3. |
| 116 | /// RepeatingTile1, RepeatingTile2, and RepeatingTile3 are used to establish a set of 0 to 3 tile patterns for which |
| 117 | /// the resulting partitions that the final Process method is called on will not cross tile boundaries in any of the |
| 118 | /// tile patterns. This can be used for a processing routine that needs to read from two tiles and write to a third |
| 119 | /// such that all the tiles are aligned and sized in a certain way. A RepeatingTile value is valid if it is non-empty. |
| 120 | /// Higher numbered RepeatingTile patterns are only used if all lower ones are non-empty. A RepeatingTile pattern must |
| 121 | /// be a multiple of UnitCell in size for all constraints of the partitionerr to be met. |
| 122 | |
| 123 | virtual dng_rect RepeatingTile3 () const; |
| 124 | |
| 125 | /// Task startup method called before any processing is done on partitions. |
| 126 | /// The Start method is called before any processing is done and can be overridden to allocate temporary buffers, etc. |
| 127 | /// |
| 128 | /// \param threadCount Total number of threads that will be used for processing. Less than or equal to MaxThreads. |
| 129 | /// \param tileSize Size of source tiles which will be processed. (Not all tiles will be this size due to edge conditions.) |
| 130 | /// \param allocator dng_memory_allocator to use for allocating temporary buffers, etc. |
| 131 | /// \param sniffer Sniffer to test for user cancellation and to set up progress. |
| 132 | |
| 133 | virtual void Start (uint32 threadCount, |
| 134 | const dng_point &tileSize, |
| 135 | dng_memory_allocator *allocator, |
| 136 | dng_abort_sniffer *sniffer); |
| 137 | |
| 138 | /// Process one tile or fully partitioned area. |
| 139 | /// This method is overridden by derived classes to implement the actual image processing. Note that the sniffer can be ignored if it is certain that a |
| 140 | /// processing task will complete very quickly. |
| 141 | /// This method should never be called directly but rather accessed via Process. |
| 142 | /// There is no allocator parameter as all allocation should be done in Start. |
| 143 | /// |
| 144 | /// \param threadIndex 0 to threadCount - 1 index indicating which thread this is. (Can be used to get a thread-specific buffer allocated in the Start method.) |
| 145 | /// \param tile Area to process. |
| 146 | /// \param sniffer dng_abort_sniffer to use to check for user cancellation and progress updates. |
| 147 | |
| 148 | virtual void Process (uint32 threadIndex, |
| 149 | const dng_rect &tile, |
| 150 | dng_abort_sniffer *sniffer) = 0; |
| 151 | |
| 152 | /// Task computation finalization and teardown method. |
| 153 | /// Called after all resources have completed processing. Can be overridden to accumulate results and free resources allocated in Start. |
| 154 | /// |
| 155 | /// \param threadCount Number of threads used for processing. Same as value passed to Start. |
| 156 | |
| 157 | virtual void Finish (uint32 threadCount); |
| 158 | |
| 159 | /// Find tile size taking into account repeating tiles, unit cell, and maximum tile size. |
| 160 | /// \param area Computation area for which to find tile size. |
| 161 | /// \retval Tile size as height and width in point. |
| 162 | |
| 163 | dng_point FindTileSize (const dng_rect &area) const; |
| 164 | |
| 165 | /// Handle one resource's worth of partitioned tiles. |
| 166 | /// Called after thread partitioning has already been done. Area may be further subdivided to handle maximum tile size, etc. |
| 167 | /// It will be rare to override this method. |
| 168 | /// |
| 169 | /// \param threadIndex 0 to threadCount - 1 index indicating which thread this is. |
| 170 | /// \param area Tile area partitioned to this resource. |
| 171 | /// \param tileSize |
| 172 | /// \param sniffer dng_abort_sniffer to use to check for user cancellation and progress updates. |
| 173 | |
| 174 | void ProcessOnThread (uint32 threadIndex, |
| 175 | const dng_rect &area, |
| 176 | const dng_point &tileSize, |
| 177 | dng_abort_sniffer *sniffer); |
| 178 | |
| 179 | /// Default resource partitioner that assumes a single resource to be used for processing. |
| 180 | /// Implementations that are aware of multiple processing resources should override (replace) this method. |
| 181 | /// This is usually done in dng_host::PerformAreaTask . |
| 182 | /// \param task The task to perform. |
| 183 | /// \param area The area on which mage processing should be performed. |
| 184 | /// \param allocator dng_memory_allocator to use for allocating temporary buffers, etc. |
| 185 | /// \param sniffer dng_abort_sniffer to use to check for user cancellation and progress updates. |
| 186 | |
| 187 | static void Perform (dng_area_task &task, |
| 188 | const dng_rect &area, |
| 189 | dng_memory_allocator *allocator, |
| 190 | dng_abort_sniffer *sniffer); |
| 191 | |
| 192 | }; |
| 193 | |
| 194 | /*****************************************************************************/ |
| 195 | |
| 196 | #endif |
| 197 | |
| 198 | /*****************************************************************************/ |
| 199 | |