diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-05 03:28:48 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-05 03:28:48 +0000 |
commit | 74da93008b8889a95d87d31e31ea3781df86b067 (patch) | |
tree | 1f23b6771edf1eb4c926fe81e83c0dbb8c80c94b | |
parent | 9e89dda1239eef8ec90837e3f02d25970d60a972 (diff) | |
download | chromium_src-74da93008b8889a95d87d31e31ea3781df86b067.zip chromium_src-74da93008b8889a95d87d31e31ea3781df86b067.tar.gz chromium_src-74da93008b8889a95d87d31e31ea3781df86b067.tar.bz2 |
cc: Set the max frames pending from the thread proxy.
When a parent compositor is present (ie, ubercompositor), throttle to a single
pending frame.
Tests:
LayerTreeHostTestMaxPendingFrames.DelegatingRenderer
LayerTreeHostTestMaxPendingFrames.GLRenderer
BUG=123444
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/11747002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175275 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/delegating_renderer.cc | 1 | ||||
-rw-r--r-- | cc/frame_rate_controller.cc | 18 | ||||
-rw-r--r-- | cc/frame_rate_controller.h | 5 | ||||
-rw-r--r-- | cc/layer_tree_host_unittest.cc | 55 | ||||
-rw-r--r-- | cc/scheduler.cc | 5 | ||||
-rw-r--r-- | cc/scheduler.h | 2 | ||||
-rw-r--r-- | cc/test/fake_output_surface.h | 16 | ||||
-rw-r--r-- | cc/thread_proxy.cc | 5 | ||||
-rw-r--r-- | cc/thread_proxy.h | 2 |
9 files changed, 95 insertions, 14 deletions
diff --git a/cc/delegating_renderer.cc b/cc/delegating_renderer.cc index da4bee4..5cf92b8 100644 --- a/cc/delegating_renderer.cc +++ b/cc/delegating_renderer.cc @@ -129,6 +129,7 @@ void DelegatingRenderer::drawFrame( RenderPassList& render_passes_in_draw_order) { TRACE_EVENT0("cc", "DelegatingRenderer::drawFrame"); NOTIMPLEMENTED(); + render_passes_in_draw_order.clear(); } bool DelegatingRenderer::swapBuffers() { diff --git a/cc/frame_rate_controller.cc b/cc/frame_rate_controller.cc index 436e80d..a9fe60f 100644 --- a/cc/frame_rate_controller.cc +++ b/cc/frame_rate_controller.cc @@ -10,14 +10,6 @@ #include "cc/time_source.h" #include "cc/thread.h" -namespace { - -// This will be the maximum number of pending frames unless -// FrameRateController::setMaxFramesPending is called. -const int defaultMaxFramesPending = 2; - -} // namespace - namespace cc { class FrameRateControllerTimeSourceAdapter : public TimeSourceClient { @@ -41,7 +33,7 @@ private: FrameRateController::FrameRateController(scoped_refptr<TimeSource> timer) : m_client(0) , m_numFramesPending(0) - , m_maxFramesPending(defaultMaxFramesPending) + , m_maxFramesPending(0) , m_timeSource(timer) , m_active(false) , m_swapBuffersCompleteSupported(true) @@ -56,7 +48,7 @@ FrameRateController::FrameRateController(scoped_refptr<TimeSource> timer) FrameRateController::FrameRateController(Thread* thread) : m_client(0) , m_numFramesPending(0) - , m_maxFramesPending(defaultMaxFramesPending) + , m_maxFramesPending(0) , m_active(false) , m_swapBuffersCompleteSupported(true) , m_isTimeSourceThrottling(false) @@ -90,7 +82,7 @@ void FrameRateController::setActive(bool active) void FrameRateController::setMaxFramesPending(int maxFramesPending) { - DCHECK(maxFramesPending > 0); + DCHECK(maxFramesPending >= 0); m_maxFramesPending = maxFramesPending; } @@ -110,13 +102,13 @@ void FrameRateController::onTimerTick() DCHECK(m_active); // Check if we have too many frames in flight. - bool throttled = m_numFramesPending >= m_maxFramesPending; + bool throttled = m_maxFramesPending && m_numFramesPending >= m_maxFramesPending; TRACE_COUNTER_ID1("cc", "ThrottledVSyncInterval", m_thread, throttled); if (m_client) m_client->vsyncTick(throttled); - if (m_swapBuffersCompleteSupported && !m_isTimeSourceThrottling && m_numFramesPending < m_maxFramesPending) + if (m_swapBuffersCompleteSupported && !m_isTimeSourceThrottling && !throttled) postManualTick(); } diff --git a/cc/frame_rate_controller.h b/cc/frame_rate_controller.h index 16a3e37..681c6d2 100644 --- a/cc/frame_rate_controller.h +++ b/cc/frame_rate_controller.h @@ -29,6 +29,10 @@ class FrameRateControllerTimeSourceAdapter; class CC_EXPORT FrameRateController { public: + enum { + kDefaultMaxFramesPending = 2 + }; + explicit FrameRateController(scoped_refptr<TimeSource>); // Alternate form of FrameRateController with unthrottled frame-rate. explicit FrameRateController(Thread*); @@ -48,6 +52,7 @@ public: void didFinishFrame(); void didAbortAllPendingFrames(); void setMaxFramesPending(int); // 0 for unlimited. + int maxFramesPending() const { return m_maxFramesPending; } // This returns null for unthrottled frame-rate. base::TimeTicks nextTickTime(); diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc index 3f879a9..e8d86cc 100644 --- a/cc/layer_tree_host_unittest.cc +++ b/cc/layer_tree_host_unittest.cc @@ -7,10 +7,12 @@ #include "base/synchronization/lock.h" #include "cc/content_layer.h" #include "cc/content_layer_client.h" +#include "cc/frame_rate_controller.h" #include "cc/layer_impl.h" #include "cc/layer_tree_host_impl.h" #include "cc/layer_tree_impl.h" #include "cc/output_surface.h" +#include "cc/resource_update_queue.h" #include "cc/single_thread_proxy.h" #include "cc/test/fake_content_layer.h" #include "cc/test/fake_content_layer_client.h" @@ -20,8 +22,8 @@ #include "cc/test/fake_scrollbar_layer.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_tree_test_common.h" -#include "cc/resource_update_queue.h" #include "cc/test/occlusion_tracker_test_common.h" +#include "cc/thread_proxy.h" #include "cc/timing_function.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" @@ -2018,5 +2020,56 @@ TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndSoftwareContent) EXPECT_EQ(0u, host->settings().maxPartialTextureUpdates); } +class LayerTreeHostTestMaxPendingFrames : public LayerTreeHostTest { +public: + LayerTreeHostTestMaxPendingFrames() + : LayerTreeHostTest() + { + } + + virtual scoped_ptr<OutputSurface> createOutputSurface() OVERRIDE + { + if (m_delegatingRenderer) + return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>(); + return FakeOutputSurface::Create3d().PassAs<OutputSurface>(); + } + + virtual void beginTest() OVERRIDE + { + postSetNeedsCommitToMainThread(); + } + + virtual void drawLayersOnThread(LayerTreeHostImpl* hostImpl) OVERRIDE + { + DCHECK(hostImpl->proxy()->hasImplThread()); + + const ThreadProxy* proxy = static_cast<ThreadProxy*>(hostImpl->proxy()); + if (m_delegatingRenderer) + EXPECT_EQ(1, proxy->maxFramesPendingForTesting()); + else + EXPECT_EQ(FrameRateController::kDefaultMaxFramesPending, proxy->maxFramesPendingForTesting()); + endTest(); + } + + virtual void afterTest() OVERRIDE + { + } + +protected: + bool m_delegatingRenderer; +}; + +TEST_F(LayerTreeHostTestMaxPendingFrames, DelegatingRenderer) +{ + m_delegatingRenderer = true; + runTest(true); +} + +TEST_F(LayerTreeHostTestMaxPendingFrames, GLRenderer) +{ + m_delegatingRenderer = false; + runTest(true); +} + } // namespace } // namespace cc diff --git a/cc/scheduler.cc b/cc/scheduler.cc index 630d25b..c2dd920 100644 --- a/cc/scheduler.cc +++ b/cc/scheduler.cc @@ -99,6 +99,11 @@ void Scheduler::setMaxFramesPending(int maxFramesPending) m_frameRateController->setMaxFramesPending(maxFramesPending); } +int Scheduler::maxFramesPending() const +{ + return m_frameRateController->maxFramesPending(); +} + void Scheduler::setSwapBuffersCompleteSupported(bool supported) { m_frameRateController->setSwapBuffersCompleteSupported(supported); diff --git a/cc/scheduler.h b/cc/scheduler.h index 93cd100..39cbeea 100644 --- a/cc/scheduler.h +++ b/cc/scheduler.h @@ -77,6 +77,8 @@ public: void beginFrameAborted(); void setMaxFramesPending(int); + int maxFramesPending() const; + void setSwapBuffersCompleteSupported(bool); void didSwapBuffersComplete(); diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index d843cca..70e79b1 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -23,6 +23,14 @@ class FakeOutputSurface : public OutputSurface { return make_scoped_ptr(new FakeOutputSurface(context3d.Pass(), false)); } + static inline scoped_ptr<FakeOutputSurface> Create3d() { + scoped_ptr<WebKit::WebGraphicsContext3D> context3d = + FakeWebGraphicsContext3D::Create( + WebKit::WebGraphicsContext3D::Attributes()) + .PassAs<WebKit::WebGraphicsContext3D>(); + return make_scoped_ptr(new FakeOutputSurface(context3d.Pass(), false)); + } + static inline scoped_ptr<FakeOutputSurface> CreateSoftware( scoped_ptr<SoftwareOutputDevice> software_device) { return make_scoped_ptr( @@ -34,6 +42,14 @@ class FakeOutputSurface : public OutputSurface { return make_scoped_ptr(new FakeOutputSurface(context3d.Pass(), true)); } + static inline scoped_ptr<FakeOutputSurface> CreateDelegating3d() { + scoped_ptr<WebKit::WebGraphicsContext3D> context3d = + FakeWebGraphicsContext3D::Create( + WebKit::WebGraphicsContext3D::Attributes()) + .PassAs<WebKit::WebGraphicsContext3D>(); + return make_scoped_ptr(new FakeOutputSurface(context3d.Pass(), true)); + } + static inline scoped_ptr<FakeOutputSurface> CreateDelegatingSoftware( scoped_ptr<SoftwareOutputDevice> software_device) { return make_scoped_ptr( diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc index ab70861..278fd4c 100644 --- a/cc/thread_proxy.cc +++ b/cc/thread_proxy.cc @@ -945,6 +945,11 @@ void ThreadProxy::initializeRendererOnImplThread(CompletionEvent* completion, bo capabilities->usingSwapCompleteCallback); } + int maxFramesPending = FrameRateController::kDefaultMaxFramesPending; + if (m_layerTreeHostImpl->outputSurface()->Capabilities().has_parent_compositor) + maxFramesPending = 1; + m_schedulerOnImplThread->setMaxFramesPending(maxFramesPending); + completion->signal(); } diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h index 3b2af67..6f35273 100644 --- a/cc/thread_proxy.h +++ b/cc/thread_proxy.h @@ -81,6 +81,8 @@ public: // ResourceUpdateControllerClient implementation virtual void readyToFinalizeTextureUpdates() OVERRIDE; + int maxFramesPendingForTesting() const { return m_schedulerOnImplThread->maxFramesPending(); } + private: ThreadProxy(LayerTreeHost*, scoped_ptr<Thread> implThread); |