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 1909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1920 GLuint* source_texture_service_id, | 1920 GLuint* source_texture_service_id, |
| 1921 GLenum* source_texture_target); | 1921 GLenum* source_texture_target); |
| 1922 | 1922 |
| 1923 // On Mac OS X, calling glReadPixels() against an FBO whose color attachment | 1923 // On Mac OS X, calling glReadPixels() against an FBO whose color attachment |
| 1924 // is an IOSurface-backed texture causes corruption of future glReadPixels() | 1924 // is an IOSurface-backed texture causes corruption of future glReadPixels() |
| 1925 // calls, even those on different OpenGL contexts. It is believed that this | 1925 // calls, even those on different OpenGL contexts. It is believed that this |
| 1926 // is the root cause of top crasher | 1926 // is the root cause of top crasher |
| 1927 // http://crbug.com/99393. <rdar://problem/10949687> | 1927 // http://crbug.com/99393. <rdar://problem/10949687> |
| 1928 bool NeedsIOSurfaceReadbackWorkaround(); | 1928 bool NeedsIOSurfaceReadbackWorkaround(); |
| 1929 | 1929 |
| 1930 bool InitializeCopyTextureCHROMIUM(const char* function_name); | |
| 1930 // Generate a member function prototype for each command in an automated and | 1931 // Generate a member function prototype for each command in an automated and |
| 1931 // typesafe way. | 1932 // typesafe way. |
| 1932 #define GLES2_CMD_OP(name) \ | 1933 #define GLES2_CMD_OP(name) \ |
| 1933 Error Handle##name(uint32_t immediate_data_size, const void* data); | 1934 Error Handle##name(uint32_t immediate_data_size, const void* data); |
| 1934 | 1935 |
| 1935 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 1936 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
| 1936 | 1937 |
| 1937 #undef GLES2_CMD_OP | 1938 #undef GLES2_CMD_OP |
| 1938 | 1939 |
| 1939 // The GL context this decoder renders to on behalf of the client. | 1940 // The GL context this decoder renders to on behalf of the client. |
| (...skipping 11857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13797 | 13798 |
| 13798 void GLES2DecoderImpl::DoCopyTextureCHROMIUM( | 13799 void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
| 13799 GLuint source_id, | 13800 GLuint source_id, |
| 13800 GLuint dest_id, | 13801 GLuint dest_id, |
| 13801 GLenum internal_format, | 13802 GLenum internal_format, |
| 13802 GLenum dest_type, | 13803 GLenum dest_type, |
| 13803 GLboolean unpack_flip_y, | 13804 GLboolean unpack_flip_y, |
| 13804 GLboolean unpack_premultiply_alpha, | 13805 GLboolean unpack_premultiply_alpha, |
| 13805 GLboolean unpack_unmultiply_alpha) { | 13806 GLboolean unpack_unmultiply_alpha) { |
| 13806 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM"); | 13807 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM"); |
| 13807 | 13808 static const char kFunctionName[] = "glCopyTextureCHROMIUM"; |
| 13808 TextureRef* source_texture_ref = GetTexture(source_id); | 13809 TextureRef* source_texture_ref = GetTexture(source_id); |
| 13809 TextureRef* dest_texture_ref = GetTexture(dest_id); | 13810 TextureRef* dest_texture_ref = GetTexture(dest_id); |
| 13810 | 13811 |
| 13811 if (!ValidateCopyTextureCHROMIUMTextures( | 13812 if (!ValidateCopyTextureCHROMIUMTextures(kFunctionName, source_texture_ref, |
| 13812 "glCopyTextureCHROMIUM", source_texture_ref, dest_texture_ref)) { | 13813 dest_texture_ref)) { |
| 13813 return; | 13814 return; |
| 13814 } | 13815 } |
| 13815 | 13816 |
| 13816 if (!ValidateCopyTextureCHROMIUMInternalFormats( | 13817 if (!ValidateCopyTextureCHROMIUMInternalFormats( |
| 13817 "glCopyTextureCHROMIUM", source_texture_ref, internal_format)) { | 13818 kFunctionName, source_texture_ref, internal_format)) { |
| 13818 return; | 13819 return; |
| 13819 } | 13820 } |
| 13820 | 13821 |
| 13821 Texture* source_texture = source_texture_ref->texture(); | 13822 Texture* source_texture = source_texture_ref->texture(); |
| 13822 Texture* dest_texture = dest_texture_ref->texture(); | 13823 Texture* dest_texture = dest_texture_ref->texture(); |
| 13823 GLenum source_target = source_texture->target(); | 13824 GLenum source_target = source_texture->target(); |
| 13824 GLenum dest_target = dest_texture->target(); | 13825 GLenum dest_target = dest_texture->target(); |
| 13825 int source_width = 0; | 13826 int source_width = 0; |
| 13826 int source_height = 0; | 13827 int source_height = 0; |
| 13827 gl::GLImage* image = | 13828 gl::GLImage* image = |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 13841 &source_width, &source_height, nullptr)) { | 13842 &source_width, &source_height, nullptr)) { |
| 13842 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, | 13843 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, |
| 13843 "glCopyTextureChromium", | 13844 "glCopyTextureChromium", |
| 13844 "source texture has no level 0"); | 13845 "source texture has no level 0"); |
| 13845 return; | 13846 return; |
| 13846 } | 13847 } |
| 13847 | 13848 |
| 13848 // Check that this type of texture is allowed. | 13849 // Check that this type of texture is allowed. |
| 13849 if (!texture_manager()->ValidForTarget(source_target, 0, | 13850 if (!texture_manager()->ValidForTarget(source_target, 0, |
| 13850 source_width, source_height, 1)) { | 13851 source_width, source_height, 1)) { |
| 13851 LOCAL_SET_GL_ERROR( | 13852 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions"); |
| 13852 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions"); | |
| 13853 return; | 13853 return; |
| 13854 } | 13854 } |
| 13855 } | 13855 } |
| 13856 | 13856 |
| 13857 GLenum source_type = 0; | 13857 GLenum source_type = 0; |
| 13858 GLenum source_internal_format = 0; | 13858 GLenum source_internal_format = 0; |
| 13859 source_texture->GetLevelType(source_target, 0, &source_type, | 13859 source_texture->GetLevelType(source_target, 0, &source_type, |
| 13860 &source_internal_format); | 13860 &source_internal_format); |
| 13861 | 13861 |
| 13862 if (dest_texture->IsImmutable()) { | 13862 if (dest_texture->IsImmutable()) { |
| 13863 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTextureCHROMIUM", | 13863 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 13864 "texture is immutable"); | 13864 "texture is immutable"); |
| 13865 return; | 13865 return; |
| 13866 } | 13866 } |
| 13867 | 13867 |
| 13868 // Clear the source texture if necessary. | 13868 // Clear the source texture if necessary. |
| 13869 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, | 13869 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, |
| 13870 source_target, 0)) { | 13870 source_target, 0)) { |
| 13871 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", | 13871 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, "dimensions too big"); |
| 13872 "dimensions too big"); | |
| 13873 return; | 13872 return; |
| 13874 } | 13873 } |
| 13875 | 13874 |
| 13876 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is | 13875 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) |
| 13877 // needed because it takes 10s of milliseconds to initialize. | 13876 return; |
| 13878 if (!copy_texture_CHROMIUM_.get()) { | |
| 13879 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); | |
| 13880 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); | |
| 13881 copy_texture_CHROMIUM_->Initialize(this, features()); | |
| 13882 RestoreCurrentFramebufferBindings(); | |
| 13883 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR) | |
| 13884 return; | |
| 13885 } | |
| 13886 | 13877 |
| 13887 GLenum dest_type_previous = dest_type; | 13878 GLenum dest_type_previous = dest_type; |
| 13888 GLenum dest_internal_format = internal_format; | 13879 GLenum dest_internal_format = internal_format; |
| 13889 int dest_width = 0; | 13880 int dest_width = 0; |
| 13890 int dest_height = 0; | 13881 int dest_height = 0; |
| 13891 bool dest_level_defined = dest_texture->GetLevelSize( | 13882 bool dest_level_defined = dest_texture->GetLevelSize( |
| 13892 dest_target, 0, &dest_width, &dest_height, nullptr); | 13883 dest_target, 0, &dest_width, &dest_height, nullptr); |
| 13893 | 13884 |
| 13894 if (dest_level_defined) { | 13885 if (dest_level_defined) { |
| 13895 dest_texture->GetLevelType(dest_target, 0, &dest_type_previous, | 13886 dest_texture->GetLevelType(dest_target, 0, &dest_type_previous, |
| 13896 &dest_internal_format); | 13887 &dest_internal_format); |
| 13897 } | 13888 } |
| 13898 | 13889 |
| 13899 // Resize the destination texture to the dimensions of the source texture. | 13890 // Resize the destination texture to the dimensions of the source texture. |
| 13900 if (!dest_level_defined || dest_width != source_width || | 13891 if (!dest_level_defined || dest_width != source_width || |
| 13901 dest_height != source_height || | 13892 dest_height != source_height || |
| 13902 dest_internal_format != internal_format || | 13893 dest_internal_format != internal_format || |
| 13903 dest_type_previous != dest_type) { | 13894 dest_type_previous != dest_type) { |
| 13904 // Ensure that the glTexImage2D succeeds. | 13895 // Ensure that the glTexImage2D succeeds. |
| 13905 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); | 13896 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName); |
| 13906 glBindTexture(dest_target, dest_texture->service_id()); | 13897 glBindTexture(dest_target, dest_texture->service_id()); |
| 13907 glTexImage2D(dest_target, 0, | 13898 glTexImage2D(dest_target, 0, |
| 13908 texture_manager()->AdjustTexInternalFormat(internal_format), | 13899 texture_manager()->AdjustTexInternalFormat(internal_format), |
| 13909 source_width, source_height, 0, | 13900 source_width, source_height, 0, |
| 13910 texture_manager()->AdjustTexFormat(internal_format), dest_type, | 13901 texture_manager()->AdjustTexFormat(internal_format), dest_type, |
| 13911 NULL); | 13902 NULL); |
| 13912 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); | 13903 GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); |
| 13913 if (error != GL_NO_ERROR) { | 13904 if (error != GL_NO_ERROR) { |
| 13914 RestoreCurrentTextureBindings(&state_, dest_target); | 13905 RestoreCurrentTextureBindings(&state_, dest_target); |
| 13915 return; | 13906 return; |
| 13916 } | 13907 } |
| 13917 | 13908 |
| 13918 texture_manager()->SetLevelInfo( | 13909 texture_manager()->SetLevelInfo( |
| 13919 dest_texture_ref, dest_target, 0, internal_format, source_width, | 13910 dest_texture_ref, dest_target, 0, internal_format, source_width, |
| 13920 source_height, 1, 0, internal_format, dest_type, | 13911 source_height, 1, 0, internal_format, dest_type, |
| 13921 gfx::Rect(source_width, source_height)); | 13912 gfx::Rect(source_width, source_height)); |
| 13922 dest_texture->ApplyFormatWorkarounds(feature_info_.get()); | 13913 dest_texture->ApplyFormatWorkarounds(feature_info_.get()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13968 GLint yoffset, | 13959 GLint yoffset, |
| 13969 GLint x, | 13960 GLint x, |
| 13970 GLint y, | 13961 GLint y, |
| 13971 GLsizei width, | 13962 GLsizei width, |
| 13972 GLsizei height, | 13963 GLsizei height, |
| 13973 GLboolean unpack_flip_y, | 13964 GLboolean unpack_flip_y, |
| 13974 GLboolean unpack_premultiply_alpha, | 13965 GLboolean unpack_premultiply_alpha, |
| 13975 GLboolean unpack_unmultiply_alpha) { | 13966 GLboolean unpack_unmultiply_alpha) { |
| 13976 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM"); | 13967 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM"); |
| 13977 | 13968 |
| 13969 static const char kFunctionName[] = "glCopySubTextureCHROMIUM"; | |
| 13978 TextureRef* source_texture_ref = GetTexture(source_id); | 13970 TextureRef* source_texture_ref = GetTexture(source_id); |
| 13979 TextureRef* dest_texture_ref = GetTexture(dest_id); | 13971 TextureRef* dest_texture_ref = GetTexture(dest_id); |
| 13980 | 13972 |
| 13981 if (!ValidateCopyTextureCHROMIUMTextures( | 13973 if (!ValidateCopyTextureCHROMIUMTextures(kFunctionName, source_texture_ref, |
| 13982 "glCopySubTextureCHROMIUM", source_texture_ref, dest_texture_ref)) { | 13974 dest_texture_ref)) { |
| 13983 return; | 13975 return; |
| 13984 } | 13976 } |
| 13985 | 13977 |
| 13986 Texture* source_texture = source_texture_ref->texture(); | 13978 Texture* source_texture = source_texture_ref->texture(); |
| 13987 Texture* dest_texture = dest_texture_ref->texture(); | 13979 Texture* dest_texture = dest_texture_ref->texture(); |
| 13988 GLenum source_target = source_texture->target(); | 13980 GLenum source_target = source_texture->target(); |
| 13989 GLenum dest_target = dest_texture->target(); | 13981 GLenum dest_target = dest_texture->target(); |
| 13990 int source_width = 0; | 13982 int source_width = 0; |
| 13991 int source_height = 0; | 13983 int source_height = 0; |
| 13992 gl::GLImage* image = | 13984 gl::GLImage* image = |
| 13993 source_texture->GetLevelImage(source_target, 0); | 13985 source_texture->GetLevelImage(source_target, 0); |
| 13994 if (image) { | 13986 if (image) { |
| 13995 gfx::Size size = image->GetSize(); | 13987 gfx::Size size = image->GetSize(); |
| 13996 source_width = size.width(); | 13988 source_width = size.width(); |
| 13997 source_height = size.height(); | 13989 source_height = size.height(); |
| 13998 if (source_width <= 0 || source_height <= 0) { | 13990 if (source_width <= 0 || source_height <= 0) { |
| 13999 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", | 13991 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid image size"); |
| 14000 "invalid image size"); | |
| 14001 return; | 13992 return; |
| 14002 } | 13993 } |
| 14003 | 13994 |
| 14004 // Ideally we should not need to check that the sub-texture copy rectangle | 13995 // Ideally we should not need to check that the sub-texture copy rectangle |
| 14005 // is valid in two different ways, here and below. However currently there | 13996 // is valid in two different ways, here and below. However currently there |
| 14006 // is no guarantee that a texture backed by a GLImage will have sensible | 13997 // is no guarantee that a texture backed by a GLImage will have sensible |
| 14007 // level info. If this synchronization were to be enforced then this and | 13998 // level info. If this synchronization were to be enforced then this and |
| 14008 // other functions in this file could be cleaned up. | 13999 // other functions in this file could be cleaned up. |
| 14009 // See: https://crbug.com/586476 | 14000 // See: https://crbug.com/586476 |
| 14010 int32_t max_x; | 14001 int32_t max_x; |
| 14011 int32_t max_y; | 14002 int32_t max_y; |
| 14012 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y) || | 14003 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y) || |
| 14013 x < 0 || y < 0 || max_x > source_width || max_y > source_height) { | 14004 x < 0 || y < 0 || max_x > source_width || max_y > source_height) { |
| 14014 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", | 14005 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14015 "source texture bad dimensions"); | 14006 "source texture bad dimensions"); |
| 14016 return; | 14007 return; |
| 14017 } | 14008 } |
| 14018 } else { | 14009 } else { |
| 14019 if (!source_texture->GetLevelSize(source_target, 0, | 14010 if (!source_texture->GetLevelSize(source_target, 0, |
| 14020 &source_width, &source_height, nullptr)) { | 14011 &source_width, &source_height, nullptr)) { |
| 14021 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", | 14012 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14022 "source texture has no level 0"); | 14013 "source texture has no level 0"); |
| 14023 return; | 14014 return; |
| 14024 } | 14015 } |
| 14025 | 14016 |
| 14026 // Check that this type of texture is allowed. | 14017 // Check that this type of texture is allowed. |
| 14027 if (!texture_manager()->ValidForTarget(source_target, 0, | 14018 if (!texture_manager()->ValidForTarget(source_target, 0, |
| 14028 source_width, source_height, 1)) { | 14019 source_width, source_height, 1)) { |
| 14029 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", | 14020 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14030 "source texture bad dimensions"); | 14021 "source texture bad dimensions"); |
| 14031 return; | 14022 return; |
| 14032 } | 14023 } |
| 14033 | 14024 |
| 14034 if (!source_texture->ValidForTexture(source_target, 0, x, y, 0, width, | 14025 if (!source_texture->ValidForTexture(source_target, 0, x, y, 0, width, |
| 14035 height, 1)) { | 14026 height, 1)) { |
| 14036 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", | 14027 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14037 "source texture bad dimensions."); | 14028 "source texture bad dimensions."); |
| 14038 return; | 14029 return; |
| 14039 } | 14030 } |
| 14040 } | 14031 } |
| 14041 | 14032 |
| 14042 GLenum source_type = 0; | 14033 GLenum source_type = 0; |
| 14043 GLenum source_internal_format = 0; | 14034 GLenum source_internal_format = 0; |
| 14044 source_texture->GetLevelType(source_target, 0, &source_type, | 14035 source_texture->GetLevelType(source_target, 0, &source_type, |
| 14045 &source_internal_format); | 14036 &source_internal_format); |
| 14046 | 14037 |
| 14047 GLenum dest_type = 0; | 14038 GLenum dest_type = 0; |
| 14048 GLenum dest_internal_format = 0; | 14039 GLenum dest_internal_format = 0; |
| 14049 bool dest_level_defined = dest_texture->GetLevelType( | 14040 bool dest_level_defined = dest_texture->GetLevelType( |
| 14050 dest_target, 0, &dest_type, &dest_internal_format); | 14041 dest_target, 0, &dest_type, &dest_internal_format); |
| 14051 if (!dest_level_defined) { | 14042 if (!dest_level_defined) { |
| 14052 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopySubTextureCHROMIUM", | 14043 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14053 "destination texture is not defined"); | 14044 "destination texture is not defined"); |
| 14054 return; | 14045 return; |
| 14055 } | 14046 } |
| 14056 if (!dest_texture->ValidForTexture(dest_target, 0, xoffset, | 14047 if (!dest_texture->ValidForTexture(dest_target, 0, xoffset, |
| 14057 yoffset, 0, width, height, 1)) { | 14048 yoffset, 0, width, height, 1)) { |
| 14058 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM", | 14049 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14059 "destination texture bad dimensions."); | 14050 "destination texture bad dimensions."); |
| 14060 return; | 14051 return; |
| 14061 } | 14052 } |
| 14062 | 14053 |
| 14063 if (!ValidateCopyTextureCHROMIUMInternalFormats("glCopySubTextureCHROMIUM", | 14054 if (!ValidateCopyTextureCHROMIUMInternalFormats( |
| 14064 source_texture_ref, | 14055 kFunctionName, source_texture_ref, dest_internal_format)) { |
| 14065 dest_internal_format)) { | |
| 14066 return; | 14056 return; |
| 14067 } | 14057 } |
| 14068 | 14058 |
| 14069 // Clear the source texture if necessary. | 14059 // Clear the source texture if necessary. |
| 14070 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, | 14060 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, |
| 14071 source_target, 0)) { | 14061 source_target, 0)) { |
| 14072 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM", | 14062 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, |
| 14073 "source texture dimensions too big"); | 14063 "source texture dimensions too big"); |
| 14074 return; | 14064 return; |
| 14075 } | 14065 } |
| 14076 | 14066 |
| 14077 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is | 14067 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) |
| 14078 // needed because it takes 10s of milliseconds to initialize. | 14068 return; |
| 14079 if (!copy_texture_CHROMIUM_.get()) { | |
| 14080 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTextureCHROMIUM"); | |
| 14081 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); | |
| 14082 copy_texture_CHROMIUM_->Initialize(this, features()); | |
| 14083 RestoreCurrentFramebufferBindings(); | |
| 14084 if (LOCAL_PEEK_GL_ERROR("glCopySubTextureCHROMIUM") != GL_NO_ERROR) | |
| 14085 return; | |
| 14086 } | |
| 14087 | 14069 |
| 14088 int dest_width = 0; | 14070 int dest_width = 0; |
| 14089 int dest_height = 0; | 14071 int dest_height = 0; |
| 14090 bool ok = dest_texture->GetLevelSize( | 14072 bool ok = dest_texture->GetLevelSize( |
| 14091 dest_target, 0, &dest_width, &dest_height, nullptr); | 14073 dest_target, 0, &dest_width, &dest_height, nullptr); |
| 14092 DCHECK(ok); | 14074 DCHECK(ok); |
| 14093 if (xoffset != 0 || yoffset != 0 || width != dest_width || | 14075 if (xoffset != 0 || yoffset != 0 || width != dest_width || |
| 14094 height != dest_height) { | 14076 height != dest_height) { |
| 14095 gfx::Rect cleared_rect; | 14077 gfx::Rect cleared_rect; |
| 14096 if (TextureManager::CombineAdjacentRects( | 14078 if (TextureManager::CombineAdjacentRects( |
| 14097 dest_texture->GetLevelClearedRect(dest_target, 0), | 14079 dest_texture->GetLevelClearedRect(dest_target, 0), |
| 14098 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) { | 14080 gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) { |
| 14099 DCHECK_GE( | 14081 DCHECK_GE( |
| 14100 cleared_rect.size().GetArea(), | 14082 cleared_rect.size().GetArea(), |
| 14101 dest_texture->GetLevelClearedRect(dest_target, 0).size().GetArea()); | 14083 dest_texture->GetLevelClearedRect(dest_target, 0).size().GetArea()); |
| 14102 texture_manager()->SetLevelClearedRect(dest_texture_ref, dest_target, 0, | 14084 texture_manager()->SetLevelClearedRect(dest_texture_ref, dest_target, 0, |
| 14103 cleared_rect); | 14085 cleared_rect); |
| 14104 } else { | 14086 } else { |
| 14105 // Otherwise clear part of texture level that is not already cleared. | 14087 // Otherwise clear part of texture level that is not already cleared. |
| 14106 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, | 14088 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, |
| 14107 dest_target, 0)) { | 14089 dest_target, 0)) { |
| 14108 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM", | 14090 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, |
| 14109 "destination texture dimensions too big"); | 14091 "destination texture dimensions too big"); |
| 14110 return; | 14092 return; |
| 14111 } | 14093 } |
| 14112 } | 14094 } |
| 14113 } else { | 14095 } else { |
| 14114 texture_manager()->SetLevelCleared(dest_texture_ref, dest_target, 0, | 14096 texture_manager()->SetLevelCleared(dest_texture_ref, dest_target, 0, |
| 14115 true); | 14097 true); |
| 14116 } | 14098 } |
| 14117 | 14099 |
| 14118 // Try using GLImage::CopyTexSubImage when possible. | 14100 // Try using GLImage::CopyTexSubImage when possible. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14151 } | 14133 } |
| 14152 } | 14134 } |
| 14153 copy_texture_CHROMIUM_->DoCopySubTexture( | 14135 copy_texture_CHROMIUM_->DoCopySubTexture( |
| 14154 this, source_target, source_texture->service_id(), source_internal_format, | 14136 this, source_target, source_texture->service_id(), source_internal_format, |
| 14155 dest_target, dest_texture->service_id(), dest_internal_format, xoffset, | 14137 dest_target, dest_texture->service_id(), dest_internal_format, xoffset, |
| 14156 yoffset, x, y, width, height, dest_width, dest_height, source_width, | 14138 yoffset, x, y, width, height, dest_width, dest_height, source_width, |
| 14157 source_height, unpack_flip_y == GL_TRUE, | 14139 source_height, unpack_flip_y == GL_TRUE, |
| 14158 unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE); | 14140 unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE); |
| 14159 } | 14141 } |
| 14160 | 14142 |
| 14143 bool GLES2DecoderImpl::InitializeCopyTextureCHROMIUM( | |
| 14144 const char* function_name) { | |
| 14145 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is | |
| 14146 // needed because it takes 10s of milliseconds to initialize. | |
| 14147 if (!copy_texture_CHROMIUM_.get()) { | |
| 14148 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); | |
| 14149 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); | |
| 14150 copy_texture_CHROMIUM_->Initialize(this, features()); | |
| 14151 if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) | |
| 14152 return false; | |
| 14153 } | |
| 14154 return true; | |
| 14155 } | |
| 14156 | |
| 14161 void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLuint source_id, | 14157 void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLuint source_id, |
| 14162 GLuint dest_id) { | 14158 GLuint dest_id) { |
| 14163 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM"); | 14159 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM"); |
| 14164 | 14160 static const char kFunctionName[] = "glCompressedCopyTextureCHROMIUM"; |
| 14165 TextureRef* source_texture_ref = GetTexture(source_id); | 14161 TextureRef* source_texture_ref = GetTexture(source_id); |
| 14166 TextureRef* dest_texture_ref = GetTexture(dest_id); | 14162 TextureRef* dest_texture_ref = GetTexture(dest_id); |
| 14167 | 14163 |
| 14168 if (!source_texture_ref || !dest_texture_ref) { | 14164 if (!source_texture_ref || !dest_texture_ref) { |
| 14169 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopyTextureCHROMIUM", | 14165 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "unknown texture ids"); |
| 14170 "unknown texture ids"); | |
| 14171 return; | 14166 return; |
| 14172 } | 14167 } |
| 14173 | 14168 |
| 14174 Texture* source_texture = source_texture_ref->texture(); | 14169 Texture* source_texture = source_texture_ref->texture(); |
| 14175 Texture* dest_texture = dest_texture_ref->texture(); | 14170 Texture* dest_texture = dest_texture_ref->texture(); |
| 14176 int source_width = 0; | 14171 int source_width = 0; |
| 14177 int source_height = 0; | 14172 int source_height = 0; |
| 14178 gl::GLImage* image = | 14173 gl::GLImage* image = |
| 14179 source_texture->GetLevelImage(source_texture->target(), 0); | 14174 source_texture->GetLevelImage(source_texture->target(), 0); |
| 14180 if (image) { | 14175 if (image) { |
| 14181 gfx::Size size = image->GetSize(); | 14176 gfx::Size size = image->GetSize(); |
| 14182 source_width = size.width(); | 14177 source_width = size.width(); |
| 14183 source_height = size.height(); | 14178 source_height = size.height(); |
| 14184 if (source_width <= 0 || source_height <= 0) { | 14179 if (source_width <= 0 || source_height <= 0) { |
| 14185 LOCAL_SET_GL_ERROR( | 14180 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid image size"); |
| 14186 GL_INVALID_VALUE, | |
| 14187 "glCompressedCopyTextureCHROMIUM", "invalid image size"); | |
| 14188 return; | 14181 return; |
| 14189 } | 14182 } |
| 14190 } else { | 14183 } else { |
| 14191 if (!source_texture->GetLevelSize(source_texture->target(), 0, | 14184 if (!source_texture->GetLevelSize(source_texture->target(), 0, |
| 14192 &source_width, &source_height, nullptr)) { | 14185 &source_width, &source_height, nullptr)) { |
| 14193 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, | 14186 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 14194 "glCompressedCopyTextureCHROMIUM", | |
| 14195 "source texture has no level 0"); | 14187 "source texture has no level 0"); |
| 14196 return; | 14188 return; |
| 14197 } | 14189 } |
| 14198 | 14190 |
| 14199 // Check that this type of texture is allowed. | 14191 // Check that this type of texture is allowed. |
| 14200 if (!texture_manager()->ValidForTarget(source_texture->target(), 0, | 14192 if (!texture_manager()->ValidForTarget(source_texture->target(), 0, |
| 14201 source_width, source_height, 1)) { | 14193 source_width, source_height, 1)) { |
| 14202 LOCAL_SET_GL_ERROR( | 14194 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "Bad dimensions"); |
| 14203 GL_INVALID_VALUE, "glCompressedCopyTextureCHROMIUM", | |
| 14204 "Bad dimensions"); | |
| 14205 return; | 14195 return; |
| 14206 } | 14196 } |
| 14207 } | 14197 } |
| 14208 | 14198 |
| 14209 GLenum source_type = 0; | 14199 GLenum source_type = 0; |
| 14210 GLenum source_internal_format = 0; | 14200 GLenum source_internal_format = 0; |
| 14211 source_texture->GetLevelType( | 14201 source_texture->GetLevelType( |
| 14212 source_texture->target(), 0, &source_type, &source_internal_format); | 14202 source_texture->target(), 0, &source_type, &source_internal_format); |
| 14213 | 14203 |
| 14214 if (dest_texture->IsImmutable()) { | 14204 if (dest_texture->IsImmutable()) { |
| 14215 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, | 14205 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 14216 "glCompressedCopyTextureCHROMIUM", | |
| 14217 "texture is immutable"); | 14206 "texture is immutable"); |
| 14218 return; | 14207 return; |
| 14219 } | 14208 } |
| 14220 | 14209 |
| 14221 if (!ValidateCompressedCopyTextureCHROMIUM( | 14210 if (!ValidateCompressedCopyTextureCHROMIUM(kFunctionName, source_texture_ref, |
| 14222 "glCompressedCopyTextureCHROMIUM", | 14211 dest_texture_ref)) { |
| 14223 source_texture_ref, dest_texture_ref)) { | |
| 14224 return; | 14212 return; |
| 14225 } | 14213 } |
| 14226 | 14214 |
| 14227 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is | 14215 if (!InitializeCopyTextureCHROMIUM(kFunctionName)) |
| 14228 // needed because it takes 10s of milliseconds to initialize. | 14216 return; |
| 14229 if (!copy_texture_CHROMIUM_.get()) { | |
| 14230 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); | |
| 14231 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); | |
| 14232 copy_texture_CHROMIUM_->Initialize(this, features()); | |
| 14233 RestoreCurrentFramebufferBindings(); | |
|
Zhenyao Mo
2016/04/27 16:44:04
I don't know why we call this in the first place b
| |
| 14234 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR) | |
| 14235 return; | |
| 14236 } | |
| 14237 | 14217 |
| 14238 // Clear the source texture if necessary. | 14218 // Clear the source texture if necessary. |
| 14239 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, | 14219 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, |
| 14240 source_texture->target(), 0)) { | 14220 source_texture->target(), 0)) { |
| 14241 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCompressedCopyTextureCHROMIUM", | 14221 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, kFunctionName, "dimensions too big"); |
| 14242 "dimensions too big"); | |
| 14243 return; | 14222 return; |
| 14244 } | 14223 } |
| 14245 | 14224 |
| 14246 ScopedTextureBinder binder( | 14225 ScopedTextureBinder binder( |
| 14247 &state_, dest_texture->service_id(), GL_TEXTURE_2D); | 14226 &state_, dest_texture->service_id(), GL_TEXTURE_2D); |
| 14248 | 14227 |
| 14249 // Try using GLImage::CopyTexImage when possible. | 14228 // Try using GLImage::CopyTexImage when possible. |
| 14250 if (image) { | 14229 if (image) { |
| 14251 GLenum dest_type = 0; | 14230 GLenum dest_type = 0; |
| 14252 GLenum dest_internal_format = 0; | 14231 GLenum dest_internal_format = 0; |
| 14253 int dest_width = 0; | 14232 int dest_width = 0; |
| 14254 int dest_height = 0; | 14233 int dest_height = 0; |
| 14255 bool dest_level_defined = dest_texture->GetLevelSize( | 14234 bool dest_level_defined = dest_texture->GetLevelSize( |
| 14256 dest_texture->target(), 0, &dest_width, &dest_height, nullptr); | 14235 dest_texture->target(), 0, &dest_width, &dest_height, nullptr); |
| 14257 | 14236 |
| 14258 if (dest_level_defined) { | 14237 if (dest_level_defined) { |
| 14259 dest_texture->GetLevelType(dest_texture->target(), 0, &dest_type, | 14238 dest_texture->GetLevelType(dest_texture->target(), 0, &dest_type, |
| 14260 &dest_internal_format); | 14239 &dest_internal_format); |
| 14261 } | 14240 } |
| 14262 | 14241 |
| 14263 // Resize the destination texture to the dimensions of the source texture. | 14242 // Resize the destination texture to the dimensions of the source texture. |
| 14264 if (!dest_level_defined || dest_width != source_width || | 14243 if (!dest_level_defined || dest_width != source_width || |
| 14265 dest_height != source_height || | 14244 dest_height != source_height || |
| 14266 dest_internal_format != source_internal_format) { | 14245 dest_internal_format != source_internal_format) { |
| 14267 GLsizei source_size = 0; | 14246 GLsizei source_size = 0; |
| 14268 | 14247 |
| 14269 bool did_get_size = GetCompressedTexSizeInBytes( | 14248 bool did_get_size = GetCompressedTexSizeInBytes( |
| 14270 "glCompressedCopyTextureCHROMIUM", source_width, source_height, | 14249 kFunctionName, source_width, source_height, 1, source_internal_format, |
| 14271 1, source_internal_format, &source_size); | 14250 &source_size); |
| 14272 DCHECK(did_get_size); | 14251 DCHECK(did_get_size); |
| 14273 | 14252 |
| 14274 // Ensure that the glCompressedTexImage2D succeeds. | 14253 // Ensure that the glCompressedTexImage2D succeeds. |
| 14275 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); | 14254 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName); |
| 14276 glCompressedTexImage2D(GL_TEXTURE_2D, 0, source_internal_format, | 14255 glCompressedTexImage2D(GL_TEXTURE_2D, 0, source_internal_format, |
| 14277 source_width, source_height, 0, source_size, | 14256 source_width, source_height, 0, source_size, |
| 14278 NULL); | 14257 NULL); |
| 14279 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopyTextureCHROMIUM"); | 14258 GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); |
| 14280 if (error != GL_NO_ERROR) { | 14259 if (error != GL_NO_ERROR) { |
| 14281 RestoreCurrentTextureBindings(&state_, dest_texture->target()); | 14260 RestoreCurrentTextureBindings(&state_, dest_texture->target()); |
| 14282 return; | 14261 return; |
| 14283 } | 14262 } |
| 14284 | 14263 |
| 14285 texture_manager()->SetLevelInfo( | 14264 texture_manager()->SetLevelInfo( |
| 14286 dest_texture_ref, dest_texture->target(), 0, source_internal_format, | 14265 dest_texture_ref, dest_texture->target(), 0, source_internal_format, |
| 14287 source_width, source_height, 1, 0, source_internal_format, | 14266 source_width, source_height, 1, 0, source_internal_format, |
| 14288 source_type, gfx::Rect(source_width, source_height)); | 14267 source_type, gfx::Rect(source_width, source_height)); |
| 14289 } else { | 14268 } else { |
| 14290 texture_manager()->SetLevelCleared( | 14269 texture_manager()->SetLevelCleared( |
| 14291 dest_texture_ref, dest_texture->target(), 0, true); | 14270 dest_texture_ref, dest_texture->target(), 0, true); |
| 14292 } | 14271 } |
| 14293 | 14272 |
| 14294 if (image->CopyTexImage(dest_texture->target())) | 14273 if (image->CopyTexImage(dest_texture->target())) |
| 14295 return; | 14274 return; |
| 14296 } | 14275 } |
| 14297 | 14276 |
| 14298 TRACE_EVENT0( | 14277 TRACE_EVENT0( |
| 14299 "gpu", | 14278 "gpu", |
| 14300 "GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM, fallback"); | 14279 "GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM, fallback"); |
| 14301 | 14280 |
| 14302 DoCopyTexImageIfNeeded(source_texture, source_texture->target()); | 14281 DoCopyTexImageIfNeeded(source_texture, source_texture->target()); |
| 14303 | 14282 |
| 14304 // As a fallback, copy into a non-compressed GL_RGBA texture. | 14283 // As a fallback, copy into a non-compressed GL_RGBA texture. |
| 14305 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); | 14284 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName); |
| 14306 glTexImage2D(dest_texture->target(), 0, GL_RGBA, source_width, source_height, | 14285 glTexImage2D(dest_texture->target(), 0, GL_RGBA, source_width, source_height, |
| 14307 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | 14286 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| 14308 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopyTextureCHROMIUM"); | 14287 GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); |
| 14309 if (error != GL_NO_ERROR) { | 14288 if (error != GL_NO_ERROR) { |
| 14310 RestoreCurrentTextureBindings(&state_, dest_texture->target()); | 14289 RestoreCurrentTextureBindings(&state_, dest_texture->target()); |
| 14311 return; | 14290 return; |
| 14312 } | 14291 } |
| 14313 | 14292 |
| 14314 texture_manager()->SetLevelInfo( | 14293 texture_manager()->SetLevelInfo( |
| 14315 dest_texture_ref, dest_texture->target(), 0, GL_RGBA, source_width, | 14294 dest_texture_ref, dest_texture->target(), 0, GL_RGBA, source_width, |
| 14316 source_height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, | 14295 source_height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| 14317 gfx::Rect(source_width, source_height)); | 14296 gfx::Rect(source_width, source_height)); |
| 14318 | 14297 |
| (...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16357 } | 16336 } |
| 16358 | 16337 |
| 16359 // Include the auto-generated part of this file. We split this because it means | 16338 // Include the auto-generated part of this file. We split this because it means |
| 16360 // we can easily edit the non-auto generated parts right here in this file | 16339 // we can easily edit the non-auto generated parts right here in this file |
| 16361 // instead of having to edit some template or the code generator. | 16340 // instead of having to edit some template or the code generator. |
| 16362 #include "base/macros.h" | 16341 #include "base/macros.h" |
| 16363 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 16342 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 16364 | 16343 |
| 16365 } // namespace gles2 | 16344 } // namespace gles2 |
| 16366 } // namespace gpu | 16345 } // namespace gpu |
| OLD | NEW |