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

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

Issue 2680703003: Reland of Select correct copy method for DoCopySubTexture (Closed)
Patch Set: fix perf regression on chromeos Created 3 years, 10 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 <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 #include <stdio.h> 10 #include <stdio.h>
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 int height, 1288 int height,
1289 int depth) override; 1289 int depth) override;
1290 1290
1291 // Restore all GL state that affects clearing. 1291 // Restore all GL state that affects clearing.
1292 void RestoreClearState(); 1292 void RestoreClearState();
1293 1293
1294 // Remembers the state of some capabilities. 1294 // Remembers the state of some capabilities.
1295 // Returns: true if glEnable/glDisable should actually be called. 1295 // Returns: true if glEnable/glDisable should actually be called.
1296 bool SetCapabilityState(GLenum cap, bool enabled); 1296 bool SetCapabilityState(GLenum cap, bool enabled);
1297 1297
1298 // Infer color encoding from internalformat
1299 static GLint GetColorEncodingFromInternalFormat(GLenum internalformat);
1300
1301 // Check that the currently bound read framebuffer's color image 1298 // Check that the currently bound read framebuffer's color image
1302 // isn't the target texture of the glCopyTex{Sub}Image{2D|3D}. 1299 // isn't the target texture of the glCopyTex{Sub}Image{2D|3D}.
1303 bool FormsTextureCopyingFeedbackLoop( 1300 bool FormsTextureCopyingFeedbackLoop(
1304 TextureRef* texture, 1301 TextureRef* texture,
1305 GLint level, 1302 GLint level,
1306 GLint layer); 1303 GLint layer);
1307 1304
1308 // Check if a framebuffer meets our requirements. 1305 // Check if a framebuffer meets our requirements.
1309 // Generates |gl_error| if the framebuffer is incomplete. 1306 // Generates |gl_error| if the framebuffer is incomplete.
1310 bool CheckFramebufferValid( 1307 bool CheckFramebufferValid(
(...skipping 3103 matching lines...) Expand 10 before | Expand all | Expand 10 after
4414 Framebuffer* draw_framebuffer = GetBoundDrawFramebuffer(); 4411 Framebuffer* draw_framebuffer = GetBoundDrawFramebuffer();
4415 bool valid = CheckFramebufferValid( 4412 bool valid = CheckFramebufferValid(
4416 draw_framebuffer, GetDrawFramebufferTarget(), gl_error, func_name); 4413 draw_framebuffer, GetDrawFramebufferTarget(), gl_error, func_name);
4417 4414
4418 Framebuffer* read_framebuffer = GetBoundReadFramebuffer(); 4415 Framebuffer* read_framebuffer = GetBoundReadFramebuffer();
4419 valid = valid && CheckFramebufferValid( 4416 valid = valid && CheckFramebufferValid(
4420 read_framebuffer, GetReadFramebufferTarget(), gl_error, func_name); 4417 read_framebuffer, GetReadFramebufferTarget(), gl_error, func_name);
4421 return valid; 4418 return valid;
4422 } 4419 }
4423 4420
4424 GLint GLES2DecoderImpl::GetColorEncodingFromInternalFormat(
4425 GLenum internalformat) {
4426 switch (internalformat) {
4427 case GL_SRGB_EXT:
4428 case GL_SRGB_ALPHA_EXT:
4429 case GL_SRGB8:
4430 case GL_SRGB8_ALPHA8:
4431 return GL_SRGB;
4432 default:
4433 return GL_LINEAR;
4434 }
4435 }
4436
4437 bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop( 4421 bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
4438 TextureRef* texture, GLint level, GLint layer) { 4422 TextureRef* texture, GLint level, GLint layer) {
4439 Framebuffer* framebuffer = GetBoundReadFramebuffer(); 4423 Framebuffer* framebuffer = GetBoundReadFramebuffer();
4440 if (!framebuffer) 4424 if (!framebuffer)
4441 return false; 4425 return false;
4442 const Framebuffer::Attachment* attachment = 4426 const Framebuffer::Attachment* attachment =
4443 framebuffer->GetReadBufferAttachment(); 4427 framebuffer->GetReadBufferAttachment();
4444 if (!attachment) 4428 if (!attachment)
4445 return false; 4429 return false;
4446 return attachment->FormsFeedbackLoop(texture, level, layer); 4430 return attachment->FormsFeedbackLoop(texture, level, layer);
(...skipping 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after
6227 tex->GetLevelType(target, tex->base_level(), &type, &internal_format)) { 6211 tex->GetLevelType(target, tex->base_level(), &type, &internal_format)) {
6228 format = TextureManager::ExtractFormatFromStorageFormat(internal_format); 6212 format = TextureManager::ExtractFormatFromStorageFormat(internal_format);
6229 glTexImage2D(target, 0, internal_format, 1, 1, 0, format, type, nullptr); 6213 glTexImage2D(target, 0, internal_format, 1, 1, 0, format, type, nullptr);
6230 texture_zero_level_set = true; 6214 texture_zero_level_set = true;
6231 } 6215 }
6232 } 6216 }
6233 6217
6234 bool enable_srgb = 0; 6218 bool enable_srgb = 0;
6235 if (target == GL_TEXTURE_2D) { 6219 if (target == GL_TEXTURE_2D) {
6236 tex->GetLevelType(target, tex->base_level(), &type, &internal_format); 6220 tex->GetLevelType(target, tex->base_level(), &type, &internal_format);
6237 enable_srgb = 6221 enable_srgb = GLES2Util::GetColorEncodingFromInternalFormat(
6238 GetColorEncodingFromInternalFormat(internal_format) == GL_SRGB; 6222 internal_format) == GL_SRGB;
6239 } 6223 }
6240 if (enable_srgb && feature_info_->feature_flags().desktop_srgb_support) { 6224 if (enable_srgb && feature_info_->feature_flags().desktop_srgb_support) {
6241 state_.EnableDisableFramebufferSRGB(enable_srgb); 6225 state_.EnableDisableFramebufferSRGB(enable_srgb);
6242 } 6226 }
6243 if (enable_srgb && workarounds().decode_encode_srgb_for_generatemipmap) { 6227 if (enable_srgb && workarounds().decode_encode_srgb_for_generatemipmap) {
6244 if (target == GL_TEXTURE_2D) { 6228 if (target == GL_TEXTURE_2D) {
6245 if (!InitializeSRGBConverter("generateMipmap")) { 6229 if (!InitializeSRGBConverter("generateMipmap")) {
6246 return; 6230 return;
6247 } 6231 }
6248 srgb_converter_->GenerateMipmap(this, tex, target); 6232 srgb_converter_->GenerateMipmap(this, tex, target);
(...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after
8048 } 8032 }
8049 } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) { 8033 } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) {
8050 is_feedback_loop = FeedbackLoopTrue; 8034 is_feedback_loop = FeedbackLoopTrue;
8051 } 8035 }
8052 } 8036 }
8053 } 8037 }
8054 8038
8055 GLenum src_internal_format = GetBoundReadFramebufferInternalFormat(); 8039 GLenum src_internal_format = GetBoundReadFramebufferInternalFormat();
8056 GLenum src_type = GetBoundReadFramebufferTextureType(); 8040 GLenum src_type = GetBoundReadFramebufferTextureType();
8057 8041
8058 bool read_buffer_has_srgb = 8042 bool read_buffer_has_srgb = GLES2Util::GetColorEncodingFromInternalFormat(
8059 GetColorEncodingFromInternalFormat(src_internal_format) == GL_SRGB; 8043 src_internal_format) == GL_SRGB;
8060 bool draw_buffers_has_srgb = false; 8044 bool draw_buffers_has_srgb = false;
8061 if ((mask & GL_COLOR_BUFFER_BIT) != 0) { 8045 if ((mask & GL_COLOR_BUFFER_BIT) != 0) {
8062 bool is_src_signed_int = 8046 bool is_src_signed_int =
8063 GLES2Util::IsSignedIntegerFormat(src_internal_format); 8047 GLES2Util::IsSignedIntegerFormat(src_internal_format);
8064 bool is_src_unsigned_int = 8048 bool is_src_unsigned_int =
8065 GLES2Util::IsUnsignedIntegerFormat(src_internal_format); 8049 GLES2Util::IsUnsignedIntegerFormat(src_internal_format);
8066 DCHECK(!is_src_signed_int || !is_src_unsigned_int); 8050 DCHECK(!is_src_signed_int || !is_src_unsigned_int);
8067 8051
8068 if ((is_src_signed_int || is_src_unsigned_int) && filter == GL_LINEAR) { 8052 if ((is_src_signed_int || is_src_unsigned_int) && filter == GL_LINEAR) {
8069 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 8053 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
(...skipping 11 matching lines...) Expand all
8081 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { 8065 for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) {
8082 GLenum dst_format = GetBoundColorDrawBufferInternalFormat( 8066 GLenum dst_format = GetBoundColorDrawBufferInternalFormat(
8083 static_cast<GLint>(ii)); 8067 static_cast<GLint>(ii));
8084 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); 8068 GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii));
8085 if (dst_format == 0) 8069 if (dst_format == 0)
8086 continue; 8070 continue;
8087 draw_buffer_has_image = true; 8071 draw_buffer_has_image = true;
8088 if (!src_internal_format) { 8072 if (!src_internal_format) {
8089 read_framebuffer_miss_image = true; 8073 read_framebuffer_miss_image = true;
8090 } 8074 }
8091 if (GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB) 8075 if (GLES2Util::GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB)
8092 draw_buffers_has_srgb = true; 8076 draw_buffers_has_srgb = true;
8093 if (read_buffer_samples > 0 && 8077 if (read_buffer_samples > 0 &&
8094 (src_sized_format != 8078 (src_sized_format !=
8095 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) { 8079 GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) {
8096 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, 8080 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
8097 "src and dst formats differ for color"); 8081 "src and dst formats differ for color");
8098 return; 8082 return;
8099 } 8083 }
8100 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format); 8084 bool is_dst_signed_int = GLES2Util::IsSignedIntegerFormat(dst_format);
8101 bool is_dst_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(dst_format); 8085 bool is_dst_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(dst_format);
(...skipping 5859 matching lines...) Expand 10 before | Expand all | Expand 10 after
13961 } 13945 }
13962 // Check we have compatible formats. 13946 // Check we have compatible formats.
13963 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format); 13947 uint32_t channels_exist = GLES2Util::GetChannelsForFormat(read_format);
13964 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format); 13948 uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
13965 if (!channels_needed || 13949 if (!channels_needed ||
13966 (channels_needed & channels_exist) != channels_needed) { 13950 (channels_needed & channels_exist) != channels_needed) {
13967 *output_error_msg = std::string("incompatible format"); 13951 *output_error_msg = std::string("incompatible format");
13968 return false; 13952 return false;
13969 } 13953 }
13970 if (feature_info_->IsWebGL2OrES3Context()) { 13954 if (feature_info_->IsWebGL2OrES3Context()) {
13971 GLint color_encoding = GetColorEncodingFromInternalFormat(read_format); 13955 GLint color_encoding =
13956 GLES2Util::GetColorEncodingFromInternalFormat(read_format);
13972 bool float_mismatch = feature_info_->ext_color_buffer_float_available() ? 13957 bool float_mismatch = feature_info_->ext_color_buffer_float_available() ?
13973 (GLES2Util::IsIntegerFormat(internal_format) != 13958 (GLES2Util::IsIntegerFormat(internal_format) !=
13974 GLES2Util::IsIntegerFormat(read_format)) : 13959 GLES2Util::IsIntegerFormat(read_format)) :
13975 GLES2Util::IsFloatFormat(internal_format); 13960 GLES2Util::IsFloatFormat(internal_format);
13976 if (color_encoding != GetColorEncodingFromInternalFormat(internal_format) || 13961 if (color_encoding !=
13977 float_mismatch || 13962 GLES2Util::GetColorEncodingFromInternalFormat(internal_format) ||
13978 (GLES2Util::IsSignedIntegerFormat(internal_format) != 13963 float_mismatch || (GLES2Util::IsSignedIntegerFormat(internal_format) !=
13979 GLES2Util::IsSignedIntegerFormat(read_format)) || 13964 GLES2Util::IsSignedIntegerFormat(read_format)) ||
13980 (GLES2Util::IsUnsignedIntegerFormat(internal_format) != 13965 (GLES2Util::IsUnsignedIntegerFormat(internal_format) !=
13981 GLES2Util::IsUnsignedIntegerFormat(read_format))) { 13966 GLES2Util::IsUnsignedIntegerFormat(read_format))) {
13982 *output_error_msg = std::string("incompatible format"); 13967 *output_error_msg = std::string("incompatible format");
13983 return false; 13968 return false;
13984 } 13969 }
13985 } 13970 }
13986 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 13971 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
13987 *output_error_msg = 13972 *output_error_msg =
13988 std::string("can not be used with depth or stencil textures"); 13973 std::string("can not be used with depth or stencil textures");
13989 return false; 13974 return false;
(...skipping 2478 matching lines...) Expand 10 before | Expand all | Expand 10 after
16468 // crbug.com/678526. Once the bug is fixed, the limitation for WebGL 2.0 and 16453 // crbug.com/678526. Once the bug is fixed, the limitation for WebGL 2.0 and
16469 // OpenGL ES 3.0 can be lifted. 16454 // OpenGL ES 3.0 can be lifted.
16470 if (((dest_level > 0 || dest_binding_target == GL_TEXTURE_CUBE_MAP) && 16455 if (((dest_level > 0 || dest_binding_target == GL_TEXTURE_CUBE_MAP) &&
16471 method == DIRECT_DRAW) || 16456 method == DIRECT_DRAW) ||
16472 (source_level > 0 && method == DIRECT_COPY)) { 16457 (source_level > 0 && method == DIRECT_COPY)) {
16473 method = DRAW_AND_COPY; 16458 method = DRAW_AND_COPY;
16474 } 16459 }
16475 16460
16476 if (feature_info_->feature_flags().desktop_srgb_support) { 16461 if (feature_info_->feature_flags().desktop_srgb_support) {
16477 bool enable_framebuffer_srgb = 16462 bool enable_framebuffer_srgb =
16478 GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB || 16463 GLES2Util::GetColorEncodingFromInternalFormat(source_internal_format) ==
16479 GetColorEncodingFromInternalFormat(internal_format) == GL_SRGB; 16464 GL_SRGB ||
16465 GLES2Util::GetColorEncodingFromInternalFormat(internal_format) ==
16466 GL_SRGB;
16480 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb); 16467 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
16481 } 16468 }
16482 16469
16483 int source_width = 0; 16470 int source_width = 0;
16484 int source_height = 0; 16471 int source_height = 0;
16485 gl::GLImage* image = 16472 gl::GLImage* image =
16486 source_texture->GetLevelImage(source_target, source_level); 16473 source_texture->GetLevelImage(source_target, source_level);
16487 if (image) { 16474 if (image) {
16488 gfx::Size size = image->GetSize(); 16475 gfx::Size size = image->GetSize();
16489 source_width = size.width(); 16476 source_width = size.width();
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
16715 } 16702 }
16716 16703
16717 CopyTextureMethod method = ValidateCopyTextureCHROMIUMInternalFormats( 16704 CopyTextureMethod method = ValidateCopyTextureCHROMIUMInternalFormats(
16718 kFunctionName, source_texture_ref, source_level, dest_internal_format); 16705 kFunctionName, source_texture_ref, source_level, dest_internal_format);
16719 // INVALID_OPERATION is already generated by 16706 // INVALID_OPERATION is already generated by
16720 // ValidateCopyTextureCHROMIUMInternalFormats. 16707 // ValidateCopyTextureCHROMIUMInternalFormats.
16721 if (method == NOT_COPYABLE) { 16708 if (method == NOT_COPYABLE) {
16722 return; 16709 return;
16723 } 16710 }
16724 16711
16712 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
16713 // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver,
16714 // although opposite in Android.
16715 // TODO(dshwang): After Mesa fixes this issue, remove this hack.
16716 // https://bugs.freedesktop.org/show_bug.cgi?id=98478, crbug.com/535198.
16717 if (Texture::ColorRenderable(GetFeatureInfo(), dest_internal_format,
16718 dest_texture->IsImmutable()) &&
16719 method == DIRECT_COPY) {
16720 method = DIRECT_DRAW;
16721 }
16722 #endif
16723
16725 // Draw to a fbo attaching level 0 of an intermediate texture, 16724 // Draw to a fbo attaching level 0 of an intermediate texture,
16726 // then copy from the fbo to dest texture level with glCopyTexImage2D. 16725 // then copy from the fbo to dest texture level with glCopyTexImage2D.
16727 // For WebGL 1.0 or OpenGL ES 2.0, DIRECT_DRAW path isn't available for 16726 // For WebGL 1.0 or OpenGL ES 2.0, DIRECT_DRAW path isn't available for
16728 // dest_level > 0 due to level > 0 isn't supported by glFramebufferTexture2D 16727 // dest_level > 0 due to level > 0 isn't supported by glFramebufferTexture2D
16729 // in ES2 context. DIRECT_DRAW path isn't available for cube map dest texture 16728 // in ES2 context. DIRECT_DRAW path isn't available for cube map dest texture
16730 // either due to it may be cube map incomplete. Go to DRAW_AND_COPY path in 16729 // either due to it may be cube map incomplete. Go to DRAW_AND_COPY path in
16731 // these cases. 16730 // these cases.
16732 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both 16731 // TODO(qiankun.miao@intel.com): for WebGL 2.0 or OpenGL ES 3.0, both
16733 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level > 16732 // DIRECT_DRAW path for dest_level > 0 and DIRECT_COPY path for source_level >
16734 // 0 are not available due to a framebuffer completeness bug: 16733 // 0 are not available due to a framebuffer completeness bug:
16735 // crbug.com/678526. Once the bug is fixed, the limitation for WebGL 2.0 and 16734 // crbug.com/678526. Once the bug is fixed, the limitation for WebGL 2.0 and
16736 // OpenGL ES 3.0 can be lifted. 16735 // OpenGL ES 3.0 can be lifted.
16737 if (((dest_level > 0 || dest_binding_target == GL_TEXTURE_CUBE_MAP) && 16736 if (((dest_level > 0 || dest_binding_target == GL_TEXTURE_CUBE_MAP) &&
16738 method == DIRECT_DRAW) || 16737 method == DIRECT_DRAW) ||
16739 (source_level > 0 && method == DIRECT_COPY)) { 16738 (source_level > 0 && method == DIRECT_COPY)) {
16740 method = DRAW_AND_COPY; 16739 method = DRAW_AND_COPY;
16741 } 16740 }
16742 16741
16743 if (feature_info_->feature_flags().desktop_srgb_support) { 16742 if (feature_info_->feature_flags().desktop_srgb_support) {
16744 bool enable_framebuffer_srgb = 16743 bool enable_framebuffer_srgb =
16745 GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB || 16744 GLES2Util::GetColorEncodingFromInternalFormat(source_internal_format) ==
16746 GetColorEncodingFromInternalFormat(dest_internal_format) == GL_SRGB; 16745 GL_SRGB ||
16746 GLES2Util::GetColorEncodingFromInternalFormat(dest_internal_format) ==
16747 GL_SRGB;
16747 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb); 16748 state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
16748 } 16749 }
16749 16750
16750 // Clear the source texture if necessary. 16751 // Clear the source texture if necessary.
16751 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, 16752 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
16752 source_target, source_level)) { 16753 source_target, source_level)) {
16753 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, 16754 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName,
16754 "source texture dimensions too big"); 16755 "source texture dimensions too big");
16755 return; 16756 return;
16756 } 16757 }
(...skipping 2493 matching lines...) Expand 10 before | Expand all | Expand 10 after
19250 } 19251 }
19251 19252
19252 // Include the auto-generated part of this file. We split this because it means 19253 // Include the auto-generated part of this file. We split this because it means
19253 // we can easily edit the non-auto generated parts right here in this file 19254 // we can easily edit the non-auto generated parts right here in this file
19254 // instead of having to edit some template or the code generator. 19255 // instead of having to edit some template or the code generator.
19255 #include "base/macros.h" 19256 #include "base/macros.h"
19256 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 19257 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
19257 19258
19258 } // namespace gles2 19259 } // namespace gles2
19259 } // namespace gpu 19260 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698