1 #include "ANGLETest.h"
2
3 class BufferDataTest : public ANGLETest
4 {
5 protected:
BufferDataTest()6 BufferDataTest()
7 : mBuffer(0),
8 mProgram(0),
9 mAttribLocation(-1)
10 {
11 setWindowWidth(16);
12 setWindowHeight(16);
13 setConfigRedBits(8);
14 setConfigGreenBits(8);
15 setConfigBlueBits(8);
16 setConfigAlphaBits(8);
17 setConfigDepthBits(24);
18 }
19
SetUp()20 virtual void SetUp()
21 {
22 ANGLETest::SetUp();
23
24 const char * vsSource = SHADER_SOURCE
25 (
26 attribute vec4 position;
27 attribute float in_attrib;
28 varying float v_attrib;
29 void main()
30 {
31 v_attrib = in_attrib;
32 gl_Position = position;
33 }
34 );
35
36 const char * fsSource = SHADER_SOURCE
37 (
38 precision mediump float;
39 varying float v_attrib;
40 void main()
41 {
42 gl_FragColor = vec4(v_attrib, 0, 0, 1);
43 }
44 );
45
46 glGenBuffers(1, &mBuffer);
47 ASSERT_NE(mBuffer, 0U);
48
49 mProgram = compileProgram(vsSource, fsSource);
50 ASSERT_NE(mProgram, 0U);
51
52 mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
53 ASSERT_NE(mAttribLocation, -1);
54
55 glClearColor(0, 0, 0, 0);
56 glClearDepthf(0.0);
57 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
58
59 glDisable(GL_DEPTH_TEST);
60
61 ASSERT_GL_NO_ERROR();
62 }
63
TearDown()64 virtual void TearDown()
65 {
66 glDeleteBuffers(1, &mBuffer);
67 glDeleteProgram(mProgram);
68
69 ANGLETest::TearDown();
70 }
71
72 GLuint mBuffer;
73 GLuint mProgram;
74 GLint mAttribLocation;
75 };
76
TEST_F(BufferDataTest,null_data)77 TEST_F(BufferDataTest, null_data)
78 {
79 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
80 EXPECT_GL_NO_ERROR();
81
82 const int numIterations = 128;
83 for (int i = 0; i < numIterations; ++i)
84 {
85 GLsizei bufferSize = sizeof(GLfloat) * (i + 1);
86 glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_STATIC_DRAW);
87 EXPECT_GL_NO_ERROR();
88
89 for (int j = 0; j < bufferSize; j++)
90 {
91 for (int k = 0; k < bufferSize - j; k++)
92 {
93 glBufferSubData(GL_ARRAY_BUFFER, k, j, NULL);
94 EXPECT_GL_NO_ERROR();
95 }
96 }
97 }
98 }
99
TEST_F(BufferDataTest,huge_setdata_should_not_crash)100 TEST_F(BufferDataTest, huge_setdata_should_not_crash)
101 {
102 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
103 EXPECT_GL_NO_ERROR();
104
105 // use as large a size as possible without causing an exception
106 GLsizei hugeSize = (1 << 30);
107
108 // on x64, use as large a GLsizei value as possible
109 if (sizeof(size_t) > 4)
110 {
111 hugeSize = std::numeric_limits<GLsizei>::max();
112 }
113
114 char *data = new (std::nothrow) char[hugeSize];
115 EXPECT_NE((char * const)NULL, data);
116
117 if (data == NULL)
118 {
119 return;
120 }
121
122 memset(data, 0, hugeSize);
123
124 float * fValue = reinterpret_cast<float*>(data);
125 for (unsigned int f = 0; f < 6; f++)
126 {
127 fValue[f] = 1.0f;
128 }
129
130 glBufferData(GL_ARRAY_BUFFER, hugeSize, data, GL_STATIC_DRAW);
131
132 GLenum error = glGetError();
133 if (error == GL_NO_ERROR)
134 {
135 // If we didn't fail because of an out of memory error, try drawing a quad
136 // using the large buffer
137
138 // DISABLED because it takes a long time, but left for posterity
139
140 //glUseProgram(mProgram);
141 //glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
142 //glEnableVertexAttribArray(mAttribLocation);
143 //glBindBuffer(GL_ARRAY_BUFFER, 0);
144 //drawQuad(mProgram, "position", 0.5f);
145 //swapBuffers();
146
147 //// Draw operations can also generate out-of-memory, which is in-spec
148 //error = glGetError();
149 //if (error == GL_NO_ERROR)
150 //{
151 // GLint viewportSize[4];
152 // glGetIntegerv(GL_VIEWPORT, viewportSize);
153
154 // GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
155 // GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;
156
157 // EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255);
158 //}
159 //else
160 //{
161 // EXPECT_EQ(GL_OUT_OF_MEMORY, error);
162 //}
163 }
164 else
165 {
166 EXPECT_EQ(GL_OUT_OF_MEMORY, error);
167 }
168
169 delete[] data;
170 }
171
172