Home | History | Annotate | Download | only in source
      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 
     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 
     46 dng_area_task::~dng_area_task ()
     47 	{
     48 
     49 	}
     50 
     51 /*****************************************************************************/
     52 
     53 dng_rect dng_area_task::RepeatingTile1 () const
     54 	{
     55 
     56 	return dng_rect ();
     57 
     58 	}
     59 
     60 /*****************************************************************************/
     61 
     62 dng_rect dng_area_task::RepeatingTile2 () const
     63 	{
     64 
     65 	return dng_rect ();
     66 
     67 	}
     68 
     69 /*****************************************************************************/
     70 
     71 dng_rect dng_area_task::RepeatingTile3 () const
     72 	{
     73 
     74 	return dng_rect ();
     75 
     76 	}
     77 
     78 /*****************************************************************************/
     79 
     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 
     90 void dng_area_task::Finish (uint32 /* threadCount */)
     91 	{
     92 
     93 	}
     94 
     95 /*****************************************************************************/
     96 
     97 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 
    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 
    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