Chromium Code Reviews| Index: android_webview/native/aw_contents.cc |
| diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc |
| index c9d38d6cfdd5c3b73accf7b8bc7ba86592b2dd29..71640d5566da8d6ad9883188bfbfe1b49c22e168 100644 |
| --- a/android_webview/native/aw_contents.cc |
| +++ b/android_webview/native/aw_contents.cc |
| @@ -316,15 +316,14 @@ jlong AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { |
| } |
| void AwContents::DrawGL(AwDrawGLInfo* draw_info) { |
| - if (!hardware_renderer_) { |
| - // TODO(boliu): Use executeHardwareAction to synchronously initialize |
| - // hardware on first functor request. Then functor can point directly |
| - // to HardwareRenderer. |
| - hardware_renderer_.reset(new HardwareRenderer(&shared_renderer_state_)); |
| + for (base::Closure c = shared_renderer_state_.PopFrontClosure(); !c.is_null(); |
| + c = shared_renderer_state_.PopFrontClosure()) { |
| + c.Run(); |
| } |
| + // TODO(boliu): Make this a task as well. |
| DrawGLResult result; |
| - if (hardware_renderer_->DrawGL(draw_info, &result)) { |
| + if (hardware_renderer_ && hardware_renderer_->DrawGL(draw_info, &result)) { |
| content::BrowserThread::PostTask( |
| content::BrowserThread::UI, |
| FROM_HERE, |
| @@ -605,13 +604,14 @@ void AwContents::OnReceivedTouchIconUrl(const std::string& url, |
| env, obj.obj(), ConvertUTF8ToJavaString(env, url).obj(), precomposed); |
| } |
| -bool AwContents::RequestDrawGL(jobject canvas) { |
| +bool AwContents::RequestDrawGL(jobject canvas, bool wait_for_completion) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| JNIEnv* env = AttachCurrentThread(); |
| ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| if (obj.is_null()) |
| return false; |
| - return Java_AwContents_requestDrawGL(env, obj.obj(), canvas); |
| + return Java_AwContents_requestDrawGL( |
| + env, obj.obj(), canvas, wait_for_completion); |
| } |
| void AwContents::PostInvalidate() { |
| @@ -726,16 +726,47 @@ 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)); |
| + // Add task but don't schedule it. It will run when DrawGL is called for |
| + // the first time. |
| + shared_renderer_state_.AppendClosure( |
| + base::Bind(&AwContents::InitializeHardwareDrawOnRenderThread, |
| + base::Unretained(this))); |
| browser_view_renderer_.OnAttachedToWindow(w, h); |
| } |
| +void AwContents::InitializeHardwareDrawOnRenderThread() { |
| + DCHECK(!hardware_renderer_); |
| + DCHECK(!shared_renderer_state_.IsHardwareInitialized()); |
| + hardware_renderer_.reset(new HardwareRenderer(&shared_renderer_state_)); |
| + shared_renderer_state_.SetHardwareInitialized(true); |
|
hush (inactive)
2014/05/01 00:35:54
why do we need this?
We are resetting hardware_ren
boliu
2014/05/01 00:46:36
Can't query hardware_renderer_ on UI thread since
hush (inactive)
2014/05/01 01:08:04
okay
On 2014/05/01 00:46:36, boliu wrote:
|
| +} |
| + |
| void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + shared_renderer_state_.ClearClosureQueue(); |
| + shared_renderer_state_.AppendClosure(base::Bind( |
| + &AwContents::ReleaseHardwareDrawOnRenderThread, base::Unretained(this))); |
| + bool draw_functor_succeeded = RequestDrawGL(NULL, true); |
|
hush (inactive)
2014/05/01 00:35:54
these 3 lines seem like a good candidate for a mem
boliu
2014/05/01 00:46:36
I thought about it, but we have 3 tasks and 3 diff
hush (inactive)
2014/05/01 01:08:04
alright
On 2014/05/01 00:46:36, boliu wrote:
|
| + if (!draw_functor_succeeded && |
| + shared_renderer_state_.IsHardwareInitialized()) { |
| + LOG(ERROR) << "Unable to free GL resources. Has the Window leaked"; |
| + // Calling release on wrong thread intentionally. |
| + ReleaseHardwareDrawOnRenderThread(); |
| + } else { |
| + shared_renderer_state_.ClearClosureQueue(); |
| + } |
| + |
| browser_view_renderer_.OnDetachedFromWindow(); |
| } |
| -void AwContents::ReleaseHardwareDrawOnRenderThread(JNIEnv* env, jobject obj) { |
| +void AwContents::ReleaseHardwareDrawOnRenderThread() { |
| + DCHECK(hardware_renderer_); |
| + DCHECK(shared_renderer_state_.IsHardwareInitialized()); |
| + // No point in running any other commands if we released hardware already. |
| + shared_renderer_state_.ClearClosureQueue(); |
| hardware_renderer_.reset(); |
| + shared_renderer_state_.SetHardwareInitialized(false); |
| } |
| base::android::ScopedJavaLocalRef<jbyteArray> |
| @@ -994,17 +1025,27 @@ void AwContents::SetJsOnlineProperty(JNIEnv* env, |
| render_view_host_ext_->SetJsOnlineProperty(network_up); |
| } |
| -void AwContents::TrimMemoryOnRenderThread(JNIEnv* env, |
| - jobject obj, |
| - jint level, |
| - jboolean visible) { |
| - if (hardware_renderer_) { |
| - if (hardware_renderer_->TrimMemory(level, visible)) { |
| - content::BrowserThread::PostTask( |
| - content::BrowserThread::UI, |
| - FROM_HERE, |
| - base::Bind(&AwContents::ForceFakeComposite, ui_thread_weak_ptr_)); |
| - } |
| +void AwContents::TrimMemory(JNIEnv* env, |
| + jobject obj, |
| + jint level, |
| + jboolean visible) { |
| + if (!shared_renderer_state_.IsHardwareInitialized()) |
| + return; |
| + |
| + shared_renderer_state_.AppendClosure( |
| + base::Bind(&AwContents::TrimMemoryOnRenderThread, |
| + base::Unretained(this), |
| + level, |
| + visible)); |
| + RequestDrawGL(NULL, true); |
| +} |
| + |
| +void AwContents::TrimMemoryOnRenderThread(int level, bool visible) { |
| + if (hardware_renderer_ && hardware_renderer_->TrimMemory(level, visible)) { |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&AwContents::ForceFakeComposite, ui_thread_weak_ptr_)); |
| } |
| } |