summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-05 03:28:48 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-05 03:28:48 +0000
commit74da93008b8889a95d87d31e31ea3781df86b067 (patch)
tree1f23b6771edf1eb4c926fe81e83c0dbb8c80c94b
parent9e89dda1239eef8ec90837e3f02d25970d60a972 (diff)
downloadchromium_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.cc1
-rw-r--r--cc/frame_rate_controller.cc18
-rw-r--r--cc/frame_rate_controller.h5
-rw-r--r--cc/layer_tree_host_unittest.cc55
-rw-r--r--cc/scheduler.cc5
-rw-r--r--cc/scheduler.h2
-rw-r--r--cc/test/fake_output_surface.h16
-rw-r--r--cc/thread_proxy.cc5
-rw-r--r--cc/thread_proxy.h2
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);