OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <list> | 10 #include <list> |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 GLenum target, | 686 GLenum target, |
687 GLint level, | 687 GLint level, |
688 GLint xoffset, | 688 GLint xoffset, |
689 GLint yoffset, | 689 GLint yoffset, |
690 GLsizei width, | 690 GLsizei width, |
691 GLsizei height, | 691 GLsizei height, |
692 GLenum format, | 692 GLenum format, |
693 GLsizei imageSize, | 693 GLsizei imageSize, |
694 const void * data); | 694 const void * data); |
695 | 695 |
696 // Wrapper for CopyTexImage2D. | |
697 void DoCopyTexImage2D( | |
698 GLenum target, | |
699 GLint level, | |
700 GLenum internal_format, | |
701 GLint x, | |
702 GLint y, | |
703 GLsizei width, | |
704 GLsizei height, | |
705 GLint border); | |
706 | |
707 // Wrapper for CopyTexSubImage2D. | |
708 void DoCopyTexSubImage2D( | |
709 GLenum target, | |
710 GLint level, | |
711 GLint xoffset, | |
712 GLint yoffset, | |
713 GLint x, | |
714 GLint y, | |
715 GLsizei width, | |
716 GLsizei height); | |
717 | |
718 // Wrapper for TexImage2D commands. | 696 // Wrapper for TexImage2D commands. |
719 error::Error DoTexImage2D( | 697 error::Error DoTexImage2D( |
720 GLenum target, | 698 GLenum target, |
721 GLint level, | 699 GLint level, |
722 GLenum internal_format, | 700 GLenum internal_format, |
723 GLsizei width, | 701 GLsizei width, |
724 GLsizei height, | 702 GLsizei height, |
725 GLint border, | 703 GLint border, |
726 GLenum format, | 704 GLenum format, |
727 GLenum type, | 705 GLenum type, |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1008 // Wrapper for glBindRenderbuffer since we need to track the current targets. | 986 // Wrapper for glBindRenderbuffer since we need to track the current targets. |
1009 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer); | 987 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer); |
1010 | 988 |
1011 // Wrapper for glBindTexture since we need to track the current targets. | 989 // Wrapper for glBindTexture since we need to track the current targets. |
1012 void DoBindTexture(GLenum target, GLuint texture); | 990 void DoBindTexture(GLenum target, GLuint texture); |
1013 | 991 |
1014 // Wrapper for glBindVertexArrayOES | 992 // Wrapper for glBindVertexArrayOES |
1015 void DoBindVertexArrayOES(GLuint array); | 993 void DoBindVertexArrayOES(GLuint array); |
1016 void EmulateVertexArrayState(); | 994 void EmulateVertexArrayState(); |
1017 | 995 |
1018 // Wrapper for glBlitFramebufferEXT. | |
1019 void DoBlitFramebufferEXT( | |
1020 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, | |
1021 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, | |
1022 GLbitfield mask, GLenum filter); | |
1023 | |
1024 // Wrapper for glBufferData. | 996 // Wrapper for glBufferData. |
1025 void DoBufferData( | 997 void DoBufferData( |
1026 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); | 998 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); |
1027 | 999 |
1028 // Wrapper for glBufferSubData. | 1000 // Wrapper for glBufferSubData. |
1029 void DoBufferSubData( | 1001 void DoBufferSubData( |
1030 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); | 1002 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); |
1031 | 1003 |
1032 // Wrapper for glCheckFramebufferStatus | 1004 // Wrapper for glCheckFramebufferStatus |
1033 GLenum DoCheckFramebufferStatus(GLenum target); | 1005 GLenum DoCheckFramebufferStatus(GLenum target); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1402 const FeatureInfo::Workarounds& workarounds() const { | 1374 const FeatureInfo::Workarounds& workarounds() const { |
1403 return feature_info_->workarounds(); | 1375 return feature_info_->workarounds(); |
1404 } | 1376 } |
1405 | 1377 |
1406 bool ShouldDeferDraws() { | 1378 bool ShouldDeferDraws() { |
1407 return !offscreen_target_frame_buffer_.get() && | 1379 return !offscreen_target_frame_buffer_.get() && |
1408 state_.bound_draw_framebuffer == NULL && | 1380 state_.bound_draw_framebuffer == NULL && |
1409 surface_->DeferDraws(); | 1381 surface_->DeferDraws(); |
1410 } | 1382 } |
1411 | 1383 |
1384 bool ShouldDeferReads() { | |
1385 return !offscreen_target_frame_buffer_.get() && | |
1386 state_.bound_read_framebuffer == NULL && | |
1387 surface_->DeferDraws(); | |
1388 } | |
1389 | |
1412 void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info); | 1390 void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info); |
1413 | 1391 |
1414 // Generate a member function prototype for each command in an automated and | 1392 // Generate a member function prototype for each command in an automated and |
1415 // typesafe way. | 1393 // typesafe way. |
1416 #define GLES2_CMD_OP(name) \ | 1394 #define GLES2_CMD_OP(name) \ |
1417 Error Handle ## name( \ | 1395 Error Handle ## name( \ |
1418 uint32 immediate_data_size, \ | 1396 uint32 immediate_data_size, \ |
1419 const gles2::name& args); \ | 1397 const gles2::name& args); \ |
1420 | 1398 |
1421 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 1399 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3117 if (offscreen_resolved_color_texture_.get()) | 3095 if (offscreen_resolved_color_texture_.get()) |
3118 offscreen_resolved_color_texture_->Destroy(); | 3096 offscreen_resolved_color_texture_->Destroy(); |
3119 offscreen_resolved_color_texture_.reset(); | 3097 offscreen_resolved_color_texture_.reset(); |
3120 offscreen_resolved_frame_buffer_.reset(); | 3098 offscreen_resolved_frame_buffer_.reset(); |
3121 | 3099 |
3122 return true; | 3100 return true; |
3123 } | 3101 } |
3124 | 3102 |
3125 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM( | 3103 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM( |
3126 uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) { | 3104 uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) { |
3127 if (ShouldDeferDraws()) | 3105 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws()) |
piman
2012/11/30 01:52:12
Note here: ResizeCHROMIUM resizes the default FBO
| |
3128 return error::kDeferCommandUntilLater; | 3106 return error::kDeferCommandUntilLater; |
3129 | 3107 |
3130 GLuint width = static_cast<GLuint>(c.width); | 3108 GLuint width = static_cast<GLuint>(c.width); |
3131 GLuint height = static_cast<GLuint>(c.height); | 3109 GLuint height = static_cast<GLuint>(c.height); |
3132 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height); | 3110 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height); |
3133 #if defined(OS_POSIX) && !defined(OS_MACOSX) && \ | 3111 #if defined(OS_POSIX) && !defined(OS_MACOSX) && \ |
3134 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) | 3112 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) |
3135 // Make sure that we are done drawing to the back buffer before resizing. | 3113 // Make sure that we are done drawing to the back buffer before resizing. |
3136 glFinish(); | 3114 glFinish(); |
3137 #endif | 3115 #endif |
(...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4493 break; | 4471 break; |
4494 case GL_RENDERBUFFER_HEIGHT: | 4472 case GL_RENDERBUFFER_HEIGHT: |
4495 *params = renderbuffer->height(); | 4473 *params = renderbuffer->height(); |
4496 break; | 4474 break; |
4497 default: | 4475 default: |
4498 glGetRenderbufferParameterivEXT(target, pname, params); | 4476 glGetRenderbufferParameterivEXT(target, pname, params); |
4499 break; | 4477 break; |
4500 } | 4478 } |
4501 } | 4479 } |
4502 | 4480 |
4503 void GLES2DecoderImpl::DoBlitFramebufferEXT( | 4481 error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT( |
4504 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, | 4482 uint32 immediate_data_size, const gles2::BlitFramebufferEXT& c) { |
4505 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, | 4483 if (ShouldDeferDraws() || ShouldDeferReads()) |
4506 GLbitfield mask, GLenum filter) { | 4484 return error::kDeferCommandUntilLater; |
4485 GLint srcX0 = static_cast<GLint>(c.srcX0); | |
4486 GLint srcY0 = static_cast<GLint>(c.srcY0); | |
4487 GLint srcX1 = static_cast<GLint>(c.srcX1); | |
4488 GLint srcY1 = static_cast<GLint>(c.srcY1); | |
4489 GLint dstX0 = static_cast<GLint>(c.dstX0); | |
4490 GLint dstY0 = static_cast<GLint>(c.dstY0); | |
4491 GLint dstX1 = static_cast<GLint>(c.dstX1); | |
4492 GLint dstY1 = static_cast<GLint>(c.dstY1); | |
4493 GLbitfield mask = static_cast<GLbitfield>(c.mask); | |
4494 GLenum filter = static_cast<GLenum>(c.filter); | |
4495 if (!validators_->blit_filter.IsValid(filter)) { | |
4496 SetGLErrorInvalidEnum("glBlitFramebufferEXT", filter, "filter"); | |
4497 return error::kNoError; | |
4498 } | |
4507 if (!features().chromium_framebuffer_multisample) { | 4499 if (!features().chromium_framebuffer_multisample) { |
4508 SetGLError(GL_INVALID_OPERATION, | 4500 SetGLError(GL_INVALID_OPERATION, |
4509 "glBlitFramebufferEXT", "function not available"); | 4501 "glBlitFramebufferEXT", "function not available"); |
4510 } | 4502 } |
4511 glDisable(GL_SCISSOR_TEST); | 4503 glDisable(GL_SCISSOR_TEST); |
4512 if (IsAngle()) { | 4504 if (IsAngle()) { |
4513 glBlitFramebufferANGLE( | 4505 glBlitFramebufferANGLE( |
4514 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); | 4506 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); |
4515 } else { | 4507 } else { |
4516 glBlitFramebufferEXT( | 4508 glBlitFramebufferEXT( |
4517 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); | 4509 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); |
4518 } | 4510 } |
4519 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); | 4511 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); |
4520 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0); | 4512 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0); |
4513 return error::kNoError; | |
4521 } | 4514 } |
4522 | 4515 |
4523 void GLES2DecoderImpl::DoRenderbufferStorageMultisample( | 4516 void GLES2DecoderImpl::DoRenderbufferStorageMultisample( |
4524 GLenum target, GLsizei samples, GLenum internalformat, | 4517 GLenum target, GLsizei samples, GLenum internalformat, |
4525 GLsizei width, GLsizei height) { | 4518 GLsizei width, GLsizei height) { |
4526 if (!features().chromium_framebuffer_multisample) { | 4519 if (!features().chromium_framebuffer_multisample) { |
4527 SetGLError(GL_INVALID_OPERATION, | 4520 SetGLError(GL_INVALID_OPERATION, |
4528 "glRenderbufferStorageMultisampleEXT", "function not available"); | 4521 "glRenderbufferStorageMultisampleEXT", "function not available"); |
4529 return; | 4522 return; |
4530 } | 4523 } |
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6285 | 6278 |
6286 state_.vertex_attrib_manager->SetDivisor( | 6279 state_.vertex_attrib_manager->SetDivisor( |
6287 index, | 6280 index, |
6288 divisor); | 6281 divisor); |
6289 glVertexAttribDivisorANGLE(index, divisor); | 6282 glVertexAttribDivisorANGLE(index, divisor); |
6290 return error::kNoError; | 6283 return error::kNoError; |
6291 } | 6284 } |
6292 | 6285 |
6293 error::Error GLES2DecoderImpl::HandleReadPixels( | 6286 error::Error GLES2DecoderImpl::HandleReadPixels( |
6294 uint32 immediate_data_size, const gles2::ReadPixels& c) { | 6287 uint32 immediate_data_size, const gles2::ReadPixels& c) { |
6288 if (ShouldDeferReads()) | |
6289 return error::kDeferCommandUntilLater; | |
6295 GLint x = c.x; | 6290 GLint x = c.x; |
6296 GLint y = c.y; | 6291 GLint y = c.y; |
6297 GLsizei width = c.width; | 6292 GLsizei width = c.width; |
6298 GLsizei height = c.height; | 6293 GLsizei height = c.height; |
6299 GLenum format = c.format; | 6294 GLenum format = c.format; |
6300 GLenum type = c.type; | 6295 GLenum type = c.type; |
6301 if (width < 0 || height < 0) { | 6296 if (width < 0 || height < 0) { |
6302 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); | 6297 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); |
6303 return error::kNoError; | 6298 return error::kNoError; |
6304 } | 6299 } |
(...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7462 start = 0; | 7457 start = 0; |
7463 } | 7458 } |
7464 GLint end = start + range; | 7459 GLint end = start + range; |
7465 if (end > sourceRange) { | 7460 if (end > sourceRange) { |
7466 range -= end - sourceRange; | 7461 range -= end - sourceRange; |
7467 } | 7462 } |
7468 *out_start = start; | 7463 *out_start = start; |
7469 *out_range = range; | 7464 *out_range = range; |
7470 } | 7465 } |
7471 | 7466 |
7472 void GLES2DecoderImpl::DoCopyTexImage2D( | 7467 error::Error GLES2DecoderImpl::HandleCopyTexImage2D( |
7473 GLenum target, | 7468 uint32 immediate_data_size, const gles2::CopyTexImage2D& c) { |
7474 GLint level, | 7469 if (ShouldDeferReads()) |
7475 GLenum internal_format, | 7470 return error::kDeferCommandUntilLater; |
7476 GLint x, | 7471 GLenum target = static_cast<GLenum>(c.target); |
7477 GLint y, | 7472 GLint level = static_cast<GLint>(c.level); |
7478 GLsizei width, | 7473 GLenum internal_format = static_cast<GLenum>(c.internalformat); |
7479 GLsizei height, | 7474 GLint x = static_cast<GLint>(c.x); |
7480 GLint border) { | 7475 GLint y = static_cast<GLint>(c.y); |
7476 GLsizei width = static_cast<GLsizei>(c.width); | |
7477 GLsizei height = static_cast<GLsizei>(c.height); | |
7478 GLint border = static_cast<GLint>(c.border); | |
7479 if (!validators_->texture_target.IsValid(target)) { | |
7480 SetGLErrorInvalidEnum("glCopyTexImage2D", target, "target"); | |
7481 return error::kNoError; | |
7482 } | |
7483 if (!validators_->texture_internal_format.IsValid(internal_format)) { | |
7484 SetGLErrorInvalidEnum("glCopyTexImage2D", internal_format, | |
7485 "internalformat"); | |
7486 return error::kNoError; | |
7487 } | |
7488 if (width < 0) { | |
7489 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "width < 0"); | |
7490 return error::kNoError; | |
7491 } | |
7492 if (height < 0) { | |
7493 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "height < 0"); | |
7494 return error::kNoError; | |
7495 } | |
7496 if (!validators_->texture_border.IsValid(border)) { | |
7497 SetGLError( | |
7498 GL_INVALID_VALUE, "glCopyTexImage2D", "border GL_INVALID_VALUE"); | |
7499 return error::kNoError; | |
7500 } | |
7481 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 7501 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
7482 if (!info) { | 7502 if (!info) { |
7483 SetGLError(GL_INVALID_OPERATION, | 7503 SetGLError(GL_INVALID_OPERATION, |
7484 "glCopyTexImage2D", "unknown texture for target"); | 7504 "glCopyTexImage2D", "unknown texture for target"); |
7485 return; | 7505 return error::kNoError; |
7486 } | 7506 } |
7487 if (info->IsImmutable()) { | 7507 if (info->IsImmutable()) { |
7488 SetGLError(GL_INVALID_OPERATION, | 7508 SetGLError(GL_INVALID_OPERATION, |
7489 "glCopyTexImage2D", "texture is immutable"); | 7509 "glCopyTexImage2D", "texture is immutable"); |
7490 } | 7510 } |
7491 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || | 7511 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || |
7492 border != 0) { | 7512 border != 0) { |
7493 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range"); | 7513 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range"); |
7494 return; | 7514 return error::kNoError; |
7495 } | 7515 } |
7496 if (!ValidateTextureParameters( | 7516 if (!ValidateTextureParameters( |
7497 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) { | 7517 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) { |
7498 return; | 7518 return error::kNoError; |
7499 } | 7519 } |
7500 | 7520 |
7501 // Check we have compatible formats. | 7521 // Check we have compatible formats. |
7502 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 7522 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
7503 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | 7523 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
7504 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); | 7524 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); |
7505 | 7525 |
7506 if ((channels_needed & channels_exist) != channels_needed) { | 7526 if ((channels_needed & channels_exist) != channels_needed) { |
7507 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); | 7527 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); |
7508 return; | 7528 return error::kNoError; |
7509 } | 7529 } |
7510 | 7530 |
7511 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { | 7531 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
7512 SetGLError( | 7532 SetGLError( |
7513 GL_INVALID_OPERATION, | 7533 GL_INVALID_OPERATION, |
7514 "glCopyImage2D", "can not be used with depth or stencil textures"); | 7534 "glCopyImage2D", "can not be used with depth or stencil textures"); |
7515 return; | 7535 return error::kNoError; |
7516 } | 7536 } |
7517 | 7537 |
7518 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { | 7538 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { |
7519 return; | 7539 return error::kNoError; |
7520 } | 7540 } |
7521 | 7541 |
7522 CopyRealGLErrorsToWrapper(); | 7542 CopyRealGLErrorsToWrapper(); |
7523 ScopedResolvedFrameBufferBinder binder(this, false, true); | 7543 ScopedResolvedFrameBufferBinder binder(this, false, true); |
7524 gfx::Size size = GetBoundReadFrameBufferSize(); | 7544 gfx::Size size = GetBoundReadFrameBufferSize(); |
7525 | 7545 |
7526 if (info->IsAttachedToFramebuffer()) { | 7546 if (info->IsAttachedToFramebuffer()) { |
7527 clear_state_dirty_ = true; | 7547 clear_state_dirty_ = true; |
7528 // TODO(gman): If textures tracked which framebuffers they were attached to | 7548 // TODO(gman): If textures tracked which framebuffers they were attached to |
7529 // we could just mark those framebuffers as not complete. | 7549 // we could just mark those framebuffers as not complete. |
(...skipping 11 matching lines...) Expand all Loading... | |
7541 if (copyX != x || | 7561 if (copyX != x || |
7542 copyY != y || | 7562 copyY != y || |
7543 copyWidth != width || | 7563 copyWidth != width || |
7544 copyHeight != height) { | 7564 copyHeight != height) { |
7545 // some part was clipped so clear the texture. | 7565 // some part was clipped so clear the texture. |
7546 if (!ClearLevel( | 7566 if (!ClearLevel( |
7547 info->service_id(), info->target(), | 7567 info->service_id(), info->target(), |
7548 target, level, internal_format, GL_UNSIGNED_BYTE, width, height, | 7568 target, level, internal_format, GL_UNSIGNED_BYTE, width, height, |
7549 info->IsImmutable())) { | 7569 info->IsImmutable())) { |
7550 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); | 7570 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); |
7551 return; | 7571 return error::kNoError; |
7552 } | 7572 } |
7553 if (copyHeight > 0 && copyWidth > 0) { | 7573 if (copyHeight > 0 && copyWidth > 0) { |
7554 GLint dx = copyX - x; | 7574 GLint dx = copyX - x; |
7555 GLint dy = copyY - y; | 7575 GLint dy = copyY - y; |
7556 GLint destX = dx; | 7576 GLint destX = dx; |
7557 GLint destY = dy; | 7577 GLint destY = dy; |
7558 glCopyTexSubImage2D(target, level, | 7578 glCopyTexSubImage2D(target, level, |
7559 destX, destY, copyX, copyY, | 7579 destX, destY, copyX, copyY, |
7560 copyWidth, copyHeight); | 7580 copyWidth, copyHeight); |
7561 } | 7581 } |
7562 } else { | 7582 } else { |
7563 glCopyTexImage2D(target, level, internal_format, | 7583 glCopyTexImage2D(target, level, internal_format, |
7564 copyX, copyY, copyWidth, copyHeight, border); | 7584 copyX, copyY, copyWidth, copyHeight, border); |
7565 } | 7585 } |
7566 GLenum error = PeekGLError(); | 7586 GLenum error = PeekGLError(); |
7567 if (error == GL_NO_ERROR) { | 7587 if (error == GL_NO_ERROR) { |
7568 texture_manager()->SetLevelInfo( | 7588 texture_manager()->SetLevelInfo( |
7569 info, target, level, internal_format, width, height, 1, | 7589 info, target, level, internal_format, width, height, 1, |
7570 border, internal_format, GL_UNSIGNED_BYTE, true); | 7590 border, internal_format, GL_UNSIGNED_BYTE, true); |
7571 } | 7591 } |
7592 return error::kNoError; | |
7572 } | 7593 } |
7573 | 7594 |
7574 void GLES2DecoderImpl::DoCopyTexSubImage2D( | 7595 |
7575 GLenum target, | 7596 error::Error GLES2DecoderImpl::HandleCopyTexSubImage2D( |
7576 GLint level, | 7597 uint32 immediate_data_size, const gles2::CopyTexSubImage2D& c) { |
7577 GLint xoffset, | 7598 if (ShouldDeferReads()) |
7578 GLint yoffset, | 7599 return error::kDeferCommandUntilLater; |
7579 GLint x, | 7600 GLenum target = static_cast<GLenum>(c.target); |
7580 GLint y, | 7601 GLint level = static_cast<GLint>(c.level); |
7581 GLsizei width, | 7602 GLint xoffset = static_cast<GLint>(c.xoffset); |
7582 GLsizei height) { | 7603 GLint yoffset = static_cast<GLint>(c.yoffset); |
7604 GLint x = static_cast<GLint>(c.x); | |
7605 GLint y = static_cast<GLint>(c.y); | |
7606 GLsizei width = static_cast<GLsizei>(c.width); | |
7607 GLsizei height = static_cast<GLsizei>(c.height); | |
7608 if (!validators_->texture_target.IsValid(target)) { | |
7609 SetGLErrorInvalidEnum("glCopyTexSubImage2D", target, "target"); | |
7610 return error::kNoError; | |
7611 } | |
7612 if (width < 0) { | |
7613 SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "width < 0"); | |
7614 return error::kNoError; | |
7615 } | |
7616 if (height < 0) { | |
7617 SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "height < 0"); | |
7618 return error::kNoError; | |
7619 } | |
7583 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 7620 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
7584 if (!info) { | 7621 if (!info) { |
7585 SetGLError(GL_INVALID_OPERATION, | 7622 SetGLError(GL_INVALID_OPERATION, |
7586 "glCopyTexSubImage2D", "unknown texture for target"); | 7623 "glCopyTexSubImage2D", "unknown texture for target"); |
7587 return; | 7624 return error::kNoError; |
7588 } | 7625 } |
7589 GLenum type = 0; | 7626 GLenum type = 0; |
7590 GLenum format = 0; | 7627 GLenum format = 0; |
7591 if (!info->GetLevelType(target, level, &type, &format) || | 7628 if (!info->GetLevelType(target, level, &type, &format) || |
7592 !info->ValidForTexture( | 7629 !info->ValidForTexture( |
7593 target, level, xoffset, yoffset, width, height, format, type)) { | 7630 target, level, xoffset, yoffset, width, height, format, type)) { |
7594 SetGLError(GL_INVALID_VALUE, | 7631 SetGLError(GL_INVALID_VALUE, |
7595 "glCopyTexSubImage2D", "bad dimensions."); | 7632 "glCopyTexSubImage2D", "bad dimensions."); |
7596 return; | 7633 return error::kNoError; |
7597 } | 7634 } |
7598 | 7635 |
7599 // Check we have compatible formats. | 7636 // Check we have compatible formats. |
7600 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 7637 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
7601 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | 7638 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
7602 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); | 7639 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); |
7603 | 7640 |
7604 if (!channels_needed || | 7641 if (!channels_needed || |
7605 (channels_needed & channels_exist) != channels_needed) { | 7642 (channels_needed & channels_exist) != channels_needed) { |
7606 SetGLError( | 7643 SetGLError( |
7607 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); | 7644 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); |
7608 return; | 7645 return error::kNoError; |
7609 } | 7646 } |
7610 | 7647 |
7611 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { | 7648 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
7612 SetGLError( | 7649 SetGLError( |
7613 GL_INVALID_OPERATION, | 7650 GL_INVALID_OPERATION, |
7614 "glCopySubImage2D", "can not be used with depth or stencil textures"); | 7651 "glCopySubImage2D", "can not be used with depth or stencil textures"); |
7615 return; | 7652 return error::kNoError; |
7616 } | 7653 } |
7617 | 7654 |
7618 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { | 7655 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { |
7619 return; | 7656 return error::kNoError; |
7620 } | 7657 } |
7621 | 7658 |
7622 ScopedResolvedFrameBufferBinder binder(this, false, true); | 7659 ScopedResolvedFrameBufferBinder binder(this, false, true); |
7623 gfx::Size size = GetBoundReadFrameBufferSize(); | 7660 gfx::Size size = GetBoundReadFrameBufferSize(); |
7624 GLint copyX = 0; | 7661 GLint copyX = 0; |
7625 GLint copyY = 0; | 7662 GLint copyY = 0; |
7626 GLint copyWidth = 0; | 7663 GLint copyWidth = 0; |
7627 GLint copyHeight = 0; | 7664 GLint copyHeight = 0; |
7628 Clip(x, width, size.width(), ©X, ©Width); | 7665 Clip(x, width, size.width(), ©X, ©Width); |
7629 Clip(y, height, size.height(), ©Y, ©Height); | 7666 Clip(y, height, size.height(), ©Y, ©Height); |
7630 | 7667 |
7631 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | 7668 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
7632 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big"); | 7669 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big"); |
7633 return; | 7670 return error::kNoError; |
7634 } | 7671 } |
7635 | 7672 |
7636 if (copyX != x || | 7673 if (copyX != x || |
7637 copyY != y || | 7674 copyY != y || |
7638 copyWidth != width || | 7675 copyWidth != width || |
7639 copyHeight != height) { | 7676 copyHeight != height) { |
7640 // some part was clipped so clear the sub rect. | 7677 // some part was clipped so clear the sub rect. |
7641 uint32 pixels_size = 0; | 7678 uint32 pixels_size = 0; |
7642 if (!GLES2Util::ComputeImageDataSizes( | 7679 if (!GLES2Util::ComputeImageDataSizes( |
7643 width, height, format, type, state_.unpack_alignment, &pixels_size, | 7680 width, height, format, type, state_.unpack_alignment, &pixels_size, |
7644 NULL, NULL)) { | 7681 NULL, NULL)) { |
7645 SetGLError( | 7682 SetGLError( |
7646 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); | 7683 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); |
7647 return; | 7684 return error::kNoError; |
7648 } | 7685 } |
7649 scoped_array<char> zero(new char[pixels_size]); | 7686 scoped_array<char> zero(new char[pixels_size]); |
7650 memset(zero.get(), 0, pixels_size); | 7687 memset(zero.get(), 0, pixels_size); |
7651 glTexSubImage2D( | 7688 glTexSubImage2D( |
7652 target, level, xoffset, yoffset, width, height, | 7689 target, level, xoffset, yoffset, width, height, |
7653 format, type, zero.get()); | 7690 format, type, zero.get()); |
7654 } | 7691 } |
7655 | 7692 |
7656 if (copyHeight > 0 && copyWidth > 0) { | 7693 if (copyHeight > 0 && copyWidth > 0) { |
7657 GLint dx = copyX - x; | 7694 GLint dx = copyX - x; |
7658 GLint dy = copyY - y; | 7695 GLint dy = copyY - y; |
7659 GLint destX = xoffset + dx; | 7696 GLint destX = xoffset + dx; |
7660 GLint destY = yoffset + dy; | 7697 GLint destY = yoffset + dy; |
7661 glCopyTexSubImage2D(target, level, | 7698 glCopyTexSubImage2D(target, level, |
7662 destX, destY, copyX, copyY, | 7699 destX, destY, copyX, copyY, |
7663 copyWidth, copyHeight); | 7700 copyWidth, copyHeight); |
7664 } | 7701 } |
7702 return error::kNoError; | |
7665 } | 7703 } |
7666 | 7704 |
7667 void GLES2DecoderImpl::DoTexSubImage2D( | 7705 void GLES2DecoderImpl::DoTexSubImage2D( |
7668 GLenum target, | 7706 GLenum target, |
7669 GLint level, | 7707 GLint level, |
7670 GLint xoffset, | 7708 GLint xoffset, |
7671 GLint yoffset, | 7709 GLint yoffset, |
7672 GLsizei width, | 7710 GLsizei width, |
7673 GLsizei height, | 7711 GLsizei height, |
7674 GLenum format, | 7712 GLenum format, |
(...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9365 gpu_trace_stack_.pop(); | 9403 gpu_trace_stack_.pop(); |
9366 } | 9404 } |
9367 | 9405 |
9368 // Include the auto-generated part of this file. We split this because it means | 9406 // Include the auto-generated part of this file. We split this because it means |
9369 // we can easily edit the non-auto generated parts right here in this file | 9407 // we can easily edit the non-auto generated parts right here in this file |
9370 // instead of having to edit some template or the code generator. | 9408 // instead of having to edit some template or the code generator. |
9371 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 9409 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
9372 | 9410 |
9373 } // namespace gles2 | 9411 } // namespace gles2 |
9374 } // namespace gpu | 9412 } // namespace gpu |
OLD | NEW |