diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-05 06:23:04 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-05 06:23:04 +0000 |
commit | 220e908a24ce7805baede951409585e8cfe0db84 (patch) | |
tree | e26f37b5919590ee5cab114f71bd230ef749c462 /android_webview | |
parent | bb664cfb48112bae9d753e567298aacb4436032c (diff) | |
download | chromium_src-220e908a24ce7805baede951409585e8cfe0db84.zip chromium_src-220e908a24ce7805baede951409585e8cfe0db84.tar.gz chromium_src-220e908a24ce7805baede951409585e8cfe0db84.tar.bz2 |
aw: Move HardwareRenderer out of BrowserViewRenderer
Hardware initialization now is done as part of HardwareRenderer constructor
and destructor. AwContents now directly owns HardwareRenderer and post
results back to BrowserViewRenderer where needed.
Expose View.executeHardwareAction to chromium and use it to run hardware
only code.
Also take this opportunity to clean up unneeded public draw_gl.h and
draw_sw.h interfaces.
Rolled corresponding AOSP change:
https://android-review.googlesource.com/#/c/83824/
BUG=344087
NOTRY=true
Review URL: https://codereview.chromium.org/185133003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254957 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
-rw-r--r-- | android_webview/browser/browser_view_renderer.cc | 70 | ||||
-rw-r--r-- | android_webview/browser/browser_view_renderer.h | 30 | ||||
-rw-r--r-- | android_webview/browser/browser_view_renderer_client.h | 4 | ||||
-rw-r--r-- | android_webview/browser/gl_view_renderer_manager.cc | 32 | ||||
-rw-r--r-- | android_webview/browser/gl_view_renderer_manager.h | 14 | ||||
-rw-r--r-- | android_webview/browser/hardware_renderer.cc | 86 | ||||
-rw-r--r-- | android_webview/browser/hardware_renderer.h | 6 | ||||
-rw-r--r-- | android_webview/browser/shared_renderer_state.cc | 13 | ||||
-rw-r--r-- | android_webview/browser/shared_renderer_state.h | 6 | ||||
-rw-r--r-- | android_webview/buildbot/aosp_manifest.xml | 2 | ||||
-rw-r--r-- | android_webview/java/src/org/chromium/android_webview/AwContents.java | 56 | ||||
-rw-r--r-- | android_webview/native/aw_contents.cc | 84 | ||||
-rw-r--r-- | android_webview/native/aw_contents.h | 27 | ||||
-rw-r--r-- | android_webview/public/browser/draw_gl.h | 16 | ||||
-rw-r--r-- | android_webview/public/browser/draw_sw.h | 4 | ||||
-rw-r--r-- | android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java | 5 |
16 files changed, 208 insertions, 247 deletions
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc index 264b3fe..526f5b6 100644 --- a/android_webview/browser/browser_view_renderer.cc +++ b/android_webview/browser/browser_view_renderer.cc @@ -5,7 +5,6 @@ #include "android_webview/browser/browser_view_renderer.h" #include "android_webview/browser/browser_view_renderer_client.h" -#include "android_webview/browser/hardware_renderer.h" #include "android_webview/browser/shared_renderer_state.h" #include "android_webview/public/browser/draw_gl.h" #include "base/android/jni_android.h" @@ -66,27 +65,18 @@ BrowserViewRenderer::~BrowserViewRenderer() { content::SynchronousCompositor::SetClientForWebContents(web_contents_, NULL); } -void BrowserViewRenderer::TrimMemory(int level) { - if (hardware_renderer_) { - client_->UpdateGlobalVisibleRect(); - bool visible = view_visible_ && window_visible_ && - !draw_gl_input_.global_visible_rect.IsEmpty(); - if (hardware_renderer_->TrimMemory(level, visible)) { - // Force a draw for compositor to drop tiles synchronously. - ForceFakeCompositeSW(); - } - } -} - bool BrowserViewRenderer::OnDraw(jobject java_canvas, bool is_hardware_canvas, const gfx::Vector2d& scroll, + const gfx::Rect& global_visible_rect, const gfx::Rect& clip) { draw_gl_input_.frame_id++; draw_gl_input_.scroll_offset = scroll; + draw_gl_input_.global_visible_rect = global_visible_rect; if (clear_view_) return false; if (is_hardware_canvas && attached_to_window_) { + shared_renderer_state_->SetDrawGLInput(draw_gl_input_); // We should be performing a hardware draw here. If we don't have the // compositor yet or if RequestDrawGL fails, it means we failed this draw // and thus return false here to clear to background color for this draw. @@ -96,34 +86,8 @@ bool BrowserViewRenderer::OnDraw(jobject java_canvas, return DrawSWInternal(java_canvas, clip); } -void BrowserViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { - if (!attached_to_window_ || !has_compositor_) - return; - - // TODO(boliu): We should remove dependency on UpdateGlobalVisibleRect - // in DrawGL. - client_->UpdateGlobalVisibleRect(); - shared_renderer_state_->SetDrawGLInput(draw_gl_input_); - - if (draw_gl_input_.global_visible_rect.IsEmpty()) - return; - - if (!hardware_renderer_) { - hardware_renderer_.reset(new HardwareRenderer(shared_renderer_state_)); - } - - hardware_renderer_->DrawGL(draw_info); - const DrawGLResult result = shared_renderer_state_->GetDrawGLResult(); - - if (result.frame_id == draw_gl_input_.frame_id) { - fallback_tick_.Cancel(); - block_invalidates_ = false; - EnsureContinuousInvalidation(!result.clip_contains_visible_rect); - } -} - -void BrowserViewRenderer::SetGlobalVisibleRect(const gfx::Rect& visible_rect) { - draw_gl_input_.global_visible_rect = visible_rect; +void BrowserViewRenderer::DidDrawGL(const DrawGLResult& result) { + DidComposite(!result.clip_contains_visible_rect); } bool BrowserViewRenderer::DrawSWInternal(jobject java_canvas, @@ -243,7 +207,6 @@ void BrowserViewRenderer::OnAttachedToWindow(int width, int height) { void BrowserViewRenderer::OnDetachedFromWindow() { TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); attached_to_window_ = false; - hardware_renderer_.reset(); } bool BrowserViewRenderer::IsAttachedToWindow() const { @@ -266,16 +229,15 @@ void BrowserViewRenderer::DidInitializeCompositor( DCHECK(compositor); DCHECK(!has_compositor_); has_compositor_ = true; - shared_renderer_state_->SetCompositor(compositor); + shared_renderer_state_->SetCompositorOnUiThread(compositor); } void BrowserViewRenderer::DidDestroyCompositor( content::SynchronousCompositor* compositor) { TRACE_EVENT0("android_webview", "BrowserViewRenderer::DidDestroyCompositor"); - DCHECK(!hardware_renderer_.get()); DCHECK(has_compositor_); has_compositor_ = false; - shared_renderer_state_->SetCompositor(NULL); + shared_renderer_state_->SetCompositorOnUiThread(NULL); } void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) { @@ -423,11 +385,10 @@ void BrowserViewRenderer::DidOverscroll(gfx::Vector2dF accumulated_overscroll, client_->DidOverscroll(rounded_overscroll_delta); } -void BrowserViewRenderer::EnsureContinuousInvalidation( - bool invalidate_ignore_compositor) { +void BrowserViewRenderer::EnsureContinuousInvalidation(bool force_invalidate) { // This method should be called again when any of these conditions change. bool need_invalidate = - compositor_needs_continuous_invalidate_ || invalidate_ignore_compositor; + compositor_needs_continuous_invalidate_ || force_invalidate; if (!need_invalidate || block_invalidates_) return; @@ -454,8 +415,8 @@ void BrowserViewRenderer::EnsureContinuousInvalidation( base::Unretained(this))); // No need to reschedule fallback tick if compositor does not need to be - // ticked. This can happen if this is reached because - // invalidate_ignore_compositor is true. + // ticked. This can happen if this is reached because force_invalidate is + // true. if (compositor_needs_continuous_invalidate_) { BrowserThread::PostDelayedTask( BrowserThread::UI, @@ -487,12 +448,15 @@ void BrowserViewRenderer::ForceFakeCompositeSW() { bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { DCHECK(has_compositor_); - bool result = shared_renderer_state_->CompositorDemandDrawSw(canvas); + DidComposite(false); + return result; +} + +void BrowserViewRenderer::DidComposite(bool force_invalidate) { fallback_tick_.Cancel(); block_invalidates_ = false; - EnsureContinuousInvalidation(false); - return result; + EnsureContinuousInvalidation(force_invalidate); } std::string BrowserViewRenderer::ToString(AwDrawGLInfo* draw_info) const { diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h index 5f43089..5ae1d9b 100644 --- a/android_webview/browser/browser_view_renderer.h +++ b/android_webview/browser/browser_view_renderer.h @@ -28,7 +28,6 @@ class WebContents; namespace android_webview { class BrowserViewRendererClient; -class HardwareRenderer; // Delegate to perform rendering actions involving Java objects. class BrowserViewRendererJavaHelper { @@ -66,19 +65,14 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { // returns true. A false return value indicates nothing was or will be drawn. // |java_canvas| is the target of the draw. |is_hardware_canvas| indicates // a GL Draw maybe possible on this canvas. |scroll| if the view's current - // scroll offset. |clip| is the canvas's clip bounds. |visible_rect| is the - // intersection of the view size and the window in window coordinates. + // scroll offset. |clip| is the canvas's clip bounds. |global_visible_rect| + // is the intersection of the view size and the window in window coordinates. bool OnDraw(jobject java_canvas, bool is_hardware_canvas, const gfx::Vector2d& scroll, + const gfx::Rect& global_visible_rect, const gfx::Rect& clip); - - // Called in response to a prior BrowserViewRendererClient::RequestDrawGL() - // call. See AwDrawGLInfo documentation for more details of the contract. - void DrawGL(AwDrawGLInfo* draw_info); - - // The global visible rect changed and this is the new value. - void SetGlobalVisibleRect(const gfx::Rect& visible_rect); + void DidDrawGL(const DrawGLResult& result); // CapturePicture API methods. skia::RefPtr<SkPicture> CapturePicture(int width, int height); @@ -105,8 +99,10 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { bool IsVisible() const; gfx::Rect GetScreenRect() const; - // ComponentCallbacks2.onTrimMemory callback. - void TrimMemory(int level); + // Force invoke the compositor to run produce a 1x1 software frame that is + // immediately discarded. This is a hack to force invoke parts of the + // compositor that are not directly exposed here. + void ForceFakeCompositeSW(); // SynchronousCompositorClient overrides virtual void DidInitializeCompositor( @@ -131,16 +127,16 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { private: // Checks the continuous invalidate and block invalidate state, and schedule - // invalidates appropriately. If |invalidate_ignore_compositor| is true, - // then send a view invalidate regardless of compositor expectation. - void EnsureContinuousInvalidation(bool invalidate_ignore_compositor); + // invalidates appropriately. If |force_invalidate| is true, then send a view + // invalidate regardless of compositor expectation. + void EnsureContinuousInvalidation(bool force_invalidate); bool DrawSWInternal(jobject java_canvas, const gfx::Rect& clip_bounds); bool CompositeSW(SkCanvas* canvas); + void DidComposite(bool force_invalidate); // If we call up view invalidate and OnDraw is not called before a deadline, // then we keep ticking the SynchronousCompositor so it can make progress. void FallbackTickFired(); - void ForceFakeCompositeSW(); gfx::Vector2d max_scroll_offset() const; @@ -153,8 +149,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { content::WebContents* web_contents_; bool has_compositor_; - scoped_ptr<HardwareRenderer> hardware_renderer_; - bool is_paused_; bool view_visible_; bool window_visible_; // Only applicable if |attached_to_window_| is true. diff --git a/android_webview/browser/browser_view_renderer_client.h b/android_webview/browser/browser_view_renderer_client.h index bd7172c..382ce0d 100644 --- a/android_webview/browser/browser_view_renderer_client.h +++ b/android_webview/browser/browser_view_renderer_client.h @@ -26,10 +26,6 @@ class BrowserViewRendererClient { // Called to trigger view invalidations. virtual void PostInvalidate() = 0; - // Synchronously call back to SetGlobalVisibleRect with current value. - // TODO(boliu): Remove this and pass value down when needed. - virtual void UpdateGlobalVisibleRect() = 0; - // Called to get view's absolute location on the screen. virtual gfx::Point GetLocationOnScreen() = 0; diff --git a/android_webview/browser/gl_view_renderer_manager.cc b/android_webview/browser/gl_view_renderer_manager.cc index 980ffeb..13a60fd 100644 --- a/android_webview/browser/gl_view_renderer_manager.cc +++ b/android_webview/browser/gl_view_renderer_manager.cc @@ -37,24 +37,23 @@ void GLViewRendererManager::MarkRenderThread() { DCHECK(render_thread_.is_equal(base::PlatformThread::CurrentHandle())); } -GLViewRendererManager::Key GLViewRendererManager::DidDrawGL(Key key, - RendererType view) { - AutoLock auto_lock(lock_); +GLViewRendererManager::Key GLViewRendererManager::PushBack(RendererType view) { MarkRenderThread(); + DCHECK(mru_list_.end() == + std::find(mru_list_.begin(), mru_list_.end(), view)); + mru_list_.push_back(view); + Key back = mru_list_.end(); + back--; + return back; +} - if (key == mru_list_.end()) { - DCHECK(mru_list_.end() == - std::find(mru_list_.begin(), mru_list_.end(), view)); - mru_list_.push_front(view); - return mru_list_.begin(); - } else { - DCHECK(*key == view); - mru_list_.splice(mru_list_.begin(), mru_list_, key); - return key; - } +void GLViewRendererManager::DidDrawGL(Key key) { + AutoLock auto_lock(lock_); + DCHECK(mru_list_.end() != key); + mru_list_.splice(mru_list_.begin(), mru_list_, key); } -void GLViewRendererManager::NoLongerExpectsDrawGL(Key key) { +void GLViewRendererManager::Remove(Key key) { AutoLock auto_lock(lock_); DCHECK(mru_list_.end() != key); mru_list_.erase(key); @@ -68,9 +67,4 @@ GLViewRendererManager::GetMostRecentlyDrawn() const { return *mru_list_.begin(); } -GLViewRendererManager::Key GLViewRendererManager::NullKey() { - AutoLock auto_lock(lock_); - return mru_list_.end(); -} - } // namespace android_webview diff --git a/android_webview/browser/gl_view_renderer_manager.h b/android_webview/browser/gl_view_renderer_manager.h index 07f1cec..1965c3e 100644 --- a/android_webview/browser/gl_view_renderer_manager.h +++ b/android_webview/browser/gl_view_renderer_manager.h @@ -28,18 +28,18 @@ class GLViewRendererManager { static GLViewRendererManager* GetInstance(); + // TODO(boliu): Move RenderThread checking out of this class. bool OnRenderThread() const; - // If |key| is NullKey(), then |view| is inserted at the front and a new key - // is returned. Otherwise |key| must point to |view| which is moved to the - // front. - Key DidDrawGL(Key key, RendererType view); + Key PushBack(RendererType view); - void NoLongerExpectsDrawGL(Key key); + // |key| must be already in manager. Move renderer corresponding to |key| to + // most recent. + void DidDrawGL(Key key); - RendererType GetMostRecentlyDrawn() const; + void Remove(Key key); - Key NullKey(); + RendererType GetMostRecentlyDrawn() const; private: friend struct base::DefaultLazyInstanceTraits<GLViewRendererManager>; diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index 8ccf5b2..083ace7 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -34,53 +34,42 @@ base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> > } // namespace -HardwareRenderer::HardwareRenderer(SharedRendererState* shared_renderer_state) - : shared_renderer_state_(shared_renderer_state), +HardwareRenderer::HardwareRenderer(SharedRendererState* state) + : shared_renderer_state_(state), last_egl_context_(eglGetCurrentContext()), - manager_key_(GLViewRendererManager::GetInstance()->NullKey()) { + manager_key_(GLViewRendererManager::GetInstance()->PushBack( + shared_renderer_state_)) { DCHECK(last_egl_context_); -} - -HardwareRenderer::~HardwareRenderer() { - GLViewRendererManager* mru = GLViewRendererManager::GetInstance(); - if (manager_key_ != mru->NullKey()) { - mru->NoLongerExpectsDrawGL(manager_key_); - manager_key_ = mru->NullKey(); + if (!g_service.Get()) { + g_service.Get() = new internal::DeferredGpuCommandService; + content::SynchronousCompositor::SetGpuService(g_service.Get()); } - if (gl_surface_) { - ScopedAppGLStateRestore state_restore( - ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); - internal::ScopedAllowGL allow_gl; + ScopedAppGLStateRestore state_restore( + ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); + internal::ScopedAllowGL allow_gl; - shared_renderer_state_->CompositorReleaseHwDraw(); - gl_surface_ = NULL; - } - DCHECK(manager_key_ == GLViewRendererManager::GetInstance()->NullKey()); + gl_surface_ = new AwGLSurface; + bool success = + shared_renderer_state_->CompositorInitializeHwDraw(gl_surface_); + DCHECK(success); } -bool HardwareRenderer::InitializeHardwareDraw() { - TRACE_EVENT0("android_webview", "InitializeHardwareDraw"); - if (!g_service.Get()) { - g_service.Get() = new internal::DeferredGpuCommandService; - content::SynchronousCompositor::SetGpuService(g_service.Get()); - } +HardwareRenderer::~HardwareRenderer() { + GLViewRendererManager* mru = GLViewRendererManager::GetInstance(); + mru->Remove(manager_key_); - bool success = true; - if (!gl_surface_) { - scoped_refptr<AwGLSurface> gl_surface = new AwGLSurface; - success = shared_renderer_state_->CompositorInitializeHwDraw(gl_surface); - if (success) - gl_surface_ = gl_surface; - } + ScopedAppGLStateRestore state_restore( + ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); + internal::ScopedAllowGL allow_gl; - return success; + shared_renderer_state_->CompositorReleaseHwDraw(); + gl_surface_ = NULL; } -void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info) { +bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) { TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); - manager_key_ = GLViewRendererManager::GetInstance()->DidDrawGL( - manager_key_, shared_renderer_state_); + GLViewRendererManager::GetInstance()->DidDrawGL(manager_key_); const DrawGLInput input = shared_renderer_state_->GetDrawGLInput(); // We need to watch if the current Android context has changed and enforce @@ -88,7 +77,7 @@ void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info) { EGLContext current_context = eglGetCurrentContext(); if (!current_context) { DLOG(ERROR) << "DrawGL called without EGLContext"; - return; + return false; } // TODO(boliu): Handle context loss. @@ -99,12 +88,7 @@ void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info) { internal::ScopedAllowGL allow_gl; if (draw_info->mode == AwDrawGLInfo::kModeProcess) - return; - - if (!InitializeHardwareDraw()) { - DLOG(ERROR) << "WebView hardware initialization failed"; - return; - } + return false; // Update memory budget. This will no-op in compositor if the policy has not // changed since last draw. @@ -129,28 +113,20 @@ void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info) { draw_info->clip_right - draw_info->clip_left, draw_info->clip_bottom - draw_info->clip_top); - gfx::Rect viewport_rect; - if (draw_info->is_layer) { - viewport_rect = clip_rect; - } else { - viewport_rect = input.global_visible_rect; - clip_rect.Intersect(viewport_rect); - } - bool did_draw = shared_renderer_state_->CompositorDemandDrawHw( gfx::Size(draw_info->width, draw_info->height), transform, - viewport_rect, + clip_rect, // viewport clip_rect, state_restore.stencil_enabled()); gl_surface_->ResetBackingFrameBufferObject(); if (did_draw) { - DrawGLResult result; - result.frame_id = input.frame_id; - result.clip_contains_visible_rect = clip_rect.Contains(viewport_rect); - shared_renderer_state_->SetDrawGLResult(result); + result->frame_id = input.frame_id; + result->clip_contains_visible_rect = + clip_rect.Contains(input.global_visible_rect); } + return did_draw; } bool HardwareRenderer::TrimMemory(int level, bool visible) { diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index a278694..13800e4 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -25,18 +25,17 @@ class DeferredGpuCommandService; class HardwareRenderer { public: - explicit HardwareRenderer(SharedRendererState* shared_renderer_state); + explicit HardwareRenderer(SharedRendererState* state); ~HardwareRenderer(); static void CalculateTileMemoryPolicy(); - void DrawGL(AwDrawGLInfo* draw_info); + bool DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result); bool TrimMemory(int level, bool visible); private: friend class internal::DeferredGpuCommandService; - bool InitializeHardwareDraw(); void SetMemoryPolicy(content::SynchronousCompositorMemoryPolicy& new_policy); SharedRendererState* shared_renderer_state_; @@ -67,6 +66,7 @@ class ScopedAllowGL { DISALLOW_COPY_AND_ASSIGN(ScopedAllowGL); }; +// TODO(boliu): Teach this class about RT. class DeferredGpuCommandService : public gpu::InProcessCommandBuffer::Service, public base::RefCountedThreadSafe<DeferredGpuCommandService> { diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc index 3e3fe3c6..596f994 100644 --- a/android_webview/browser/shared_renderer_state.cc +++ b/android_webview/browser/shared_renderer_state.cc @@ -53,9 +53,10 @@ void SharedRendererState::ClientRequestDrawGLOnUIThread() { } } -void SharedRendererState::SetCompositor( +void SharedRendererState::SetCompositorOnUiThread( content::SynchronousCompositor* compositor) { AutoLock lock(lock_); + DCHECK(ui_loop_->BelongsToCurrentThread()); both().compositor = compositor; } @@ -113,16 +114,6 @@ DrawGLInput SharedRendererState::GetDrawGLInput() const { return both().draw_gl_input; } -void SharedRendererState::SetDrawGLResult(const DrawGLResult& result) { - AutoLock lock(lock_); - both().draw_gl_result = result; -} - -DrawGLResult SharedRendererState::GetDrawGLResult() const { - AutoLock lock(lock_); - return both().draw_gl_result; -} - internal::BothThreads& SharedRendererState::both() { lock_.AssertAcquired(); return both_threads_; diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h index f863d62..9410e27 100644 --- a/android_webview/browser/shared_renderer_state.h +++ b/android_webview/browser/shared_renderer_state.h @@ -41,7 +41,6 @@ struct BothThreads { // TODO(boliu): Remove |compositor| from shared state. content::SynchronousCompositor* compositor; DrawGLInput draw_gl_input; - DrawGLResult draw_gl_result; BothThreads(); }; @@ -61,7 +60,7 @@ class SharedRendererState { void ClientRequestDrawGL(); // Holds the compositor and lock protects all calls into it. - void SetCompositor(content::SynchronousCompositor* compositor); + void SetCompositorOnUiThread(content::SynchronousCompositor* compositor); bool CompositorInitializeHwDraw(scoped_refptr<gfx::GLSurface> surface); void CompositorReleaseHwDraw(); bool CompositorDemandDrawHw(gfx::Size surface_size, @@ -77,9 +76,6 @@ class SharedRendererState { void SetDrawGLInput(const DrawGLInput& input); DrawGLInput GetDrawGLInput() const; - void SetDrawGLResult(const DrawGLResult& result); - DrawGLResult GetDrawGLResult() const; - private: void ClientRequestDrawGLOnUIThread(); internal::BothThreads& both(); diff --git a/android_webview/buildbot/aosp_manifest.xml b/android_webview/buildbot/aosp_manifest.xml index f83ed5d..b791f02 100644 --- a/android_webview/buildbot/aosp_manifest.xml +++ b/android_webview/buildbot/aosp_manifest.xml @@ -244,7 +244,7 @@ <project path="frameworks/testing" name="platform/frameworks/testing" /> <project path="frameworks/uiautomator" name="platform/frameworks/uiautomator" /> <project path="frameworks/volley" name="platform/frameworks/volley" /> - <project path="frameworks/webview" name="platform/frameworks/webview" revision="efe9d9c0d598bc9cfecf53803997f2afdf93318e" remote="aosp" /> + <project path="frameworks/webview" name="platform/frameworks/webview" revision="f246f9015ed47f7a7d03764d0271918318c82e93" remote="aosp" /> <project path="frameworks/wilhelm" name="platform/frameworks/wilhelm" /> <project path="hardware/akm" name="platform/hardware/akm" /> <project path="hardware/broadcom/libbt" name="platform/hardware/broadcom/libbt" groups="pdk" /> diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index f2c85db..4cbd00d 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -138,6 +138,12 @@ public class AwContents { * should fallback to the SW path. */ boolean requestDrawGL(Canvas canvas); + + /** + * Run the action on with EGLContext current or return false. + * See hidden View#executeHardwareAction for details. + */ + public boolean executeHardwareAction(Runnable action); } private long mNativeAwContents; @@ -419,9 +425,18 @@ public class AwContents { //-------------------------------------------------------------------------------------------- private class AwComponentCallbacks implements ComponentCallbacks2 { @Override - public void onTrimMemory(int level) { + public void onTrimMemory(final int level) { if (mNativeAwContents == 0) return; - nativeTrimMemory(mNativeAwContents, level); + boolean visibleRectEmpty = getGlobalVisibleRect().isEmpty(); + final boolean visible = mIsViewVisible && mIsWindowVisible && !visibleRectEmpty; + // Don't care about return value of executeHardwareAction since if view is not + // hardware accelerated, then there is nothing to clean up anyway. + mInternalAccessAdapter.executeHardwareAction(new Runnable() { + @Override + public void run() { + nativeTrimMemoryOnRenderThread(mNativeAwContents, level, visible); + } + }); } @Override @@ -561,7 +576,6 @@ public class AwContents { mContentsClient.installWebContentsObserver(mContentViewCore); mSettings.setWebContents(nativeWebContents); nativeSetDipScale(mNativeAwContents, (float) mDIPScale); - updateGlobalVisibleRect(); // The only call to onShow. onHide should never be called. mContentViewCore.onShow(); @@ -720,20 +734,15 @@ public class AwContents { return nativeGetAwDrawGLViewContext(mNativeAwContents); } - // This is only to avoid heap allocations inside updateGLobalVisibleRect. It should treated + // This is only to avoid heap allocations inside getGlobalVisibleRect. It should treated // as a local variable in the function and not used anywhere else. private static final Rect sLocalGlobalVisibleRect = new Rect(); - @CalledByNative - private void updateGlobalVisibleRect() { - if (mNativeAwContents == 0) return; + private Rect getGlobalVisibleRect() { if (!mContainerView.getGlobalVisibleRect(sLocalGlobalVisibleRect)) { sLocalGlobalVisibleRect.setEmpty(); } - - nativeSetGlobalVisibleRect(mNativeAwContents, sLocalGlobalVisibleRect.left, - sLocalGlobalVisibleRect.top, sLocalGlobalVisibleRect.right, - sLocalGlobalVisibleRect.bottom); + return sLocalGlobalVisibleRect; } //-------------------------------------------------------------------------------------------- @@ -751,9 +760,12 @@ public class AwContents { mScrollOffsetManager.syncScrollOffsetFromOnDraw(); canvas.getClipBounds(mClipBoundsTemporary); + Rect globalVisibleRect = getGlobalVisibleRect(); if (!nativeOnDraw(mNativeAwContents, canvas, canvas.isHardwareAccelerated(), mContainerView.getScrollX(), mContainerView.getScrollY(), + globalVisibleRect.left, globalVisibleRect.top, + globalVisibleRect.right, globalVisibleRect.bottom, mClipBoundsTemporary.left, mClipBoundsTemporary.top, mClipBoundsTemporary.right, mClipBoundsTemporary.bottom)) { // Can happen during initialization when compositor is not set up. Or when clearView @@ -1548,7 +1560,7 @@ public class AwContents { nativeOnAttachedToWindow(mNativeAwContents, mContainerView.getWidth(), mContainerView.getHeight()); mSettings.setEnableSupportedHardwareAcceleratedFeatures( - mContainerView.isHardwareAccelerated()); + mContainerView.isHardwareAccelerated()); if (mComponentCallbacks != null) return; mComponentCallbacks = new AwComponentCallbacks(); @@ -1563,6 +1575,18 @@ public class AwContents { mIsAttachedToWindow = false; hideAutofillPopup(); if (mNativeAwContents != 0) { + if (mContainerView.isHardwareAccelerated()) { + boolean result = mInternalAccessAdapter.executeHardwareAction(new Runnable() { + @Override + public void run() { + nativeReleaseHardwareDrawOnRenderThread(mNativeAwContents); + } + }); + if (!result) { + Log.d(TAG, "executeHardwareAction failed"); + } + } + nativeOnDetachedFromWindow(mNativeAwContents); } @@ -2031,9 +2055,8 @@ public class AwContents { private native void nativeAddVisitedLinks(long nativeAwContents, String[] visitedLinks); private native boolean nativeOnDraw(long nativeAwContents, Canvas canvas, boolean isHardwareAccelerated, int scrollX, int scrollY, + int visibleLeft, int visibleTop, int visibleRight, int visibleBottom, int clipLeft, int clipTop, int clipRight, int clipBottom); - private native void nativeSetGlobalVisibleRect(long nativeAwContents, int visibleLeft, - int visibleTop, int visibleRight, int visibleBottom); private native void nativeFindAllAsync(long nativeAwContents, String searchString); private native void nativeFindNext(long nativeAwContents, boolean forward); private native void nativeClearMatches(long nativeAwContents); @@ -2051,6 +2074,7 @@ public class AwContents { private native void nativeSetIsPaused(long nativeAwContents, boolean paused); private native void nativeOnAttachedToWindow(long nativeAwContents, int w, int h); private static native void nativeOnDetachedFromWindow(long nativeAwContents); + private static native void nativeReleaseHardwareDrawOnRenderThread(long nativeAwContents); private native void nativeSetDipScale(long nativeAwContents, float dipScale); private native void nativeSetFixedLayoutSize(long nativeAwContents, int widthDip, int heightDip); @@ -2077,7 +2101,9 @@ public class AwContents { private native void nativeSetJsOnlineProperty(long nativeAwContents, boolean networkUp); - private native void nativeTrimMemory(long nativeAwContents, int level); + private native void nativeTrimMemoryOnRenderThread(long nativeAwContents, int level, + boolean visible); private native void nativeCreatePdfExporter(long nativeAwContents, AwPdfExporter awPdfExporter); + } diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index 2b35fc5..7e8d684 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc @@ -11,6 +11,7 @@ #include "android_webview/browser/aw_resource_context.h" #include "android_webview/browser/browser_view_renderer.h" #include "android_webview/browser/gpu_memory_buffer_factory_impl.h" +#include "android_webview/browser/hardware_renderer.h" #include "android_webview/browser/net_disk_cache_remover.h" #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h" #include "android_webview/common/aw_hit_test_data.h" @@ -86,8 +87,8 @@ static void DrawGLFunction(int view_context, void* spare) { // |view_context| is the value that was returned from the java // AwContents.onPrepareDrawGL; this cast must match the code there. - reinterpret_cast<android_webview::BrowserViewRenderer*>(view_context)->DrawGL( - draw_info); + reinterpret_cast<android_webview::AwContents*>(view_context) + ->DrawGL(draw_info); } } @@ -184,7 +185,9 @@ AwContents* AwContents::FromID(int render_process_id, int render_view_id) { } AwContents::AwContents(scoped_ptr<WebContents> web_contents) - : web_contents_(web_contents.Pass()), + : weak_factory_on_ui_thread_(this), + ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), + web_contents_(web_contents.Pass()), shared_renderer_state_( BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), this), @@ -302,6 +305,7 @@ void AwContents::SetAwAutofillManagerDelegate(jobject delegate) { AwContents::~AwContents() { DCHECK(AwContents::FromWebContents(web_contents_.get()) == this); + DCHECK(!hardware_renderer_.get()); web_contents_->RemoveUserData(kAwContentsUserDataKey); if (find_helper_.get()) find_helper_->SetListener(NULL); @@ -362,7 +366,28 @@ jint GetNativeInstanceCount(JNIEnv* env, jclass) { jint AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - return reinterpret_cast<jint>(&browser_view_renderer_); + return reinterpret_cast<jint>(this); +} + +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_)); + } + + DrawGLResult result; + if (hardware_renderer_->DrawGL(draw_info, &result)) { + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind(&AwContents::DidDrawGL, ui_thread_weak_ptr_, result)); + } +} + +void AwContents::DidDrawGL(const DrawGLResult& result) { + browser_view_renderer_.DidDrawGL(result); } namespace { @@ -651,14 +676,6 @@ void AwContents::PostInvalidate() { Java_AwContents_postInvalidateOnAnimation(env, obj.obj()); } -void AwContents::UpdateGlobalVisibleRect() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); - if (!obj.is_null()) - Java_AwContents_updateGlobalVisibleRect(env, obj.obj()); -} - void AwContents::OnNewPicture() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); JNIEnv* env = AttachCurrentThread(); @@ -771,6 +788,10 @@ void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { browser_view_renderer_.OnDetachedFromWindow(); } +void AwContents::ReleaseHardwareDrawOnRenderThread(JNIEnv* env, jobject obj) { + hardware_renderer_.reset(); +} + base::android::ScopedJavaLocalRef<jbyteArray> AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -809,6 +830,10 @@ bool AwContents::OnDraw(JNIEnv* env, jboolean is_hardware_accelerated, jint scroll_x, jint scroll_y, + jint visible_left, + jint visible_top, + jint visible_right, + jint visible_bottom, jint clip_left, jint clip_top, jint clip_right, @@ -818,22 +843,12 @@ bool AwContents::OnDraw(JNIEnv* env, canvas, is_hardware_accelerated, gfx::Vector2d(scroll_x, scroll_y), - gfx::Rect( - clip_left, clip_top, clip_right - clip_left, clip_bottom - clip_top)); -} - -void AwContents::SetGlobalVisibleRect(JNIEnv* env, - jobject obj, - jint visible_left, - jint visible_top, - jint visible_right, - jint visible_bottom) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - browser_view_renderer_.SetGlobalVisibleRect( gfx::Rect(visible_left, visible_top, visible_right - visible_left, - visible_bottom - visible_top)); + visible_bottom - visible_top), + gfx::Rect( + clip_left, clip_top, clip_right - clip_left, clip_bottom - clip_top)); } void AwContents::SetPendingWebContentsForPopup( @@ -1026,9 +1041,22 @@ void AwContents::SetJsOnlineProperty(JNIEnv* env, render_view_host_ext_->SetJsOnlineProperty(network_up); } -void AwContents::TrimMemory(JNIEnv* env, jobject obj, jint level) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - browser_view_renderer_.TrimMemory(level); +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::ForceFakeComposite() { + browser_view_renderer_.ForceFakeCompositeSW(); } void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) { diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index 5b11de1..93c2f2f 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h @@ -23,6 +23,7 @@ class SkBitmap; class TabContents; +struct AwDrawGLInfo; namespace content { class WebContents; @@ -34,6 +35,7 @@ class AwContentsContainer; class AwContentsClientBridge; class AwPdfExporter; class AwWebContentsDelegate; +class HardwareRenderer; // Native side of java-class of same name. // Provides the ownership of and access to browser components required for @@ -98,6 +100,7 @@ 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); @@ -109,16 +112,14 @@ class AwContents : public FindHelper::Listener, jboolean is_hardware_accelerated, jint scroll_x, jint scroll_y, + jint visible_left, + jint visible_top, + jint visible_right, + jint visible_bottom, jint clip_left, jint clip_top, jint clip_right, jint clip_bottom); - void SetGlobalVisibleRect(JNIEnv* env, - jobject obj, - jint visible_left, - jint visible_top, - jint visible_right, - jint visible_bottom); jint GetAwDrawGLViewContext(JNIEnv* env, jobject obj); jlong CapturePicture(JNIEnv* env, jobject obj, int width, int height); void EnableOnNewPicture(JNIEnv* env, jobject obj, jboolean enabled); @@ -126,6 +127,8 @@ class AwContents : public FindHelper::Listener, void SetExtraHeadersForUrl(JNIEnv* env, jobject obj, jstring url, jstring extra_headers); + void DrawGL(AwDrawGLInfo* draw_info); + // Geolocation API support void ShowGeolocationPrompt(const GURL& origin, base::Callback<void(bool)>); void HideGeolocationPrompt(const GURL& origin); @@ -160,7 +163,6 @@ class AwContents : public FindHelper::Listener, // BrowserViewRenderer::Client implementation. virtual bool RequestDrawGL(jobject canvas) OVERRIDE; virtual void PostInvalidate() OVERRIDE; - virtual void UpdateGlobalVisibleRect() OVERRIDE; virtual void OnNewPicture() OVERRIDE; virtual gfx::Point GetLocationOnScreen() OVERRIDE; virtual void SetMaxContainerViewScrollOffset( @@ -192,11 +194,19 @@ class AwContents : public FindHelper::Listener, void SetAwAutofillManagerDelegate(jobject delegate); void SetJsOnlineProperty(JNIEnv* env, jobject obj, jboolean network_up); - void TrimMemory(JNIEnv* env, jobject obj, jint level); + void TrimMemoryOnRenderThread(JNIEnv* env, + jobject obj, + jint level, + jboolean visible); private: void InitAutofillIfNecessary(bool enabled); void SetAndroidWebViewRendererPrefs(); + void DidDrawGL(const DrawGLResult& result); + void ForceFakeComposite(); + + base::WeakPtrFactory<AwContents> weak_factory_on_ui_thread_; + base::WeakPtr<AwContents> ui_thread_weak_ptr_; JavaObjectWeakGlobalRef java_ref_; scoped_ptr<content::WebContents> web_contents_; @@ -208,6 +218,7 @@ class AwContents : public FindHelper::Listener, scoped_ptr<AwContents> pending_contents_; SharedRendererState shared_renderer_state_; BrowserViewRenderer browser_view_renderer_; + scoped_ptr<HardwareRenderer> hardware_renderer_; scoped_ptr<AwPdfExporter> pdf_exporter_; // GURL is supplied by the content layer as requesting frame. diff --git a/android_webview/public/browser/draw_gl.h b/android_webview/public/browser/draw_gl.h index e3108d5..f898025 100644 --- a/android_webview/public/browser/draw_gl.h +++ b/android_webview/public/browser/draw_gl.h @@ -50,22 +50,6 @@ struct AwDrawGLInfo { // Input: current transformation matrix in surface pixels. // Uses the column-based OpenGL matrix format. float transform[16]; - - // Output: tells the caller what to do next. - enum StatusMask { - kStatusMaskDone = 0x0, - kStatusMaskDraw = 0x1, - kStatusMaskInvoke = 0x2, - }; - - // Output: mask indicating the status after calling the functor. - unsigned int status_mask; - - // Output: dirty region to redraw in surface coordinates. - float dirty_left; - float dirty_top; - float dirty_right; - float dirty_bottom; }; // Function to invoke a direct GL draw into the client's pre-configured diff --git a/android_webview/public/browser/draw_sw.h b/android_webview/public/browser/draw_sw.h index 91becfc..97d6607 100644 --- a/android_webview/public/browser/draw_sw.h +++ b/android_webview/public/browser/draw_sw.h @@ -48,10 +48,6 @@ typedef bool (AwIsSkiaVersionCompatibleFunction)(SkiaVersionFunction function); struct AwDrawSWFunctionTable { AwAccessPixelsFunction* access_pixels; AwReleasePixelsFunction* release_pixels; - - // Deprecated. Remove them. - AwCreatePictureFunction* deprecated_create_picture; - AwIsSkiaVersionCompatibleFunction* deprecated_is_skia_version_compatible; }; #endif // ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_SW_H_ diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java index c1e8073..86cc22d 100644 --- a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java +++ b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java @@ -255,5 +255,10 @@ public class AwTestContainerView extends FrameLayout { public boolean requestDrawGL(Canvas canvas) { return false; } + + @Override + public boolean executeHardwareAction(Runnable action) { + return false; + } } } |