Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| index 406f728c6ec9ae5d4313aeaa1acc792c7f4fb3af..5e10048f5d5e1dc87491211ac23c2660727ac3d4 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -693,28 +693,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| GLsizei imageSize, |
| const void * data); |
| - // Wrapper for CopyTexImage2D. |
| - void DoCopyTexImage2D( |
| - GLenum target, |
| - GLint level, |
| - GLenum internal_format, |
| - GLint x, |
| - GLint y, |
| - GLsizei width, |
| - GLsizei height, |
| - GLint border); |
| - |
| - // Wrapper for CopyTexSubImage2D. |
| - void DoCopyTexSubImage2D( |
| - GLenum target, |
| - GLint level, |
| - GLint xoffset, |
| - GLint yoffset, |
| - GLint x, |
| - GLint y, |
| - GLsizei width, |
| - GLsizei height); |
| - |
| // Wrapper for TexImage2D commands. |
| error::Error DoTexImage2D( |
| GLenum target, |
| @@ -1015,12 +993,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| void DoBindVertexArrayOES(GLuint array); |
| void EmulateVertexArrayState(); |
| - // 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); |
| @@ -1409,6 +1381,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| surface_->DeferDraws(); |
| } |
| + bool ShouldDeferReads() { |
| + return !offscreen_target_frame_buffer_.get() && |
| + state_.bound_read_framebuffer == NULL && |
| + surface_->DeferDraws(); |
| + } |
| + |
| void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info); |
| // Generate a member function prototype for each command in an automated and |
| @@ -3124,7 +3102,7 @@ bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { |
| error::Error GLES2DecoderImpl::HandleResizeCHROMIUM( |
| uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) { |
| - if (ShouldDeferDraws()) |
| + if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws()) |
|
piman
2012/11/30 01:52:12
Note here: ResizeCHROMIUM resizes the default FBO
|
| return error::kDeferCommandUntilLater; |
| GLuint width = static_cast<GLuint>(c.width); |
| @@ -4500,10 +4478,24 @@ void GLES2DecoderImpl::DoGetRenderbufferParameteriv( |
| } |
| } |
| -void GLES2DecoderImpl::DoBlitFramebufferEXT( |
| - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, |
| - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, |
| - GLbitfield mask, GLenum filter) { |
| +error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT( |
| + uint32 immediate_data_size, const gles2::BlitFramebufferEXT& c) { |
| + if (ShouldDeferDraws() || ShouldDeferReads()) |
| + return error::kDeferCommandUntilLater; |
| + 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)) { |
| + SetGLErrorInvalidEnum("glBlitFramebufferEXT", filter, "filter"); |
| + return error::kNoError; |
| + } |
| if (!features().chromium_framebuffer_multisample) { |
| SetGLError(GL_INVALID_OPERATION, |
| "glBlitFramebufferEXT", "function not available"); |
| @@ -4518,6 +4510,7 @@ void GLES2DecoderImpl::DoBlitFramebufferEXT( |
| } |
| EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); |
| UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0); |
| + return error::kNoError; |
| } |
| void GLES2DecoderImpl::DoRenderbufferStorageMultisample( |
| @@ -6292,6 +6285,8 @@ error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( |
| error::Error GLES2DecoderImpl::HandleReadPixels( |
| uint32 immediate_data_size, const gles2::ReadPixels& c) { |
| + if (ShouldDeferReads()) |
| + return error::kDeferCommandUntilLater; |
| GLint x = c.x; |
| GLint y = c.y; |
| GLsizei width = c.width; |
| @@ -7469,20 +7464,45 @@ static void Clip( |
| *out_range = range; |
| } |
| -void GLES2DecoderImpl::DoCopyTexImage2D( |
| - GLenum target, |
| - GLint level, |
| - GLenum internal_format, |
| - GLint x, |
| - GLint y, |
| - GLsizei width, |
| - GLsizei height, |
| - GLint border) { |
| +error::Error GLES2DecoderImpl::HandleCopyTexImage2D( |
| + uint32 immediate_data_size, const gles2::CopyTexImage2D& c) { |
| + if (ShouldDeferReads()) |
| + return error::kDeferCommandUntilLater; |
| + GLenum target = static_cast<GLenum>(c.target); |
| + GLint level = static_cast<GLint>(c.level); |
| + GLenum internal_format = static_cast<GLenum>(c.internalformat); |
| + GLint x = static_cast<GLint>(c.x); |
| + GLint y = static_cast<GLint>(c.y); |
| + GLsizei width = static_cast<GLsizei>(c.width); |
| + GLsizei height = static_cast<GLsizei>(c.height); |
| + GLint border = static_cast<GLint>(c.border); |
| + if (!validators_->texture_target.IsValid(target)) { |
| + SetGLErrorInvalidEnum("glCopyTexImage2D", target, "target"); |
| + return error::kNoError; |
| + } |
| + if (!validators_->texture_internal_format.IsValid(internal_format)) { |
| + SetGLErrorInvalidEnum("glCopyTexImage2D", internal_format, |
| + "internalformat"); |
| + return error::kNoError; |
| + } |
| + if (width < 0) { |
| + SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "width < 0"); |
| + return error::kNoError; |
| + } |
| + if (height < 0) { |
| + SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "height < 0"); |
| + return error::kNoError; |
| + } |
| + if (!validators_->texture_border.IsValid(border)) { |
| + SetGLError( |
| + GL_INVALID_VALUE, "glCopyTexImage2D", "border GL_INVALID_VALUE"); |
| + return error::kNoError; |
| + } |
| TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| if (!info) { |
| SetGLError(GL_INVALID_OPERATION, |
| "glCopyTexImage2D", "unknown texture for target"); |
| - return; |
| + return error::kNoError; |
| } |
| if (info->IsImmutable()) { |
| SetGLError(GL_INVALID_OPERATION, |
| @@ -7491,11 +7511,11 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || |
| border != 0) { |
| SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range"); |
| - return; |
| + return error::kNoError; |
| } |
| if (!ValidateTextureParameters( |
| "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) { |
| - return; |
| + return error::kNoError; |
| } |
| // Check we have compatible formats. |
| @@ -7505,18 +7525,18 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| if ((channels_needed & channels_exist) != channels_needed) { |
| SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); |
| - return; |
| + return error::kNoError; |
| } |
| if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
| SetGLError( |
| GL_INVALID_OPERATION, |
| "glCopyImage2D", "can not be used with depth or stencil textures"); |
| - return; |
| + return error::kNoError; |
| } |
| if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { |
| - return; |
| + return error::kNoError; |
| } |
| CopyRealGLErrorsToWrapper(); |
| @@ -7548,7 +7568,7 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| target, level, internal_format, GL_UNSIGNED_BYTE, width, height, |
| info->IsImmutable())) { |
| SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); |
| - return; |
| + return error::kNoError; |
| } |
| if (copyHeight > 0 && copyWidth > 0) { |
| GLint dx = copyX - x; |
| @@ -7569,22 +7589,39 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| info, target, level, internal_format, width, height, 1, |
| border, internal_format, GL_UNSIGNED_BYTE, true); |
| } |
| + return error::kNoError; |
| } |
| -void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| - GLenum target, |
| - GLint level, |
| - GLint xoffset, |
| - GLint yoffset, |
| - GLint x, |
| - GLint y, |
| - GLsizei width, |
| - GLsizei height) { |
| + |
| +error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D( |
| + uint32 immediate_data_size, const gles2::CopyTexSubImage2D& c) { |
| + if (ShouldDeferReads()) |
| + return error::kDeferCommandUntilLater; |
| + GLenum target = static_cast<GLenum>(c.target); |
| + GLint level = static_cast<GLint>(c.level); |
| + GLint xoffset = static_cast<GLint>(c.xoffset); |
| + GLint yoffset = static_cast<GLint>(c.yoffset); |
| + GLint x = static_cast<GLint>(c.x); |
| + GLint y = static_cast<GLint>(c.y); |
| + GLsizei width = static_cast<GLsizei>(c.width); |
| + GLsizei height = static_cast<GLsizei>(c.height); |
| + if (!validators_->texture_target.IsValid(target)) { |
| + SetGLErrorInvalidEnum("glCopyTexSubImage2D", target, "target"); |
| + return error::kNoError; |
| + } |
| + if (width < 0) { |
| + SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "width < 0"); |
| + return error::kNoError; |
| + } |
| + if (height < 0) { |
| + SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "height < 0"); |
| + return error::kNoError; |
| + } |
| TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| if (!info) { |
| SetGLError(GL_INVALID_OPERATION, |
| "glCopyTexSubImage2D", "unknown texture for target"); |
| - return; |
| + return error::kNoError; |
| } |
| GLenum type = 0; |
| GLenum format = 0; |
| @@ -7593,7 +7630,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| target, level, xoffset, yoffset, width, height, format, type)) { |
| SetGLError(GL_INVALID_VALUE, |
| "glCopyTexSubImage2D", "bad dimensions."); |
| - return; |
| + return error::kNoError; |
| } |
| // Check we have compatible formats. |
| @@ -7605,18 +7642,18 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| (channels_needed & channels_exist) != channels_needed) { |
| SetGLError( |
| GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); |
| - return; |
| + return error::kNoError; |
| } |
| if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
| SetGLError( |
| GL_INVALID_OPERATION, |
| "glCopySubImage2D", "can not be used with depth or stencil textures"); |
| - return; |
| + return error::kNoError; |
| } |
| if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { |
| - return; |
| + return error::kNoError; |
| } |
| ScopedResolvedFrameBufferBinder binder(this, false, true); |
| @@ -7630,7 +7667,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
| SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big"); |
| - return; |
| + return error::kNoError; |
| } |
| if (copyX != x || |
| @@ -7644,7 +7681,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| NULL, NULL)) { |
| SetGLError( |
| GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); |
| - return; |
| + return error::kNoError; |
| } |
| scoped_array<char> zero(new char[pixels_size]); |
| memset(zero.get(), 0, pixels_size); |
| @@ -7662,6 +7699,7 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D( |
| destX, destY, copyX, copyY, |
| copyWidth, copyHeight); |
| } |
| + return error::kNoError; |
| } |
| void GLES2DecoderImpl::DoTexSubImage2D( |