1 /*****************************************************************************/
2 // Copyright 2006-2012 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.cpp#1 $ */
10 /* $DateTime: 2012/05/30 13:28:51 $ */
11 /* $Change: 832332 $ */
12 /* $Author: tknoll $ */
13 
14 /*****************************************************************************/
15 
16 #include "dng_area_task.h"
17 
18 #include "dng_abort_sniffer.h"
19 #include "dng_flags.h"
20 #include "dng_sdk_limits.h"
21 #include "dng_tile_iterator.h"
22 #include "dng_utils.h"
23 
24 #if qImagecore
25 extern bool gPrintTimings;
26 #endif
27 
28 /*****************************************************************************/
29 
dng_area_task()30 dng_area_task::dng_area_task ()
31 
32 	:	fMaxThreads   (kMaxMPThreads)
33 
34 	,	fMinTaskArea  (256 * 256)
35 
36 	,	fUnitCell	  (1, 1)
37 
38 	,	fMaxTileSize  (256, 256)
39 
40 	{
41 
42 	}
43 
44 /*****************************************************************************/
45 
~dng_area_task()46 dng_area_task::~dng_area_task ()
47 	{
48 
49 	}
50 
51 /*****************************************************************************/
52 
RepeatingTile1() const53 dng_rect dng_area_task::RepeatingTile1 () const
54 	{
55 
56 	return dng_rect ();
57 
58 	}
59 
60 /*****************************************************************************/
61 
RepeatingTile2() const62 dng_rect dng_area_task::RepeatingTile2 () const
63 	{
64 
65 	return dng_rect ();
66 
67 	}
68 
69 /*****************************************************************************/
70 
RepeatingTile3() const71 dng_rect dng_area_task::RepeatingTile3 () const
72 	{
73 
74 	return dng_rect ();
75 
76 	}
77 
78 /*****************************************************************************/
79 
Start(uint32,const dng_point &,dng_memory_allocator *,dng_abort_sniffer *)80 void dng_area_task::Start (uint32 /* threadCount */,
81 						   const dng_point & /* tileSize */,
82 						   dng_memory_allocator * /* allocator */,
83 						   dng_abort_sniffer * /* sniffer */)
84 	{
85 
86 	}
87 
88 /*****************************************************************************/
89 
Finish(uint32)90 void dng_area_task::Finish (uint32 /* threadCount */)
91 	{
92 
93 	}
94 
95 /*****************************************************************************/
96 
FindTileSize(const dng_rect & area) const97 dng_point dng_area_task::FindTileSize (const dng_rect &area) const
98 	{
99 
100 	dng_rect repeatingTile1 = RepeatingTile1 ();
101 	dng_rect repeatingTile2 = RepeatingTile2 ();
102 	dng_rect repeatingTile3 = RepeatingTile3 ();
103 
104 	if (repeatingTile1.IsEmpty ())
105 		{
106 		repeatingTile1 = area;
107 		}
108 
109 	if (repeatingTile2.IsEmpty ())
110 		{
111 		repeatingTile2 = area;
112 		}
113 
114 	if (repeatingTile3.IsEmpty ())
115 		{
116 		repeatingTile3 = area;
117 		}
118 
119 	uint32 repeatV = Min_uint32 (Min_uint32 (repeatingTile1.H (),
120 											 repeatingTile2.H ()),
121 											 repeatingTile3.H ());
122 
123 	uint32 repeatH = Min_uint32 (Min_uint32 (repeatingTile1.W (),
124 											 repeatingTile2.W ()),
125 											 repeatingTile3.W ());
126 
127 	dng_point maxTileSize = MaxTileSize ();
128 
129 	dng_point tileSize;
130 
131 	tileSize.v = Min_int32 (repeatV, maxTileSize.v);
132 	tileSize.h = Min_int32 (repeatH, maxTileSize.h);
133 
134 	// What this is doing is, if the smallest repeating image tile is larger than the
135 	// maximum tile size, adjusting the tile size down so that the tiles are as small
136 	// as possible while still having the same number of tiles covering the
137 	// repeat area.  This makes the areas more equal in size, making MP
138 	// algorithms work better.
139 
140 	// The image core team did not understand this code, and disabled it.
141 	// Really stupid idea to turn off code you don't understand!
142 	// I'm undoing this removal, because I think the code is correct and useful.
143 
144 	uint32 countV = (repeatV + tileSize.v - 1) / tileSize.v;
145 	uint32 countH = (repeatH + tileSize.h - 1) / tileSize.h;
146 
147 	tileSize.v = (repeatV + countV - 1) / countV;
148 	tileSize.h = (repeatH + countH - 1) / countH;
149 
150 	// Round up to unit cell size.
151 
152 	dng_point unitCell = UnitCell ();
153 
154 	if (unitCell.h != 1 || unitCell.v != 1)
155 		{
156 		tileSize.v = ((tileSize.v + unitCell.v - 1) / unitCell.v) * unitCell.v;
157 		tileSize.h = ((tileSize.h + unitCell.h - 1) / unitCell.h) * unitCell.h;
158 		}
159 
160 	// But if that is larger than maximum tile size, round down to unit cell size.
161 
162 	if (tileSize.v > maxTileSize.v)
163 		{
164 		tileSize.v = (maxTileSize.v / unitCell.v) * unitCell.v;
165 		}
166 
167 	if (tileSize.h > maxTileSize.h)
168 		{
169 		tileSize.h = (maxTileSize.h / unitCell.h) * unitCell.h;
170 		}
171 
172 	#if qImagecore
173     if (gPrintTimings)
174 		{
175         fprintf (stdout, "\nRender tile for below: %d x %d\n", (int32) tileSize.h, (int32) tileSize.v);
176 		}
177 	#endif
178 
179 	return tileSize;
180 
181 	}
182 
183 /*****************************************************************************/
184 
ProcessOnThread(uint32 threadIndex,const dng_rect & area,const dng_point & tileSize,dng_abort_sniffer * sniffer)185 void dng_area_task::ProcessOnThread (uint32 threadIndex,
186 									 const dng_rect &area,
187 									 const dng_point &tileSize,
188 									 dng_abort_sniffer *sniffer)
189 	{
190 
191 	dng_rect repeatingTile1 = RepeatingTile1 ();
192 	dng_rect repeatingTile2 = RepeatingTile2 ();
193 	dng_rect repeatingTile3 = RepeatingTile3 ();
194 
195 	if (repeatingTile1.IsEmpty ())
196 		{
197 		repeatingTile1 = area;
198 		}
199 
200 	if (repeatingTile2.IsEmpty ())
201 		{
202 		repeatingTile2 = area;
203 		}
204 
205 	if (repeatingTile3.IsEmpty ())
206 		{
207 		repeatingTile3 = area;
208 		}
209 
210 	dng_rect tile1;
211 
212 	dng_tile_iterator iter1 (repeatingTile3, area);
213 
214 	while (iter1.GetOneTile (tile1))
215 		{
216 
217 		dng_rect tile2;
218 
219 		dng_tile_iterator iter2 (repeatingTile2, tile1);
220 
221 		while (iter2.GetOneTile (tile2))
222 			{
223 
224 			dng_rect tile3;
225 
226 			dng_tile_iterator iter3 (repeatingTile1, tile2);
227 
228 			while (iter3.GetOneTile (tile3))
229 				{
230 
231 				dng_rect tile4;
232 
233 				dng_tile_iterator iter4 (tileSize, tile3);
234 
235 				while (iter4.GetOneTile (tile4))
236 					{
237 
238 					dng_abort_sniffer::SniffForAbort (sniffer);
239 
240 					Process (threadIndex, tile4, sniffer);
241 
242 					}
243 
244 				}
245 
246 			}
247 
248 		}
249 
250 	}
251 
252 /*****************************************************************************/
253 
Perform(dng_area_task & task,const dng_rect & area,dng_memory_allocator * allocator,dng_abort_sniffer * sniffer)254 void dng_area_task::Perform (dng_area_task &task,
255 				  			 const dng_rect &area,
256 				  			 dng_memory_allocator *allocator,
257 				  			 dng_abort_sniffer *sniffer)
258 	{
259 
260 	dng_point tileSize (task.FindTileSize (area));
261 
262 	task.Start (1, tileSize, allocator, sniffer);
263 
264 	task.ProcessOnThread (0, area, tileSize, sniffer);
265 
266 	task.Finish (1);
267 
268 	}
269 
270 /*****************************************************************************/
271