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 <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 GLsizei width, | 1057 GLsizei width, |
1058 GLsizei height, | 1058 GLsizei height, |
1059 GLboolean unpack_flip_y, | 1059 GLboolean unpack_flip_y, |
1060 GLboolean unpack_premultiply_alpha, | 1060 GLboolean unpack_premultiply_alpha, |
1061 GLboolean unpack_unmultiply_alpha); | 1061 GLboolean unpack_unmultiply_alpha); |
1062 | 1062 |
1063 void DoCompressedCopyTextureCHROMIUM(GLenum target, | 1063 void DoCompressedCopyTextureCHROMIUM(GLenum target, |
1064 GLuint source_id, | 1064 GLuint source_id, |
1065 GLuint dest_id); | 1065 GLuint dest_id); |
1066 | 1066 |
| 1067 void DoCompressedCopySubTextureCHROMIUM(GLenum target, |
| 1068 GLuint source_id, |
| 1069 GLuint dest_id, |
| 1070 GLint xoffset, |
| 1071 GLint yoffset, |
| 1072 GLint x, |
| 1073 GLint y, |
| 1074 GLsizei width, |
| 1075 GLsizei height); |
| 1076 |
1067 // Wrapper for TexStorage2DEXT. | 1077 // Wrapper for TexStorage2DEXT. |
1068 void DoTexStorage2DEXT( | 1078 void DoTexStorage2DEXT( |
1069 GLenum target, | 1079 GLenum target, |
1070 GLint levels, | 1080 GLint levels, |
1071 GLenum internal_format, | 1081 GLenum internal_format, |
1072 GLsizei width, | 1082 GLsizei width, |
1073 GLsizei height); | 1083 GLsizei height); |
1074 | 1084 |
1075 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); | 1085 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); |
1076 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, | 1086 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, |
(...skipping 11722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12799 } else { | 12809 } else { |
12800 copy_texture_CHROMIUM_->DoCopyTexture( | 12810 copy_texture_CHROMIUM_->DoCopyTexture( |
12801 this, source_texture->target(), source_texture->service_id(), | 12811 this, source_texture->target(), source_texture->service_id(), |
12802 source_internal_format, dest_texture->service_id(), GL_RGBA, | 12812 source_internal_format, dest_texture->service_id(), GL_RGBA, |
12803 source_width, source_height, false, false, false); | 12813 source_width, source_height, false, false, false); |
12804 } | 12814 } |
12805 | 12815 |
12806 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); | 12816 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); |
12807 } | 12817 } |
12808 | 12818 |
| 12819 void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target, |
| 12820 GLuint source_id, |
| 12821 GLuint dest_id, |
| 12822 GLint xoffset, |
| 12823 GLint yoffset, |
| 12824 GLint x, |
| 12825 GLint y, |
| 12826 GLsizei width, |
| 12827 GLsizei height) { |
| 12828 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM"); |
| 12829 |
| 12830 TextureRef* source_texture_ref = GetTexture(source_id); |
| 12831 TextureRef* dest_texture_ref = GetTexture(dest_id); |
| 12832 Texture* source_texture = source_texture_ref->texture(); |
| 12833 Texture* dest_texture = dest_texture_ref->texture(); |
| 12834 int source_width = 0; |
| 12835 int source_height = 0; |
| 12836 gfx::GLImage* image = |
| 12837 source_texture->GetLevelImage(source_texture->target(), 0); |
| 12838 if (image) { |
| 12839 gfx::Size size = image->GetSize(); |
| 12840 source_width = size.width(); |
| 12841 source_height = size.height(); |
| 12842 if (source_width <= 0 || source_height <= 0) { |
| 12843 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12844 "invalid image size"); |
| 12845 return; |
| 12846 } |
| 12847 } else { |
| 12848 if (!source_texture->GetLevelSize(source_texture->target(), 0, |
| 12849 &source_width, &source_height, nullptr)) { |
| 12850 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12851 "source texture has no level 0"); |
| 12852 return; |
| 12853 } |
| 12854 |
| 12855 // Check that this type of texture is allowed. |
| 12856 if (!texture_manager()->ValidForTarget(source_texture->target(), 0, |
| 12857 source_width, source_height, 1)) { |
| 12858 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12859 "source texture bad dimensions"); |
| 12860 return; |
| 12861 } |
| 12862 } |
| 12863 |
| 12864 GLenum source_type = 0; |
| 12865 GLenum source_internal_format = 0; |
| 12866 source_texture->GetLevelType(source_texture->target(), 0, &source_type, |
| 12867 &source_internal_format); |
| 12868 if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0, |
| 12869 width, height, 1, source_type)) { |
| 12870 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12871 "source texture bad dimensions."); |
| 12872 return; |
| 12873 } |
| 12874 |
| 12875 GLenum dest_type = 0; |
| 12876 GLenum dest_internal_format = 0; |
| 12877 bool dest_level_defined = dest_texture->GetLevelType( |
| 12878 dest_texture->target(), 0, &dest_type, &dest_internal_format); |
| 12879 if (!dest_level_defined) { |
| 12880 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 12881 "glCompressedCopySubTextureCHROMIUM", |
| 12882 "destination texture is not defined"); |
| 12883 return; |
| 12884 } |
| 12885 if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset, |
| 12886 yoffset, 0, width, height, 1, dest_type)) { |
| 12887 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12888 "destination texture bad dimensions."); |
| 12889 return; |
| 12890 } |
| 12891 |
| 12892 if (!ValidateCompressedCopyTextureCHROMIUM( |
| 12893 "glCompressedCopySubTextureCHROMIUM", target, source_texture_ref, |
| 12894 dest_texture_ref)) { |
| 12895 return; |
| 12896 } |
| 12897 |
| 12898 if (!ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM", |
| 12899 source_texture->target(), 0, x, y, 0, |
| 12900 width, height, 1, |
| 12901 source_internal_format, |
| 12902 source_texture) || |
| 12903 !ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM", |
| 12904 dest_texture->target(), 0, |
| 12905 xoffset, yoffset, 0, width, height, 1, |
| 12906 dest_internal_format, |
| 12907 dest_texture)) { |
| 12908 return; |
| 12909 } |
| 12910 |
| 12911 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is |
| 12912 // needed because it takes 10s of milliseconds to initialize. |
| 12913 if (!copy_texture_CHROMIUM_.get()) { |
| 12914 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopySubTextureCHROMIUM"); |
| 12915 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); |
| 12916 copy_texture_CHROMIUM_->Initialize(this); |
| 12917 RestoreCurrentFramebufferBindings(); |
| 12918 if (LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM") != |
| 12919 GL_NO_ERROR) { |
| 12920 return; |
| 12921 } |
| 12922 } |
| 12923 |
| 12924 // Clear the source texture if necessary. |
| 12925 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, |
| 12926 source_texture->target(), 0)) { |
| 12927 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCompressedCopySubTextureCHROMIUM", |
| 12928 "source texture dimensions too big"); |
| 12929 return; |
| 12930 } |
| 12931 |
| 12932 int dest_width = 0; |
| 12933 int dest_height = 0; |
| 12934 bool ok = dest_texture->GetLevelSize( |
| 12935 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); |
| 12936 DCHECK(ok); |
| 12937 if (xoffset != 0 || yoffset != 0 || width != dest_width || |
| 12938 height != dest_height) { |
| 12939 gfx::Rect cleared_rect; |
| 12940 if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0), |
| 12941 gfx::Rect(xoffset, yoffset, width, height), |
| 12942 &cleared_rect)) { |
| 12943 DCHECK_GE(cleared_rect.size().GetArea(), |
| 12944 dest_texture->GetLevelClearedRect(target, 0).size().GetArea()); |
| 12945 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0, |
| 12946 cleared_rect); |
| 12947 } else { |
| 12948 // Otherwise clear part of texture level that is not already cleared. |
| 12949 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, |
| 12950 0)) { |
| 12951 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, |
| 12952 "glCompressedCopySubTextureCHROMIUM", |
| 12953 "destination texture dimensions too big"); |
| 12954 return; |
| 12955 } |
| 12956 } |
| 12957 } else { |
| 12958 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, |
| 12959 true); |
| 12960 } |
| 12961 |
| 12962 ScopedTextureBinder binder( |
| 12963 &state_, dest_texture->service_id(), GL_TEXTURE_2D); |
| 12964 |
| 12965 ScopedModifyPixels modify(dest_texture_ref); |
| 12966 |
| 12967 // Try using GLImage::CopyTexSubImage when possible. |
| 12968 if (image) { |
| 12969 if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset), |
| 12970 gfx::Rect(x, y, width, height))) { |
| 12971 return; |
| 12972 } |
| 12973 } |
| 12974 |
| 12975 TRACE_EVENT0( |
| 12976 "gpu", |
| 12977 "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM, fallback"); |
| 12978 |
| 12979 DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); |
| 12980 |
| 12981 // As a fallback, copy into a non-compressed GL_RGBA texture. |
| 12982 if (dest_internal_format != GL_RGBA) { |
| 12983 // To preserve the contents of the original destination texture we must |
| 12984 // first copy the original destination texture to a temporary storage, then |
| 12985 // copy it back to the original destination texture. |
| 12986 GLuint tmp_service_id; |
| 12987 glGenTextures(1, &tmp_service_id); |
| 12988 DCHECK_NE(0u, tmp_service_id); |
| 12989 |
| 12990 glBindTexture(GL_TEXTURE_2D, tmp_service_id); |
| 12991 |
| 12992 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); |
| 12993 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, 0, GL_RGBA, |
| 12994 GL_UNSIGNED_BYTE, NULL); |
| 12995 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM"); |
| 12996 if (error != GL_NO_ERROR) |
| 12997 return; |
| 12998 |
| 12999 copy_texture_CHROMIUM_->DoCopyTexture( |
| 13000 this, dest_texture->target(), dest_texture->service_id(), |
| 13001 dest_internal_format, tmp_service_id, GL_RGBA, |
| 13002 dest_width, dest_height, false, false, false); |
| 13003 |
| 13004 // Redefine destination texture to use RGBA. |
| 13005 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); |
| 13006 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); |
| 13007 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, 0, GL_RGBA, |
| 13008 GL_UNSIGNED_BYTE, NULL); |
| 13009 error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM"); |
| 13010 if (error != GL_NO_ERROR) |
| 13011 return; |
| 13012 |
| 13013 texture_manager()->SetLevelInfo( |
| 13014 dest_texture_ref, GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, |
| 13015 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(dest_width, dest_height)); |
| 13016 |
| 13017 copy_texture_CHROMIUM_->DoCopyTexture( |
| 13018 this, GL_TEXTURE_2D, tmp_service_id, GL_RGBA, |
| 13019 dest_texture->service_id(), GL_RGBA, |
| 13020 dest_width, dest_height, false, false, false); |
| 13021 |
| 13022 glDeleteTextures(1, &tmp_service_id); |
| 13023 } |
| 13024 |
| 13025 // TODO(hkuang): get the StreamTexture transform matrix in GPU process. |
| 13026 // crbug.com/226218. |
| 13027 copy_texture_CHROMIUM_->DoCopySubTexture( |
| 13028 this, source_texture->target(), source_texture->service_id(), |
| 13029 source_internal_format, dest_texture->service_id(), GL_RGBA, |
| 13030 xoffset, yoffset, x, y, width, height, dest_width, dest_height, |
| 13031 source_width, source_height, false, false, false); |
| 13032 |
| 13033 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); |
| 13034 } |
| 13035 |
12809 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { | 13036 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { |
12810 switch (internalformat) { | 13037 switch (internalformat) { |
12811 case GL_R8: | 13038 case GL_R8: |
12812 return GL_UNSIGNED_BYTE; | 13039 return GL_UNSIGNED_BYTE; |
12813 case GL_R8_SNORM: | 13040 case GL_R8_SNORM: |
12814 return GL_BYTE; | 13041 return GL_BYTE; |
12815 case GL_R16F: | 13042 case GL_R16F: |
12816 return GL_HALF_FLOAT; | 13043 return GL_HALF_FLOAT; |
12817 case GL_R32F: | 13044 case GL_R32F: |
12818 return GL_FLOAT; | 13045 return GL_FLOAT; |
(...skipping 1737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14556 return error::kNoError; | 14783 return error::kNoError; |
14557 } | 14784 } |
14558 | 14785 |
14559 // Include the auto-generated part of this file. We split this because it means | 14786 // Include the auto-generated part of this file. We split this because it means |
14560 // we can easily edit the non-auto generated parts right here in this file | 14787 // we can easily edit the non-auto generated parts right here in this file |
14561 // instead of having to edit some template or the code generator. | 14788 // instead of having to edit some template or the code generator. |
14562 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 14789 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
14563 | 14790 |
14564 } // namespace gles2 | 14791 } // namespace gles2 |
14565 } // namespace gpu | 14792 } // namespace gpu |
OLD | NEW |