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

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

Issue 954053002: gpu: Avoid detaching images with glTexSubImage2D (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: new tests Created 5 years, 9 months 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
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 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 GLenum buffer_mode); 1184 GLenum buffer_mode);
1185 1185
1186 // Clear any textures used by the current program. 1186 // Clear any textures used by the current program.
1187 bool ClearUnclearedTextures(); 1187 bool ClearUnclearedTextures();
1188 1188
1189 // Clears any uncleared attachments attached to the given frame buffer. 1189 // Clears any uncleared attachments attached to the given frame buffer.
1190 // Returns false if there was a generated GL error. 1190 // Returns false if there was a generated GL error.
1191 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer); 1191 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
1192 1192
1193 // overridden from GLES2Decoder 1193 // overridden from GLES2Decoder
1194 bool ClearLevel(unsigned service_id, 1194 bool ClearLevel(Texture* texture,
1195 unsigned bind_target,
1196 unsigned target, 1195 unsigned target,
1197 int level, 1196 int level,
1198 unsigned internal_format, 1197 unsigned internal_format,
1199 unsigned format, 1198 unsigned format,
1200 unsigned type, 1199 unsigned type,
1201 int width, 1200 int width,
1202 int height, 1201 int height,
1203 bool is_texture_immutable) override; 1202 bool is_texture_immutable) override;
1204 1203
1205 // Restore all GL state that affects clearing. 1204 // Restore all GL state that affects clearing.
(...skipping 7197 matching lines...) Expand 10 before | Expand all | Expand 10 after
8403 } 8402 }
8404 8403
8405 void GLES2DecoderImpl::DoBufferSubData( 8404 void GLES2DecoderImpl::DoBufferSubData(
8406 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { 8405 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
8407 // Just delegate it. Some validation is actually done before this. 8406 // Just delegate it. Some validation is actually done before this.
8408 buffer_manager()->ValidateAndDoBufferSubData( 8407 buffer_manager()->ValidateAndDoBufferSubData(
8409 &state_, target, offset, size, data); 8408 &state_, target, offset, size, data);
8410 } 8409 }
8411 8410
8412 bool GLES2DecoderImpl::ClearLevel( 8411 bool GLES2DecoderImpl::ClearLevel(
8413 unsigned service_id, 8412 Texture* texture,
8414 unsigned bind_target,
8415 unsigned target, 8413 unsigned target,
8416 int level, 8414 int level,
8417 unsigned internal_format, 8415 unsigned internal_format,
8418 unsigned format, 8416 unsigned format,
8419 unsigned type, 8417 unsigned type,
8420 int width, 8418 int width,
8421 int height, 8419 int height,
8422 bool is_texture_immutable) { 8420 bool is_texture_immutable) {
8423 uint32 channels = GLES2Util::GetChannelsForFormat(format); 8421 uint32 channels = GLES2Util::GetChannelsForFormat(format);
8424 if (feature_info_->feature_flags().angle_depth_texture && 8422 if (feature_info_->feature_flags().angle_depth_texture &&
8425 (channels & GLES2Util::kDepth) != 0) { 8423 (channels & GLES2Util::kDepth) != 0) {
8426 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D 8424 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8427 // on depth formats. 8425 // on depth formats.
8428 GLuint fb = 0; 8426 GLuint fb = 0;
8429 glGenFramebuffersEXT(1, &fb); 8427 glGenFramebuffersEXT(1, &fb);
8430 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); 8428 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8431 8429
8432 bool have_stencil = (channels & GLES2Util::kStencil) != 0; 8430 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8433 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : 8431 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8434 GL_DEPTH_ATTACHMENT; 8432 GL_DEPTH_ATTACHMENT;
8435 8433
8436 glFramebufferTexture2DEXT( 8434 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target,
8437 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level); 8435 texture->service_id(), level);
8438 // ANGLE promises a depth only attachment ok. 8436 // ANGLE promises a depth only attachment ok.
8439 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != 8437 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8440 GL_FRAMEBUFFER_COMPLETE) { 8438 GL_FRAMEBUFFER_COMPLETE) {
8441 return false; 8439 return false;
8442 } 8440 }
8443 glClearStencil(0); 8441 glClearStencil(0);
8444 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask); 8442 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8445 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask); 8443 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
8446 glClearDepth(1.0f); 8444 glClearDepth(1.0f);
8447 state_.SetDeviceDepthMask(GL_TRUE); 8445 state_.SetDeviceDepthMask(GL_TRUE);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
8486 NULL, NULL)) { 8484 NULL, NULL)) {
8487 return false; 8485 return false;
8488 } 8486 }
8489 } else { 8487 } else {
8490 tile_height = height; 8488 tile_height = height;
8491 } 8489 }
8492 8490
8493 // Assumes the size has already been checked. 8491 // Assumes the size has already been checked.
8494 scoped_ptr<char[]> zero(new char[size]); 8492 scoped_ptr<char[]> zero(new char[size]);
8495 memset(zero.get(), 0, size); 8493 memset(zero.get(), 0, size);
8496 glBindTexture(bind_target, service_id); 8494 glBindTexture(texture->target(), texture->service_id());
8497 8495
8496 bool has_images = texture->HasImages();
8498 GLint y = 0; 8497 GLint y = 0;
8499 while (y < height) { 8498 while (y < height) {
8500 GLint h = y + tile_height > height ? height - y : tile_height; 8499 GLint h = y + tile_height > height ? height - y : tile_height;
8501 if (is_texture_immutable || h != height) { 8500 if (is_texture_immutable || h != height || has_images) {
8502 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); 8501 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8503 } else { 8502 } else {
8504 glTexImage2D( 8503 glTexImage2D(
8505 target, level, internal_format, width, h, 0, format, type, 8504 target, level, internal_format, width, h, 0, format, type,
8506 zero.get()); 8505 zero.get());
8507 } 8506 }
8508 y += tile_height; 8507 y += tile_height;
8509 } 8508 }
8510 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 8509 TextureRef* bound_texture =
8511 &state_, bind_target); 8510 texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
8512 glBindTexture(bind_target, texture ? texture->service_id() : 0); 8511 glBindTexture(texture->target(),
8512 bound_texture ? bound_texture->service_id() : 0);
8513 return true; 8513 return true;
8514 } 8514 }
8515 8515
8516 namespace { 8516 namespace {
8517 8517
8518 const int kS3TCBlockWidth = 4; 8518 const int kS3TCBlockWidth = 4;
8519 const int kS3TCBlockHeight = 4; 8519 const int kS3TCBlockHeight = 4;
8520 const int kS3TCDXT1BlockSize = 8; 8520 const int kS3TCDXT1BlockSize = 8;
8521 const int kS3TCDXT3AndDXT5BlockSize = 16; 8521 const int kS3TCDXT3AndDXT5BlockSize = 16;
8522 8522
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
9163 GLint copyWidth = 0; 9163 GLint copyWidth = 0;
9164 GLint copyHeight = 0; 9164 GLint copyHeight = 0;
9165 Clip(x, width, size.width(), &copyX, &copyWidth); 9165 Clip(x, width, size.width(), &copyX, &copyWidth);
9166 Clip(y, height, size.height(), &copyY, &copyHeight); 9166 Clip(y, height, size.height(), &copyY, &copyHeight);
9167 9167
9168 if (copyX != x || 9168 if (copyX != x ||
9169 copyY != y || 9169 copyY != y ||
9170 copyWidth != width || 9170 copyWidth != width ||
9171 copyHeight != height) { 9171 copyHeight != height) {
9172 // some part was clipped so clear the texture. 9172 // some part was clipped so clear the texture.
9173 if (!ClearLevel( 9173 if (!ClearLevel(texture, target, level, internal_format, internal_format,
9174 texture->service_id(), texture->target(), 9174 GL_UNSIGNED_BYTE, width, height, texture->IsImmutable())) {
9175 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
9176 width, height, texture->IsImmutable())) {
9177 LOCAL_SET_GL_ERROR( 9175 LOCAL_SET_GL_ERROR(
9178 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); 9176 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
9179 return; 9177 return;
9180 } 9178 }
9181 if (copyHeight > 0 && copyWidth > 0) { 9179 if (copyHeight > 0 && copyWidth > 0) {
9182 GLint dx = copyX - x; 9180 GLint dx = copyX - x;
9183 GLint dy = copyY - y; 9181 GLint dy = copyY - y;
9184 GLint destX = dx; 9182 GLint destX = dx;
9185 GLint destY = dy; 9183 GLint destY = dy;
9186 ScopedModifyPixels modify(texture_ref); 9184 ScopedModifyPixels modify(texture_ref);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
9439 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); 9437 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
9440 return error::kNoError; 9438 return error::kNoError;
9441 } 9439 }
9442 ScopedTextureUploadTimer timer(&texture_state_); 9440 ScopedTextureUploadTimer timer(&texture_state_);
9443 glTexSubImage2D( 9441 glTexSubImage2D(
9444 target, level, xoffset, yoffset, width, height, format, type, data); 9442 target, level, xoffset, yoffset, width, height, format, type, data);
9445 return error::kNoError; 9443 return error::kNoError;
9446 } 9444 }
9447 9445
9448 if (!texture_state_.texsubimage2d_faster_than_teximage2d && 9446 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
9449 !texture->IsImmutable()) { 9447 !texture->IsImmutable() &&
9448 !texture->HasImages()) {
9450 ScopedTextureUploadTimer timer(&texture_state_); 9449 ScopedTextureUploadTimer timer(&texture_state_);
9451 GLenum internal_format; 9450 GLenum internal_format;
9452 GLenum tex_type; 9451 GLenum tex_type;
9453 texture->GetLevelType(target, level, &tex_type, &internal_format); 9452 texture->GetLevelType(target, level, &tex_type, &internal_format);
9454 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need 9453 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9455 // to look it up. 9454 // to look it up.
9456 glTexImage2D( 9455 glTexImage2D(
9457 target, level, internal_format, width, height, 0, format, type, data); 9456 target, level, internal_format, width, height, 0, format, type, data);
9458 } else { 9457 } else {
9459 ScopedTextureUploadTimer timer(&texture_state_); 9458 ScopedTextureUploadTimer timer(&texture_state_);
(...skipping 2666 matching lines...) Expand 10 before | Expand all | Expand 10 after
12126 } 12125 }
12127 } 12126 }
12128 12127
12129 // Include the auto-generated part of this file. We split this because it means 12128 // Include the auto-generated part of this file. We split this because it means
12130 // we can easily edit the non-auto generated parts right here in this file 12129 // we can easily edit the non-auto generated parts right here in this file
12131 // instead of having to edit some template or the code generator. 12130 // instead of having to edit some template or the code generator.
12132 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 12131 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
12133 12132
12134 } // namespace gles2 12133 } // namespace gles2
12135 } // namespace gpu 12134 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698