TuttleOFX
1
|
00001 // Copyright Tom Brinkman 2008. Distributed under the Boost 00002 // Software License, Version 1.0. (See accompanying 00003 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00004 00005 #ifndef _parallel_grid_hpp_ 00006 #define _parallel_grid_hpp_ 00007 00008 #include <vector> 00009 #include <boost/gil/gil_all.hpp> 00010 #include <boost/function.hpp> 00011 00012 #include <tbb/parallel_for.h> 00013 #include <tbb/parallel_reduce.h> 00014 #include <tbb/blocked_range.h> 00015 #include <tbb/task_scheduler_init.h> 00016 #include <tbb/tick_count.h> 00017 00018 #include <sections.hpp> 00019 00020 namespace layer 00021 { 00022 00023 template <typename view_t> 00024 struct parallel_draw 00025 { 00026 typedef boost::function<void (view_t&)> layer_t; 00027 00028 std::vector<view_t> views; 00029 std::vector<layer_t> layers; 00030 parallel_draw(std::vector<layer_t>& layers, std::vector<view_t>& views) : 00031 views(views), layers(layers){} 00032 00033 void operator()(const tbb::blocked_range<size_t>& blocks) const 00034 { 00035 BOOST_ASSERT(layers.size() == views.size()); 00036 for (std::size_t block = blocks.begin(); block != blocks.end(); ++block) 00037 { 00038 view_t v = views[block]; 00039 layers[block](v); 00040 } 00041 } 00042 }; 00043 00044 template <typename view_t> 00045 struct parallel_grid 00046 { 00047 typedef boost::function<void (view_t&)> layer_t; 00048 typedef std::vector<layer_t> layers_t; 00049 layers_t layers; 00050 int cols; 00051 int margin; 00052 00053 parallel_grid(layer_t* p, int total, int cols, int margin = 5) : 00054 cols(cols), margin(margin) 00055 { 00056 for (int n = 0; n < total; ++n) 00057 layers.push_back(p[n]); 00058 } 00059 00060 void operator()(view_t& view) 00061 { 00062 using namespace boost::gil; 00063 00064 int y = 0; 00065 std::vector<view_t> views; 00066 00067 int rows = (int)ceil(layers.size()/(double)cols); 00068 sections ycurr(view.height()+margin,rows); 00069 for (; ycurr; ycurr++) 00070 { 00071 int yheight = *ycurr-margin; 00072 int x = 0; 00073 00074 sections xcurr(view.width()+margin,cols); 00075 for (; xcurr; xcurr++) 00076 { 00077 int xwidth = *xcurr-margin; 00078 views.push_back(subimage_view(view,x,y,xwidth,yheight)); 00079 x += xwidth+margin; 00080 } 00081 00082 y += yheight+margin; 00083 } 00084 00085 tbb::parallel_for(tbb::blocked_range<std::size_t>(0,views.size()), 00086 parallel_draw<view_t>(layers,views), tbb::auto_partitioner()); 00087 } 00088 }; 00089 00090 } 00091 00092 #endif