diff options
author | zmo <zmo@chromium.org> | 2015-08-05 15:30:38 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-05 22:31:07 +0000 |
commit | 02f3a3045fbc74e1b2d30ae27a8c5ac55d5ea52f (patch) | |
tree | 8cf998eae10ee01271e9f89da40c4df0e8db22e9 /gpu | |
parent | 4d0314d731f9bb9e672204238c4f23ebd1345c87 (diff) | |
download | chromium_src-02f3a3045fbc74e1b2d30ae27a8c5ac55d5ea52f.zip chromium_src-02f3a3045fbc74e1b2d30ae27a8c5ac55d5ea52f.tar.gz chromium_src-02f3a3045fbc74e1b2d30ae27a8c5ac55d5ea52f.tar.bz2 |
Fine tune ReadBuffer() impl in GPU command buffer.
BUG=429053
TEST=gpu_unittests, webgl2_conformance
R=piman@chromium.org
NOTRY=true
Review URL: https://codereview.chromium.org/1254383010
Cr-Commit-Position: refs/heads/master@{#341990}
Diffstat (limited to 'gpu')
14 files changed, 188 insertions, 8 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index b53cb45..8af6f76 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -904,6 +904,32 @@ _NAMED_TYPE_INFO = { 'GL_PROXY_TEXTURE_CUBE_MAP', ] }, + 'ReadBuffer': { + 'type': 'GLenum', + 'valid': [ + 'GL_NONE', + 'GL_BACK', + 'GL_COLOR_ATTACHMENT0', + 'GL_COLOR_ATTACHMENT1', + 'GL_COLOR_ATTACHMENT2', + 'GL_COLOR_ATTACHMENT3', + 'GL_COLOR_ATTACHMENT4', + 'GL_COLOR_ATTACHMENT5', + 'GL_COLOR_ATTACHMENT6', + 'GL_COLOR_ATTACHMENT7', + 'GL_COLOR_ATTACHMENT8', + 'GL_COLOR_ATTACHMENT9', + 'GL_COLOR_ATTACHMENT10', + 'GL_COLOR_ATTACHMENT11', + 'GL_COLOR_ATTACHMENT12', + 'GL_COLOR_ATTACHMENT13', + 'GL_COLOR_ATTACHMENT14', + 'GL_COLOR_ATTACHMENT15', + ], + 'invalid': [ + 'GL_RENDERBUFFER', + ] + }, 'TextureTarget': { 'type': 'GLenum', 'valid': [ @@ -3240,6 +3266,7 @@ _FUNCTION_INFO = { }, 'ReadBuffer': { 'unsafe': True, + 'decoder_func': 'DoReadBuffer', 'trace_level': 1, }, 'ReadPixels': { diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 7c7d3ca..958efac 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -1715,7 +1715,7 @@ void GLES2Implementation::PolygonOffset(GLfloat factor, GLfloat units) { void GLES2Implementation::ReadBuffer(GLenum src) { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReadBuffer(" - << GLES2Util::GetStringEnum(src) << ")"); + << GLES2Util::GetStringReadBuffer(src) << ")"); helper_->ReadBuffer(src); CheckGLError(); } diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 83b1aa4..253b4bf 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -1438,9 +1438,9 @@ TEST_F(GLES2ImplementationTest, ReadBuffer) { cmds::ReadBuffer cmd; }; Cmds expected; - expected.cmd.Init(1); + expected.cmd.Init(GL_NONE); - gl_->ReadBuffer(1); + gl_->ReadBuffer(GL_NONE); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 9adf094..27e8d06 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -141,7 +141,7 @@ GL_APICALL void GL_APIENTRY glLinkProgram (GLidProgram program); GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); GL_APICALL void GL_APIENTRY glPixelStorei (GLenumPixelStore pname, GLintPixelStoreAlignment param); GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src); +GL_APICALL void GL_APIENTRY glReadBuffer (GLenumReadBuffer src); GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenumReadPixelFormat format, GLenumReadPixelType type, void* pixels); GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenumRenderBufferTarget target, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index f2a13ce..e23d2c4 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h @@ -57,6 +57,7 @@ static std::string GetStringProgramParameter(uint32_t value); static std::string GetStringQueryObjectParameter(uint32_t value); static std::string GetStringQueryParameter(uint32_t value); static std::string GetStringQueryTarget(uint32_t value); +static std::string GetStringReadBuffer(uint32_t value); static std::string GetStringReadPixelFormat(uint32_t value); static std::string GetStringReadPixelType(uint32_t value); static std::string GetStringRenderBufferFormat(uint32_t value); diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index ba22b67b..1fd3b97 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -4143,6 +4143,31 @@ std::string GLES2Util::GetStringQueryTarget(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringReadBuffer(uint32_t value) { + static const EnumToString string_table[] = { + {GL_NONE, "GL_NONE"}, + {GL_BACK, "GL_BACK"}, + {GL_COLOR_ATTACHMENT0, "GL_COLOR_ATTACHMENT0"}, + {GL_COLOR_ATTACHMENT1, "GL_COLOR_ATTACHMENT1"}, + {GL_COLOR_ATTACHMENT2, "GL_COLOR_ATTACHMENT2"}, + {GL_COLOR_ATTACHMENT3, "GL_COLOR_ATTACHMENT3"}, + {GL_COLOR_ATTACHMENT4, "GL_COLOR_ATTACHMENT4"}, + {GL_COLOR_ATTACHMENT5, "GL_COLOR_ATTACHMENT5"}, + {GL_COLOR_ATTACHMENT6, "GL_COLOR_ATTACHMENT6"}, + {GL_COLOR_ATTACHMENT7, "GL_COLOR_ATTACHMENT7"}, + {GL_COLOR_ATTACHMENT8, "GL_COLOR_ATTACHMENT8"}, + {GL_COLOR_ATTACHMENT9, "GL_COLOR_ATTACHMENT9"}, + {GL_COLOR_ATTACHMENT10, "GL_COLOR_ATTACHMENT10"}, + {GL_COLOR_ATTACHMENT11, "GL_COLOR_ATTACHMENT11"}, + {GL_COLOR_ATTACHMENT12, "GL_COLOR_ATTACHMENT12"}, + {GL_COLOR_ATTACHMENT13, "GL_COLOR_ATTACHMENT13"}, + {GL_COLOR_ATTACHMENT14, "GL_COLOR_ATTACHMENT14"}, + {GL_COLOR_ATTACHMENT15, "GL_COLOR_ATTACHMENT15"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringReadPixelFormat(uint32_t value) { static const EnumToString string_table[] = { {GL_ALPHA, "GL_ALPHA"}, diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index 2798a5e..7a5bf5b 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc @@ -320,7 +320,8 @@ Framebuffer::Framebuffer( deleted_(false), service_id_(service_id), has_been_bound_(false), - framebuffer_complete_state_count_id_(0) { + framebuffer_complete_state_count_id_(0), + read_buffer_(GL_COLOR_ATTACHMENT0) { manager->StartTracking(this); DCHECK_GT(manager->max_draw_buffers_, 0u); draw_buffers_.reset(new GLenum[manager->max_draw_buffers_]); @@ -683,6 +684,12 @@ const Framebuffer::Attachment* return NULL; } +const Framebuffer::Attachment* Framebuffer::GetReadBufferAttachment() const { + if (read_buffer_ == GL_NONE) + return nullptr; + return GetAttachment(read_buffer_); +} + void Framebuffer::OnTextureRefDetached(TextureRef* texture) { manager_->OnTextureRefDetached(texture); } diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h index 1721254..a5ee819 100644 --- a/gpu/command_buffer/service/framebuffer_manager.h +++ b/gpu/command_buffer/service/framebuffer_manager.h @@ -100,6 +100,8 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { const Attachment* GetAttachment(GLenum attachment) const; + const Attachment* GetReadBufferAttachment() const; + bool IsDeleted() const { return deleted_; } @@ -159,6 +161,14 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { void OnWillRenderTo() const; void OnDidRenderTo() const; + void set_read_buffer(GLenum read_buffer) { + read_buffer_ = read_buffer; + } + + GLenum read_buffer() const { + return read_buffer_; + } + private: friend class FramebufferManager; friend class base::RefCounted<Framebuffer>; @@ -210,6 +220,8 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { scoped_ptr<GLenum[]> draw_buffers_; + GLenum read_buffer_; + DISALLOW_COPY_AND_ASSIGN(Framebuffer); }; diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 36b87f6..1944971 100644 --- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -975,6 +975,28 @@ TEST_F(FramebufferInfoES3Test, DifferentDimensions) { framebuffer_->IsPossiblyComplete()); } +TEST_F(FramebufferInfoES3Test, ReadBuffer) { + const GLuint kRenderbufferClientId = 33; + const GLuint kRenderbufferServiceId = 333; + + EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT0), + framebuffer_->read_buffer()); + framebuffer_->set_read_buffer(GL_NONE); + EXPECT_EQ(static_cast<GLenum>(GL_NONE), framebuffer_->read_buffer()); + EXPECT_FALSE(framebuffer_->GetReadBufferAttachment()); + + framebuffer_->set_read_buffer(GL_COLOR_ATTACHMENT1); + EXPECT_FALSE(framebuffer_->GetReadBufferAttachment()); + + renderbuffer_manager_->CreateRenderbuffer( + kRenderbufferClientId, kRenderbufferServiceId); + Renderbuffer* renderbuffer = + renderbuffer_manager_->GetRenderbuffer(kRenderbufferClientId); + ASSERT_TRUE(renderbuffer != NULL); + framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT1, renderbuffer); + EXPECT_TRUE(framebuffer_->GetReadBufferAttachment()); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index f845026..66ef1c5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -1580,6 +1580,9 @@ class GLES2DecoderImpl : public GLES2Decoder, // Wrapper for glLinkProgram void DoLinkProgram(GLuint program); + // Wrapper for glReadBuffer + void DoReadBuffer(GLenum src); + // Wrapper for glRenderbufferStorage. void DoRenderbufferStorage( GLenum target, GLenum internalformat, GLsizei width, GLsizei height); @@ -1965,6 +1968,10 @@ class GLES2DecoderImpl : public GLES2Decoder, GLenum back_buffer_color_format_; bool back_buffer_has_depth_; bool back_buffer_has_stencil_; + // This tracks read buffer for both offscreen/onscreen backbuffer cases. + // TODO(zmo): when ES3 APIs are exposed to Nacl, make sure read_buffer_ + // setting is set correctly when SwapBuffers(). + GLenum back_buffer_read_buffer_; bool surfaceless_; @@ -2529,6 +2536,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) back_buffer_color_format_(0), back_buffer_has_depth_(false), back_buffer_has_stencil_(false), + back_buffer_read_buffer_(GL_BACK), surfaceless_(false), backbuffer_needs_clear_bits_(0), current_decoder_error_(error::kNoError), @@ -5010,6 +5018,20 @@ bool GLES2DecoderImpl::GetHelper( } return true; } + case GL_READ_BUFFER: + *num_written = 1; + if (params) { + Framebuffer* framebuffer = + GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER); + GLenum read_buffer; + if (framebuffer) { + read_buffer = framebuffer->read_buffer(); + } else { + read_buffer = back_buffer_read_buffer_; + } + *params = static_cast<GLint>(read_buffer); + } + return true; } } switch (pname) { @@ -6321,6 +6343,47 @@ void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) { ExitCommandProcessingEarly(); } +void GLES2DecoderImpl::DoReadBuffer(GLenum src) { + switch (src) { + case GL_NONE: + case GL_BACK: + break; + default: + { + GLenum upper_limit = static_cast<GLenum>( + group_->max_color_attachments() + GL_COLOR_ATTACHMENT0); + if (src < GL_COLOR_ATTACHMENT0 || src >= upper_limit) { + LOCAL_SET_GL_ERROR( + GL_INVALID_ENUM, "glReadBuffer", "invalid enum for src"); + return; + } + } + break; + } + + Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER); + if (framebuffer) { + if (src == GL_BACK) { + LOCAL_SET_GL_ERROR( + GL_INVALID_ENUM, "glReadBuffer", + "invalid src for a named framebuffer"); + return; + } + framebuffer->set_read_buffer(src); + } else { + if (src != GL_NONE && src != GL_BACK) { + LOCAL_SET_GL_ERROR( + GL_INVALID_ENUM, "glReadBuffer", + "invalid src for the default framebuffer"); + return; + } + back_buffer_read_buffer_ = src; + if (GetBackbufferServiceId() && src == GL_BACK) + src = GL_COLOR_ATTACHMENT0; + } + glReadBuffer(src); +} + void GLES2DecoderImpl::DoSamplerParameterfv( GLuint sampler, GLenum pname, const GLfloat* params) { DCHECK(params); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 15865d2..279728e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2421,7 +2421,7 @@ error::Error GLES2DecoderImpl::HandleReadBuffer(uint32_t immediate_data_size, *static_cast<const gles2::cmds::ReadBuffer*>(cmd_data); (void)c; GLenum src = static_cast<GLenum>(c.src); - glReadBuffer(src); + DoReadBuffer(src); return error::kNoError; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index a89f014..858c166 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h @@ -792,10 +792,10 @@ TEST_P(GLES2DecoderTest2, PolygonOffsetValidArgs) { } TEST_P(GLES2DecoderTest2, ReadBufferValidArgs) { - EXPECT_CALL(*gl_, ReadBuffer(1)); + EXPECT_CALL(*gl_, ReadBuffer(GL_NONE)); SpecializedSetup<cmds::ReadBuffer, 0>(true); cmds::ReadBuffer cmd; - cmd.Init(1); + cmd.Init(GL_NONE); decoder_->set_unsafe_es3_apis_enabled(true); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index 688285b..229987d 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -60,6 +60,7 @@ ValueValidator<GLenum> program_parameter; ValueValidator<GLenum> query_object_parameter; ValueValidator<GLenum> query_parameter; ValueValidator<GLenum> query_target; +ValueValidator<GLenum> read_buffer; ValueValidator<GLenum> read_pixel_format; ValueValidator<GLenum> read_pixel_type; ValueValidator<GLenum> render_buffer_format; diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 77b1dc4..7092ef09 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -508,6 +508,27 @@ static const GLenum valid_query_target_table[] = { GL_COMMANDS_COMPLETED_CHROMIUM, }; +static const GLenum valid_read_buffer_table[] = { + GL_NONE, + GL_BACK, + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT4, + GL_COLOR_ATTACHMENT5, + GL_COLOR_ATTACHMENT6, + GL_COLOR_ATTACHMENT7, + GL_COLOR_ATTACHMENT8, + GL_COLOR_ATTACHMENT9, + GL_COLOR_ATTACHMENT10, + GL_COLOR_ATTACHMENT11, + GL_COLOR_ATTACHMENT12, + GL_COLOR_ATTACHMENT13, + GL_COLOR_ATTACHMENT14, + GL_COLOR_ATTACHMENT15, +}; + static const GLenum valid_read_pixel_format_table[] = { GL_ALPHA, GL_RGB, GL_RGBA, }; @@ -1019,6 +1040,7 @@ Validators::Validators() arraysize(valid_query_parameter_table)), query_target(valid_query_target_table, arraysize(valid_query_target_table)), + read_buffer(valid_read_buffer_table, arraysize(valid_read_buffer_table)), read_pixel_format(valid_read_pixel_format_table, arraysize(valid_read_pixel_format_table)), read_pixel_type(valid_read_pixel_type_table, |