Commit decf5cf1 authored by boliu@chromium.org's avatar boliu@chromium.org

Leak instead of deadlock if executeHardwareAction fails

If executeHardwareAction fails in onDetachedFromWindow, then
HardwareRenderer destructor will deadlock later when being destroyed on
UI thread. In this case, run the destructor on UI without deadlock but
leak GL resources instead.

Achieve this by running always running release gl even on UI thread, and
making the allow_gl global to be a true thread local, which can be set
to true on UI thread.

BUG=
TBR=benm

Review URL: https://codereview.chromium.org/255783007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266429 0039d316-1c4b-4281-b951-d872f2087c98
parent 5f8f374c
...@@ -25,20 +25,7 @@ GLViewRendererManager::GLViewRendererManager() {} ...@@ -25,20 +25,7 @@ GLViewRendererManager::GLViewRendererManager() {}
GLViewRendererManager::~GLViewRendererManager() {} GLViewRendererManager::~GLViewRendererManager() {}
bool GLViewRendererManager::OnRenderThread() const {
AutoLock auto_lock(lock_);
return render_thread_.is_equal(base::PlatformThread::CurrentHandle());
}
void GLViewRendererManager::MarkRenderThread() {
lock_.AssertAcquired();
if (render_thread_.is_null())
render_thread_ = base::PlatformThread::CurrentHandle();
DCHECK(render_thread_.is_equal(base::PlatformThread::CurrentHandle()));
}
GLViewRendererManager::Key GLViewRendererManager::PushBack(RendererType view) { GLViewRendererManager::Key GLViewRendererManager::PushBack(RendererType view) {
MarkRenderThread();
DCHECK(mru_list_.end() == DCHECK(mru_list_.end() ==
std::find(mru_list_.begin(), mru_list_.end(), view)); std::find(mru_list_.begin(), mru_list_.end(), view));
mru_list_.push_back(view); mru_list_.push_back(view);
......
...@@ -28,9 +28,6 @@ class GLViewRendererManager { ...@@ -28,9 +28,6 @@ class GLViewRendererManager {
static GLViewRendererManager* GetInstance(); static GLViewRendererManager* GetInstance();
// TODO(boliu): Move RenderThread checking out of this class.
bool OnRenderThread() const;
Key PushBack(RendererType view); Key PushBack(RendererType view);
// |key| must be already in manager. Move renderer corresponding to |key| to // |key| must be already in manager. Move renderer corresponding to |key| to
...@@ -47,10 +44,7 @@ class GLViewRendererManager { ...@@ -47,10 +44,7 @@ class GLViewRendererManager {
GLViewRendererManager(); GLViewRendererManager();
~GLViewRendererManager(); ~GLViewRendererManager();
void MarkRenderThread();
mutable base::Lock lock_; mutable base::Lock lock_;
base::PlatformThreadHandle render_thread_;
ListType mru_list_; ListType mru_list_;
DISALLOW_COPY_AND_ASSIGN(GLViewRendererManager); DISALLOW_COPY_AND_ASSIGN(GLViewRendererManager);
......
...@@ -206,23 +206,22 @@ void HardwareRenderer::CalculateTileMemoryPolicy() { ...@@ -206,23 +206,22 @@ void HardwareRenderer::CalculateTileMemoryPolicy() {
namespace internal { namespace internal {
bool ScopedAllowGL::allow_gl = false; base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
// static // static
bool ScopedAllowGL::IsAllowed() { bool ScopedAllowGL::IsAllowed() {
return GLViewRendererManager::GetInstance()->OnRenderThread() && allow_gl; return allow_gl.Get().Get();
} }
ScopedAllowGL::ScopedAllowGL() { ScopedAllowGL::ScopedAllowGL() {
DCHECK(GLViewRendererManager::GetInstance()->OnRenderThread()); DCHECK(!allow_gl.Get().Get());
DCHECK(!allow_gl); allow_gl.Get().Set(true);
allow_gl = true;
if (g_service.Get()) if (g_service.Get())
g_service.Get()->RunTasks(); g_service.Get()->RunTasks();
} }
ScopedAllowGL::~ScopedAllowGL() { allow_gl = false; } ScopedAllowGL::~ScopedAllowGL() { allow_gl.Get().Set(false); }
DeferredGpuCommandService::DeferredGpuCommandService() {} DeferredGpuCommandService::DeferredGpuCommandService() {}
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#include "android_webview/browser/gl_view_renderer_manager.h" #include "android_webview/browser/gl_view_renderer_manager.h"
#include "android_webview/browser/shared_renderer_state.h" #include "android_webview/browser/shared_renderer_state.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/threading/thread_local.h"
#include "content/public/browser/android/synchronous_compositor.h" #include "content/public/browser/android/synchronous_compositor.h"
struct AwDrawGLInfo; struct AwDrawGLInfo;
...@@ -61,7 +63,7 @@ class ScopedAllowGL { ...@@ -61,7 +63,7 @@ class ScopedAllowGL {
static bool IsAllowed(); static bool IsAllowed();
private: private:
static bool allow_gl; static base::LazyInstance<base::ThreadLocalBoolean> allow_gl;
DISALLOW_COPY_AND_ASSIGN(ScopedAllowGL); DISALLOW_COPY_AND_ASSIGN(ScopedAllowGL);
}; };
......
...@@ -1615,16 +1615,16 @@ public class AwContents { ...@@ -1615,16 +1615,16 @@ public class AwContents {
mIsAttachedToWindow = false; mIsAttachedToWindow = false;
hideAutofillPopup(); hideAutofillPopup();
if (mNativeAwContents != 0) { if (mNativeAwContents != 0) {
if (mContainerView.isHardwareAccelerated()) { Runnable releaseHardware = new Runnable() {
boolean result = mInternalAccessAdapter.executeHardwareAction(new Runnable() { @Override
@Override public void run() {
public void run() { nativeReleaseHardwareDrawOnRenderThread(mNativeAwContents);
nativeReleaseHardwareDrawOnRenderThread(mNativeAwContents);
}
});
if (!result) {
Log.d(TAG, "executeHardwareAction failed");
} }
};
boolean result = mInternalAccessAdapter.executeHardwareAction(releaseHardware);
if (!result) {
Log.e(TAG, "May leak or deadlock. Leaked window?");
releaseHardware.run();
} }
nativeOnDetachedFromWindow(mNativeAwContents); nativeOnDetachedFromWindow(mNativeAwContents);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment