Add option to not generate resources on bind in OpenGL ES
This allowes us to more efficiently manage ids. It is
not OpenGL ES 2.0 compatible though it probably fits most OpenGL ES
programs.
Note that we need to turn this off on Pepper and/or probably
provide a way for Pepper to turn on on. I'm not sure of the
path Pepper takes to setup. Assuming it goes through
GraphicsContext3D then changes to webkit will be needed to
get the flag all the way down through IPC to the GPU process.
TEST=unit tests and ran a few pages in a chrome build
BUG=92260
Review URL: http://codereview.chromium.org/7633060
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96904 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index 36c8d039..b93c034c 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -16,9 +16,10 @@
namespace gpu {
namespace gles2 {
-ContextGroup::ContextGroup()
+ContextGroup::ContextGroup(bool bind_generates_resource)
: initialized_(false),
have_context_(true),
+ bind_generates_resource_(bind_generates_resource),
max_vertex_attribs_(0u),
max_texture_units_(0u),
max_texture_image_units_(0u),
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index a2e6382..f130dc6f 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -36,7 +36,7 @@
public:
typedef scoped_refptr<ContextGroup> Ref;
- ContextGroup();
+ explicit ContextGroup(bool bind_generates_resource);
~ContextGroup();
// This should only be called by GLES2Decoder.
@@ -48,6 +48,10 @@
have_context_ = have_context;
}
+ bool bind_generates_resource() {
+ return bind_generates_resource_;
+ }
+
uint32 max_vertex_attribs() const {
return max_vertex_attribs_;
}
@@ -113,6 +117,7 @@
// Whether or not this context is initialized.
bool initialized_;
bool have_context_;
+ bool bind_generates_resource_;
uint32 max_vertex_attribs_;
uint32 max_texture_units_;
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index a651854b..c8a78f3 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -36,7 +36,7 @@
virtual void SetUp() {
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
- group_ = ContextGroup::Ref(new ContextGroup());
+ group_ = ContextGroup::Ref(new ContextGroup(true));
}
virtual void TearDown() {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 7a04a7c7..22e01c29 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2682,6 +2682,12 @@
if (client_id != 0) {
info = GetBufferInfo(client_id);
if (!info) {
+ if (!group_->bind_generates_resource()) {
+ SetGLError(GL_INVALID_VALUE,
+ "glBindBuffer: id not generated by glGenBuffers");
+ return;
+ }
+
// It's a new id so make a buffer info for it.
glGenBuffersARB(1, &service_id);
CreateBufferInfo(client_id, service_id);
@@ -2761,6 +2767,12 @@
if (client_id != 0) {
info = GetFramebufferInfo(client_id);
if (!info) {
+ if (!group_->bind_generates_resource()) {
+ SetGLError(GL_INVALID_VALUE,
+ "glBindFramebuffer: id not generated by glGenFramebuffers");
+ return;
+ }
+
// It's a new id so make a framebuffer info for it.
glGenFramebuffersEXT(1, &service_id);
CreateFramebufferInfo(client_id, service_id);
@@ -2800,6 +2812,13 @@
if (client_id != 0) {
info = GetRenderbufferInfo(client_id);
if (!info) {
+ if (!group_->bind_generates_resource()) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glBindRenderbuffer: id not generated by glGenRenderbuffers");
+ return;
+ }
+
// It's a new id so make a renderbuffer info for it.
glGenRenderbuffersEXT(1, &service_id);
CreateRenderbufferInfo(client_id, service_id);
@@ -2822,6 +2841,12 @@
if (client_id != 0) {
info = GetTextureInfo(client_id);
if (!info) {
+ if (!group_->bind_generates_resource()) {
+ SetGLError(GL_INVALID_VALUE,
+ "glBindTexture: id not generated by glGenTextures");
+ return;
+ }
+
// It's a new id so make a texture info for it.
glGenTextures(1, &service_id);
CreateTextureInfo(client_id, service_id);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index d619b120..fa85ea5 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -96,7 +96,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
SetupDefaultProgram();
}
};
@@ -3190,7 +3191,8 @@
false, // has stencil
true, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3220,7 +3222,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3250,7 +3253,8 @@
false, // has stencil
false, // request alpha
true, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3280,7 +3284,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3310,7 +3315,8 @@
true, // has stencil
false, // request alpha
false, // request depth
- true); // request stencil
+ true, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3340,7 +3346,8 @@
true, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3370,7 +3377,8 @@
false, // has stencil
false, // request alpha
true, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
Enable cmd;
cmd.Init(GL_DEPTH_TEST);
@@ -3426,7 +3434,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
Enable cmd;
cmd.Init(GL_DEPTH_TEST);
@@ -3482,7 +3491,8 @@
true, // has stencil
false, // request alpha
false, // request depth
- true); // request stencil
+ true, // request stencil
+ true); // bind generates resource
Enable cmd;
cmd.Init(GL_STENCIL_TEST);
@@ -3538,7 +3548,8 @@
true, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
Enable cmd;
cmd.Init(GL_STENCIL_TEST);
@@ -3594,7 +3605,8 @@
true, // has stencil
false, // request alpha
true, // request depth
- true); // request stencil
+ true, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3637,7 +3649,8 @@
true, // has stencil
false, // request alpha
true, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -3680,7 +3693,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
kServiceRenderbufferId);
DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
@@ -3756,7 +3770,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
kServiceRenderbufferId);
DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
@@ -4107,7 +4122,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
kServiceRenderbufferId);
EXPECT_CALL(*gl_, GetError())
@@ -4169,7 +4185,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -4225,7 +4242,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, GetError())
.WillOnce(Return(GL_NO_ERROR))
@@ -4296,7 +4314,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kNewServiceId));
EXPECT_CALL(*gl_, GenTextures(1, _))
.WillOnce(SetArgumentPointee<1>(kNewServiceId));
@@ -4317,7 +4336,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
EXPECT_CALL(*gl_, GetError())
@@ -4349,7 +4369,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_);
@@ -4368,7 +4389,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
@@ -4425,7 +4447,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
@@ -4464,7 +4487,8 @@
false, // has stencil
false, // request alpha
false, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
GLenum target = GL_TEXTURE_EXTERNAL_OES;
GLint level = 0;
@@ -4485,6 +4509,38 @@
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
+TEST_F(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
+ InitDecoder(
+ "", // extensions
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false, // request stencil
+ false); // bind generates resource
+
+ BindTexture cmd1;
+ cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+ BindBuffer cmd2;
+ cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+ BindFramebuffer cmd3;
+ cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+
+ BindRenderbuffer cmd4;
+ cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
// TODO(gman): Complete this test.
// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
// }
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 d80576d..41e42ad0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -55,7 +55,8 @@
false, // has stencil
true, // request alpha
true, // request depth
- false); // request stencil
+ false, // request stencil
+ true); // bind generates resource
}
void GLES2DecoderTestBase::InitDecoder(
@@ -65,11 +66,12 @@
bool has_stencil,
bool request_alpha,
bool request_depth,
- bool request_stencil) {
+ bool request_stencil,
+ bool bind_generates_resource) {
gl_.reset(new StrictMock<MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
surface_manager_.reset(new StrictMock<MockSurfaceManager>);
- group_ = ContextGroup::Ref(new ContextGroup());
+ group_ = ContextGroup::Ref(new ContextGroup(bind_generates_resource));
InSequence sequence;
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 22d341a..be2ba020 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -168,7 +168,8 @@
bool has_stencil,
bool request_alpha,
bool request_depth,
- bool request_stencil);
+ bool request_stencil,
+ bool bind_generates_resource);
const ContextGroup& group() const {
return *group_.get();