diff options
author | boliu <boliu@chromium.org> | 2015-10-01 13:43:55 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-01 20:45:00 +0000 |
commit | 7193f016b6690ff20901da162d3b445748cf1b6f (patch) | |
tree | 95f596e8cc846e91ffbaf7b3b228d5fdf1093c8c /android_webview | |
parent | 7c04ca6d03f4f4df96e93c24fa591eac1965a6f2 (diff) | |
download | chromium_src-7193f016b6690ff20901da162d3b445748cf1b6f.zip chromium_src-7193f016b6690ff20901da162d3b445748cf1b6f.tar.gz chromium_src-7193f016b6690ff20901da162d3b445748cf1b6f.tar.bz2 |
aw: Handle skipped hardware frame correctly
Render thread is still holding the previous frame, which can still be
used to draw in the functor. Update the android_webview bits of code to
handle this correctly. Return true from OnHardwareDraw when render
thread already has a previous frame.
BUG=526842
Review URL: https://codereview.chromium.org/1372193003
Cr-Commit-Position: refs/heads/master@{#351879}
Diffstat (limited to 'android_webview')
-rw-r--r-- | android_webview/browser/browser_view_renderer.cc | 2 | ||||
-rw-r--r-- | android_webview/browser/browser_view_renderer_unittest.cc | 43 | ||||
-rw-r--r-- | android_webview/browser/shared_renderer_state.cc | 9 | ||||
-rw-r--r-- | android_webview/browser/shared_renderer_state.h | 2 | ||||
-rw-r--r-- | android_webview/browser/test/rendering_test.cc | 18 | ||||
-rw-r--r-- | android_webview/browser/test/rendering_test.h | 3 |
6 files changed, 75 insertions, 2 deletions
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc index 556feef..e9602d1 100644 --- a/android_webview/browser/browser_view_renderer.cc +++ b/android_webview/browser/browser_view_renderer.cc @@ -262,7 +262,7 @@ bool BrowserViewRenderer::CompositeHw() { if (!frame.get()) { TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", TRACE_EVENT_SCOPE_THREAD); - return false; + return shared_renderer_state_.HasFrameOnUI(); } scoped_ptr<ChildFrame> child_frame = make_scoped_ptr( diff --git a/android_webview/browser/browser_view_renderer_unittest.cc b/android_webview/browser/browser_view_renderer_unittest.cc index 9e2289c..5b2ec24 100644 --- a/android_webview/browser/browser_view_renderer_unittest.cc +++ b/android_webview/browser/browser_view_renderer_unittest.cc @@ -63,6 +63,7 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { } void WillOnDraw() override { + RenderingTest::WillOnDraw(); // Step 0: A single onDraw on screen. The parent draw constraints // of the BVR will updated to be the initial constraints. // Step 1: A single onDrraw off screen. The parent draw constraints of the @@ -143,4 +144,46 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { RENDERING_TEST_F(TestAnimateInAndOutOfScreen); +class CompositorNoFrameTest : public RenderingTest { + public: + CompositorNoFrameTest() : on_draw_count_(0) {} + + void StartTest() override { + browser_view_renderer_->PostInvalidate(); + } + + void WillOnDraw() override { + if (0 == on_draw_count_) { + // No frame from compositor. + } else if (1 == on_draw_count_) { + SetCompositorFrame(); + } else if (2 == on_draw_count_) { + // No frame from compositor. + } + // There may be trailing invalidates. + } + + void DidOnDraw(bool success) override { + if (0 == on_draw_count_) { + // Should fail as there has been no frames from compositor. + EXPECT_FALSE(success); + browser_view_renderer_->PostInvalidate(); + } else if (1 == on_draw_count_) { + // Should succeed with frame from compositor. + EXPECT_TRUE(success); + browser_view_renderer_->PostInvalidate(); + } else if (2 == on_draw_count_) { + // Should still succeed with last frame, even if no frame from compositor. + EXPECT_TRUE(success); + EndTest(); + } + on_draw_count_++; + } + + private: + int on_draw_count_; +}; + +RENDERING_TEST_F(CompositorNoFrameTest); + } // namespace android_webview diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc index 69a41e5..e62c502 100644 --- a/android_webview/browser/shared_renderer_state.cc +++ b/android_webview/browser/shared_renderer_state.cc @@ -90,6 +90,7 @@ SharedRendererState::SharedRendererState( : ui_loop_(ui_loop), browser_view_renderer_(browser_view_renderer), renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()), + hardware_renderer_has_frame_(false), inside_hardware_release_(false), weak_factory_on_ui_thread_(this) { DCHECK(ui_loop_->BelongsToCurrentThread()); @@ -170,6 +171,8 @@ void SharedRendererState::SetCompositorFrameOnUI(scoped_ptr<ChildFrame> frame) { scoped_ptr<ChildFrame> SharedRendererState::PassCompositorFrameOnRT() { base::AutoLock lock(lock_); + hardware_renderer_has_frame_ = + hardware_renderer_has_frame_ || child_frame_.get(); return child_frame_.Pass(); } @@ -278,6 +281,7 @@ void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { } if (IsInsideHardwareRelease()) { + hardware_renderer_has_frame_ = false; hardware_renderer_.reset(); // Flush the idle queue in tear down. DeferredGpuCommandService::GetInstance()->PerformAllIdleWork(); @@ -342,6 +346,11 @@ void SharedRendererState::ReleaseCompositorResourcesIfNeededOnUI( } } +bool SharedRendererState::HasFrameOnUI() const { + base::AutoLock lock(lock_); + return hardware_renderer_has_frame_ || child_frame_.get(); +} + void SharedRendererState::InitializeHardwareDrawIfNeededOnUI() { DCHECK(ui_loop_->BelongsToCurrentThread()); GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); diff --git a/android_webview/browser/shared_renderer_state.h b/android_webview/browser/shared_renderer_state.h index 8969cef..dca3bcc 100644 --- a/android_webview/browser/shared_renderer_state.h +++ b/android_webview/browser/shared_renderer_state.h @@ -49,6 +49,7 @@ class SharedRendererState { bool ReturnedResourcesEmptyOnUI() const; scoped_ptr<ChildFrame> PassUncommittedFrameOnUI(); void DeleteHardwareRendererOnUI(); + bool HasFrameOnUI() const; // RT thread methods. gfx::Vector2d GetScrollOffsetOnRT(); @@ -95,6 +96,7 @@ class SharedRendererState { // Accessed by both UI and RT thread. mutable base::Lock lock_; + bool hardware_renderer_has_frame_; gfx::Vector2d scroll_offset_; scoped_ptr<ChildFrame> child_frame_; bool inside_hardware_release_; diff --git a/android_webview/browser/test/rendering_test.cc b/android_webview/browser/test/rendering_test.cc index 6b8e57e..4e37cf9 100644 --- a/android_webview/browser/test/rendering_test.cc +++ b/android_webview/browser/test/rendering_test.cc @@ -8,6 +8,7 @@ #include "android_webview/browser/child_frame.h" #include "base/location.h" #include "base/thread_task_runner_handle.h" +#include "cc/output/compositor_frame.h" #include "content/public/test/test_synchronous_compositor_android.h" namespace android_webview { @@ -64,6 +65,23 @@ void RenderingTest::QuitMessageLoop() { message_loop_->QuitWhenIdle(); } +void RenderingTest::SetCompositorFrame() { + DCHECK(compositor_.get()); + scoped_ptr<cc::CompositorFrame> compositor_frame(new cc::CompositorFrame); + scoped_ptr<cc::DelegatedFrameData> frame(new cc::DelegatedFrameData); + scoped_ptr<cc::RenderPass> root_pass(cc::RenderPass::Create()); + gfx::Rect viewport(browser_view_renderer_->size()); + root_pass->SetNew(cc::RenderPassId(1, 1), viewport, viewport, + gfx::Transform()); + frame->render_pass_list.push_back(root_pass.Pass()); + compositor_frame->delegated_frame_data = frame.Pass(); + compositor_->SetHardwareFrame(compositor_frame.Pass()); +} + +void RenderingTest::WillOnDraw() { + SetCompositorFrame(); +} + bool RenderingTest::RequestDrawGL(bool wait_for_completion) { window_->RequestDrawGL(wait_for_completion); return true; diff --git a/android_webview/browser/test/rendering_test.h b/android_webview/browser/test/rendering_test.h index b3cdb4c..0d510ab 100644 --- a/android_webview/browser/test/rendering_test.h +++ b/android_webview/browser/test/rendering_test.h @@ -46,7 +46,7 @@ class RenderingTest : public testing::Test, void ParentDrawConstraintsUpdated( const ParentCompositorDrawConstraints& draw_constraints) override {} // WindowHooks overrides. - void WillOnDraw() override {} + void WillOnDraw() override; void DidOnDraw(bool success) override {} void WillSyncOnRT(SharedRendererState* functor) override {} void DidSyncOnRT(SharedRendererState* functor) override {} @@ -67,6 +67,7 @@ class RenderingTest : public testing::Test, void InitializeCompositor(); void Attach(); void EndTest(); + void SetCompositorFrame(); scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; scoped_ptr<BrowserViewRenderer> browser_view_renderer_; |