summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-22 02:09:50 +0000
committerboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-22 02:09:50 +0000
commit686474c7f1a4c06b092fc8fd9ff91e49aa41c274 (patch)
treefc4595be9c0c0914e64ff28717ef699f30173fd3
parent604d033db0ce3e967e00f4f84f6ffaa217f525f7 (diff)
downloadchromium_src-686474c7f1a4c06b092fc8fd9ff91e49aa41c274.zip
chromium_src-686474c7f1a4c06b092fc8fd9ff91e49aa41c274.tar.gz
chromium_src-686474c7f1a4c06b092fc8fd9ff91e49aa41c274.tar.bz2
aw: Release hardware onTrimMemory(MODERATE)
Frameworks destroys the underlying EGLContext on after certain levels of onTrimMemory, so webview must also release its hardware draw resources to avoid using stale references. Factor out release hardware resource code in aw_contents.cc and browser_view_renderer.cc, and call it in onTrimMemory. BUG=395657 Review URL: https://codereview.chromium.org/408803002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284591 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--android_webview/browser/browser_view_renderer.cc27
-rw-r--r--android_webview/browser/browser_view_renderer.h1
-rw-r--r--android_webview/browser/shared_renderer_state.cc21
-rw-r--r--android_webview/browser/shared_renderer_state.h24
-rw-r--r--android_webview/native/aw_contents.cc21
-rw-r--r--android_webview/native/aw_contents.h1
6 files changed, 68 insertions, 27 deletions
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index fd00b6b..ef039bf 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -240,6 +240,7 @@ bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) {
if (!hardware_enabled_) {
hardware_enabled_ = compositor_->InitializeHwDraw();
if (hardware_enabled_) {
+ tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this);
gpu::GLInProcessContext* share_context = compositor_->GetShareContext();
DCHECK(share_context);
shared_renderer_state_->SetSharedContext(share_context);
@@ -404,27 +405,27 @@ void BrowserViewRenderer::OnAttachedToWindow(int width, int height) {
attached_to_window_ = true;
width_ = width;
height_ = height;
- tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this);
}
void BrowserViewRenderer::OnDetachedFromWindow() {
TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow");
attached_to_window_ = false;
- if (hardware_enabled_) {
- ReturnUnusedResource(shared_renderer_state_->PassDrawGLInput());
- ReturnResourceFromParent();
- DCHECK(shared_renderer_state_->ReturnedResourcesEmpty());
-
- compositor_->ReleaseHwDraw();
- shared_renderer_state_->SetSharedContext(NULL);
- hardware_enabled_ = false;
- }
+ DCHECK(!hardware_enabled_);
+}
+
+void BrowserViewRenderer::ReleaseHardware() {
+ DCHECK(hardware_enabled_);
+ ReturnUnusedResource(shared_renderer_state_->PassDrawGLInput());
+ ReturnResourceFromParent();
+ DCHECK(shared_renderer_state_->ReturnedResourcesEmpty());
+
+ compositor_->ReleaseHwDraw();
+ shared_renderer_state_->SetSharedContext(NULL);
+ hardware_enabled_ = false;
+
SynchronousCompositorMemoryPolicy zero_policy;
RequestMemoryPolicy(zero_policy);
GlobalTileManager::GetInstance()->Remove(tile_manager_key_);
- // The hardware resources are released in the destructor of hardware renderer,
- // so we don't need to do it here.
- // See AwContents::ReleaseHardwareDrawOnRenderThread(JNIEnv*, jobject).
}
bool BrowserViewRenderer::IsVisible() const {
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index c89df00..e130334 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -106,6 +106,7 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
gfx::Rect GetScreenRect() const;
bool attached_to_window() const { return attached_to_window_; }
bool hardware_enabled() const { return hardware_enabled_; }
+ void ReleaseHardware();
// Set the memory policy in shared renderer state and request the tiles from
// GlobalTileManager. The actually amount of memory allowed by
diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc
index 8845b76..582908e 100644
--- a/android_webview/browser/shared_renderer_state.cc
+++ b/android_webview/browser/shared_renderer_state.cc
@@ -23,7 +23,7 @@ SharedRendererState::SharedRendererState(
client_on_ui_(client),
weak_factory_on_ui_thread_(this),
ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()),
- hardware_allowed_(false),
+ inside_hardware_release_(false),
share_context_(NULL) {
DCHECK(ui_loop_->BelongsToCurrentThread());
DCHECK(client_on_ui_);
@@ -62,14 +62,14 @@ scoped_ptr<DrawGLInput> SharedRendererState::PassDrawGLInput() {
return draw_gl_input_.Pass();
}
-void SharedRendererState::SetHardwareAllowed(bool allowed) {
+void SharedRendererState::SetInsideHardwareRelease(bool inside) {
base::AutoLock lock(lock_);
- hardware_allowed_ = allowed;
+ inside_hardware_release_ = inside;
}
-bool SharedRendererState::IsHardwareAllowed() const {
+bool SharedRendererState::IsInsideHardwareRelease() const {
base::AutoLock lock(lock_);
- return hardware_allowed_;
+ return inside_hardware_release_;
}
void SharedRendererState::SetSharedContext(gpu::GLInProcessContext* context) {
@@ -103,4 +103,15 @@ bool SharedRendererState::ReturnedResourcesEmpty() const {
return returned_resources_.empty();
}
+InsideHardwareReleaseReset::InsideHardwareReleaseReset(
+ SharedRendererState* shared_renderer_state)
+ : shared_renderer_state_(shared_renderer_state) {
+ DCHECK(!shared_renderer_state_->IsInsideHardwareRelease());
+ shared_renderer_state_->SetInsideHardwareRelease(true);
+}
+
+InsideHardwareReleaseReset::~InsideHardwareReleaseReset() {
+ shared_renderer_state_->SetInsideHardwareRelease(false);
+}
+
} // namespace android_webview
diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h
index 89554ac..01363f1 100644
--- a/android_webview/browser/shared_renderer_state.h
+++ b/android_webview/browser/shared_renderer_state.h
@@ -24,6 +24,7 @@ class GLInProcessContext;
namespace android_webview {
class BrowserViewRendererClient;
+class InsideHardwareReleaseReset;
// Set by BrowserViewRenderer and read by HardwareRenderer.
struct DrawGLInput {
@@ -48,9 +49,7 @@ class SharedRendererState {
void SetDrawGLInput(scoped_ptr<DrawGLInput> input);
scoped_ptr<DrawGLInput> PassDrawGLInput();
- // Set by UI and read by RT.
- void SetHardwareAllowed(bool allowed);
- bool IsHardwareAllowed() const;
+ bool IsInsideHardwareRelease() const;
void SetSharedContext(gpu::GLInProcessContext* context);
gpu::GLInProcessContext* GetSharedContext() const;
@@ -60,7 +59,10 @@ class SharedRendererState {
bool ReturnedResourcesEmpty() const;
private:
+ friend class InsideHardwareReleaseReset;
+
void ClientRequestDrawGLOnUIThread();
+ void SetInsideHardwareRelease(bool inside);
scoped_refptr<base::MessageLoopProxy> ui_loop_;
BrowserViewRendererClient* client_on_ui_;
@@ -70,9 +72,23 @@ class SharedRendererState {
// Accessed by both UI and RT thread.
mutable base::Lock lock_;
scoped_ptr<DrawGLInput> draw_gl_input_;
- bool hardware_allowed_;
+ bool inside_hardware_release_;
gpu::GLInProcessContext* share_context_;
cc::ReturnedResourceArray returned_resources_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedRendererState);
+};
+
+class InsideHardwareReleaseReset {
+ public:
+ explicit InsideHardwareReleaseReset(
+ SharedRendererState* shared_renderer_state);
+ ~InsideHardwareReleaseReset();
+
+ private:
+ SharedRendererState* shared_renderer_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(InsideHardwareReleaseReset);
};
} // namespace android_webview
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 37e05a5..32cc8d1 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -356,7 +356,7 @@ void AwContents::DrawGL(AwDrawGLInfo* draw_info) {
: ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
ScopedAllowGL allow_gl;
- if (!shared_renderer_state_.IsHardwareAllowed()) {
+ if (shared_renderer_state_.IsInsideHardwareRelease()) {
hardware_renderer_.reset();
return;
}
@@ -843,7 +843,6 @@ void AwContents::SetIsPaused(JNIEnv* env, jobject obj, bool paused) {
void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- shared_renderer_state_.SetHardwareAllowed(true);
browser_view_renderer_.OnAttachedToWindow(w, h);
}
@@ -859,7 +858,12 @@ void AwContents::InitializeHardwareDrawIfNeeded() {
void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- shared_renderer_state_.SetHardwareAllowed(false);
+ ReleaseHardwareDrawIfNeeded();
+ browser_view_renderer_.OnDetachedFromWindow();
+}
+
+void AwContents::ReleaseHardwareDrawIfNeeded() {
+ InsideHardwareReleaseReset inside_reset(&shared_renderer_state_);
bool hardware_initialized = browser_view_renderer_.hardware_enabled();
if (hardware_initialized) {
@@ -871,10 +875,9 @@ void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) {
info.mode = AwDrawGLInfo::kModeProcess;
DrawGL(&info);
}
+ browser_view_renderer_.ReleaseHardware();
}
-
DCHECK(!hardware_renderer_);
- browser_view_renderer_.OnDetachedFromWindow();
GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
@@ -1132,6 +1135,14 @@ void AwContents::TrimMemory(JNIEnv* env,
jint level,
jboolean visible) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ enum {
+ TRIM_MEMORY_MODERATE = 60,
+ };
+ if (level >= TRIM_MEMORY_MODERATE) {
+ ReleaseHardwareDrawIfNeeded();
+ return;
+ }
+
browser_view_renderer_.TrimMemory(level, visible);
}
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index 6ff2e57..ddfeaf3 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -228,6 +228,7 @@ class AwContents : public FindHelper::Listener,
void InitAutofillIfNecessary(bool enabled);
void InitializeHardwareDrawIfNeeded();
+ void ReleaseHardwareDrawIfNeeded();
// Geolocation API support
void ShowGeolocationPrompt(const GURL& origin, base::Callback<void(bool)>);