Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 11412262: gpu: Defer reads from default framebuffer when needed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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(), &copyX, &copyWidth); 7665 Clip(x, width, size.width(), &copyX, &copyWidth);
7629 Clip(y, height, size.height(), &copyY, &copyHeight); 7666 Clip(y, height, size.height(), &copyY, &copyHeight);
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698