• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "ANGLETest.h"
2 
3 #include <cstdint>
4 
5 class BufferDataTest : public ANGLETest
6 {
7   protected:
BufferDataTest()8     BufferDataTest()
9         : mBuffer(0),
10           mProgram(0),
11           mAttribLocation(-1)
12     {
13         setWindowWidth(16);
14         setWindowHeight(16);
15         setConfigRedBits(8);
16         setConfigGreenBits(8);
17         setConfigBlueBits(8);
18         setConfigAlphaBits(8);
19         setConfigDepthBits(24);
20     }
21 
SetUp()22     virtual void SetUp()
23     {
24         ANGLETest::SetUp();
25 
26         const char * vsSource = SHADER_SOURCE
27         (
28             attribute vec4 position;
29             attribute float in_attrib;
30             varying float v_attrib;
31             void main()
32             {
33                 v_attrib = in_attrib;
34                 gl_Position = position;
35             }
36         );
37 
38         const char * fsSource = SHADER_SOURCE
39         (
40             precision mediump float;
41             varying float v_attrib;
42             void main()
43             {
44                 gl_FragColor = vec4(v_attrib, 0, 0, 1);
45             }
46         );
47 
48         glGenBuffers(1, &mBuffer);
49         ASSERT_NE(mBuffer, 0U);
50 
51         mProgram = CompileProgram(vsSource, fsSource);
52         ASSERT_NE(mProgram, 0U);
53 
54         mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
55         ASSERT_NE(mAttribLocation, -1);
56 
57         glClearColor(0, 0, 0, 0);
58         glClearDepthf(0.0);
59         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
60 
61         glDisable(GL_DEPTH_TEST);
62 
63         ASSERT_GL_NO_ERROR();
64     }
65 
TearDown()66     virtual void TearDown()
67     {
68         glDeleteBuffers(1, &mBuffer);
69         glDeleteProgram(mProgram);
70 
71         ANGLETest::TearDown();
72     }
73 
74     GLuint mBuffer;
75     GLuint mProgram;
76     GLint mAttribLocation;
77 };
78 
TEST_F(BufferDataTest,NULLData)79 TEST_F(BufferDataTest, NULLData)
80 {
81     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
82     EXPECT_GL_NO_ERROR();
83 
84     const int numIterations = 128;
85     for (int i = 0; i < numIterations; ++i)
86     {
87         GLsizei bufferSize = sizeof(GLfloat) * (i + 1);
88         glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_STATIC_DRAW);
89         EXPECT_GL_NO_ERROR();
90 
91         for (int j = 0; j < bufferSize; j++)
92         {
93             for (int k = 0; k < bufferSize - j; k++)
94             {
95                 glBufferSubData(GL_ARRAY_BUFFER, k, j, NULL);
96                 EXPECT_GL_NO_ERROR();
97             }
98         }
99     }
100 }
101 
TEST_F(BufferDataTest,ZeroNonNULLData)102 TEST_F(BufferDataTest, ZeroNonNULLData)
103 {
104     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
105     EXPECT_GL_NO_ERROR();
106 
107     char *zeroData = new char[0];
108     glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW);
109     EXPECT_GL_NO_ERROR();
110 
111     glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData);
112     EXPECT_GL_NO_ERROR();
113 
114     delete [] zeroData;
115 }
116 
TEST_F(BufferDataTest,NULLResolvedData)117 TEST_F(BufferDataTest, NULLResolvedData)
118 {
119     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
120     glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
121 
122     glUseProgram(mProgram);
123     glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
124     glEnableVertexAttribArray(mAttribLocation);
125     glBindBuffer(GL_ARRAY_BUFFER, 0);
126 
127     drawQuad(mProgram, "position", 0.5f);
128 }
129 
TEST_F(BufferDataTest,HugeSetDataShouldNotCrash)130 TEST_F(BufferDataTest, HugeSetDataShouldNotCrash)
131 {
132     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
133     EXPECT_GL_NO_ERROR();
134 
135     GLsizei allocSize = std::numeric_limits<GLsizei>::max() >> 2;
136 
137     uint8_t *data = NULL;
138     while (data == NULL && allocSize >= 4)
139     {
140         data = new (std::nothrow) uint8_t[allocSize];
141 
142         if (data == NULL)
143         {
144             allocSize >>= 1;
145         }
146     }
147 
148     ASSERT_NE(static_cast<uint8_t*>(NULL), data);
149     memset(data, 0, allocSize);
150 
151     float * fValue = reinterpret_cast<float*>(data);
152     for (unsigned int f = 0; f < 6; f++)
153     {
154         fValue[f] = 1.0f;
155     }
156 
157     glBufferData(GL_ARRAY_BUFFER, allocSize, data, GL_STATIC_DRAW);
158 
159     GLenum error = glGetError();
160     if (error == GL_NO_ERROR)
161     {
162         // If we didn't fail because of an out of memory error, try drawing a quad
163         // using the large buffer
164 
165         // DISABLED because it takes a long time, but left for posterity
166 
167         //glUseProgram(mProgram);
168         //glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
169         //glEnableVertexAttribArray(mAttribLocation);
170         //glBindBuffer(GL_ARRAY_BUFFER, 0);
171         //drawQuad(mProgram, "position", 0.5f);
172         //swapBuffers();
173 
174         //// Draw operations can also generate out-of-memory, which is in-spec
175         //error = glGetError();
176         //if (error == GL_NO_ERROR)
177         //{
178         //    GLint viewportSize[4];
179         //    glGetIntegerv(GL_VIEWPORT, viewportSize);
180 
181         //    GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
182         //    GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;
183 
184         //    EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255);
185         //}
186         //else
187         //{
188         //    EXPECT_EQ(GL_OUT_OF_MEMORY, error);
189         //}
190     }
191     else
192     {
193         EXPECT_EQ(GL_OUT_OF_MEMORY, error);
194     }
195 
196     delete[] data;
197 }
198 
199 class IndexedBufferCopyTest : public ANGLETest
200 {
201   protected:
IndexedBufferCopyTest()202     IndexedBufferCopyTest()
203     {
204         setWindowWidth(16);
205         setWindowHeight(16);
206         setConfigRedBits(8);
207         setConfigGreenBits(8);
208         setConfigBlueBits(8);
209         setConfigAlphaBits(8);
210         setConfigDepthBits(24);
211         setClientVersion(3);
212     }
213 
SetUp()214     virtual void SetUp()
215     {
216         ANGLETest::SetUp();
217 
218         const char * vsSource = SHADER_SOURCE
219         (
220             attribute vec3 in_attrib;
221             varying vec3 v_attrib;
222             void main()
223             {
224                 v_attrib = in_attrib;
225                 gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
226                 gl_PointSize = 100.0;
227             }
228         );
229 
230         const char * fsSource = SHADER_SOURCE
231         (
232             precision mediump float;
233             varying vec3 v_attrib;
234             void main()
235             {
236                 gl_FragColor = vec4(v_attrib, 1);
237             }
238         );
239 
240         glGenBuffers(2, mBuffers);
241         ASSERT_NE(mBuffers[0], 0U);
242         ASSERT_NE(mBuffers[1], 0U);
243 
244         glGenBuffers(1, &mElementBuffer);
245         ASSERT_NE(mElementBuffer, 0U);
246 
247         mProgram = CompileProgram(vsSource, fsSource);
248         ASSERT_NE(mProgram, 0U);
249 
250         mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
251         ASSERT_NE(mAttribLocation, -1);
252 
253         glClearColor(0, 0, 0, 0);
254         glDisable(GL_DEPTH_TEST);
255         glClear(GL_COLOR_BUFFER_BIT);
256 
257         ASSERT_GL_NO_ERROR();
258     }
259 
TearDown()260     virtual void TearDown()
261     {
262         glDeleteBuffers(2, mBuffers);
263         glDeleteBuffers(1, &mElementBuffer);
264         glDeleteProgram(mProgram);
265 
266         ANGLETest::TearDown();
267     }
268 
269     GLuint mBuffers[2];
270     GLuint mElementBuffer;
271     GLuint mProgram;
272     GLint mAttribLocation;
273 };
274 
275 // The following test covers an ANGLE bug where our index ranges
276 // weren't updated from CopyBufferSubData calls
277 // https://code.google.com/p/angleproject/issues/detail?id=709
TEST_F(IndexedBufferCopyTest,IndexRangeBug)278 TEST_F(IndexedBufferCopyTest, IndexRangeBug)
279 {
280     unsigned char vertexData[] = { 255, 0, 0, 0, 0, 0 };
281     unsigned int indexData[] = { 0, 1 };
282 
283     glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
284     glBufferData(GL_ARRAY_BUFFER, sizeof(char) * 6, vertexData, GL_STATIC_DRAW);
285 
286     glUseProgram(mProgram);
287     glVertexAttribPointer(mAttribLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3, NULL);
288     glEnableVertexAttribArray(mAttribLocation);
289 
290     ASSERT_GL_NO_ERROR();
291 
292     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer);
293     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 1, indexData, GL_STATIC_DRAW);
294 
295     glUseProgram(mProgram);
296 
297     ASSERT_GL_NO_ERROR();
298 
299     glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
300 
301     EXPECT_GL_NO_ERROR();
302     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
303 
304     glBindBuffer(GL_COPY_READ_BUFFER, mBuffers[1]);
305     glBufferData(GL_COPY_READ_BUFFER, 4, &indexData[1], GL_STATIC_DRAW);
306 
307     glBindBuffer(GL_COPY_WRITE_BUFFER, mElementBuffer);
308 
309     glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(int));
310 
311     ASSERT_GL_NO_ERROR();
312 
313     glClear(GL_COLOR_BUFFER_BIT);
314     EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
315 
316     unsigned char newData[] = { 0, 255, 0 };
317     glBufferSubData(GL_ARRAY_BUFFER, 3, 3, newData);
318 
319     glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
320 
321     EXPECT_GL_NO_ERROR();
322     EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
323 }
324