1 /*
2  Copyright (c) 2013 yvt
3 
4  This file is part of OpenSpades.
5 
6  OpenSpades is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OpenSpades is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OpenSpades.  If not, see <http://www.gnu.org/licenses/>.
18 
19  */
20 
21 #pragma once
22 
23 #include <algorithm>
24 #include <array>
25 #include <memory>
26 
27 #include <Core/ConcurrentDispatch.h>
28 #include <Core/Debug.h>
29 
30 namespace spades {
31 	namespace draw {
32 		int GetNumSWRendererThreads();
33 
InvokeParallel(F f,unsigned int numThreads)34 		template <class F> static void InvokeParallel(F f, unsigned int numThreads) {
35 			SPAssert(numThreads <= 32);
36 			std::array<std::unique_ptr<ConcurrentDispatch>, 32> disp;
37 			for (auto i = 1U; i < numThreads; i++) {
38 				auto ff = [i, &f]() { f(i); };
39 				disp[i] = std::unique_ptr<ConcurrentDispatch>(
40 				  static_cast<ConcurrentDispatch *>(new FunctionDispatch<decltype(ff)>(ff)));
41 				disp[i]->Start();
42 			}
43 			f(0);
44 			for (auto i = 1U; i < numThreads; i++) {
45 				disp[i]->Join();
46 			}
47 		}
48 
InvokeParallel2(F f)49 		template <class F> static void InvokeParallel2(F f) {
50 
51 			unsigned int numThreads = static_cast<unsigned int>(GetNumSWRendererThreads());
52 			numThreads = std::max(numThreads, 1U);
53 			numThreads = std::min(numThreads, 32U);
54 
55 			std::array<std::unique_ptr<ConcurrentDispatch>, 32> disp;
56 			for (auto i = 1U; i < numThreads; i++) {
57 				auto ff = [i, &f, numThreads]() { f(i, numThreads); };
58 				disp[i] = std::unique_ptr<ConcurrentDispatch>(
59 				  static_cast<ConcurrentDispatch *>(new FunctionDispatch<decltype(ff)>(ff)));
60 				disp[i]->Start();
61 			}
62 			f(0, numThreads);
63 			for (auto i = 1U; i < numThreads; i++) {
64 				disp[i]->Join();
65 			}
66 		}
67 
ToFixed8(float v)68 		static inline int ToFixed8(float v) {
69 			int i = static_cast<int>(v * 255.f + .5f);
70 			return std::max(std::min(i, 255), 0);
71 		}
72 
ToFixedFactor8(float v)73 		static inline int ToFixedFactor8(float v) {
74 			int i = static_cast<int>(v * 256.f + .5f);
75 			return std::max(std::min(i, 256), 0);
76 		}
77 	}
78 }
79