summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorbajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-12 16:25:57 +0000
committerbajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-12 16:25:57 +0000
commitab4fd728dca3d8d59564dd5fb552eea244929363 (patch)
treee46ae4f2fefcb282c0212f96ec6d254739c66319 /gpu
parente9ec622093449d24d4f5182eb6c60f0266308eb3 (diff)
downloadchromium_src-ab4fd728dca3d8d59564dd5fb552eea244929363.zip
chromium_src-ab4fd728dca3d8d59564dd5fb552eea244929363.tar.gz
chromium_src-ab4fd728dca3d8d59564dd5fb552eea244929363.tar.bz2
Added emulation of the OES_vertex_array_object WebGL extension for devices that
do not support it natively, such as those using ANGLE. TEST=Visit https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/oes-vertex-array-object.html on an ANGLE device. All tests should pass. Review URL: https://chromiumcodereview.appspot.com/10983072 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161589 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/feature_info.cc18
-rw-r--r--gpu/command_buffer/service/feature_info.h1
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc37
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc74
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc373
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc72
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h6
-rw-r--r--gpu/command_buffer/service/vertex_attrib_manager.cc4
8 files changed, 393 insertions, 192 deletions
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 7f15dbf..606db90 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -84,7 +84,8 @@ FeatureInfo::FeatureFlags::FeatureFlags()
disable_workarounds(false),
is_intel(false),
is_nvidia(false),
- is_amd(false) {
+ is_amd(false),
+ is_mesa(false) {
}
FeatureInfo::FeatureInfo() {
@@ -207,6 +208,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
feature_flags_.is_nvidia |= string_set.Contains("nvidia");
feature_flags_.is_amd |=
string_set.Contains("amd") || string_set.Contains("ati");
+ feature_flags_.is_mesa |= string_set.Contains("mesa");
}
}
@@ -344,11 +346,15 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
validators_.render_buffer_format.AddValue(GL_DEPTH24_STENCIL8);
}
- if (ext.Desire("GL_OES_vertex_array_object") &&
- (ext.Have("GL_OES_vertex_array_object") ||
- ext.Have("GL_ARB_vertex_array_object") ||
- ext.Have("GL_APPLE_vertex_array_object"))) {
- feature_flags_.native_vertex_array_object_ = true;
+ if (ext.Desire("GL_OES_vertex_array_object")) {
+ if (ext.Have("GL_OES_vertex_array_object") ||
+ ext.Have("GL_ARB_vertex_array_object") ||
+ ext.Have("GL_APPLE_vertex_array_object")) {
+ feature_flags_.native_vertex_array_object_ = true;
+ }
+
+ // OES_vertex_array_object is emulated if not present natively,
+ // so the extension string is always exposed.
AddExtensionString("GL_OES_vertex_array_object");
}
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index 5f3fbe0..2f3268d 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -43,6 +43,7 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool is_intel;
bool is_nvidia;
bool is_amd;
+ bool is_mesa;
};
FeatureInfo();
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index f08d4ce..3d14e7c 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -9,6 +9,7 @@
#include "gpu/command_buffer/service/test_helper.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_implementation.h"
using ::gfx::MockGLInterface;
using ::testing::_;
@@ -88,9 +89,11 @@ TEST_F(FeatureInfoTest, Basic) {
).use_arb_occlusion_query2_for_occlusion_query_boolean);
EXPECT_FALSE(info_->feature_flags(
).use_arb_occlusion_query_for_occlusion_query_boolean);
+ EXPECT_FALSE(info_->feature_flags().native_vertex_array_object_);
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_FALSE(info_->feature_flags().is_amd);
+ EXPECT_FALSE(info_->feature_flags().is_mesa);
// Test good types.
{
@@ -765,7 +768,7 @@ TEST_F(FeatureInfoTest, InitializeOES_vertex_array_object) {
SetupInitExpectations("GL_OES_vertex_array_object");
info_->Initialize(NULL);
EXPECT_THAT(info_->extensions(),
- HasSubstr("GL_OES_vertex_array_object"));
+ HasSubstr("GL_OES_vertex_array_object"));
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object_);
}
@@ -773,7 +776,7 @@ TEST_F(FeatureInfoTest, InitializeARB_vertex_array_object) {
SetupInitExpectations("GL_ARB_vertex_array_object");
info_->Initialize(NULL);
EXPECT_THAT(info_->extensions(),
- HasSubstr("GL_OES_vertex_array_object"));
+ HasSubstr("GL_OES_vertex_array_object"));
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object_);
}
@@ -781,7 +784,7 @@ TEST_F(FeatureInfoTest, InitializeAPPLE_vertex_array_object) {
SetupInitExpectations("GL_APPLE_vertex_array_object");
info_->Initialize(NULL);
EXPECT_THAT(info_->extensions(),
- HasSubstr("GL_OES_vertex_array_object"));
+ HasSubstr("GL_OES_vertex_array_object"));
EXPECT_TRUE(info_->feature_flags().native_vertex_array_object_);
}
@@ -791,6 +794,8 @@ TEST_F(FeatureInfoTest, InitializeNo_vertex_array_object) {
// Even if the native extensions are not available the implementation
// may still emulate the GL_OES_vertex_array_object functionality. In this
// scenario native_vertex_array_object must be false.
+ EXPECT_THAT(info_->extensions(),
+ HasSubstr("GL_OES_vertex_array_object"));
EXPECT_FALSE(info_->feature_flags().native_vertex_array_object_);
}
@@ -800,6 +805,7 @@ TEST_F(FeatureInfoTest, IsIntel) {
EXPECT_TRUE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_FALSE(info_->feature_flags().is_amd);
+ EXPECT_FALSE(info_->feature_flags().is_mesa);
SetupInitExpectationsWithVendor("", "", "IntEl");
FeatureInfo::Ref feature_info(new FeatureInfo());
@@ -807,6 +813,7 @@ TEST_F(FeatureInfoTest, IsIntel) {
EXPECT_TRUE(feature_info->feature_flags().is_intel);
EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
EXPECT_FALSE(feature_info->feature_flags().is_amd);
+ EXPECT_FALSE(info_->feature_flags().is_mesa);
}
TEST_F(FeatureInfoTest, IsNvidia) {
@@ -815,6 +822,7 @@ TEST_F(FeatureInfoTest, IsNvidia) {
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_TRUE(info_->feature_flags().is_nvidia);
EXPECT_FALSE(info_->feature_flags().is_amd);
+ EXPECT_FALSE(info_->feature_flags().is_mesa);
SetupInitExpectationsWithVendor("", "", "NViDiA");
{
@@ -823,6 +831,7 @@ TEST_F(FeatureInfoTest, IsNvidia) {
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_TRUE(feature_info->feature_flags().is_nvidia);
EXPECT_FALSE(feature_info->feature_flags().is_amd);
+ EXPECT_FALSE(feature_info->feature_flags().is_mesa);
}
SetupInitExpectationsWithVendor("", "NVIDIA Corporation", "");
@@ -832,6 +841,7 @@ TEST_F(FeatureInfoTest, IsNvidia) {
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_TRUE(feature_info->feature_flags().is_nvidia);
EXPECT_FALSE(feature_info->feature_flags().is_amd);
+ EXPECT_FALSE(feature_info->feature_flags().is_mesa);
}
}
@@ -841,6 +851,7 @@ TEST_F(FeatureInfoTest, IsAMD) {
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_TRUE(info_->feature_flags().is_amd);
+ EXPECT_FALSE(info_->feature_flags().is_mesa);
SetupInitExpectationsWithVendor("", "", "AmD");
FeatureInfo::Ref feature_info(new FeatureInfo());
@@ -848,6 +859,7 @@ TEST_F(FeatureInfoTest, IsAMD) {
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
EXPECT_TRUE(feature_info->feature_flags().is_amd);
+ EXPECT_FALSE(feature_info->feature_flags().is_mesa);
}
TEST_F(FeatureInfoTest, IsAMDATI) {
@@ -856,6 +868,7 @@ TEST_F(FeatureInfoTest, IsAMDATI) {
EXPECT_FALSE(info_->feature_flags().is_intel);
EXPECT_FALSE(info_->feature_flags().is_nvidia);
EXPECT_TRUE(info_->feature_flags().is_amd);
+ EXPECT_FALSE(info_->feature_flags().is_mesa);
SetupInitExpectationsWithVendor("", "", "AtI");
FeatureInfo::Ref feature_info(new FeatureInfo());
@@ -863,6 +876,24 @@ TEST_F(FeatureInfoTest, IsAMDATI) {
EXPECT_FALSE(feature_info->feature_flags().is_intel);
EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
EXPECT_TRUE(feature_info->feature_flags().is_amd);
+ EXPECT_FALSE(feature_info->feature_flags().is_mesa);
+}
+
+TEST_F(FeatureInfoTest, IsMesa) {
+ SetupInitExpectationsWithVendor("", "MesA", "");
+ info_->Initialize(NULL);
+ EXPECT_FALSE(info_->feature_flags().is_intel);
+ EXPECT_FALSE(info_->feature_flags().is_nvidia);
+ EXPECT_FALSE(info_->feature_flags().is_amd);
+ EXPECT_TRUE(info_->feature_flags().is_mesa);
+
+ SetupInitExpectationsWithVendor("", "", "meSa");
+ FeatureInfo::Ref feature_info(new FeatureInfo());
+ feature_info->Initialize(NULL);
+ EXPECT_FALSE(feature_info->feature_flags().is_intel);
+ EXPECT_FALSE(feature_info->feature_flags().is_nvidia);
+ EXPECT_FALSE(feature_info->feature_flags().is_amd);
+ EXPECT_TRUE(feature_info->feature_flags().is_mesa);
}
} // namespace gles2
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f5d455c..1159ba4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1037,6 +1037,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Wrapper for glBindVertexArrayOES
void DoBindVertexArrayOES(GLuint array);
+ void EmulateVertexArrayState();
// Wrapper for glBlitFramebufferEXT.
void DoBlitFramebufferEXT(
@@ -2130,7 +2131,8 @@ bool GLES2DecoderImpl::Initialize(
default_vertex_attrib_manager_ = new VertexAttribManager();
default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
- vertex_attrib_manager_ = default_vertex_attrib_manager_;
+ // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
+ DoBindVertexArrayOES(0);
query_manager_.reset(new QueryManager(this, feature_info_));
vertex_array_manager_.reset(new VertexArrayManager());
@@ -2394,10 +2396,6 @@ bool GLES2DecoderImpl::Initialize(
DoBindFramebuffer(GL_FRAMEBUFFER, 0);
DoBindRenderbuffer(GL_RENDERBUFFER, 0);
- if (feature_info_->feature_flags().native_vertex_array_object_) {
- DoBindVertexArrayOES(0);
- }
-
// AMD and Intel drivers on Mac OS apparently get gl_PointCoord
// backward from the spec and this setting makes them work
// correctly. rdar://problem/11883495
@@ -8820,33 +8818,31 @@ error::Error GLES2DecoderImpl::HandleEndQueryEXT(
bool GLES2DecoderImpl::GenVertexArraysOESHelper(
GLsizei n, const GLuint* client_ids) {
-
- if (!feature_info_->feature_flags().native_vertex_array_object_) {
- // TODO(bajones): Emulate if not present
- SetGLError(GL_INVALID_OPERATION, "glGenVertexArraysOES", "not supported.");
- }
-
for (GLsizei ii = 0; ii < n; ++ii) {
if (GetVertexAttribManager(client_ids[ii])) {
return false;
}
}
- scoped_array<GLuint> service_ids(new GLuint[n]);
- glGenVertexArraysOES(n, service_ids.get());
- for (GLsizei ii = 0; ii < n; ++ii) {
- CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
+
+ if (!feature_info_->feature_flags().native_vertex_array_object_) {
+ // Emulated VAO
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ CreateVertexAttribManager(client_ids[ii], 0);
+ }
+ } else {
+ scoped_array<GLuint> service_ids(new GLuint[n]);
+
+ glGenVertexArraysOES(n, service_ids.get());
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
+ }
}
+
return true;
}
void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
GLsizei n, const GLuint* client_ids) {
- if (!feature_info_->feature_flags().native_vertex_array_object_) {
- // TODO(bajones): Emulate if not present
- SetGLError(GL_INVALID_OPERATION,
- "glDeleteVertexArraysOES", "not supported.");
- }
-
for (GLsizei ii = 0; ii < n; ++ii) {
VertexAttribManager* vao =
GetVertexAttribManager(client_ids[ii]);
@@ -8860,11 +8856,6 @@ void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
}
void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
- if (!feature_info_->feature_flags().native_vertex_array_object_) {
- // TODO(bajones): Emulate if not present
- SetGLError(GL_INVALID_OPERATION, "glBindVertexArrayOES", "not supported.");
- }
-
VertexAttribManager* vao = NULL;
GLuint service_id = 0;
if (client_id != 0) {
@@ -8881,21 +8872,36 @@ void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
} else {
service_id = vao->service_id();
}
-
- vertex_attrib_manager_ = vao;
} else {
- vertex_attrib_manager_ = default_vertex_attrib_manager_;
+ vao = default_vertex_attrib_manager_;
}
- glBindVertexArrayOES(service_id);
+ // Only set the VAO state if it's changed
+ if (vertex_attrib_manager_ != vao) {
+ vertex_attrib_manager_ = vao;
+ if (!feature_info_->feature_flags().native_vertex_array_object_) {
+ EmulateVertexArrayState();
+ } else {
+ glBindVertexArrayOES(service_id);
+ }
+ }
}
-bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
- if (!feature_info_->feature_flags().native_vertex_array_object_) {
- // TODO(bajones): Emulate if not present
- SetGLError(GL_INVALID_OPERATION, "glIsVertexArrayOES", "not supported.");
+// Used when OES_vertex_array_object isn't natively supported
+void GLES2DecoderImpl::EmulateVertexArrayState() {
+ // Setup the Vertex attribute state
+ for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
+ RestoreStateForAttrib(vv);
}
+ // Setup the element buffer
+ BufferManager::BufferInfo* element_array_buffer =
+ vertex_attrib_manager_->element_array_buffer();
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
+ element_array_buffer ? element_array_buffer->service_id() : 0);
+}
+
+bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
const VertexAttribManager* vao =
GetVertexAttribManager(client_id);
return vao && vao->IsValid() && !vao->IsDeleted();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 3a1f4c5..59e82c9 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -130,47 +130,6 @@ class GLES2DecoderANGLEManualInitTest : public GLES2DecoderANGLETest {
}
};
-class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest {
- public:
- GLES2DecoderVertexArraysOESTest() { }
-
- bool vertex_array_deleted_manually_;
-
- virtual void SetUp() {
- InitDecoder(
- "GL_OES_vertex_array_object", // extensions
- false, // has alpha
- false, // has depth
- false, // has stencil
- false, // request alpha
- false, // request depth
- false, // request stencil
- true); // bind generates resource
- SetupDefaultProgram();
-
- EXPECT_CALL(*gl_, GenVertexArraysOES(_, _))
- .WillOnce(SetArgumentPointee<1>(kServiceVertexArrayId))
- .RetiresOnSaturation();
- GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
-
- vertex_array_deleted_manually_ = false;
- }
-
- virtual void TearDown() {
- // This should only be set if the test handled deletion of the vertex array
- // itself. Necessary because vertex_array_objects are not sharable, and thus
- // not managed in the ContextGroup, meaning they will be destroyed during
- // test tear down
- if (!vertex_array_deleted_manually_) {
- EXPECT_CALL(*gl_, DeleteVertexArraysOES(1, _))
- .Times(1)
- .RetiresOnSaturation();
- }
-
- GLES2DecoderWithShaderTest::TearDown();
- }
-};
-
TEST_F(GLES2DecoderWithShaderTest, DrawArraysNoAttributesSucceeds) {
SetupTexture();
AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
@@ -7576,144 +7535,276 @@ TEST_F(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUM) {
EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
}
+class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest {
+ public:
+ GLES2DecoderVertexArraysOESTest() { }
+
+ bool vertex_array_deleted_manually_;
+
+ virtual void SetUp() {
+ InitDecoder(
+ "GL_OES_vertex_array_object", // extensions
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ true); // bind generates resource
+ SetupDefaultProgram();
+
+ AddExpectationsForGenVertexArraysOES();
+ GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
+
+ vertex_array_deleted_manually_ = false;
+ }
+
+ virtual void TearDown() {
+ // This should only be set if the test handled deletion of the vertex array
+ // itself. Necessary because vertex_array_objects are not sharable, and thus
+ // not managed in the ContextGroup, meaning they will be destroyed during
+ // test tear down
+ if (!vertex_array_deleted_manually_) {
+ AddExpectationsForDeleteVertexArraysOES();
+ }
+
+ GLES2DecoderWithShaderTest::TearDown();
+ }
+
+ void GenVertexArraysOESValidArgs() {
+ AddExpectationsForGenVertexArraysOES();
+ GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
+ GenVertexArraysOES cmd;
+ cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
+ AddExpectationsForDeleteVertexArraysOES();
+ }
+
+ void GenVertexArraysOESInvalidArgs() {
+ EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
+ GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
+ GenVertexArraysOES cmd;
+ cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
+ }
+
+ void GenVertexArraysOESImmediateValidArgs() {
+ AddExpectationsForGenVertexArraysOES();
+ GenVertexArraysOESImmediate* cmd =
+ GetImmediateAs<GenVertexArraysOESImmediate>();
+ GLuint temp = kNewClientId;
+ cmd->Init(1, &temp);
+ EXPECT_EQ(error::kNoError,
+ ExecuteImmediateCmd(*cmd, sizeof(temp)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
+ AddExpectationsForDeleteVertexArraysOES();
+ }
+
+ void GenVertexArraysOESImmediateInvalidArgs() {
+ EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
+ GenVertexArraysOESImmediate* cmd =
+ GetImmediateAs<GenVertexArraysOESImmediate>();
+ cmd->Init(1, &client_vertexarray_id_);
+ EXPECT_EQ(error::kInvalidArguments,
+ ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_)));
+ }
+
+ void DeleteVertexArraysOESValidArgs() {
+ AddExpectationsForDeleteVertexArraysOES();
+ GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
+ DeleteVertexArraysOES cmd;
+ cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(
+ GetVertexArrayInfo(client_vertexarray_id_) == NULL);
+ vertex_array_deleted_manually_ = true;
+ }
+
+ void DeleteVertexArraysOESInvalidArgs() {
+ GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
+ DeleteVertexArraysOES cmd;
+ cmd.Init(1, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ }
+
+ void DeleteVertexArraysOESImmediateValidArgs() {
+ AddExpectationsForDeleteVertexArraysOES();
+ DeleteVertexArraysOESImmediate& cmd =
+ *GetImmediateAs<DeleteVertexArraysOESImmediate>();
+ cmd.Init(1, &client_vertexarray_id_);
+ EXPECT_EQ(error::kNoError,
+ ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ EXPECT_TRUE(
+ GetVertexArrayInfo(client_vertexarray_id_) == NULL);
+ vertex_array_deleted_manually_ = true;
+ }
+
+ void DeleteVertexArraysOESImmediateInvalidArgs() {
+ DeleteVertexArraysOESImmediate& cmd =
+ *GetImmediateAs<DeleteVertexArraysOESImmediate>();
+ GLuint temp = kInvalidClientId;
+ cmd.Init(1, &temp);
+ EXPECT_EQ(error::kNoError,
+ ExecuteImmediateCmd(cmd, sizeof(temp)));
+ }
+
+ void IsVertexArrayOESValidArgs() {
+ IsVertexArrayOES cmd;
+ cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ }
+
+ void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
+ IsVertexArrayOES cmd;
+ cmd.Init(
+ client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(
+ client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ }
+
+ void BindVertexArrayOESValidArgs() {
+ AddExpectationsForBindVertexArrayOES();
+ BindVertexArrayOES cmd;
+ cmd.Init(client_vertexarray_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ }
+
+ void BindVertexArrayOESValidArgsNewId() {
+ BindVertexArrayOES cmd;
+ cmd.Init(kNewClientId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+ }
+};
+
+class GLES2DecoderEmulatedVertexArraysOESTest
+ : public GLES2DecoderVertexArraysOESTest {
+ public:
+ GLES2DecoderEmulatedVertexArraysOESTest() { }
+
+ virtual void SetUp() {
+ InitDecoder(
+ "", // extensions
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ true); // bind generates resource
+ SetupDefaultProgram();
+
+ AddExpectationsForGenVertexArraysOES();
+ GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
+
+ vertex_array_deleted_manually_ = false;
+ }
+};
+
+// Test vertex array objects with native support
TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESValidArgs) {
- EXPECT_CALL(*gl_, GenVertexArraysOES(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId));
- GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
- SpecializedSetup<GenVertexArraysOES, 0>(true);
- GenVertexArraysOES cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
- EXPECT_CALL(*gl_, DeleteVertexArraysOES(1, _))
- .Times(1);
+ GenVertexArraysOESValidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, GenVertexArraysOESValidArgs) {
+ GenVertexArraysOESValidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESInvalidArgs) {
- EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
- GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
- SpecializedSetup<GenVertexArraysOES, 0>(false);
- GenVertexArraysOES cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
+ GenVertexArraysOESInvalidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, ) {
+ GenVertexArraysOESInvalidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESImmediateValidArgs) {
- EXPECT_CALL(*gl_, GenVertexArraysOES(1, _))
- .WillOnce(SetArgumentPointee<1>(kNewServiceId));
- GenVertexArraysOESImmediate* cmd =
- GetImmediateAs<GenVertexArraysOESImmediate>();
- GLuint temp = kNewClientId;
- SpecializedSetup<GenVertexArraysOESImmediate, 0>(true);
- cmd->Init(1, &temp);
- EXPECT_EQ(error::kNoError,
- ExecuteImmediateCmd(*cmd, sizeof(temp)));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
- EXPECT_CALL(*gl_, DeleteVertexArraysOES(1, _))
- .Times(1);
+ GenVertexArraysOESImmediateValidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ GenVertexArraysOESImmediateValidArgs) {
+ GenVertexArraysOESImmediateValidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest,
GenVertexArraysOESImmediateInvalidArgs) {
- EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
- GenVertexArraysOESImmediate* cmd =
- GetImmediateAs<GenVertexArraysOESImmediate>();
- SpecializedSetup<GenVertexArraysOESImmediate, 0>(false);
- cmd->Init(1, &client_vertexarray_id_);
- EXPECT_EQ(error::kInvalidArguments,
- ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_)));
+ GenVertexArraysOESImmediateInvalidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ GenVertexArraysOESImmediateInvalidArgs) {
+ GenVertexArraysOESImmediateInvalidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESValidArgs) {
- EXPECT_CALL(
- *gl_,
- DeleteVertexArraysOES(1, Pointee(kServiceVertexArrayId)))
- .Times(1);
- GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
- SpecializedSetup<DeleteVertexArraysOES, 0>(true);
- DeleteVertexArraysOES cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(
- GetVertexArrayInfo(client_vertexarray_id_) == NULL);
- vertex_array_deleted_manually_ = true;
+ DeleteVertexArraysOESValidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ DeleteVertexArraysOESValidArgs) {
+ DeleteVertexArraysOESValidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESInvalidArgs) {
- GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
- SpecializedSetup<DeleteVertexArraysOES, 0>(false);
- DeleteVertexArraysOES cmd;
- cmd.Init(1, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ DeleteVertexArraysOESInvalidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ DeleteVertexArraysOESInvalidArgs) {
+ DeleteVertexArraysOESInvalidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest,
DeleteVertexArraysOESImmediateValidArgs) {
- EXPECT_CALL(
- *gl_,
- DeleteVertexArraysOES(1, Pointee(kServiceVertexArrayId)))
- .Times(1);
- DeleteVertexArraysOESImmediate& cmd =
- *GetImmediateAs<DeleteVertexArraysOESImmediate>();
- SpecializedSetup<DeleteVertexArraysOESImmediate, 0>(true);
- cmd.Init(1, &client_vertexarray_id_);
- EXPECT_EQ(error::kNoError,
- ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(
- GetVertexArrayInfo(client_vertexarray_id_) == NULL);
- vertex_array_deleted_manually_ = true;
+ DeleteVertexArraysOESImmediateValidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ DeleteVertexArraysOESImmediateValidArgs) {
+ DeleteVertexArraysOESImmediateValidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest,
DeleteVertexArraysOESImmediateInvalidArgs) {
- DeleteVertexArraysOESImmediate& cmd =
- *GetImmediateAs<DeleteVertexArraysOESImmediate>();
- SpecializedSetup<DeleteVertexArraysOESImmediate, 0>(false);
- GLuint temp = kInvalidClientId;
- cmd.Init(1, &temp);
- EXPECT_EQ(error::kNoError,
- ExecuteImmediateCmd(cmd, sizeof(temp)));
+ DeleteVertexArraysOESImmediateInvalidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ DeleteVertexArraysOESImmediateInvalidArgs) {
+ DeleteVertexArraysOESImmediateInvalidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest, IsVertexArrayOESValidArgs) {
- SpecializedSetup<IsVertexArrayOES, 0>(true);
- IsVertexArrayOES cmd;
- cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ IsVertexArrayOESValidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, IsVertexArrayOESValidArgs) {
+ IsVertexArrayOESValidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest,
IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
- SpecializedSetup<IsVertexArrayOES, 0>(false);
- IsVertexArrayOES cmd;
- cmd.Init(
- client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- cmd.Init(
- client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ IsVertexArrayOESInvalidArgsBadSharedMemoryId();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
+ IsVertexArrayOESInvalidArgsBadSharedMemoryId();
}
TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgs) {
- EXPECT_CALL(*gl_, BindVertexArrayOES(kServiceVertexArrayId));
- SpecializedSetup<BindVertexArrayOES, 0>(true);
- BindVertexArrayOES cmd;
- cmd.Init(client_vertexarray_id_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ BindVertexArrayOESValidArgs();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, BindVertexArrayOESValidArgs) {
+ BindVertexArrayOESValidArgs();
}
TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgsNewId) {
- SpecializedSetup<BindVertexArrayOES, 0>(true);
- BindVertexArrayOES cmd;
- cmd.Init(kNewClientId);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
+ BindVertexArrayOESValidArgsNewId();
+}
+TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
+ BindVertexArrayOESValidArgsNewId) {
+ BindVertexArrayOESValidArgsNewId();
}
// TODO(gman): Complete this test.
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 0350fd7..b51aa55 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -15,6 +15,7 @@
#include "gpu/command_buffer/service/cmd_buffer_engine.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_implementation.h"
@@ -98,6 +99,8 @@ void GLES2DecoderTestBase::InitDecoder(
AddExpectationsForVertexAttribManager();
+ AddExpectationsForBindVertexArrayOES();
+
EXPECT_CALL(*gl_, EnableVertexAttribArray(0))
.Times(1)
.RetiresOnSaturation();
@@ -305,12 +308,6 @@ void GLES2DecoderTestBase::InitDecoder(
.Times(1)
.RetiresOnSaturation();
- if (group_->feature_info()->feature_flags().native_vertex_array_object_) {
- EXPECT_CALL(*gl_, BindVertexArrayOES(0))
- .Times(1)
- .RetiresOnSaturation();
- }
-
engine_.reset(new StrictMock<MockCommandBufferEngine>());
Buffer buffer = engine_->GetSharedMemoryBuffer(kSharedMemoryId);
shared_memory_offset_ = kSharedMemoryOffset;
@@ -987,6 +984,69 @@ void GLES2DecoderTestBase::DoVertexAttribDivisorANGLE(
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
+void GLES2DecoderTestBase::AddExpectationsForGenVertexArraysOES(){
+ if (group_->feature_info()->feature_flags().native_vertex_array_object_) {
+ EXPECT_CALL(*gl_, GenVertexArraysOES(1, _))
+ .WillOnce(SetArgumentPointee<1>(kServiceVertexArrayId))
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::AddExpectationsForDeleteVertexArraysOES(){
+ if (group_->feature_info()->feature_flags().native_vertex_array_object_) {
+ EXPECT_CALL(*gl_, DeleteVertexArraysOES(1, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::AddExpectationsForBindVertexArrayOES() {
+ if (group_->feature_info()->feature_flags().native_vertex_array_object_) {
+ EXPECT_CALL(*gl_, BindVertexArrayOES(_))
+ .Times(1)
+ .RetiresOnSaturation();
+ } else {
+ for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
+ AddExpectationsForRestoreAttribState(vv);
+ }
+
+ EXPECT_CALL(*gl_, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ }
+}
+
+void GLES2DecoderTestBase::AddExpectationsForRestoreAttribState(GLuint attrib) {
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, VertexAttribPointer(attrib, _, _, _, _, _))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(attrib, _))
+ .Times(testing::AtMost(1))
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
+ .Times(1)
+ .RetiresOnSaturation();
+
+ if (attrib != 0 ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
+
+ // TODO(bajones): Not sure if I can tell which of these will be called
+ EXPECT_CALL(*gl_, EnableVertexAttribArray(attrib))
+ .Times(testing::AtMost(1))
+ .RetiresOnSaturation();
+
+ EXPECT_CALL(*gl_, DisableVertexAttribArray(attrib))
+ .Times(testing::AtMost(1))
+ .RetiresOnSaturation();
+ }
+}
+
// GCC requires these declarations, but MSVC requires they not be present
#ifndef COMPILER_MSVC
const int GLES2DecoderTestBase::kBackBufferWidth;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index a5294f1..f2fd38b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -196,6 +196,7 @@ class GLES2DecoderTestBase : public testing::Test {
void DoBindFramebuffer(GLenum target, GLuint client_id, GLuint service_id);
void DoBindRenderbuffer(GLenum target, GLuint client_id, GLuint service_id);
void DoBindTexture(GLenum target, GLuint client_id, GLuint service_id);
+ void DoBindVertexArrayOES(GLuint client_id, GLuint service_id);
bool DoIsBuffer(GLuint client_id);
bool DoIsFramebuffer(GLuint client_id);
@@ -328,6 +329,11 @@ class GLES2DecoderTestBase : public testing::Test {
void AddExpectationsForSimulatedAttrib0(
GLsizei num_vertices, GLuint buffer_id);
+ void AddExpectationsForGenVertexArraysOES();
+ void AddExpectationsForDeleteVertexArraysOES();
+ void AddExpectationsForBindVertexArrayOES();
+ void AddExpectationsForRestoreAttribState(GLuint attrib);
+
GLvoid* BufferOffset(unsigned i) {
return static_cast<int8 *>(NULL)+(i);
}
diff --git a/gpu/command_buffer/service/vertex_attrib_manager.cc b/gpu/command_buffer/service/vertex_attrib_manager.cc
index 7d15938..f8bc061 100644
--- a/gpu/command_buffer/service/vertex_attrib_manager.cc
+++ b/gpu/command_buffer/service/vertex_attrib_manager.cc
@@ -86,8 +86,8 @@ VertexAttribManager::VertexAttribManager(
VertexAttribManager::~VertexAttribManager() {
if (manager_) {
if (manager_->have_context_) {
- GLuint id = service_id();
- glDeleteVertexArraysOES(1, &id);
+ if (service_id_ != 0) // 0 indicates an emulated VAO
+ glDeleteVertexArraysOES(1, &service_id_);
}
manager_->StopTracking(this);
manager_ = NULL;