diff --git a/gpu/command_buffer/service/shared_image/gl_texture_holder.cc b/gpu/command_buffer/service/shared_image/gl_texture_holder.cc index a5dd82c7bcfe1..a035b1fd78741 100644 --- a/gpu/command_buffer/service/shared_image/gl_texture_holder.cc +++ b/gpu/command_buffer/service/shared_image/gl_texture_holder.cc @@ -160,22 +160,17 @@ void GLTextureHolder::Initialize( if (is_passthrough_) { passthrough_texture_->SetEstimatedSize(format_.EstimatedSizeInBytes(size_)); - } else { - // TODO(piman): We pretend the texture was created in an ES2 context, so - // that it can be used in other ES2 contexts, and so we have to pass - // gl_format as the internal format in the LevelInfo. - // https://crbug.com/628064 - texture_->SetLevelInfo(format_desc_.target, 0, format_desc_.data_format, - size_.width(), size_.height(), /*depth=*/1, 0, - format_desc_.data_format, format_desc_.data_type, - /*cleared_rect=*/gfx::Rect()); - texture_->SetImmutable(true, format_info.supports_storage); } gl::GLApi* api = gl::g_current_gl_context; gl::ScopedRestoreTexture scoped_restore(api, format_desc_.target, GetServiceId()); + // Drain any pre-existing GL errors so the post-allocation check below is + // attributable to the storage call. + while (api->glGetErrorFn() != GL_NO_ERROR) { + } + // Initialize the texture storage/image parameters and upload initial pixels // if available. if (format_info.supports_storage) { @@ -224,6 +219,26 @@ void GLTextureHolder::Initialize( } if (!is_passthrough_) { + // Only commit decoder-side LevelInfo / immutable state once the native + // allocation has succeeded. If the driver rejected the allocation (e.g. + // GL_OUT_OF_MEMORY), leaving LevelInfo at {0,0,0} ensures + // Texture::ValidForTexture rejects subsequent TexSubImage calls instead of + // forwarding oversized writes to a zero-storage native texture. This + // mirrors the fix in GLES2DecoderImpl::TexStorageImpl. + if (api->glGetErrorFn() == GL_NO_ERROR) { + // TODO(piman): We pretend the texture was created in an ES2 context, so + // that it can be used in other ES2 contexts, and so we have to pass + // gl_format as the internal format in the LevelInfo. + // https://crbug.com/628064 + texture_->SetLevelInfo(format_desc_.target, 0, format_desc_.data_format, + size_.width(), size_.height(), /*depth=*/1, 0, + format_desc_.data_format, format_desc_.data_type, + /*cleared_rect=*/gfx::Rect()); + texture_->SetImmutable(true, format_info.supports_storage); + } else { + LOG(ERROR) << "GLTextureHolder: native storage allocation failed; " + "leaving LevelInfo unset to block ValidForTexture."; + } // Must be set after initial pixel upload. texture_->SetCompatibilitySwizzle(format_info.swizzle); }