Commit 686474c7 authored by boliu@chromium.org's avatar boliu@chromium.org

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
parent 604d033d
...@@ -240,6 +240,7 @@ bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { ...@@ -240,6 +240,7 @@ bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) {
if (!hardware_enabled_) { if (!hardware_enabled_) {
hardware_enabled_ = compositor_->InitializeHwDraw(); hardware_enabled_ = compositor_->InitializeHwDraw();
if (hardware_enabled_) { if (hardware_enabled_) {
tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this);
gpu::GLInProcessContext* share_context = compositor_->GetShareContext(); gpu::GLInProcessContext* share_context = compositor_->GetShareContext();
DCHECK(share_context); DCHECK(share_context);
shared_renderer_state_->SetSharedContext(share_context); shared_renderer_state_->SetSharedContext(share_context);
...@@ -404,13 +405,16 @@ void BrowserViewRenderer::OnAttachedToWindow(int width, int height) { ...@@ -404,13 +405,16 @@ void BrowserViewRenderer::OnAttachedToWindow(int width, int height) {
attached_to_window_ = true; attached_to_window_ = true;
width_ = width; width_ = width;
height_ = height; height_ = height;
tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this);
} }
void BrowserViewRenderer::OnDetachedFromWindow() { void BrowserViewRenderer::OnDetachedFromWindow() {
TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow");
attached_to_window_ = false; attached_to_window_ = false;
if (hardware_enabled_) { DCHECK(!hardware_enabled_);
}
void BrowserViewRenderer::ReleaseHardware() {
DCHECK(hardware_enabled_);
ReturnUnusedResource(shared_renderer_state_->PassDrawGLInput()); ReturnUnusedResource(shared_renderer_state_->PassDrawGLInput());
ReturnResourceFromParent(); ReturnResourceFromParent();
DCHECK(shared_renderer_state_->ReturnedResourcesEmpty()); DCHECK(shared_renderer_state_->ReturnedResourcesEmpty());
...@@ -418,13 +422,10 @@ void BrowserViewRenderer::OnDetachedFromWindow() { ...@@ -418,13 +422,10 @@ void BrowserViewRenderer::OnDetachedFromWindow() {
compositor_->ReleaseHwDraw(); compositor_->ReleaseHwDraw();
shared_renderer_state_->SetSharedContext(NULL); shared_renderer_state_->SetSharedContext(NULL);
hardware_enabled_ = false; hardware_enabled_ = false;
}
SynchronousCompositorMemoryPolicy zero_policy; SynchronousCompositorMemoryPolicy zero_policy;
RequestMemoryPolicy(zero_policy); RequestMemoryPolicy(zero_policy);
GlobalTileManager::GetInstance()->Remove(tile_manager_key_); 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 { bool BrowserViewRenderer::IsVisible() const {
......
...@@ -106,6 +106,7 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient, ...@@ -106,6 +106,7 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
gfx::Rect GetScreenRect() const; gfx::Rect GetScreenRect() const;
bool attached_to_window() const { return attached_to_window_; } bool attached_to_window() const { return attached_to_window_; }
bool hardware_enabled() const { return hardware_enabled_; } bool hardware_enabled() const { return hardware_enabled_; }
void ReleaseHardware();
// Set the memory policy in shared renderer state and request the tiles from // Set the memory policy in shared renderer state and request the tiles from
// GlobalTileManager. The actually amount of memory allowed by // GlobalTileManager. The actually amount of memory allowed by
......
...@@ -23,7 +23,7 @@ SharedRendererState::SharedRendererState( ...@@ -23,7 +23,7 @@ SharedRendererState::SharedRendererState(
client_on_ui_(client), client_on_ui_(client),
weak_factory_on_ui_thread_(this), weak_factory_on_ui_thread_(this),
ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()),
hardware_allowed_(false), inside_hardware_release_(false),
share_context_(NULL) { share_context_(NULL) {
DCHECK(ui_loop_->BelongsToCurrentThread()); DCHECK(ui_loop_->BelongsToCurrentThread());
DCHECK(client_on_ui_); DCHECK(client_on_ui_);
...@@ -62,14 +62,14 @@ scoped_ptr<DrawGLInput> SharedRendererState::PassDrawGLInput() { ...@@ -62,14 +62,14 @@ scoped_ptr<DrawGLInput> SharedRendererState::PassDrawGLInput() {
return draw_gl_input_.Pass(); return draw_gl_input_.Pass();
} }
void SharedRendererState::SetHardwareAllowed(bool allowed) { void SharedRendererState::SetInsideHardwareRelease(bool inside) {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
hardware_allowed_ = allowed; inside_hardware_release_ = inside;
} }
bool SharedRendererState::IsHardwareAllowed() const { bool SharedRendererState::IsInsideHardwareRelease() const {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
return hardware_allowed_; return inside_hardware_release_;
} }
void SharedRendererState::SetSharedContext(gpu::GLInProcessContext* context) { void SharedRendererState::SetSharedContext(gpu::GLInProcessContext* context) {
...@@ -103,4 +103,15 @@ bool SharedRendererState::ReturnedResourcesEmpty() const { ...@@ -103,4 +103,15 @@ bool SharedRendererState::ReturnedResourcesEmpty() const {
return returned_resources_.empty(); 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 } // namespace android_webview
...@@ -24,6 +24,7 @@ class GLInProcessContext; ...@@ -24,6 +24,7 @@ class GLInProcessContext;
namespace android_webview { namespace android_webview {
class BrowserViewRendererClient; class BrowserViewRendererClient;
class InsideHardwareReleaseReset;
// Set by BrowserViewRenderer and read by HardwareRenderer. // Set by BrowserViewRenderer and read by HardwareRenderer.
struct DrawGLInput { struct DrawGLInput {
...@@ -48,9 +49,7 @@ class SharedRendererState { ...@@ -48,9 +49,7 @@ class SharedRendererState {
void SetDrawGLInput(scoped_ptr<DrawGLInput> input); void SetDrawGLInput(scoped_ptr<DrawGLInput> input);
scoped_ptr<DrawGLInput> PassDrawGLInput(); scoped_ptr<DrawGLInput> PassDrawGLInput();
// Set by UI and read by RT. bool IsInsideHardwareRelease() const;
void SetHardwareAllowed(bool allowed);
bool IsHardwareAllowed() const;
void SetSharedContext(gpu::GLInProcessContext* context); void SetSharedContext(gpu::GLInProcessContext* context);
gpu::GLInProcessContext* GetSharedContext() const; gpu::GLInProcessContext* GetSharedContext() const;
...@@ -60,7 +59,10 @@ class SharedRendererState { ...@@ -60,7 +59,10 @@ class SharedRendererState {
bool ReturnedResourcesEmpty() const; bool ReturnedResourcesEmpty() const;
private: private:
friend class InsideHardwareReleaseReset;
void ClientRequestDrawGLOnUIThread(); void ClientRequestDrawGLOnUIThread();
void SetInsideHardwareRelease(bool inside);
scoped_refptr<base::MessageLoopProxy> ui_loop_; scoped_refptr<base::MessageLoopProxy> ui_loop_;
BrowserViewRendererClient* client_on_ui_; BrowserViewRendererClient* client_on_ui_;
...@@ -70,9 +72,23 @@ class SharedRendererState { ...@@ -70,9 +72,23 @@ class SharedRendererState {
// Accessed by both UI and RT thread. // Accessed by both UI and RT thread.
mutable base::Lock lock_; mutable base::Lock lock_;
scoped_ptr<DrawGLInput> draw_gl_input_; scoped_ptr<DrawGLInput> draw_gl_input_;
bool hardware_allowed_; bool inside_hardware_release_;
gpu::GLInProcessContext* share_context_; gpu::GLInProcessContext* share_context_;
cc::ReturnedResourceArray returned_resources_; 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 } // namespace android_webview
......
...@@ -356,7 +356,7 @@ void AwContents::DrawGL(AwDrawGLInfo* draw_info) { ...@@ -356,7 +356,7 @@ void AwContents::DrawGL(AwDrawGLInfo* draw_info) {
: ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
ScopedAllowGL allow_gl; ScopedAllowGL allow_gl;
if (!shared_renderer_state_.IsHardwareAllowed()) { if (shared_renderer_state_.IsInsideHardwareRelease()) {
hardware_renderer_.reset(); hardware_renderer_.reset();
return; return;
} }
...@@ -843,7 +843,6 @@ void AwContents::SetIsPaused(JNIEnv* env, jobject obj, bool paused) { ...@@ -843,7 +843,6 @@ void AwContents::SetIsPaused(JNIEnv* env, jobject obj, bool paused) {
void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
shared_renderer_state_.SetHardwareAllowed(true);
browser_view_renderer_.OnAttachedToWindow(w, h); browser_view_renderer_.OnAttachedToWindow(w, h);
} }
...@@ -859,7 +858,12 @@ void AwContents::InitializeHardwareDrawIfNeeded() { ...@@ -859,7 +858,12 @@ void AwContents::InitializeHardwareDrawIfNeeded() {
void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 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(); bool hardware_initialized = browser_view_renderer_.hardware_enabled();
if (hardware_initialized) { if (hardware_initialized) {
...@@ -871,10 +875,9 @@ void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { ...@@ -871,10 +875,9 @@ void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) {
info.mode = AwDrawGLInfo::kModeProcess; info.mode = AwDrawGLInfo::kModeProcess;
DrawGL(&info); DrawGL(&info);
} }
browser_view_renderer_.ReleaseHardware();
} }
DCHECK(!hardware_renderer_); DCHECK(!hardware_renderer_);
browser_view_renderer_.OnDetachedFromWindow();
GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); GLViewRendererManager* manager = GLViewRendererManager::GetInstance();
...@@ -1132,6 +1135,14 @@ void AwContents::TrimMemory(JNIEnv* env, ...@@ -1132,6 +1135,14 @@ void AwContents::TrimMemory(JNIEnv* env,
jint level, jint level,
jboolean visible) { jboolean visible) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
enum {
TRIM_MEMORY_MODERATE = 60,
};
if (level >= TRIM_MEMORY_MODERATE) {
ReleaseHardwareDrawIfNeeded();
return;
}
browser_view_renderer_.TrimMemory(level, visible); browser_view_renderer_.TrimMemory(level, visible);
} }
......
...@@ -228,6 +228,7 @@ class AwContents : public FindHelper::Listener, ...@@ -228,6 +228,7 @@ class AwContents : public FindHelper::Listener,
void InitAutofillIfNecessary(bool enabled); void InitAutofillIfNecessary(bool enabled);
void InitializeHardwareDrawIfNeeded(); void InitializeHardwareDrawIfNeeded();
void ReleaseHardwareDrawIfNeeded();
// Geolocation API support // Geolocation API support
void ShowGeolocationPrompt(const GURL& origin, base::Callback<void(bool)>); void ShowGeolocationPrompt(const GURL& origin, base::Callback<void(bool)>);
......
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