TuttleOFX  1
parallel_grid.hpp
Go to the documentation of this file.
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