#include "ANGLETest.h"
+#include <cstdint>
+
class BufferDataTest : public ANGLETest
{
-protected:
+ protected:
BufferDataTest()
: mBuffer(0),
mProgram(0),
GLint mAttribLocation;
};
-TEST_F(BufferDataTest, null_data)
+TEST_F(BufferDataTest, NULLData)
{
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
EXPECT_GL_NO_ERROR();
}
}
-TEST_F(BufferDataTest, huge_setdata_should_not_crash)
+TEST_F(BufferDataTest, ZeroNonNULLData)
{
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
EXPECT_GL_NO_ERROR();
- // use as large a size as possible without causing an exception
- GLsizei hugeSize = (1 << 30);
+ char *zeroData = new char[0];
+ glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW);
+ EXPECT_GL_NO_ERROR();
- // on x64, use as large a GLsizei value as possible
- if (sizeof(size_t) > 4)
- {
- hugeSize = std::numeric_limits<GLsizei>::max();
- }
+ glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData);
+ EXPECT_GL_NO_ERROR();
+
+ delete [] zeroData;
+}
+
+TEST_F(BufferDataTest, HugeSetDataShouldNotCrash)
+{
+ glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
+ EXPECT_GL_NO_ERROR();
- char *data = new (std::nothrow) char[hugeSize];
- EXPECT_NE((char * const)NULL, data);
+ GLsizei allocSize = std::numeric_limits<GLsizei>::max() >> 2;
- if (data == NULL)
+ uint8_t *data = NULL;
+ while (data == NULL && allocSize >= 4)
{
- return;
+ data = new (std::nothrow) uint8_t[allocSize];
+
+ if (data == NULL)
+ {
+ allocSize <<= 1;
+ }
}
- memset(data, 0, hugeSize);
+ ASSERT_NE(static_cast<uint8_t*>(NULL), data);
+ memset(data, 0, allocSize);
float * fValue = reinterpret_cast<float*>(data);
for (unsigned int f = 0; f < 6; f++)
fValue[f] = 1.0f;
}
- glBufferData(GL_ARRAY_BUFFER, hugeSize, data, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, allocSize, data, GL_STATIC_DRAW);
GLenum error = glGetError();
if (error == GL_NO_ERROR)
delete[] data;
}
+class IndexedBufferCopyTest : public ANGLETest
+{
+ protected:
+ IndexedBufferCopyTest()
+ {
+ setWindowWidth(16);
+ setWindowHeight(16);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ setConfigDepthBits(24);
+ setClientVersion(3);
+ }
+
+ virtual void SetUp()
+ {
+ ANGLETest::SetUp();
+
+ const char * vsSource = SHADER_SOURCE
+ (
+ attribute vec3 in_attrib;
+ varying vec3 v_attrib;
+ void main()
+ {
+ v_attrib = in_attrib;
+ gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
+ gl_PointSize = 100.0;
+ }
+ );
+
+ const char * fsSource = SHADER_SOURCE
+ (
+ precision mediump float;
+ varying vec3 v_attrib;
+ void main()
+ {
+ gl_FragColor = vec4(v_attrib, 1);
+ }
+ );
+
+ glGenBuffers(2, mBuffers);
+ ASSERT_NE(mBuffers[0], 0U);
+ ASSERT_NE(mBuffers[1], 0U);
+
+ glGenBuffers(1, &mElementBuffer);
+ ASSERT_NE(mElementBuffer, 0U);
+
+ mProgram = compileProgram(vsSource, fsSource);
+ ASSERT_NE(mProgram, 0U);
+
+ mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
+ ASSERT_NE(mAttribLocation, -1);
+
+ glClearColor(0, 0, 0, 0);
+ glDisable(GL_DEPTH_TEST);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ ASSERT_GL_NO_ERROR();
+ }
+
+ virtual void TearDown()
+ {
+ glDeleteBuffers(2, mBuffers);
+ glDeleteBuffers(1, &mElementBuffer);
+ glDeleteProgram(mProgram);
+
+ ANGLETest::TearDown();
+ }
+
+ GLuint mBuffers[2];
+ GLuint mElementBuffer;
+ GLuint mProgram;
+ GLint mAttribLocation;
+};
+
+// The following test covers an ANGLE bug where our index ranges
+// weren't updated from CopyBufferSubData calls
+// https://code.google.com/p/angleproject/issues/detail?id=709
+TEST_F(IndexedBufferCopyTest, IndexRangeBug)
+{
+ unsigned char vertexData[] = { 255, 0, 0, 0, 0, 0 };
+ unsigned int indexData[] = { 0, 1 };
+
+ glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(char) * 6, vertexData, GL_STATIC_DRAW);
+
+ glUseProgram(mProgram);
+ glVertexAttribPointer(mAttribLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3, NULL);
+ glEnableVertexAttribArray(mAttribLocation);
+
+ ASSERT_GL_NO_ERROR();
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 1, indexData, GL_STATIC_DRAW);
+
+ glUseProgram(mProgram);
+
+ ASSERT_GL_NO_ERROR();
+
+ glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
+
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
+
+ glBindBuffer(GL_COPY_READ_BUFFER, mBuffers[1]);
+ glBufferData(GL_COPY_READ_BUFFER, 4, &indexData[1], GL_STATIC_DRAW);
+
+ glBindBuffer(GL_COPY_WRITE_BUFFER, mElementBuffer);
+
+ glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(int));
+
+ ASSERT_GL_NO_ERROR();
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
+
+ unsigned char newData[] = { 0, 255, 0 };
+ glBufferSubData(GL_ARRAY_BUFFER, 3, 3, newData);
+
+ glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
+
+ EXPECT_GL_NO_ERROR();
+ EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
+}