1 #pragma once
2 
3 #ifndef Y_TILEDARRAY_H
4 #define Y_TILEDARRAY_H
5 
6 #include <yafray_constants.h>
7 #include <cstring>
8 #include "y_alloc.h"
9 
10 __BEGIN_YAFRAY
11 
12 template<class T, int logBlockSize> class tiledArray2D_t
13 {
14 public:
tiledArray2D_t()15 	tiledArray2D_t(): data(nullptr), nx(0), ny(0), xBlocks(0)
16 	{
17 		blockSize = 1 << logBlockSize;
18 		blockMask = blockSize-1;
19 	}
nx(x)20 	tiledArray2D_t(int x, int y, bool init=false): nx(x), ny(y)
21 	{
22 		blockSize = 1 << logBlockSize;
23 		blockMask = blockSize-1;
24 		xBlocks = roundUp(x) >> logBlockSize;
25 		int nAlloc = roundUp(x) * roundUp(y);
26 		data = (T *)y_memalign(64, nAlloc * sizeof(T));
27 		if(init)
28 		{
29 			for (int i = 0; i < nAlloc; ++i) new (&data[i]) T();
30 		}
31 	}
32 	void resize(int x, int y, bool init=false)
33 	{
34 		xBlocks = roundUp(x) >> logBlockSize;
35 		int nAlloc = roundUp(x) * roundUp(y);
36 		T *old = data;
37 		if(old) y_free(old);
38 		data = (T *)y_memalign(64, nAlloc * sizeof(T));
39 		if(init)
40 		{
41 			for (int i = 0; i < nAlloc; ++i) new (&data[i]) T();
42 		}
43 		nx = x; ny = y;
44 		xBlocks = roundUp(x) >> logBlockSize;
45 	}
tileSize()46 	int tileSize() const { return blockSize; }
xSize()47 	int xSize() const { return nx; }
ySize()48 	int ySize() const { return ny; }
getData()49 	T* getData(){ return data; }
size()50 	unsigned int size() const { return roundUp(nx) * roundUp(ny); }
roundUp(int x)51 	int roundUp(int x) const {
52 		return (x + blockSize - 1) & ~(blockSize - 1);
53 	}
54 
~tiledArray2D_t()55 	~tiledArray2D_t() {
56 		for (int i = 0; i < nx * ny; ++i)
57 			data[i].~T();
58 		if(data) y_free(data);
59 	}
operator()60 	T &operator()(int x, int y) {
61 		int bx = block(x), by = block(y);
62 		int ox = offset(x), oy = offset(y);
63 		int offset = (xBlocks * by + bx) << (logBlockSize*2);
64 		offset += (oy << logBlockSize) + ox;
65 		return data[offset];
66 	}
operator()67 	const T &operator()(int x, int y) const {
68 		int bx = block(x), by = block(y);
69 		int ox = offset(x), oy = offset(y);
70 		int offset = (xBlocks * by + bx) << (logBlockSize*2);
71 		offset += (oy << logBlockSize) + ox;
72 		return data[offset];
73 	}
74 protected:
block(int a)75 	int block(int a) const { return (a >> logBlockSize); }
offset(int a)76 	int offset(int a) const { return (a & blockMask); }
77 	// BlockedArray Private Data
78 	T *data;
79 	int nx, ny, xBlocks;
80 	int blockSize, blockMask;
81 };
82 
83 
84 template<int logBlockSize> class tiledBitArray2D_t
85 {
86 	public:
nx(x)87 		tiledBitArray2D_t(int x, int y, bool init=false): nx(x), ny(y)
88 		{
89 			blockSize = 1 << logBlockSize;
90 			blockMask = blockSize-1;
91 			xBlocks = roundUp(x) >> logBlockSize;
92 			nAlloc = roundUp(x) * roundUp(y);
93 			data = (unsigned int *)y_memalign(64, nAlloc * sizeof(unsigned int));
94 			if(init) std::memset(data, 0, nAlloc);
95 		}
~tiledBitArray2D_t()96 		~tiledBitArray2D_t() { if(data) y_free(data); }
roundUp(int x)97 		int roundUp(int x) const{ return (x + blockSize - 1) & ~(blockSize - 1); }
clear()98 		void clear(){ std::memset(data, 0, nAlloc); }
setBit(int x,int y)99 		void setBit(int x, int y)
100 		{
101 			int bx = block(x), by = block(y);
102 			int ox = offset(x), oy = offset(y);
103 			int block_offset = (xBlocks * by + bx) << ((logBlockSize)*2);
104 			int bit_offset = block_offset + ((oy << logBlockSize) | ox);
105 			int el_offset = bit_offset >> 5;
106 			int word_offset = bit_offset & 31;
107 			data[el_offset] |= (1 << word_offset);
108 		}
clearBit(int x,int y)109 		void clearBit(int x, int y)
110 		{
111 			int bx = block(x), by = block(y);
112 			int ox = offset(x), oy = offset(y);
113 			int block_offset = (xBlocks * by + bx) << ((logBlockSize)*2);
114 			int bit_offset = block_offset + ((oy << logBlockSize) | ox);
115 			int el_offset = bit_offset >> 5;
116 			int word_offset = bit_offset & 31;
117 			data[el_offset] &= ~(1 << word_offset);
118 		}
getBit(int x,int y)119 		bool getBit(int x, int y)
120 		{
121 			int bx = block(x), by = block(y);
122 			int ox = offset(x), oy = offset(y);
123 			int block_offset = (xBlocks * by + bx) << ((logBlockSize)*2);
124 			int bit_offset = block_offset + ((oy << logBlockSize) | ox);
125 			int el_offset = bit_offset >> 5;
126 			int word_offset = bit_offset & 31;
127 			return data[el_offset] & (1 << word_offset);
128 		}
129 	protected:
130 		tiledBitArray2D_t();
block(int a)131 		int block(int a) const { return (a >> logBlockSize); }
offset(int a)132 		int offset(int a) const { return (a & blockMask); }
133 		// BlockedArray Private Data
134 		unsigned int *data;
135 		size_t nAlloc;
136 		int nx, ny, xBlocks;
137 		int blockSize, blockMask;
138 };
139 
140 __END_YAFRAY
141 #endif // Y_TILEDARRAY_H
142