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 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 GLsizei width, | 957 GLsizei width, |
958 GLsizei height, | 958 GLsizei height, |
959 GLboolean unpack_flip_y, | 959 GLboolean unpack_flip_y, |
960 GLboolean unpack_premultiply_alpha, | 960 GLboolean unpack_premultiply_alpha, |
961 GLboolean unpack_unmultiply_alpha); | 961 GLboolean unpack_unmultiply_alpha); |
962 | 962 |
963 void DoCompressedCopyTextureCHROMIUM(GLenum target, | 963 void DoCompressedCopyTextureCHROMIUM(GLenum target, |
964 GLuint source_id, | 964 GLuint source_id, |
965 GLuint dest_id); | 965 GLuint dest_id); |
966 | 966 |
967 void DoCompressedCopySubTextureCHROMIUM(GLenum target, | |
968 GLuint source_id, | |
969 GLuint dest_id, | |
970 GLint xoffset, | |
971 GLint yoffset, | |
972 GLint x, | |
973 GLint y, | |
974 GLsizei width, | |
975 GLsizei height); | |
976 | |
977 // Wrapper for TexStorage2DEXT. | 967 // Wrapper for TexStorage2DEXT. |
978 void DoTexStorage2DEXT( | 968 void DoTexStorage2DEXT( |
979 GLenum target, | 969 GLenum target, |
980 GLint levels, | 970 GLint levels, |
981 GLenum internal_format, | 971 GLenum internal_format, |
982 GLsizei width, | 972 GLsizei width, |
983 GLsizei height); | 973 GLsizei height); |
984 | 974 |
985 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); | 975 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); |
986 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, | 976 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, |
(...skipping 12702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13689 source_height, false, false, false, kIdentityMatrix); | 13679 source_height, false, false, false, kIdentityMatrix); |
13690 } else { | 13680 } else { |
13691 copy_texture_CHROMIUM_->DoCopyTexture( | 13681 copy_texture_CHROMIUM_->DoCopyTexture( |
13692 this, source_texture->target(), source_texture->service_id(), | 13682 this, source_texture->target(), source_texture->service_id(), |
13693 source_internal_format, dest_texture->target(), | 13683 source_internal_format, dest_texture->target(), |
13694 dest_texture->service_id(), GL_RGBA, source_width, source_height, false, | 13684 dest_texture->service_id(), GL_RGBA, source_width, source_height, false, |
13695 false, false); | 13685 false, false); |
13696 } | 13686 } |
13697 } | 13687 } |
13698 | 13688 |
13699 void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target, | |
13700 GLuint source_id, | |
13701 GLuint dest_id, | |
13702 GLint xoffset, | |
13703 GLint yoffset, | |
13704 GLint x, | |
13705 GLint y, | |
13706 GLsizei width, | |
13707 GLsizei height) { | |
13708 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM"); | |
13709 | |
13710 TextureRef* source_texture_ref = GetTexture(source_id); | |
13711 TextureRef* dest_texture_ref = GetTexture(dest_id); | |
13712 | |
13713 if (!source_texture_ref || !dest_texture_ref) { | |
13714 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", | |
13715 "unknown texture ids"); | |
13716 return; | |
13717 } | |
13718 | |
13719 Texture* source_texture = source_texture_ref->texture(); | |
13720 Texture* dest_texture = dest_texture_ref->texture(); | |
13721 int source_width = 0; | |
13722 int source_height = 0; | |
13723 gl::GLImage* image = | |
13724 source_texture->GetLevelImage(source_texture->target(), 0); | |
13725 if (image) { | |
13726 gfx::Size size = image->GetSize(); | |
13727 source_width = size.width(); | |
13728 source_height = size.height(); | |
13729 if (source_width <= 0 || source_height <= 0) { | |
13730 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", | |
13731 "invalid image size"); | |
13732 return; | |
13733 } | |
13734 } else { | |
13735 if (!source_texture->GetLevelSize(source_texture->target(), 0, | |
13736 &source_width, &source_height, nullptr)) { | |
13737 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", | |
13738 "source texture has no level 0"); | |
13739 return; | |
13740 } | |
13741 | |
13742 // Check that this type of texture is allowed. | |
13743 if (!texture_manager()->ValidForTarget(source_texture->target(), 0, | |
13744 source_width, source_height, 1)) { | |
13745 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", | |
13746 "source texture bad dimensions"); | |
13747 return; | |
13748 } | |
13749 } | |
13750 | |
13751 GLenum source_type = 0; | |
13752 GLenum source_internal_format = 0; | |
13753 source_texture->GetLevelType(source_texture->target(), 0, &source_type, | |
13754 &source_internal_format); | |
13755 if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0, | |
13756 width, height, 1)) { | |
13757 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", | |
13758 "source texture bad dimensions."); | |
13759 return; | |
13760 } | |
13761 | |
13762 GLenum dest_type = 0; | |
13763 GLenum dest_internal_format = 0; | |
13764 bool dest_level_defined = dest_texture->GetLevelType( | |
13765 dest_texture->target(), 0, &dest_type, &dest_internal_format); | |
13766 if (!dest_level_defined) { | |
13767 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, | |
13768 "glCompressedCopySubTextureCHROMIUM", | |
13769 "destination texture is not defined"); | |
13770 return; | |
13771 } | |
13772 if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset, | |
13773 yoffset, 0, width, height, 1)) { | |
13774 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", | |
13775 "destination texture bad dimensions."); | |
13776 return; | |
13777 } | |
13778 | |
13779 if (!ValidateCompressedCopyTextureCHROMIUM( | |
13780 "glCompressedCopySubTextureCHROMIUM", target, source_texture_ref, | |
13781 dest_texture_ref)) { | |
13782 return; | |
13783 } | |
13784 | |
13785 if (!ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM", | |
13786 source_texture->target(), 0, x, y, 0, | |
13787 width, height, 1, | |
13788 source_internal_format, | |
13789 source_texture) || | |
13790 !ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM", | |
13791 dest_texture->target(), 0, | |
13792 xoffset, yoffset, 0, width, height, 1, | |
13793 dest_internal_format, | |
13794 dest_texture)) { | |
13795 return; | |
13796 } | |
13797 | |
13798 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is | |
13799 // needed because it takes 10s of milliseconds to initialize. | |
13800 if (!copy_texture_CHROMIUM_.get()) { | |
13801 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopySubTextureCHROMIUM"); | |
13802 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); | |
13803 copy_texture_CHROMIUM_->Initialize(this); | |
13804 RestoreCurrentFramebufferBindings(); | |
13805 if (LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM") != | |
13806 GL_NO_ERROR) { | |
13807 return; | |
13808 } | |
13809 } | |
13810 | |
13811 // Clear the source texture if necessary. | |
13812 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, | |
13813 source_texture->target(), 0)) { | |
13814 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCompressedCopySubTextureCHROMIUM", | |
13815 "source texture dimensions too big"); | |
13816 return; | |
13817 } | |
13818 | |
13819 int dest_width = 0; | |
13820 int dest_height = 0; | |
13821 bool ok = dest_texture->GetLevelSize( | |
13822 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); | |
13823 DCHECK(ok); | |
13824 if (xoffset != 0 || yoffset != 0 || width != dest_width || | |
13825 height != dest_height) { | |
13826 gfx::Rect cleared_rect; | |
13827 if (TextureManager::CombineAdjacentRects( | |
13828 dest_texture->GetLevelClearedRect(target, 0), | |
13829 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) { | |
13830 DCHECK_GE(cleared_rect.size().GetArea(), | |
13831 dest_texture->GetLevelClearedRect(target, 0).size().GetArea()); | |
13832 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0, | |
13833 cleared_rect); | |
13834 } else { | |
13835 // Otherwise clear part of texture level that is not already cleared. | |
13836 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, | |
13837 0)) { | |
13838 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, | |
13839 "glCompressedCopySubTextureCHROMIUM", | |
13840 "destination texture dimensions too big"); | |
13841 return; | |
13842 } | |
13843 } | |
13844 } else { | |
13845 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, | |
13846 true); | |
13847 } | |
13848 | |
13849 ScopedTextureBinder binder( | |
13850 &state_, dest_texture->service_id(), GL_TEXTURE_2D); | |
13851 | |
13852 // Try using GLImage::CopyTexSubImage when possible. | |
13853 if (image && | |
13854 image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset), | |
13855 gfx::Rect(x, y, width, height))) { | |
13856 return; | |
13857 } | |
13858 | |
13859 TRACE_EVENT0( | |
13860 "gpu", | |
13861 "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM, fallback"); | |
13862 | |
13863 DoCopyTexImageIfNeeded(source_texture, source_texture->target()); | |
13864 | |
13865 // As a fallback, copy into a non-compressed GL_RGBA texture. | |
13866 if (dest_internal_format != GL_RGBA) { | |
13867 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), dest_texture->target()); | |
13868 | |
13869 // To preserve the contents of the original destination texture we must | |
13870 // first copy the original destination texture to a temporary storage, then | |
13871 // copy it back to the original destination texture. | |
13872 GLenum tmp_target = GL_TEXTURE_2D; | |
13873 GLuint tmp_service_id; | |
13874 glGenTextures(1, &tmp_service_id); | |
13875 DCHECK_NE(0u, tmp_service_id); | |
13876 | |
13877 glBindTexture(tmp_target, tmp_service_id); | |
13878 | |
13879 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); | |
13880 glTexImage2D(tmp_target, 0, GL_RGBA, dest_width, dest_height, 0, GL_RGBA, | |
13881 GL_UNSIGNED_BYTE, NULL); | |
13882 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM"); | |
13883 if (error != GL_NO_ERROR) | |
13884 return; | |
13885 | |
13886 copy_texture_CHROMIUM_->DoCopyTexture( | |
13887 this, dest_texture->target(), dest_texture->service_id(), | |
13888 dest_internal_format, tmp_target, tmp_service_id, GL_RGBA, | |
13889 dest_width, dest_height, false, false, false); | |
13890 | |
13891 // Redefine destination texture to use RGBA. | |
13892 glBindTexture(dest_texture->target(), dest_texture->service_id()); | |
13893 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); | |
13894 glTexImage2D(dest_texture->target(), 0, GL_RGBA, dest_width, dest_height, 0, | |
13895 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | |
13896 error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM"); | |
13897 if (error != GL_NO_ERROR) | |
13898 return; | |
13899 | |
13900 texture_manager()->SetLevelInfo(dest_texture_ref, dest_texture->target(), 0, | |
13901 GL_RGBA, dest_width, dest_height, 1, 0, | |
13902 GL_RGBA, GL_UNSIGNED_BYTE, | |
13903 gfx::Rect(dest_width, dest_height)); | |
13904 | |
13905 copy_texture_CHROMIUM_->DoCopyTexture( | |
13906 this, tmp_target, tmp_service_id, GL_RGBA, | |
13907 dest_texture->target(), dest_texture->service_id(), GL_RGBA, | |
13908 dest_width, dest_height, false, false, false); | |
13909 | |
13910 glDeleteTextures(1, &tmp_service_id); | |
13911 } | |
13912 | |
13913 // TODO(hkuang): get the StreamTexture transform matrix in GPU process. | |
13914 // crbug.com/226218. | |
13915 copy_texture_CHROMIUM_->DoCopySubTexture( | |
13916 this, source_texture->target(), source_texture->service_id(), | |
13917 source_internal_format, dest_texture->target(), | |
13918 dest_texture->service_id(), GL_RGBA, xoffset, yoffset, x, y, width, | |
13919 height, dest_width, dest_height, source_width, source_height, false, | |
13920 false, false); | |
13921 } | |
13922 | |
13923 void GLES2DecoderImpl::DoTexStorage2DEXT( | 13689 void GLES2DecoderImpl::DoTexStorage2DEXT( |
13924 GLenum target, | 13690 GLenum target, |
13925 GLint levels, | 13691 GLint levels, |
13926 GLenum internal_format, | 13692 GLenum internal_format, |
13927 GLsizei width, | 13693 GLsizei width, |
13928 GLsizei height) { | 13694 GLsizei height) { |
13929 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT", | 13695 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT", |
13930 "width", width, "height", height); | 13696 "width", width, "height", height); |
13931 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || | 13697 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || |
13932 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) { | 13698 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) { |
(...skipping 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15805 } | 15571 } |
15806 | 15572 |
15807 // Include the auto-generated part of this file. We split this because it means | 15573 // Include the auto-generated part of this file. We split this because it means |
15808 // we can easily edit the non-auto generated parts right here in this file | 15574 // we can easily edit the non-auto generated parts right here in this file |
15809 // instead of having to edit some template or the code generator. | 15575 // instead of having to edit some template or the code generator. |
15810 #include "base/macros.h" | 15576 #include "base/macros.h" |
15811 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 15577 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
15812 | 15578 |
15813 } // namespace gles2 | 15579 } // namespace gles2 |
15814 } // namespace gpu | 15580 } // namespace gpu |
OLD | NEW |