diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 08:29:39 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 08:29:39 +0000 |
commit | 2d32fe0a2958b1cfc4739f76f14f306af17293f2 (patch) | |
tree | e56ab6c0e22ffd357ee610d3e1a3a7d4b94538e7 /android_webview/native | |
parent | 7f9287d47599b4688fd974f93240b08c72c67575 (diff) | |
download | chromium_src-2d32fe0a2958b1cfc4739f76f14f306af17293f2.zip chromium_src-2d32fe0a2958b1cfc4739f76f14f306af17293f2.tar.gz chromium_src-2d32fe0a2958b1cfc4739f76f14f306af17293f2.tar.bz2 |
Add synchronous requestDrawGL
And stop using executeHardwareAction and use synchronous
requestDrawGL. The branching structure needs to happen in DrawGL.
Add a queue of closures to SharedRendererState. So the general pattern is
1. Add closure to queue
2. requestDrawGL
Need to be careful not to let the queue grow unboundedly if requestDrawGL
returns false.
BUG=
Review URL: https://codereview.chromium.org/255023004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267484 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview/native')
-rw-r--r-- | android_webview/native/aw_contents.cc | 82 | ||||
-rw-r--r-- | android_webview/native/aw_contents.h | 14 |
2 files changed, 69 insertions, 27 deletions
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index c9d38d6..ee0e87b 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,15 @@ 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)); + DCHECK(!canvas || !wait_for_completion); 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 +727,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); +} + 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); + 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 +1026,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_)); } } diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index 24e430f..6c7d467 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h @@ -100,7 +100,6 @@ class AwContents : public FindHelper::Listener, void SetIsPaused(JNIEnv* env, jobject obj, bool paused); void OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h); void OnDetachedFromWindow(JNIEnv* env, jobject obj); - void ReleaseHardwareDrawOnRenderThread(JNIEnv* env, jobject obj); base::android::ScopedJavaLocalRef<jbyteArray> GetOpaqueState( JNIEnv* env, jobject obj); jboolean RestoreFromOpaqueState(JNIEnv* env, jobject obj, jbyteArray state); @@ -163,8 +162,8 @@ class AwContents : public FindHelper::Listener, virtual void OnWebLayoutContentsSizeChanged( const gfx::Size& contents_size) OVERRIDE; - // BrowserViewRenderer::Client implementation. - virtual bool RequestDrawGL(jobject canvas) OVERRIDE; + // BrowserViewRendererClient implementation. + virtual bool RequestDrawGL(jobject canvas, bool wait_for_completion) OVERRIDE; virtual void PostInvalidate() OVERRIDE; virtual void OnNewPicture() OVERRIDE; virtual gfx::Point GetLocationOnScreen() OVERRIDE; @@ -197,16 +196,17 @@ class AwContents : public FindHelper::Listener, void SetAwAutofillManagerDelegate(jobject delegate); void SetJsOnlineProperty(JNIEnv* env, jobject obj, jboolean network_up); - void TrimMemoryOnRenderThread(JNIEnv* env, - jobject obj, - jint level, - jboolean visible); + void TrimMemory(JNIEnv* env, jobject obj, jint level, jboolean visible); private: void InitAutofillIfNecessary(bool enabled); void DidDrawGL(const DrawGLResult& result); void ForceFakeComposite(); + void InitializeHardwareDrawOnRenderThread(); + void ReleaseHardwareDrawOnRenderThread(); + void TrimMemoryOnRenderThread(int level, bool visible); + base::WeakPtrFactory<AwContents> weak_factory_on_ui_thread_; base::WeakPtr<AwContents> ui_thread_weak_ptr_; |