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