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
33class 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