Let the application manage PBOs.
[movit] / flat_input_test.cpp
1 // Unit tests for FlatInput.
2
3 #include <GL/glew.h>
4 #include <stddef.h>
5
6 #include "effect_chain.h"
7 #include "flat_input.h"
8 #include "gtest/gtest.h"
9 #include "test_util.h"
10 #include "util.h"
11
12 TEST(FlatInput, SimpleGrayscale) {
13         const int size = 4;
14
15         float data[size] = {
16                 0.0,
17                 0.5,
18                 0.7,
19                 1.0,
20         };
21         float expected_data[4 * size] = {
22                 0.0, 0.0, 0.0, 1.0,
23                 0.5, 0.5, 0.5, 1.0,
24                 0.7, 0.7, 0.7, 1.0,
25                 1.0, 1.0, 1.0, 1.0,
26         };
27         float out_data[4 * size];
28
29         EffectChainTester tester(data, 1, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
30         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
31
32         expect_equal(expected_data, out_data, 4, size);
33 }
34
35 TEST(FlatInput, RGB) {
36         const int size = 5;
37
38         float data[3 * size] = {
39                 0.0, 0.0, 0.0,
40                 0.5, 0.0, 0.0,
41                 0.0, 0.5, 0.0,
42                 0.0, 0.0, 0.7,
43                 0.0, 0.3, 0.7,
44         };
45         float expected_data[4 * size] = {
46                 0.0, 0.0, 0.0, 1.0,
47                 0.5, 0.0, 0.0, 1.0,
48                 0.0, 0.5, 0.0, 1.0,
49                 0.0, 0.0, 0.7, 1.0,
50                 0.0, 0.3, 0.7, 1.0,
51         };
52         float out_data[4 * size];
53
54         EffectChainTester tester(data, 1, size, FORMAT_RGB, COLORSPACE_sRGB, GAMMA_LINEAR);
55         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
56
57         expect_equal(expected_data, out_data, 4, size);
58 }
59
60 TEST(FlatInput, RGBA) {
61         const int size = 5;
62
63         float data[4 * size] = {
64                 0.0, 0.0, 0.0, 1.0,
65                 0.5, 0.0, 0.0, 0.3,
66                 0.0, 0.5, 0.0, 0.7,
67                 0.0, 0.0, 0.7, 1.0,
68                 0.0, 0.3, 0.7, 0.2,
69         };
70         float expected_data[4 * size] = {
71                 0.0, 0.0, 0.0, 1.0,
72                 0.5, 0.0, 0.0, 0.3,
73                 0.0, 0.5, 0.0, 0.7,
74                 0.0, 0.0, 0.7, 1.0,
75                 0.0, 0.3, 0.7, 0.2,
76         };
77         float out_data[4 * size];
78
79         EffectChainTester tester(data, 1, size, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
80         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
81
82         expect_equal(expected_data, out_data, 4, size);
83 }
84
85 // Note: The sRGB conversion itself is tested in EffectChainTester,
86 // since it also wants to test the chain building itself.
87 // Here, we merely test that alpha is left alone; the test will usually
88 // run using the sRGB OpenGL extension, but might be run with a
89 // GammaExpansionEffect if the card/driver happens not to support that.
90 TEST(FlatInput, AlphaIsNotModifiedBySRGBConversion) {
91         const int size = 5;
92
93         unsigned char data[4 * size] = {
94                 0, 0, 0, 0,
95                 0, 0, 0, 63,
96                 0, 0, 0, 127,
97                 0, 0, 0, 191,
98                 0, 0, 0, 255,
99         };
100         float expected_data[4 * size] = {
101                 0, 0, 0, 0.0 / 255.0,
102                 0, 0, 0, 63.0 / 255.0,
103                 0, 0, 0, 127.0 / 255.0,
104                 0, 0, 0, 191.0 / 255.0,
105                 0, 0, 0, 255.0 / 255.0,
106         };
107         float out_data[4 * size];
108
109         EffectChainTester tester(NULL, 1, size);
110         tester.add_input(data, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_sRGB);
111         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
112
113         expect_equal(expected_data, out_data, 4, size);
114 }
115
116 TEST(FlatInput, BGR) {
117         const int size = 5;
118
119         float data[3 * size] = {
120                 0.0, 0.0, 0.0,
121                 0.5, 0.0, 0.0,
122                 0.0, 0.5, 0.0,
123                 0.0, 0.0, 0.7,
124                 0.0, 0.3, 0.7,
125         };
126         float expected_data[4 * size] = {
127                 0.0, 0.0, 0.0, 1.0,
128                 0.0, 0.0, 0.5, 1.0,
129                 0.0, 0.5, 0.0, 1.0,
130                 0.7, 0.0, 0.0, 1.0,
131                 0.7, 0.3, 0.0, 1.0,
132         };
133         float out_data[4 * size];
134
135         EffectChainTester tester(data, 1, size, FORMAT_BGR, COLORSPACE_sRGB, GAMMA_LINEAR);
136         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
137
138         expect_equal(expected_data, out_data, 4, size);
139 }
140
141 TEST(FlatInput, BGRA) {
142         const int size = 5;
143
144         float data[4 * size] = {
145                 0.0, 0.0, 0.0, 1.0,
146                 0.5, 0.0, 0.0, 0.3,
147                 0.0, 0.5, 0.0, 0.7,
148                 0.0, 0.0, 0.7, 1.0,
149                 0.0, 0.3, 0.7, 0.2,
150         };
151         float expected_data[4 * size] = {
152                 0.0, 0.0, 0.0, 1.0,
153                 0.0, 0.0, 0.5, 0.3,
154                 0.0, 0.5, 0.0, 0.7,
155                 0.7, 0.0, 0.0, 1.0,
156                 0.7, 0.3, 0.0, 0.2,
157         };
158         float out_data[4 * size];
159
160         EffectChainTester tester(data, 1, size, FORMAT_BGRA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
161         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
162
163         expect_equal(expected_data, out_data, 4, size);
164 }
165
166 TEST(FlatInput, Pitch) {
167         const int pitch = 3;
168         const int width = 2;
169         const int height = 4;
170
171         float data[pitch * height] = {
172                 0.0, 1.0, 999.0f,
173                 0.5, 0.5, 999.0f,
174                 0.7, 0.2, 999.0f,
175                 1.0, 0.6, 999.0f,
176         };
177         float expected_data[4 * width * height] = {
178                 0.0, 0.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,
179                 0.5, 0.5, 0.5, 1.0,  0.5, 0.5, 0.5, 1.0,
180                 0.7, 0.7, 0.7, 1.0,  0.2, 0.2, 0.2, 1.0,
181                 1.0, 1.0, 1.0, 1.0,  0.6, 0.6, 0.6, 1.0,
182         };
183         float out_data[4 * width * height];
184
185         EffectChainTester tester(NULL, width, height);
186
187         ImageFormat format;
188         format.color_space = COLORSPACE_sRGB;
189         format.gamma_curve = GAMMA_LINEAR;
190
191         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
192         input->set_pitch(pitch);
193         input->set_pixel_data(data);
194         tester.get_chain()->add_input(input);
195
196         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
197         expect_equal(expected_data, out_data, 4 * width, height);
198 }
199
200 TEST(FlatInput, UpdatedData) {
201         const int width = 2;
202         const int height = 4;
203
204         float data[width * height] = {
205                 0.0, 1.0,
206                 0.5, 0.5,
207                 0.7, 0.2,
208                 1.0, 0.6,
209         };
210         float out_data[width * height];
211
212         EffectChainTester tester(NULL, width, height);
213
214         ImageFormat format;
215         format.color_space = COLORSPACE_sRGB;
216         format.gamma_curve = GAMMA_LINEAR;
217
218         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
219         input->set_pixel_data(data);
220         tester.get_chain()->add_input(input);
221
222         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
223         expect_equal(data, out_data, width, height);
224
225         data[6] = 0.3;
226         input->invalidate_pixel_data();
227
228         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
229         expect_equal(data, out_data, width, height);
230 }
231
232 TEST(FlatInput, PBO) {
233         const int width = 3;
234         const int height = 2;
235
236         float data[width * height] = {
237                 0.0, 1.0, 0.5,
238                 0.5, 0.5, 0.2,
239         };
240         float expected_data[4 * width * height] = {
241                 0.0, 0.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,  0.5, 0.5, 0.5, 1.0,
242                 0.5, 0.5, 0.5, 1.0,  0.5, 0.5, 0.5, 1.0,  0.2, 0.2, 0.2, 1.0,
243         };
244         float out_data[4 * width * height];
245
246         GLuint pbo;
247         glGenBuffers(1, &pbo);
248         glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
249         glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * sizeof(float), data, GL_STREAM_DRAW);
250         glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
251
252         EffectChainTester tester(NULL, width, height);
253
254         ImageFormat format;
255         format.color_space = COLORSPACE_sRGB;
256         format.gamma_curve = GAMMA_LINEAR;
257
258         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
259         input->set_pixel_data((float *)BUFFER_OFFSET(0), pbo);
260         tester.get_chain()->add_input(input);
261
262         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
263         expect_equal(expected_data, out_data, 4 * width, height);
264
265         glDeleteBuffers(1, &pbo);
266 }