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

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

Issue 1736093002: Add a workaround for copyTexImage2D as it is sometimes broken on OSX. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Compile error, nits. Created 4 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 <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 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 void DoBindFragmentInputLocationCHROMIUM(GLuint program_id, 1898 void DoBindFragmentInputLocationCHROMIUM(GLuint program_id,
1899 GLint location, 1899 GLint location,
1900 const std::string& name); 1900 const std::string& name);
1901 1901
1902 // If |texture_manager_version_| doesn't match the current version, then this 1902 // If |texture_manager_version_| doesn't match the current version, then this
1903 // will rebind all external textures to match their current service_id. 1903 // will rebind all external textures to match their current service_id.
1904 void RestoreAllExternalTextureBindingsIfNeeded() override; 1904 void RestoreAllExternalTextureBindingsIfNeeded() override;
1905 1905
1906 const SamplerState& GetSamplerStateForTextureUnit(GLenum target, GLuint unit); 1906 const SamplerState& GetSamplerStateForTextureUnit(GLenum target, GLuint unit);
1907 1907
1908 // copyTexImage2D doesn't work on OSX under very specific conditions.
1909 // Returns whether those conditions have been met. If this method returns
1910 // true, |source_texture_service_id| and |source_texture_target| are also
1911 // populated, since they are needed to implement the workaround.
1912 bool NeedsCopyTextureImageWorkaround(GLenum internal_format,
1913 int32_t channels_exist,
1914 GLuint* source_texture_service_id,
1915 GLenum* source_texture_target);
1916
1908 // Generate a member function prototype for each command in an automated and 1917 // Generate a member function prototype for each command in an automated and
1909 // typesafe way. 1918 // typesafe way.
1910 #define GLES2_CMD_OP(name) \ 1919 #define GLES2_CMD_OP(name) \
1911 Error Handle##name(uint32_t immediate_data_size, const void* data); 1920 Error Handle##name(uint32_t immediate_data_size, const void* data);
1912 1921
1913 GLES2_COMMAND_LIST(GLES2_CMD_OP) 1922 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1914 1923
1915 #undef GLES2_CMD_OP 1924 #undef GLES2_CMD_OP
1916 1925
1917 // The GL context this decoder renders to on behalf of the client. 1926 // The GL context this decoder renders to on behalf of the client.
(...skipping 9719 matching lines...) Expand 10 before | Expand all | Expand 10 after
11637 if (copyHeight > 0 && copyWidth > 0) { 11646 if (copyHeight > 0 && copyWidth > 0) {
11638 GLint dx = copyX - x; 11647 GLint dx = copyX - x;
11639 GLint dy = copyY - y; 11648 GLint dy = copyY - y;
11640 GLint destX = dx; 11649 GLint destX = dx;
11641 GLint destY = dy; 11650 GLint destY = dy;
11642 glCopyTexSubImage2D(target, level, 11651 glCopyTexSubImage2D(target, level,
11643 destX, destY, copyX, copyY, 11652 destX, destY, copyX, copyY,
11644 copyWidth, copyHeight); 11653 copyWidth, copyHeight);
11645 } 11654 }
11646 } else { 11655 } else {
11647 glCopyTexImage2D(target, level, texture_manager()->AdjustTexInternalFormat( 11656 GLenum final_internal_format =
11648 internal_format), 11657 texture_manager()->AdjustTexInternalFormat(internal_format);
11649 copyX, copyY, copyWidth, copyHeight, border); 11658
11659 // The service id and target of the texture attached to READ_FRAMEBUFFER.
11660 GLuint source_texture_service_id = 0;
11661 GLenum source_texture_target = 0;
11662 bool use_workaround = NeedsCopyTextureImageWorkaround(
11663 final_internal_format, channels_exist, &source_texture_service_id,
11664 &source_texture_target);
11665 if (use_workaround) {
11666 GLenum dest_texture_target = target;
11667 GLenum framebuffer_target = features().chromium_framebuffer_multisample
11668 ? GL_READ_FRAMEBUFFER_EXT
11669 : GL_FRAMEBUFFER;
11670
11671 GLenum temp_internal_format = 0;
11672 if (channels_exist == GLES2Util::kRGBA) {
11673 temp_internal_format = GL_RGBA;
11674 } else if (channels_exist == GLES2Util::kRGB) {
11675 temp_internal_format = GL_RGB;
11676 } else {
11677 NOTREACHED();
11678 }
11679
11680 GLuint temp_texture;
11681 {
11682 // Copy from the read framebuffer into |temp_texture|.
11683 glGenTextures(1, &temp_texture);
11684 ScopedTextureBinder binder(&state_, temp_texture,
11685 source_texture_target);
11686 glCopyTexImage2D(source_texture_target, 0, temp_internal_format, copyX,
11687 copyY, copyWidth, copyHeight, border);
11688
11689 // Attach the temp texture to the read framebuffer.
11690 glFramebufferTexture2DEXT(framebuffer_target, GL_COLOR_ATTACHMENT0,
11691 source_texture_target, temp_texture, 0);
11692 }
11693
11694 // Copy to the final texture.
11695 DCHECK_EQ(static_cast<GLuint>(GL_TEXTURE_2D), dest_texture_target);
11696 glCopyTexImage2D(dest_texture_target, level, final_internal_format, 0, 0,
11697 copyWidth, copyHeight, 0);
11698
11699 // Rebind source texture.
11700 glFramebufferTexture2DEXT(framebuffer_target, GL_COLOR_ATTACHMENT0,
11701 source_texture_target,
11702 source_texture_service_id, 0);
11703
11704 glDeleteTextures(1, &temp_texture);
11705 } else {
11706 glCopyTexImage2D(target, level, final_internal_format, copyX, copyY,
11707 copyWidth, copyHeight, border);
11708 }
11650 } 11709 }
11651 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); 11710 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
11652 if (error == GL_NO_ERROR) { 11711 if (error == GL_NO_ERROR) {
11653 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, 11712 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format,
11654 width, height, 1, border, format, 11713 width, height, 1, border, format,
11655 type, gfx::Rect(width, height)); 11714 type, gfx::Rect(width, height));
11656 texture->ApplyFormatWorkarounds(feature_info_.get()); 11715 texture->ApplyFormatWorkarounds(feature_info_.get());
11657 } 11716 }
11658 11717
11659 // This may be a slow command. Exit command processing to allow for 11718 // This may be a slow command. Exit command processing to allow for
(...skipping 4311 matching lines...) Expand 10 before | Expand all | Expand 10 after
15971 return sampler->sampler_state(); 16030 return sampler->sampler_state();
15972 } 16031 }
15973 TextureUnit& texture_unit = state_.texture_units[unit]; 16032 TextureUnit& texture_unit = state_.texture_units[unit];
15974 TextureRef* texture_ref = texture_unit.GetInfoForSamplerType(target).get(); 16033 TextureRef* texture_ref = texture_unit.GetInfoForSamplerType(target).get();
15975 if (texture_ref) 16034 if (texture_ref)
15976 return texture_ref->texture()->sampler_state(); 16035 return texture_ref->texture()->sampler_state();
15977 16036
15978 return default_sampler_state_; 16037 return default_sampler_state_;
15979 } 16038 }
15980 16039
16040 bool GLES2DecoderImpl::NeedsCopyTextureImageWorkaround(
16041 GLenum internal_format,
16042 int32_t channels_exist,
16043 GLuint* source_texture_service_id,
16044 GLenum* source_texture_target) {
16045 // On some OSX devices, copyTexImage2D will fail if all of these conditions
16046 // are met:
16047 // 1. The internal format of the new texture is not GL_RGB or GL_RGBA.
16048 // 2. The image of the read FBO is backed by an IOSurface.
16049 // See https://crbug.com/581777#c4 for more details.
16050 if (!workarounds().use_intermediary_for_copy_texture_image)
16051 return false;
16052
16053 if (internal_format == GL_RGB || internal_format == GL_RGBA)
16054 return false;
16055
16056 GLenum framebuffer_target = features().chromium_framebuffer_multisample
16057 ? GL_READ_FRAMEBUFFER_EXT
16058 : GL_FRAMEBUFFER;
16059 Framebuffer* framebuffer =
16060 GetFramebufferInfoForTarget(framebuffer_target);
16061 if (!framebuffer)
16062 return false;
16063
16064 const Framebuffer::Attachment* attachment =
16065 framebuffer->GetReadBufferAttachment();
16066 if (!attachment)
16067 return false;
16068
16069 if (!attachment->IsTextureAttachment())
16070 return false;
16071
16072 TextureRef* texture =
16073 texture_manager()->GetTexture(attachment->object_name());
16074 if (!texture->texture()->HasImages())
16075 return false;
16076
16077 // The workaround only works if the source texture consists of the channels
16078 // kRGB or kRGBA.
16079 if (channels_exist != GLES2Util::kRGBA && channels_exist != GLES2Util::kRGB)
16080 return false;
16081
16082 *source_texture_target = texture->texture()->target();
16083 *source_texture_service_id = texture->service_id();
16084 return true;
16085 }
16086
15981 error::Error GLES2DecoderImpl::HandleBindFragmentInputLocationCHROMIUMBucket( 16087 error::Error GLES2DecoderImpl::HandleBindFragmentInputLocationCHROMIUMBucket(
15982 uint32_t immediate_data_size, 16088 uint32_t immediate_data_size,
15983 const void* cmd_data) { 16089 const void* cmd_data) {
15984 const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket& c = 16090 const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket& c =
15985 *static_cast<const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket*>( 16091 *static_cast<const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket*>(
15986 cmd_data); 16092 cmd_data);
15987 if (!features().chromium_path_rendering) { 16093 if (!features().chromium_path_rendering) {
15988 return error::kUnknownCommand; 16094 return error::kUnknownCommand;
15989 } 16095 }
15990 16096
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
16134 } 16240 }
16135 16241
16136 // Include the auto-generated part of this file. We split this because it means 16242 // Include the auto-generated part of this file. We split this because it means
16137 // we can easily edit the non-auto generated parts right here in this file 16243 // we can easily edit the non-auto generated parts right here in this file
16138 // instead of having to edit some template or the code generator. 16244 // instead of having to edit some template or the code generator.
16139 #include "base/macros.h" 16245 #include "base/macros.h"
16140 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 16246 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
16141 16247
16142 } // namespace gles2 16248 } // namespace gles2
16143 } // namespace gpu 16249 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698