Add OpenglRender_unittests, fix glGetTexImage unavailability
glGetTexImage isn't necessarily supported on host, so do a fallback.
TODO: Add the GL snapshot tests back
Bug: 171711491
Change-Id: I94b034c20ed5a48fcff4cae17485e9e9abf0dbd9
diff --git a/stream-servers/tests/GLSnapshotVertexAttributes_unittest.cpp b/stream-servers/tests/GLSnapshotVertexAttributes_unittest.cpp
new file mode 100644
index 0000000..f8438dd
--- /dev/null
+++ b/stream-servers/tests/GLSnapshotVertexAttributes_unittest.cpp
@@ -0,0 +1,305 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "GLSnapshotTestStateUtils.h"
+#include "GLSnapshotTesting.h"
+#include "OpenGLTestContext.h"
+
+#include <gtest/gtest.h>
+
+#include <algorithm>
+
+namespace emugl {
+
+enum class GlVertexAttribMode { SingleValue = 0, Array = 1, Buffer = 2 };
+
+struct GlVertexAttrib {
+ GlVertexAttribMode mode;
+ GlValues values;
+ GLint size;
+ GLenum type;
+ GLboolean normalized;
+ GLsizei stride;
+ GLboolean enabled;
+ GLvoid* pointer;
+ GLuint bufferBinding;
+};
+
+static const GlVertexAttrib kGLES2DefaultVertexAttrib = {
+ .mode = GlVertexAttribMode::SingleValue,
+ .values = {.ints = {}, .floats = {0, 0, 0, 1}},
+ .size = 4,
+ .type = GL_FLOAT,
+ .normalized = GL_FALSE,
+ .stride = 0,
+ .enabled = GL_FALSE,
+ .pointer = nullptr,
+ .bufferBinding = 0};
+
+static const GlBufferData kTestAttachedBuffer = {.size = 16,
+ .bytes = nullptr,
+ .usage = GL_STATIC_DRAW};
+
+class SnapshotGlVertexAttributesTest
+ : public SnapshotSetValueTest<GlVertexAttrib> {
+public:
+ virtual void stateCheck(GlVertexAttrib expected) override {
+ EXPECT_TRUE(compareIntParameter(GL_VERTEX_ATTRIB_ARRAY_ENABLED,
+ expected.enabled));
+ }
+
+ virtual void stateChange() override {
+ GlVertexAttrib changed = *m_changed_value;
+ if (changed.enabled) {
+ gl->glEnableVertexAttribArray(m_index);
+ } else {
+ gl->glDisableVertexAttribArray(m_index);
+ }
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+ }
+
+ void selectIndex(GLuint index) {
+ GLint maxAttribs;
+ gl->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+ if (index >= maxAttribs) {
+ fprintf(stderr,
+ "cannot select index %d: GL_MAX_VERTEX_ATTRIBS is %d.\n",
+ index, maxAttribs);
+ return;
+ }
+ m_index = index;
+ }
+
+protected:
+ testing::AssertionResult compareFloatParameter(GLenum paramName,
+ GLfloat expected) {
+ std::vector<GLfloat> v = {expected};
+ return compareFloatParameter(paramName, v);
+ }
+
+ testing::AssertionResult compareFloatParameter(
+ GLenum paramName,
+ const std::vector<GLfloat>& expected) {
+ std::vector<GLfloat> values;
+ values.resize(std::max((GLuint)4, (GLuint)expected.size()));
+ gl->glGetVertexAttribfv(m_index, paramName, &(values[0]));
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+ return compareVector<GLfloat>(
+ expected, values,
+ "float(s) for parameter " + describeGlEnum(paramName) +
+ " of vertex attribute " + std::to_string(m_index));
+ }
+
+ testing::AssertionResult compareIntParameter(GLenum paramName,
+ GLint expected) {
+ std::vector<GLint> v = {expected};
+ return compareIntParameter(paramName, v);
+ }
+
+ testing::AssertionResult compareIntParameter(
+ GLenum paramName,
+ const std::vector<GLint>& expected) {
+ std::vector<GLint> values;
+ values.resize(std::max((GLuint)4, (GLuint)expected.size()));
+ gl->glGetVertexAttribiv(m_index, paramName, &(values[0]));
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+ return compareVector<GLint>(
+ expected, values,
+ "int(s) for parameter " + describeGlEnum(paramName) +
+ " of vertex attribute " + std::to_string(m_index));
+ }
+
+ GLuint m_index = 0;
+};
+
+class SnapshotGlVertexAttribSingleValueTest
+ : public SnapshotGlVertexAttributesTest {
+public:
+ void stateCheck(GlVertexAttrib expected) override {
+ SnapshotGlVertexAttributesTest::stateCheck(expected);
+
+ // check current element value
+ switch (expected.type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_FIXED:
+ EXPECT_TRUE(compareIntParameter(GL_CURRENT_VERTEX_ATTRIB,
+ expected.values.ints));
+ break;
+ case GL_FLOAT:
+ EXPECT_TRUE(compareFloatParameter(GL_CURRENT_VERTEX_ATTRIB,
+ expected.values.floats));
+ break;
+ default:
+ ADD_FAILURE() << "Unexpected type " << expected.type
+ << " for vertex attribute " << m_index;
+ }
+ }
+
+ void stateChange() override {
+ SnapshotGlVertexAttributesTest::stateChange();
+ GlVertexAttrib changed = *m_changed_value;
+ switch (changed.type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_FIXED:
+ // TODO(benzene): support GLES3+
+ FAIL() << "GLES2 only supports float vertex attributes "
+ "(VertexAttrib{1234}f).";
+ case GL_FLOAT:
+ switch (changed.values.floats.size()) {
+ case 1:
+ gl->glVertexAttrib1fv(
+ m_index, (GLfloat*)&changed.values.floats[0]);
+ break;
+ case 2:
+ gl->glVertexAttrib2fv(
+ m_index, (GLfloat*)&changed.values.floats[0]);
+ break;
+ case 3:
+ gl->glVertexAttrib3fv(
+ m_index, (GLfloat*)&changed.values.floats[0]);
+ break;
+ case 4:
+ gl->glVertexAttrib4fv(
+ m_index, (GLfloat*)&changed.values.floats[0]);
+ break;
+ default:
+ ADD_FAILURE() << "Unsupported size " << changed.size
+ << " for vertex attribute " << m_index;
+ }
+ break;
+ default:
+ ADD_FAILURE() << "Unsupported type " << changed.type
+ << " for vertex attribute " << m_index;
+ }
+ }
+};
+
+class SnapshotGlVertexAttribArrayTest : public SnapshotGlVertexAttributesTest {
+public:
+ virtual void stateCheck(GlVertexAttrib expected) override {
+ SnapshotGlVertexAttributesTest::stateCheck(expected);
+ // check parameters
+ EXPECT_TRUE(compareIntParameter(GL_VERTEX_ATTRIB_ARRAY_SIZE,
+ expected.size));
+ EXPECT_TRUE(compareIntParameter(GL_VERTEX_ATTRIB_ARRAY_TYPE,
+ expected.type));
+ EXPECT_TRUE(compareIntParameter(GL_VERTEX_ATTRIB_ARRAY_STRIDE,
+ expected.stride));
+ EXPECT_TRUE(compareIntParameter(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED,
+ expected.normalized));
+ EXPECT_TRUE(compareIntParameter(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
+ expected.bufferBinding));
+
+ GLvoid* pointer;
+ gl->glGetVertexAttribPointerv(m_index, GL_VERTEX_ATTRIB_ARRAY_POINTER,
+ &pointer);
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+ EXPECT_EQ(expected.pointer, pointer);
+ }
+
+ virtual void stateChange() override {
+ SnapshotGlVertexAttributesTest::stateChange();
+ GlVertexAttrib changed = *m_changed_value;
+ gl->glVertexAttribPointer(m_index, changed.size, changed.type,
+ changed.normalized, changed.stride,
+ changed.pointer);
+ }
+};
+
+class SnapshotGlVertexAttribBufferTest
+ : public SnapshotGlVertexAttribArrayTest {
+public:
+ void stateCheck(GlVertexAttrib expected) override {
+ SnapshotGlVertexAttribArrayTest::stateCheck(expected);
+ }
+
+ void stateChange() override {
+ GlVertexAttrib changed = *m_changed_value;
+
+ // Set up buffer to be bound before glVertexAttribPointer,
+ // which will copy ARRAY_BUFFER_BINDING into the attrib's binding
+ if (gl->glIsBuffer(changed.bufferBinding) == GL_TRUE) {
+ gl->glBindBuffer(GL_ARRAY_BUFFER, changed.bufferBinding);
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError())
+ << "Failed to bind buffer " << changed.bufferBinding;
+ GLint bindresult;
+ gl->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &bindresult);
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+ } else {
+ ADD_FAILURE() << "Tried to bind buffer with vertex attributes but "
+ << changed.bufferBinding << " is not a valid buffer.";
+ }
+
+ SnapshotGlVertexAttribArrayTest::stateChange();
+
+ if (changed.bufferBinding != 0) {
+ // Clear the array buffer binding
+ gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+
+ GLint bindresult;
+ gl->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &bindresult);
+ EXPECT_EQ(GL_NO_ERROR, gl->glGetError());
+ }
+ }
+};
+
+TEST_F(SnapshotGlVertexAttribSingleValueTest, PreserveCurrentFloatAttrib) {
+ selectIndex(31);
+ GlVertexAttrib testAttrib = kGLES2DefaultVertexAttrib;
+ testAttrib.values = {.ints = {}, .floats = {.1, .3}},
+ setExpectedValues(kGLES2DefaultVertexAttrib, testAttrib);
+ doCheckedSnapshot();
+}
+
+TEST_F(SnapshotGlVertexAttribArrayTest, DISABLED_PreserveArrayProperties) {
+ selectIndex(5);
+ GLfloat testArrayContents[] = {2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f};
+ GlVertexAttrib arrayAttrib = kGLES2DefaultVertexAttrib;
+ arrayAttrib.mode = GlVertexAttribMode::Array;
+ arrayAttrib.size = 3;
+ arrayAttrib.stride = sizeof(GLfloat) * 3;
+ arrayAttrib.normalized = GL_TRUE;
+ arrayAttrib.enabled = GL_TRUE;
+ arrayAttrib.pointer = testArrayContents;
+ setExpectedValues(kGLES2DefaultVertexAttrib, arrayAttrib);
+ doCheckedSnapshot();
+}
+
+TEST_F(SnapshotGlVertexAttribBufferTest, AttachArrayBuffer) {
+ selectIndex(15);
+ GLfloat testBuffContents[] = {
+ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f,
+ 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f,
+ };
+ GlBufferData data = kTestAttachedBuffer;
+ data.bytes = testBuffContents;
+ GLuint buffer = createBuffer(gl, data);
+ GlVertexAttrib withBuffer = kGLES2DefaultVertexAttrib;
+ withBuffer.mode = GlVertexAttribMode::Buffer;
+ withBuffer.enabled = GL_TRUE;
+ withBuffer.pointer = reinterpret_cast<GLvoid*>(2); // offset
+ withBuffer.bufferBinding = buffer;
+ setExpectedValues(kGLES2DefaultVertexAttrib, withBuffer);
+ doCheckedSnapshot();
+}
+
+} // namespace emugl