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) {
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,13 +405,16 @@ 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_) {
DCHECK(!hardware_enabled_);
}
void BrowserViewRenderer::ReleaseHardware() {
DCHECK(hardware_enabled_);
ReturnUnusedResource(shared_renderer_state_->PassDrawGLInput());
ReturnResourceFromParent();
DCHECK(shared_renderer_state_->ReturnedResourcesEmpty());
......@@ -418,13 +422,10 @@ void BrowserViewRenderer::OnDetachedFromWindow() {
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 {
......
......@@ -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
......
......@@ -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
......@@ -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
......
......@@ -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);
}
......
......@@ -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)>);
......
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