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 <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 Loading... | |
| 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 Loading... | |
| 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 // The service id and target of the destination texture. | |
| 11667 GLuint dest_texture_service_id = texture->service_id(); | |
| 11668 GLenum dest_texture_target = target; | |
| 11669 | |
| 11670 // Copy from the read framebuffer into |temp_texture|. | |
| 11671 GLuint temp_texture; | |
| 11672 GLenum temp_internal_format = 0; | |
| 11673 if (channels_exist == GLES2Util::kRGBA) { | |
| 11674 temp_internal_format = GL_RGBA; | |
| 11675 } else if (channels_exist == GLES2Util::kRGB) { | |
| 11676 temp_internal_format = GL_RGB; | |
| 11677 } else { | |
| 11678 NOTREACHED(); | |
| 11679 } | |
| 11680 glGenTextures(1, &temp_texture); | |
| 11681 glBindTexture(source_texture_target, temp_texture); | |
| 11682 glCopyTexImage2D(source_texture_target, 0, temp_internal_format, copyX, | |
|
Ken Russell (switch to Gerrit)
2016/03/15 21:11:23
Is there any chance that source_texture_target wil
erikchen
2016/03/15 22:25:53
Ooof. This is what I get for not using ScopedTextu
| |
| 11683 copyY, copyWidth, copyHeight, border); | |
| 11684 | |
| 11685 // Attach the temp texture. | |
| 11686 GLenum framebuffer_target = features().chromium_framebuffer_multisample | |
| 11687 ? GL_READ_FRAMEBUFFER_EXT | |
| 11688 : GL_FRAMEBUFFER; | |
| 11689 glFramebufferTexture2DEXT(framebuffer_target, GL_COLOR_ATTACHMENT0, | |
| 11690 source_texture_target, temp_texture, 0); | |
| 11691 | |
| 11692 // Copy to the final texture. | |
| 11693 glBindTexture(dest_texture_target, dest_texture_service_id); | |
| 11694 DCHECK_EQ(static_cast<GLuint>(GL_TEXTURE_2D), target); | |
| 11695 glCopyTexImage2D(target, level, final_internal_format, 0, 0, copyWidth, | |
|
Ken Russell (switch to Gerrit)
2016/03/15 21:11:23
This uses "target" while the glBindTexture call us
erikchen
2016/03/15 22:25:53
I switched both to use dest_texture_target. Actual
| |
| 11696 copyHeight, 0); | |
| 11697 | |
| 11698 // Rebind source texture. | |
| 11699 glFramebufferTexture2DEXT(framebuffer_target, GL_COLOR_ATTACHMENT0, | |
| 11700 source_texture_target, | |
| 11701 source_texture_service_id, 0); | |
| 11702 | |
| 11703 glDeleteTextures(1, &temp_texture); | |
| 11704 } else { | |
| 11705 glCopyTexImage2D(target, level, final_internal_format, copyX, copyY, | |
| 11706 copyWidth, copyHeight, border); | |
| 11707 } | |
| 11650 } | 11708 } |
| 11651 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); | 11709 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); |
| 11652 if (error == GL_NO_ERROR) { | 11710 if (error == GL_NO_ERROR) { |
| 11653 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, | 11711 texture_manager()->SetLevelInfo(texture_ref, target, level, internal_format, |
| 11654 width, height, 1, border, format, | 11712 width, height, 1, border, format, |
| 11655 type, gfx::Rect(width, height)); | 11713 type, gfx::Rect(width, height)); |
| 11656 texture->ApplyFormatWorkarounds(feature_info_.get()); | 11714 texture->ApplyFormatWorkarounds(feature_info_.get()); |
| 11657 } | 11715 } |
| 11658 | 11716 |
| 11659 // This may be a slow command. Exit command processing to allow for | 11717 // This may be a slow command. Exit command processing to allow for |
| (...skipping 4311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15971 return sampler->sampler_state(); | 16029 return sampler->sampler_state(); |
| 15972 } | 16030 } |
| 15973 TextureUnit& texture_unit = state_.texture_units[unit]; | 16031 TextureUnit& texture_unit = state_.texture_units[unit]; |
| 15974 TextureRef* texture_ref = texture_unit.GetInfoForSamplerType(target).get(); | 16032 TextureRef* texture_ref = texture_unit.GetInfoForSamplerType(target).get(); |
| 15975 if (texture_ref) | 16033 if (texture_ref) |
| 15976 return texture_ref->texture()->sampler_state(); | 16034 return texture_ref->texture()->sampler_state(); |
| 15977 | 16035 |
| 15978 return default_sampler_state_; | 16036 return default_sampler_state_; |
| 15979 } | 16037 } |
| 15980 | 16038 |
| 16039 bool GLES2DecoderImpl::NeedsCopyTextureImageWorkaround( | |
| 16040 GLenum internal_format, | |
| 16041 int32_t channels_exist, | |
| 16042 GLuint* source_texture_service_id, | |
| 16043 GLenum* source_texture_target) { | |
| 16044 // On some OSX devices, copyTexImage2D will fail if all of these conditions | |
| 16045 // are met: | |
| 16046 // 1. The internal format of the new texture is not GL_RGB or GL_RGBA. | |
| 16047 // 2. The image of the read FBO is backed by an IOSurface. | |
| 16048 // See https://crbug.com/581777#c4 for more details. | |
| 16049 if (!workarounds().use_intermediary_for_copy_texture_image) | |
| 16050 return false; | |
| 16051 | |
| 16052 if (internal_format == GL_RGB || internal_format == GL_RGBA) | |
| 16053 return false; | |
| 16054 | |
| 16055 GLenum framebuffer_target = features().chromium_framebuffer_multisample | |
| 16056 ? GL_READ_FRAMEBUFFER_EXT | |
| 16057 : GL_FRAMEBUFFER; | |
| 16058 Framebuffer* framebuffer = | |
| 16059 GetFramebufferInfoForTarget(framebuffer_target); | |
| 16060 if (!framebuffer) | |
| 16061 return false; | |
| 16062 | |
| 16063 const Framebuffer::Attachment* attachment = | |
| 16064 framebuffer->GetReadBufferAttachment(); | |
| 16065 if (!attachment) | |
| 16066 return false; | |
| 16067 | |
| 16068 if (!attachment->IsTextureAttachment()) | |
| 16069 return false; | |
| 16070 | |
| 16071 TextureRef* texture = | |
| 16072 texture_manager()->GetTexture(attachment->object_name()); | |
| 16073 if (!texture->texture()->HasImages()) | |
| 16074 return false; | |
| 16075 | |
| 16076 // The workaround only works if the source texture consists of the channels | |
| 16077 // kRGB or kRGBA. | |
| 16078 if (channels_exist != GLES2Util::kRGBA && channels_exist != GLES2Util::kRGB) | |
| 16079 return false; | |
| 16080 | |
| 16081 *source_texture_target = texture->texture()->target(); | |
| 16082 *source_texture_service_id = texture->service_id(); | |
| 16083 return true; | |
| 16084 } | |
| 16085 | |
| 15981 error::Error GLES2DecoderImpl::HandleBindFragmentInputLocationCHROMIUMBucket( | 16086 error::Error GLES2DecoderImpl::HandleBindFragmentInputLocationCHROMIUMBucket( |
| 15982 uint32_t immediate_data_size, | 16087 uint32_t immediate_data_size, |
| 15983 const void* cmd_data) { | 16088 const void* cmd_data) { |
| 15984 const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket& c = | 16089 const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket& c = |
| 15985 *static_cast<const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket*>( | 16090 *static_cast<const gles2::cmds::BindFragmentInputLocationCHROMIUMBucket*>( |
| 15986 cmd_data); | 16091 cmd_data); |
| 15987 if (!features().chromium_path_rendering) { | 16092 if (!features().chromium_path_rendering) { |
| 15988 return error::kUnknownCommand; | 16093 return error::kUnknownCommand; |
| 15989 } | 16094 } |
| 15990 | 16095 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16134 } | 16239 } |
| 16135 | 16240 |
| 16136 // Include the auto-generated part of this file. We split this because it means | 16241 // 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 | 16242 // 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. | 16243 // instead of having to edit some template or the code generator. |
| 16139 #include "base/macros.h" | 16244 #include "base/macros.h" |
| 16140 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 16245 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 16141 | 16246 |
| 16142 } // namespace gles2 | 16247 } // namespace gles2 |
| 16143 } // namespace gpu | 16248 } // namespace gpu |
| OLD | NEW |