Chromium Code Reviews| 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 |