diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 04:00:49 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 04:00:49 +0000 |
commit | 40245ccfa40e45cd002830cc9170fdd0b8578d00 (patch) | |
tree | fb593832c869799b0ce4249441067cda3326463a | |
parent | 7300a267b737821996da4efd4b89ac216308c59e (diff) | |
download | chromium_src-40245ccfa40e45cd002830cc9170fdd0b8578d00.zip chromium_src-40245ccfa40e45cd002830cc9170fdd0b8578d00.tar.gz chromium_src-40245ccfa40e45cd002830cc9170fdd0b8578d00.tar.bz2 |
[Android] Add workaround to unbind gpu memory buffer only on NVIDIA
For gralloc backed gpu memory buffer on Android, it is undefined whether
locking for read/write while the buffer is bound to a texture is
allowed.
On nvidia devices (eg 2012 nexus 7), lock without unbind will lead to
deadlocks in the driver (crbug.com/264096).
However on other nexus gpu vendors (img, arm, qualcomm), unbind is very
expensive since it flushes the gpu pipeline. And vendors have advised
that lock while bound is allowed and is the right solution to this
slowness, as long as the texture is eventually recycled or deleted.
Add a workaround for nvidia to only unbind in GLImage::DidUseTexImage.
BUG=
Review URL: https://codereview.chromium.org/66033009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234740 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/image_manager.cc | 9 | ||||
-rw-r--r-- | gpu/command_buffer/service/image_manager.h | 4 | ||||
-rw-r--r-- | gpu/config/gpu_driver_bug_list_json.cc | 16 | ||||
-rw-r--r-- | gpu/config/gpu_driver_bug_workaround_type.h | 2 | ||||
-rw-r--r-- | ui/gl/gl_image.cc | 4 | ||||
-rw-r--r-- | ui/gl/gl_image.h | 4 | ||||
-rw-r--r-- | ui/gl/gl_image_egl.cc | 12 | ||||
-rw-r--r-- | ui/gl/gl_image_egl.h | 2 |
9 files changed, 54 insertions, 3 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0af257a..e3fcd46 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -2482,6 +2482,10 @@ bool GLES2DecoderImpl::Initialize( context_->SetUnbindFboOnMakeCurrent(); } + if (feature_info_->workarounds().release_image_after_use) { + image_manager()->SetReleaseAfterUse(); + } + // Only compositor contexts are known to use only the subset of GL // that can be safely migrated between the iGPU and the dGPU. Mark // those contexts as safe to forcibly transition between the GPUs. diff --git a/gpu/command_buffer/service/image_manager.cc b/gpu/command_buffer/service/image_manager.cc index a09af15..f39eba2 100644 --- a/gpu/command_buffer/service/image_manager.cc +++ b/gpu/command_buffer/service/image_manager.cc @@ -9,7 +9,7 @@ namespace gpu { namespace gles2 { -ImageManager::ImageManager() { +ImageManager::ImageManager() : release_after_use_(false) { } ImageManager::~ImageManager() { @@ -37,6 +37,9 @@ bool ImageManager::RegisterGpuMemoryBuffer(int32 id, if (!gl_image) return false; + if (release_after_use_) + gl_image->SetReleaseAfterUse(); + AddImage(gl_image.get(), id); return true; } @@ -61,5 +64,9 @@ gfx::GLImage* ImageManager::LookupImage(int32 service_id) { return NULL; } +void ImageManager::SetReleaseAfterUse() { + release_after_use_ = true; +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/image_manager.h b/gpu/command_buffer/service/image_manager.h index a125ae8..51e006d 100644 --- a/gpu/command_buffer/service/image_manager.h +++ b/gpu/command_buffer/service/image_manager.h @@ -37,6 +37,9 @@ class GPU_EXPORT ImageManager void RemoveImage(int32 service_id); gfx::GLImage* LookupImage(int32 service_id); + // For Android specific workaround. + void SetReleaseAfterUse(); + private: friend class base::RefCounted<ImageManager>; @@ -44,6 +47,7 @@ class GPU_EXPORT ImageManager typedef base::hash_map<uint32, scoped_refptr<gfx::GLImage> > GLImageMap; GLImageMap gl_images_; + bool release_after_use_; DISALLOW_COPY_AND_ASSIGN(ImageManager); }; diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index 0eeda19..903680a 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc @@ -19,7 +19,7 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "3.1", + "version": "3.2", "entries": [ { "id": 1, @@ -678,6 +678,20 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( "features": [ "wake_up_gpu_before_drawing" ] + }, + { + "id": 50, + "description": "NVIDIA driver requires unbinding a GpuMemoryBuffer from the texture before mapping it to main memory", + "os": { + "type": "android" + }, + "gl_vendor": { + "op": "beginwith", + "value": "NVIDIA" + }, + "features": [ + "release_image_after_use" + ] } ] } diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 92a516cf..872793c 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h @@ -80,6 +80,8 @@ validate_multisample_buffer_allocation) \ GPU_OP(WAKE_UP_GPU_BEFORE_DRAWING, \ wake_up_gpu_before_drawing) \ + GPU_OP(RELEASE_IMAGE_AFTER_USE, \ + release_image_after_use) \ namespace gpu { diff --git a/ui/gl/gl_image.cc b/ui/gl/gl_image.cc index ff7eb56..311acba 100644 --- a/ui/gl/gl_image.cc +++ b/ui/gl/gl_image.cc @@ -27,6 +27,10 @@ void GLImage::DidUseTexImage() { NOTIMPLEMENTED(); } +void GLImage::SetReleaseAfterUse() { + // Default no-op implementation for workaround. +} + GLImage::~GLImage() {} } // namespace gfx diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index 859966c..e96a76d 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -39,6 +39,10 @@ class GL_EXPORT GLImage : public base::RefCounted<GLImage> { // Called after the texture has been used for drawing. virtual void DidUseTexImage(); + // Indicate that image should be released after use. + // (For an Android work-around only). + virtual void SetReleaseAfterUse(); + // Create a GL image for a window. static scoped_refptr<GLImage> CreateGLImage(gfx::PluginWindowHandle window); diff --git a/ui/gl/gl_image_egl.cc b/ui/gl/gl_image_egl.cc index aeafc9a..283b4c7 100644 --- a/ui/gl/gl_image_egl.cc +++ b/ui/gl/gl_image_egl.cc @@ -12,6 +12,7 @@ namespace gfx { GLImageEGL::GLImageEGL(gfx::Size size) : egl_image_(EGL_NO_IMAGE_KHR), size_(size), + release_after_use_(false), in_use_(false) { } @@ -76,7 +77,8 @@ bool GLImageEGL::BindTexImage() { } void GLImageEGL::ReleaseTexImage() { - // Nothing to do here as image is released after each use. + // Nothing to do here as image is released after each use or there is no need + // to release image. } void GLImageEGL::WillUseTexImage() { @@ -90,6 +92,10 @@ void GLImageEGL::WillUseTexImage() { void GLImageEGL::DidUseTexImage() { DCHECK(in_use_); in_use_ = false; + + if (!release_after_use_) + return; + char zero[4] = { 0, }; glTexImage2D(GL_TEXTURE_2D, 0, @@ -102,4 +108,8 @@ void GLImageEGL::DidUseTexImage() { &zero); } +void GLImageEGL::SetReleaseAfterUse() { + release_after_use_ = true; +} + } // namespace gfx diff --git a/ui/gl/gl_image_egl.h b/ui/gl/gl_image_egl.h index 2c64f4d..f316624 100644 --- a/ui/gl/gl_image_egl.h +++ b/ui/gl/gl_image_egl.h @@ -23,6 +23,7 @@ class GL_EXPORT GLImageEGL : public GLImage { virtual void ReleaseTexImage() OVERRIDE; virtual void WillUseTexImage() OVERRIDE; virtual void DidUseTexImage() OVERRIDE; + virtual void SetReleaseAfterUse() OVERRIDE; protected: virtual ~GLImageEGL(); @@ -30,6 +31,7 @@ class GL_EXPORT GLImageEGL : public GLImage { private: EGLImageKHR egl_image_; gfx::Size size_; + bool release_after_use_; bool in_use_; DISALLOW_COPY_AND_ASSIGN(GLImageEGL); |