diff options
Diffstat (limited to 'gpu/command_buffer/service')
9 files changed, 318 insertions, 57 deletions
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index c0a9a98..5cedbbd 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -142,6 +142,18 @@ bool ContextGroup::Initialize() { } } + // Check for multisample support + if (strstr(extensions, "GL_EXT_framebuffer_multisample")) { + extension_flags_.ext_framebuffer_multisample = true; + validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); + validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT); + validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT); + validators_.g_l_state.AddValue(GL_DRAW_FRAMEBUFFER_BINDING_EXT); + validators_.render_buffer_parameter.AddValue(GL_MAX_SAMPLES_EXT); + AddExtensionString("GL_EXT_framebuffer_multisample"); + AddExtensionString("GL_EXT_framebuffer_blit"); + } + // TODO(gman): Add support for these extensions. // GL_OES_depth24 // GL_OES_depth32 diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index a38f369..77b1c7a 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -30,6 +30,14 @@ class TextureManager; // resources. class ContextGroup { public: + struct ExtensionFlags { + ExtensionFlags() + : ext_framebuffer_multisample(false) { + } + + bool ext_framebuffer_multisample; + }; + ContextGroup(); ~ContextGroup(); @@ -101,6 +109,10 @@ class ContextGroup { return extensions_; } + const ExtensionFlags& extension_flags() const { + return extension_flags_; + } + private: void AddExtensionString(const std::string& str); @@ -135,6 +147,9 @@ class ContextGroup { // The extensions string returned by glGetString(GL_EXTENSIONS); std::string extensions_; + // Flags for some extensions + ExtensionFlags extension_flags_; + DISALLOW_COPY_AND_ASSIGN(ContextGroup); }; diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc index 34c8adc..c8717c4 100644 --- a/gpu/command_buffer/service/context_group_unittest.cc +++ b/gpu/command_buffer/service/context_group_unittest.cc @@ -122,6 +122,7 @@ TEST_F(ContextGroupTest, Basic) { EXPECT_TRUE(group_.texture_manager() == NULL); EXPECT_TRUE(group_.program_manager() == NULL); EXPECT_TRUE(group_.shader_manager() == NULL); + EXPECT_FALSE(group_.extension_flags().ext_framebuffer_multisample); } TEST_F(ContextGroupTest, InitializeNoExtensions) { @@ -286,6 +287,24 @@ TEST_F(ContextGroupTest, InitializeOES_texture_half_float_linearGLES2) { EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES)); } +TEST_F(ContextGroupTest, InitializeEXT_framebuffer_multisample) { + SetupInitExpectations("GL_EXT_framebuffer_multisample"); + group_.Initialize(); + EXPECT_TRUE(group_.extension_flags().ext_framebuffer_multisample); + EXPECT_THAT(group_.extensions(), HasSubstr("GL_EXT_framebuffer_multisample")); + EXPECT_THAT(group_.extensions(), HasSubstr("GL_EXT_framebuffer_blit")); + EXPECT_TRUE(group_.validators()->frame_buffer_target.IsValid( + GL_READ_FRAMEBUFFER_EXT)); + EXPECT_TRUE(group_.validators()->frame_buffer_target.IsValid( + GL_DRAW_FRAMEBUFFER_EXT)); + EXPECT_TRUE(group_.validators()->g_l_state.IsValid( + GL_READ_FRAMEBUFFER_BINDING_EXT)); + EXPECT_TRUE(group_.validators()->g_l_state.IsValid( + GL_DRAW_FRAMEBUFFER_BINDING_EXT)); + EXPECT_TRUE(group_.validators()->render_buffer_parameter.IsValid( + GL_MAX_SAMPLES_EXT)); +} + } // 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 ab36100..639ba86 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -556,11 +556,13 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, virtual void SetSwapBuffersCallback(Callback0::Type* callback); + // Restores the current state to the user's settings. + void RestoreCurrentFramebufferBindings(); + void RestoreCurrentRenderbufferBindings(); + void RestoreCurrentTexture2DBindings(); + private: friend class ScopedGLErrorSuppressor; - friend class ScopedTexture2DBinder; - friend class ScopedFrameBufferBinder; - friend class ScopedRenderBufferBinder; friend class ScopedDefaultGLContext; friend class RenderBuffer; friend class FrameBuffer; @@ -635,7 +637,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Get the size (in pixels) of the currently bound frame buffer (either FBO // or regular back buffer). - gfx::Size GetBoundFrameBufferSize(); + gfx::Size GetBoundReadFrameBufferSize(); // Wrapper for CompressedTexImage2D commands. error::Error DoCompressedTexImage2D( @@ -848,7 +850,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, GLuint client_id, const char* data, uint32 data_size); // Clears any uncleared render buffers attached to the given frame buffer. - void ClearUnclearedRenderbuffers(FramebufferManager::FramebufferInfo* info); + void ClearUnclearedRenderbuffers( + GLenum target, FramebufferManager::FramebufferInfo* info); // Remembers the state of some capabilities. void SetCapabilityState(GLenum cap, bool enabled); @@ -897,6 +900,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Wrapper for glBindTexture since we need to track the current targets. void DoBindTexture(GLenum target, GLuint texture); + // Wrapper for glBlitFramebufferEXT. + void DoBlitFramebufferEXT( + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + // Wrapper for glBufferData. void DoBufferData( GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); @@ -1010,6 +1019,11 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, void DoRenderbufferStorage( GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + // Wrapper for glRenderbufferStorageMultisampleEXT. + void DoRenderbufferStorageMultisample( + GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height); + // Wrapper for glReleaseShaderCompiler. void DoReleaseShaderCompiler() { } @@ -1115,6 +1129,25 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, return (info && !info->IsDeleted()) ? info : NULL; } + // Gets the framebuffer info for a particular target. + FramebufferManager::FramebufferInfo* GetFramebufferInfoForTarget( + GLenum target) { + FramebufferManager::FramebufferInfo* info = NULL; + switch (target) { + case GL_FRAMEBUFFER: + case GL_DRAW_FRAMEBUFFER: + info = bound_draw_framebuffer_; + break; + case GL_READ_FRAMEBUFFER: + info = bound_read_framebuffer_; + break; + default: + NOTREACHED(); + break; + } + return (info && !info->IsDeleted()) ? info : NULL; + } + // Validates the program and location for a glGetUniform call and returns // a SizeResult setup to receive the result. Returns true if glGetUniform // should be called. @@ -1219,8 +1252,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // The program in use by glUseProgram ProgramManager::ProgramInfo::Ref current_program_; - // The currently bound framebuffer - FramebufferManager::FramebufferInfo::Ref bound_framebuffer_; + // The currently bound framebuffers + FramebufferManager::FramebufferInfo::Ref bound_read_framebuffer_; + FramebufferManager::FramebufferInfo::Ref bound_draw_framebuffer_; // The currently bound renderbuffer RenderbufferManager::RenderbufferInfo::Ref bound_renderbuffer_; @@ -1279,15 +1313,7 @@ ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, ScopedTexture2DBinder::~ScopedTexture2DBinder() { ScopedGLErrorSuppressor suppressor(decoder_); - GLES2DecoderImpl::TextureUnit& info = decoder_->texture_units_[0]; - GLuint last_id; - if (info.bound_texture_2d) - last_id = info.bound_texture_2d->service_id(); - else - last_id = 0; - - glBindTexture(GL_TEXTURE_2D, last_id); - glActiveTexture(GL_TEXTURE0 + decoder_->active_texture_unit_); + decoder_->RestoreCurrentTexture2DBindings(); } ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, @@ -1299,10 +1325,7 @@ ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, ScopedRenderBufferBinder::~ScopedRenderBufferBinder() { ScopedGLErrorSuppressor suppressor(decoder_); - glBindRenderbufferEXT( - GL_RENDERBUFFER, - decoder_->bound_renderbuffer_ ? - decoder_->bound_renderbuffer_->service_id() : 0); + decoder_->RestoreCurrentRenderbufferBindings(); } ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, @@ -1314,16 +1337,7 @@ ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { ScopedGLErrorSuppressor suppressor(decoder_); - FramebufferManager::FramebufferInfo* info = - decoder_->bound_framebuffer_.get(); - GLuint framebuffer_id = info ? info->service_id() : 0; - if (framebuffer_id == 0 && - decoder_->offscreen_target_frame_buffer_.get()) { - glBindFramebufferEXT(GL_FRAMEBUFFER, - decoder_->offscreen_target_frame_buffer_->id()); - } else { - glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_id); - } + decoder_->RestoreCurrentFramebufferBindings(); } ScopedDefaultGLContext::ScopedDefaultGLContext(GLES2DecoderImpl* decoder) @@ -1828,16 +1842,67 @@ bool GLES2DecoderImpl::MakeCurrent() { return context_.get() ? context_->MakeCurrent() : false; } -gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() { - if (bound_framebuffer_ != 0) { +void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() { + glBindRenderbufferEXT( + GL_RENDERBUFFER, + bound_renderbuffer_ ? bound_renderbuffer_->service_id() : 0); +} + +static void RebindCurrentFramebuffer( + GLenum target, + FramebufferManager::FramebufferInfo* info, + FrameBuffer* offscreen_frame_buffer) { + GLuint framebuffer_id = info ? info->service_id() : 0; + if (framebuffer_id == 0 && offscreen_frame_buffer) { + framebuffer_id = offscreen_frame_buffer->id(); + } + glBindFramebufferEXT(target, framebuffer_id); +} + +void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { + if (!group_->extension_flags().ext_framebuffer_multisample) { + RebindCurrentFramebuffer( + GL_FRAMEBUFFER, + bound_draw_framebuffer_.get(), + offscreen_target_frame_buffer_.get()); + } else { + RebindCurrentFramebuffer( + GL_READ_FRAMEBUFFER_EXT, + bound_read_framebuffer_.get(), + offscreen_target_frame_buffer_.get()); + RebindCurrentFramebuffer( + GL_DRAW_FRAMEBUFFER_EXT, + bound_draw_framebuffer_.get(), + offscreen_target_frame_buffer_.get()); + } +} + +void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() { + GLES2DecoderImpl::TextureUnit& info = texture_units_[0]; + GLuint last_id; + if (info.bound_texture_2d) { + last_id = info.bound_texture_2d->service_id(); + } else { + last_id = 0; + } + + glBindTexture(GL_TEXTURE_2D, last_id); + glActiveTexture(GL_TEXTURE0 + active_texture_unit_); +} + +gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { + if (bound_read_framebuffer_ != 0) { int width = 0; int height = 0; + GLenum target = group_->extension_flags().ext_framebuffer_multisample ? + GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; + // Assume we have to have COLOR_ATTACHMENT0. Should we check for depth and // stencil. GLint fb_type = 0; glGetFramebufferAttachmentParameterivEXT( - GL_FRAMEBUFFER, + target, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &fb_type); @@ -1846,7 +1911,7 @@ gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() { { GLint renderbuffer_id = 0; glGetFramebufferAttachmentParameterivEXT( - GL_FRAMEBUFFER, + target, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer_id); @@ -1866,7 +1931,7 @@ gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() { { GLint texture_id = 0; glGetFramebufferAttachmentParameterivEXT( - GL_FRAMEBUFFER, + target, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &texture_id); @@ -1879,12 +1944,12 @@ gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() { GLint level = 0; GLint face = 0; glGetFramebufferAttachmentParameterivEXT( - GL_FRAMEBUFFER, + target, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &level); glGetFramebufferAttachmentParameterivEXT( - GL_FRAMEBUFFER, + target, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &face); @@ -2262,7 +2327,13 @@ void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { service_id = info->service_id(); } } - bound_framebuffer_ = info; + + if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) { + bound_draw_framebuffer_ = info; + } + if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) { + bound_read_framebuffer_ = info; + } // When rendering to an offscreen frame buffer, instead of unbinding from // the current frame buffer, bind to the offscreen target frame buffer. @@ -2458,12 +2529,26 @@ bool GLES2DecoderImpl::GetHelper( } return true; case GL_FRAMEBUFFER_BINDING: + // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING) + *num_written = 1; + if (params) { + if (bound_draw_framebuffer_) { + GLuint client_id = 0; + framebuffer_manager()->GetClientId( + bound_draw_framebuffer_->service_id(), &client_id); + *params = client_id; + } else { + *params = 0; + } + } + return true; + case GL_READ_FRAMEBUFFER_BINDING: *num_written = 1; if (params) { - if (bound_framebuffer_) { + if (bound_read_framebuffer_) { GLuint client_id = 0; framebuffer_manager()->GetClientId( - bound_framebuffer_->service_id(), &client_id); + bound_read_framebuffer_->service_id(), &client_id); *params = client_id; } else { *params = 0; @@ -2802,7 +2887,9 @@ void GLES2DecoderImpl::DoDrawArrays( void GLES2DecoderImpl::DoFramebufferRenderbuffer( GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint client_renderbuffer_id) { - if (!bound_framebuffer_) { + FramebufferManager::FramebufferInfo* framebuffer_info = + GetFramebufferInfoForTarget(target); + if (!framebuffer_info) { SetGLError(GL_INVALID_OPERATION, "glFramebufferRenderbuffer: no framebuffer bound"); return; @@ -2822,9 +2909,9 @@ void GLES2DecoderImpl::DoFramebufferRenderbuffer( target, attachment, renderbuffertarget, service_id); if (service_id == 0 || glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) { - bound_framebuffer_->AttachRenderbuffer(attachment, info); + framebuffer_info->AttachRenderbuffer(attachment, info); if (info) { - ClearUnclearedRenderbuffers(bound_framebuffer_); + ClearUnclearedRenderbuffers(target, framebuffer_info); } } } @@ -2901,7 +2988,10 @@ void GLES2DecoderImpl::DoStencilMaskSeparate(GLenum face, GLuint mask) { // are cleared because they are textures so we only need to clear // the renderbuffers. void GLES2DecoderImpl::ClearUnclearedRenderbuffers( - FramebufferManager::FramebufferInfo* info) { + GLenum target, FramebufferManager::FramebufferInfo* info) { + if (target == GL_READ_FRAMEBUFFER_EXT) { + // TODO(gman): bind this to the DRAW point, clear then bind back to READ + } GLbitfield clear_bits = 0; if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) { glClearColor(0, 0, 0, 0); @@ -2939,10 +3029,16 @@ void GLES2DecoderImpl::ClearUnclearedRenderbuffers( if (enable_scissor_test_) { glEnable(GL_SCISSOR_TEST); } + + if (target == GL_READ_FRAMEBUFFER_EXT) { + // TODO(gman): rebind draw. + } } GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { - if (!bound_framebuffer_) { + FramebufferManager::FramebufferInfo* info = + GetFramebufferInfoForTarget(target); + if (!info) { return GL_FRAMEBUFFER_COMPLETE; } return glCheckFramebufferStatusEXT(target); @@ -2951,7 +3047,9 @@ GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { void GLES2DecoderImpl::DoFramebufferTexture2D( GLenum target, GLenum attachment, GLenum textarget, GLuint client_texture_id, GLint level) { - if (!bound_framebuffer_) { + FramebufferManager::FramebufferInfo* framebuffer_info = + GetFramebufferInfoForTarget(target); + if (!framebuffer_info) { SetGLError(GL_INVALID_OPERATION, "glFramebufferTexture2D: no framebuffer bound."); return; @@ -2970,13 +3068,15 @@ void GLES2DecoderImpl::DoFramebufferTexture2D( glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); if (service_id != 0 && glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) { - ClearUnclearedRenderbuffers(bound_framebuffer_); + ClearUnclearedRenderbuffers(target, framebuffer_info); } } void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( GLenum target, GLenum attachment, GLenum pname, GLint* params) { - if (!bound_framebuffer_) { + FramebufferManager::FramebufferInfo* framebuffer_info = + GetFramebufferInfoForTarget(target); + if (!framebuffer_info) { SetGLError(GL_INVALID_OPERATION, "glFramebufferAttachmentParameteriv: no framebuffer bound"); return; @@ -3017,6 +3117,48 @@ void GLES2DecoderImpl::DoGetRenderbufferParameteriv( glGetRenderbufferParameterivEXT(target, pname, params); } +void GLES2DecoderImpl::DoBlitFramebufferEXT( + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { + if (!group_->extension_flags().ext_framebuffer_multisample) { + SetGLError(GL_INVALID_OPERATION, + "glBlitFramebufferEXT: function not available"); + } + glBlitFramebufferEXT( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +void GLES2DecoderImpl::DoRenderbufferStorageMultisample( + GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height) { + if (!group_->extension_flags().ext_framebuffer_multisample) { + SetGLError(GL_INVALID_OPERATION, + "glRenderbufferStorageMultisampleEXT: function not available"); + return; + } + bound_renderbuffer_->set_internal_format(internalformat); + + if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { + switch (internalformat) { + case GL_DEPTH_COMPONENT16: + internalformat = GL_DEPTH_COMPONENT; + break; + case GL_RGBA4: + case GL_RGB5_A1: + internalformat = GL_RGBA; + break; + case GL_RGB565: + internalformat = GL_RGB; + break; + } + } + + glRenderbufferStorageMultisampleEXT( + target, samples, internalformat, width, height); + // TODO(gman) should not set internal format unless this succeeds +} + void GLES2DecoderImpl::DoRenderbufferStorage( GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { if (!bound_renderbuffer_) { @@ -3042,6 +3184,7 @@ void GLES2DecoderImpl::DoRenderbufferStorage( } glRenderbufferStorageEXT(target, internalformat, width, height); + // TODO(gman) should not set internal format unless this succeeds } void GLES2DecoderImpl::DoLinkProgram(GLuint program) { @@ -4087,7 +4230,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels( CopyRealGLErrorsToWrapper(); // Get the size of the current fbo or backbuffer. - gfx::Size max_size = GetBoundFrameBufferSize(); + gfx::Size max_size = GetBoundReadFrameBufferSize(); GLint max_x; GLint max_y; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 0ae6355..aefe831 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2723,6 +2723,68 @@ error::Error GLES2DecoderImpl::HandleViewport( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT( + uint32 immediate_data_size, const gles2::BlitFramebufferEXT& c) { + GLint srcX0 = static_cast<GLint>(c.srcX0); + GLint srcY0 = static_cast<GLint>(c.srcY0); + GLint srcX1 = static_cast<GLint>(c.srcX1); + GLint srcY1 = static_cast<GLint>(c.srcY1); + GLint dstX0 = static_cast<GLint>(c.dstX0); + GLint dstY0 = static_cast<GLint>(c.dstY0); + GLint dstX1 = static_cast<GLint>(c.dstX1); + GLint dstY1 = static_cast<GLint>(c.dstY1); + GLbitfield mask = static_cast<GLbitfield>(c.mask); + GLenum filter = static_cast<GLenum>(c.filter); + if (!validators_->blit_filter.IsValid(filter)) { + SetGLError( + GL_INVALID_ENUM, "glBlitFramebufferEXT: filter GL_INVALID_ENUM"); + return error::kNoError; + } + DoBlitFramebufferEXT( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT( + uint32 immediate_data_size, + const gles2::RenderbufferStorageMultisampleEXT& c) { + GLenum target = static_cast<GLenum>(c.target); + GLsizei samples = static_cast<GLsizei>(c.samples); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + if (!validators_->render_buffer_target.IsValid(target)) { + SetGLError( + GL_INVALID_ENUM, + "glRenderbufferStorageMultisampleEXT: target GL_INVALID_ENUM"); + return error::kNoError; + } + if (samples < 0) { + SetGLError( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: samples < 0"); + return error::kNoError; + } + if (!validators_->render_buffer_format.IsValid(internalformat)) { + SetGLError( + GL_INVALID_ENUM, + "glRenderbufferStorageMultisampleEXT: internalformat GL_INVALID_ENUM"); + return error::kNoError; + } + if (width < 0) { + SetGLError( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: width < 0"); + return error::kNoError; + } + if (height < 0) { + SetGLError( + GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: height < 0"); + return error::kNoError; + } + DoRenderbufferStorageMultisample( + target, samples, internalformat, width, height); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleGetMaxValueInBuffer( uint32 immediate_data_size, const gles2::GetMaxValueInBuffer& c) { GLuint buffer_id = c.buffer_id; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index 00fee19..4c7257e 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -79,7 +79,7 @@ TEST_F(GLES2DecoderTest1, BindFramebufferInvalidArgs0_0) { EXPECT_CALL(*gl_, BindFramebufferEXT(_, _)).Times(0); SpecializedSetup<BindFramebuffer, 0>(false); BindFramebuffer cmd; - cmd.Init(GL_RENDERBUFFER, client_framebuffer_id_); + cmd.Init(GL_READ_FRAMEBUFFER, client_framebuffer_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -274,7 +274,7 @@ TEST_F(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_0) { EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0); SpecializedSetup<CheckFramebufferStatus, 0>(false); CheckFramebufferStatus cmd; - cmd.Init(GL_RENDERBUFFER, shared_memory_id_, shared_memory_offset_); + cmd.Init(GL_READ_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -780,7 +780,7 @@ TEST_F(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_0) { SpecializedSetup<FramebufferRenderbuffer, 0>(false); FramebufferRenderbuffer cmd; cmd.Init( - GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, client_renderbuffer_id_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); @@ -816,8 +816,8 @@ TEST_F(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_0) { SpecializedSetup<FramebufferTexture2D, 0>(false); FramebufferTexture2D cmd; cmd.Init( - GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_, - 5); + GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + client_texture_id_, 5); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } @@ -1300,7 +1300,7 @@ TEST_F(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_0) { result->size = 0; GetFramebufferAttachmentParameteriv cmd; cmd.Init( - GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, + GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, shared_memory_id_, shared_memory_offset_); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); @@ -1751,5 +1751,7 @@ TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) { // TODO(gman): GetUniformLocation +// TODO(gman): GetUniformLocationImmediate + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_ 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 9d8cc0a..0b6aee3 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 @@ -8,8 +8,6 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ -// TODO(gman): GetUniformLocationImmediate - // TODO(gman): GetUniformLocationBucket @@ -1601,6 +1599,8 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } +// TODO(gman): BlitFramebufferEXT +// TODO(gman): RenderbufferStorageMultisampleEXT // TODO(gman): SwapBuffers // TODO(gman): GetMaxValueInBuffer // TODO(gman): GenSharedIds diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index f6500fd..455d593 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -8,6 +8,7 @@ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_AUTOGEN_H_ ValueValidator<GLenum> attachment; +ValueValidator<GLenum> blit_filter; ValueValidator<GLenum> buffer_parameter; ValueValidator<GLenum> buffer_target; ValueValidator<GLenum> buffer_usage; 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 3b2407a..fda2b8b 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -13,6 +13,11 @@ static GLenum valid_attachment_table[] = { GL_STENCIL_ATTACHMENT, }; +static GLenum valid_blit_filter_table[] = { + GL_NEAREST, + GL_LINEAR, +}; + static GLenum valid_buffer_parameter_table[] = { GL_BUFFER_SIZE, GL_BUFFER_USAGE, @@ -413,6 +418,8 @@ static GLenum valid_vertex_pointer_table[] = { Validators::Validators() : attachment( valid_attachment_table, arraysize(valid_attachment_table)), + blit_filter( + valid_blit_filter_table, arraysize(valid_blit_filter_table)), buffer_parameter( valid_buffer_parameter_table, arraysize( valid_buffer_parameter_table)), |