Diff
Modified: trunk/Source/WebCore/ChangeLog (110463 => 110464)
--- trunk/Source/WebCore/ChangeLog 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/ChangeLog 2012-03-12 20:08:20 UTC (rev 110464)
@@ -1,3 +1,40 @@
+2012-03-12 Nat Duca <[email protected]>
+
+ [Chromium] Force compositeAndReadback through regular scheduling flow
+ https://bugs.webkit.org/show_bug.cgi?id=77049
+
+ Reviewed by James Robinson.
+
+ * platform/graphics/chromium/cc/CCFrameRateController.cpp:
+ (WebCore::CCFrameRateController::onTimerTick):
+ * platform/graphics/chromium/cc/CCFrameRateController.h:
+ (CCFrameRateControllerClient):
+ * platform/graphics/chromium/cc/CCScheduler.cpp:
+ (WebCore::CCScheduler::setNeedsForcedCommit):
+ (WebCore):
+ (WebCore::CCScheduler::vsyncTick):
+ * platform/graphics/chromium/cc/CCScheduler.h:
+ (CCScheduler):
+ * platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp:
+ (WebCore::CCSchedulerStateMachine::CCSchedulerStateMachine):
+ (WebCore::CCSchedulerStateMachine::nextAction):
+ (WebCore::CCSchedulerStateMachine::updateState):
+ (WebCore::CCSchedulerStateMachine::setNeedsForcedCommit):
+ (WebCore):
+ * platform/graphics/chromium/cc/CCSchedulerStateMachine.h:
+ (CCSchedulerStateMachine):
+ * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+ (WebCore::CCThreadProxy::CCThreadProxy):
+ (WebCore::CCThreadProxy::compositeAndReadback):
+ (WebCore::CCThreadProxy::requestReadbackOnImplThread):
+ (WebCore::CCThreadProxy::forceBeginFrameOnImplThread):
+ (WebCore::CCThreadProxy::scheduledActionBeginFrame):
+ (WebCore::CCThreadProxy::beginFrame):
+ * platform/graphics/chromium/cc/CCThreadProxy.h:
+ (CCThreadProxy):
+ (WebCore::CCThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState):
+ (BeginFrameAndCommitState):
+
2012-03-12 Joshua Bell <[email protected]>
IndexedDB: Handle LevelDB database corruption
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCFrameRateController.cpp (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCFrameRateController.cpp 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCFrameRateController.cpp 2012-03-12 20:08:20 UTC (rev 110464)
@@ -87,7 +87,7 @@
}
if (m_client)
- m_client->beginFrame();
+ m_client->vsyncTick();
}
void CCFrameRateController::didBeginFrame()
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCFrameRateController.h (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCFrameRateController.h 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCFrameRateController.h 2012-03-12 20:08:20 UTC (rev 110464)
@@ -35,7 +35,7 @@
class CCFrameRateControllerClient {
public:
- virtual void beginFrame() = 0;
+ virtual void vsyncTick() = 0;
protected:
virtual ~CCFrameRateControllerClient() { }
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp 2012-03-12 20:08:20 UTC (rev 110464)
@@ -56,6 +56,12 @@
processScheduledActions();
}
+void CCScheduler::setNeedsForcedCommit()
+{
+ m_stateMachine.setNeedsForcedCommit();
+ processScheduledActions();
+}
+
void CCScheduler::setNeedsRedraw()
{
m_stateMachine.setNeedsRedraw();
@@ -101,13 +107,13 @@
processScheduledActions();
}
-void CCScheduler::beginFrame()
+void CCScheduler::vsyncTick()
{
if (m_updateMoreResourcesPending) {
m_updateMoreResourcesPending = false;
m_stateMachine.beginUpdateMoreResourcesComplete(m_client->hasMoreResourceUpdates());
}
- TRACE_EVENT("CCScheduler::beginFrame", this, 0);
+ TRACE_EVENT("CCScheduler::vsyncTick", this, 0);
m_stateMachine.didEnterVSync();
processScheduledActions();
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h 2012-03-12 20:08:20 UTC (rev 110464)
@@ -63,9 +63,13 @@
void setVisible(bool);
void setNeedsCommit();
+
+ // Like setNeedsCommit(), but ensures a commit will definitely happen even if we are not visible.
+ void setNeedsForcedCommit();
+
void setNeedsRedraw();
- // As setNeedsRedraw(), but ensures the draw will definitely happen even if we are not visible.
+ // Like setNeedsRedraw(), but ensures the draw will definitely happen even if we are not visible.
void setNeedsForcedRedraw();
void beginFrameComplete();
@@ -80,7 +84,7 @@
bool redrawPending() const { return m_stateMachine.redrawPending(); }
// CCFrameRateControllerClient implementation
- virtual void beginFrame();
+ virtual void vsyncTick();
private:
CCScheduler(CCSchedulerClient*, PassOwnPtr<CCFrameRateController>);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp 2012-03-12 20:08:20 UTC (rev 110464)
@@ -35,6 +35,7 @@
, m_needsRedraw(false)
, m_needsForcedRedraw(false)
, m_needsCommit(false)
+ , m_needsForcedCommit(false)
, m_updateMoreResourcesPending(false)
, m_insideVSync(false)
, m_visible(false)
@@ -75,13 +76,15 @@
case COMMIT_STATE_IDLE:
if (m_contextState != CONTEXT_ACTIVE && m_needsForcedRedraw)
return ACTION_DRAW;
+ if (m_contextState != CONTEXT_ACTIVE && m_needsForcedCommit)
+ return ACTION_BEGIN_FRAME;
if (m_contextState == CONTEXT_LOST)
return ACTION_BEGIN_CONTEXT_RECREATION;
if (m_contextState == CONTEXT_RECREATING)
return ACTION_NONE;
if (shouldDraw())
return ACTION_DRAW;
- if (m_needsCommit && m_visible)
+ if (m_needsCommit && (m_visible || m_needsForcedCommit))
return ACTION_BEGIN_FRAME;
return ACTION_NONE;
@@ -105,7 +108,7 @@
return ACTION_DRAW;
// COMMIT_STATE_WAITING_FOR_FIRST_DRAW wants to enforce a draw. If m_canDraw is false,
// proceed to the next step (similar as in COMMIT_STATE_IDLE).
- if (!m_canDraw && m_needsCommit && m_visible)
+ if (!m_canDraw && m_needsCommit && (m_visible || m_needsForcedCommit))
return ACTION_BEGIN_FRAME;
return ACTION_NONE;
}
@@ -120,9 +123,10 @@
return;
case ACTION_BEGIN_FRAME:
- ASSERT(m_visible);
+ ASSERT(m_visible || m_needsForcedCommit);
m_commitState = COMMIT_STATE_FRAME_IN_PROGRESS;
m_needsCommit = false;
+ m_needsForcedCommit = false;
return;
case ACTION_BEGIN_UPDATE_MORE_RESOURCES:
@@ -131,7 +135,7 @@
return;
case ACTION_COMMIT:
- if (m_needsCommit || !m_visible)
+ if ((m_needsCommit || !m_visible) && !m_needsForcedCommit)
m_commitState = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
else
m_commitState = COMMIT_STATE_IDLE;
@@ -200,6 +204,11 @@
m_needsCommit = true;
}
+void CCSchedulerStateMachine::setNeedsForcedCommit()
+{
+ m_needsForcedCommit = true;
+}
+
void CCSchedulerStateMachine::beginFrameComplete()
{
ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h 2012-03-12 20:08:20 UTC (rev 110464)
@@ -56,6 +56,7 @@
CONTEXT_LOST,
CONTEXT_RECREATING,
};
+
bool commitPending() const
{
return m_commitState != COMMIT_STATE_IDLE;
@@ -99,6 +100,10 @@
// thread to main.
void setNeedsCommit();
+ // As setNeedsCommit(), but ensures the beginFrame will definitely happen even if
+ // we are not visible.
+ void setNeedsForcedCommit();
+
// Call this only in response to receiving an ACTION_BEGIN_FRAME
// from nextState. Indicates that all painting is complete and that
// updating of compositor resources can begin.
@@ -127,6 +132,7 @@
bool m_needsRedraw;
bool m_needsForcedRedraw;
bool m_needsCommit;
+ bool m_needsForcedCommit;
bool m_updateMoreResourcesPending;
bool m_insideVSync;
bool m_visible;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp 2012-03-12 20:08:20 UTC (rev 110464)
@@ -64,9 +64,8 @@
, m_compositorIdentifier(-1)
, m_layerRendererInitialized(false)
, m_started(false)
- , m_lastExecutedBeginFrameAndCommitSequenceNumber(-1)
- , m_numBeginFrameAndCommitsIssuedOnImplThread(0)
, m_mainThreadProxy(CCScopedThreadProxy::create(CCProxy::mainThread()))
+ , m_beginFrameCompletionEventOnImplThread(0)
, m_readbackRequestOnImplThread(0)
, m_finishAllRenderingCompletionEventOnImplThread(0)
, m_commitCompletionEventOnImplThread(0)
@@ -94,25 +93,14 @@
return false;
}
- // If a commit is pending, perform the commit first.
- if (m_commitRequested) {
- // This bit of code is uglier than it should be because returning
- // pointers via the CCThread task model is really messy. Effectively, we
- // are making a blocking call to createBeginFrameAndCommitTaskOnImplThread,
- // and trying to get the CCMainThread::Task it returns so we can run it.
- OwnPtr<CCThread::Task> beginFrameAndCommitTask;
- {
- CCThread::Task* taskPtr = 0;
- CCCompletionEvent completion;
- CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::obtainBeginFrameAndCommitTaskFromCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&taskPtr)));
- completion.wait();
- beginFrameAndCommitTask = adoptPtr(taskPtr);
- }
- beginFrameAndCommitTask->performTask();
- }
+ // Perform a synchronous commit.
+ CCCompletionEvent beginFrameCompletion;
+ CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::forceBeginFrameOnImplThread, AllowCrossThreadAccess(&beginFrameCompletion)));
+ beginFrameCompletion.wait();
+ beginFrame();
- // Draw using the new tree and read back the results.
+ // Perform a synchronous readback.
ReadbackRequest request;
request.rect = rect;
request.pixels = pixels;
@@ -131,6 +119,7 @@
return;
}
m_readbackRequestOnImplThread = request;
+ m_schedulerOnImplThread->setNeedsRedraw();
m_schedulerOnImplThread->setNeedsForcedRedraw();
}
@@ -385,55 +374,51 @@
m_schedulerOnImplThread->setNeedsForcedRedraw();
}
-void CCThreadProxy::scheduledActionBeginFrame()
+void CCThreadProxy::forceBeginFrameOnImplThread(CCCompletionEvent* completion)
{
- TRACE_EVENT("CCThreadProxy::scheduledActionBeginFrame", this, 0);
- m_mainThreadProxy->postTask(createBeginFrameAndCommitTaskOnImplThread());
-}
+ TRACE_EVENT0("cc", "CCThreadProxy::forceBeginFrameOnImplThread");
+ ASSERT(!m_beginFrameCompletionEventOnImplThread);
-void CCThreadProxy::obtainBeginFrameAndCommitTaskFromCCThread(CCCompletionEvent* completion, CCThread::Task** taskPtr)
-{
- OwnPtr<CCThread::Task> task = createBeginFrameAndCommitTaskOnImplThread();
- *taskPtr = task.leakPtr();
- completion->signal();
+ if (m_schedulerOnImplThread->commitPending()) {
+ completion->signal();
+ return;
+ }
+
+ m_beginFrameCompletionEventOnImplThread = completion;
+ m_schedulerOnImplThread->setNeedsCommit();
+ m_schedulerOnImplThread->setNeedsForcedCommit();
}
-PassOwnPtr<CCThread::Task> CCThreadProxy::createBeginFrameAndCommitTaskOnImplThread()
+void CCThreadProxy::scheduledActionBeginFrame()
{
- TRACE_EVENT("CCThreadProxy::createBeginFrameAndCommitTaskOnImplThread", this, 0);
- ASSERT(isImplThread());
- double frameBeginTime = currentTime();
+ TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionBeginFrame");
+ ASSERT(!m_pendingBeginFrameRequest);
+ m_pendingBeginFrameRequest = adoptPtr(new BeginFrameAndCommitState());
+ m_pendingBeginFrameRequest->frameBeginTime = 0;
+ m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
- // NOTE, it is possible to receieve a request for a
- // beginFrameAndCommitOnImplThread from finishAllRendering while a
- // beginFrameAndCommitOnImplThread is enqueued. Since CCThread doesn't
- // provide a threadsafe way to cancel tasks, it is important that
- // beginFrameAndCommit be structured to understand that it may get called at
- // a point that it shouldn't. We do this by assigning a sequence number to
- // every new beginFrameAndCommit task. Then, beginFrameAndCommit tracks the
- // last executed sequence number, dropping beginFrameAndCommit with sequence
- // numbers below the last executed one.
- int thisTaskSequenceNumber = m_numBeginFrameAndCommitsIssuedOnImplThread;
- m_numBeginFrameAndCommitsIssuedOnImplThread++;
- OwnPtr<CCScrollAndScaleSet> scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
- return createCCThreadTask(this, &CCThreadProxy::beginFrameAndCommit, thisTaskSequenceNumber, frameBeginTime, scrollInfo.release());
+ m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrame));
+
+ if (m_beginFrameCompletionEventOnImplThread) {
+ m_beginFrameCompletionEventOnImplThread->signal();
+ m_beginFrameCompletionEventOnImplThread = 0;
+ }
}
-void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTime, PassOwnPtr<CCScrollAndScaleSet> scrollInfo)
+void CCThreadProxy::beginFrame()
{
- TRACE_EVENT("CCThreadProxy::beginFrameAndCommit", this, 0);
+ TRACE_EVENT0("cc", "CCThreadProxy::beginFrame");
ASSERT(isMainThread());
if (!m_layerTreeHost)
return;
- // Drop beginFrameAndCommit calls that occur out of sequence. See createBeginFrameAndCommitTaskOnImplThread for
- // an explanation of how out-of-sequence beginFrameAndCommit tasks can occur.
- if (sequenceNumber < m_lastExecutedBeginFrameAndCommitSequenceNumber) {
- TRACE_EVENT("EarlyOut_StaleBeginFrameAndCommit", this, 0);
+ if (!m_pendingBeginFrameRequest) {
+ TRACE_EVENT0("cc", "EarlyOut_StaleBeginFrameMessage");
return;
}
- m_lastExecutedBeginFrameAndCommitSequenceNumber = sequenceNumber;
+ OwnPtr<BeginFrameAndCommitState> request(m_pendingBeginFrameRequest.release());
+
// Do not notify the impl thread of commit requests that occur during
// the apply/animate/layout part of the beginFrameAndCommit process since
// those commit requests will get painted immediately. Once we have done
@@ -448,14 +433,12 @@
// FIXME: technically, scroll deltas need to be applied for dropped commits as well.
// Re-do the commit flow so that we don't send the scrollInfo on the BFAC message.
- m_layerTreeHost->applyScrollAndScale(*scrollInfo);
+ m_layerTreeHost->applyScrollAndScale(*request->scrollInfo);
// FIXME: recreate the context if it was requested by the impl thread.
- m_layerTreeHost->updateAnimations(frameBeginTime);
+ m_layerTreeHost->updateAnimations(request->frameBeginTime);
m_layerTreeHost->layout();
- ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);
-
// Clear the commit flag after updating animations and layout here --- objects that only
// layout when painted will trigger another setNeedsCommit inside
// updateLayers.
@@ -482,8 +465,6 @@
}
m_layerTreeHost->commitComplete();
-
- ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);
}
void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion)
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h (110463 => 110464)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h 2012-03-12 20:08:20 UTC (rev 110464)
@@ -90,8 +90,16 @@
explicit CCThreadProxy(CCLayerTreeHost*);
friend class CCThreadProxyContextRecreationTimer;
+ // Set on impl thread, read on main thread.
+ struct BeginFrameAndCommitState {
+ BeginFrameAndCommitState() : frameBeginTime(0) { }
+ double frameBeginTime;
+ OwnPtr<CCScrollAndScaleSet> scrollInfo;
+ };
+ OwnPtr<BeginFrameAndCommitState> m_pendingBeginFrameRequest;
+
// Called on main thread
- void beginFrameAndCommit(int sequenceNumber, double frameBeginTime, PassOwnPtr<CCScrollAndScaleSet>);
+ void beginFrame();
void didCommitAndDrawFrame();
void didCompleteSwapBuffers();
void setAnimationEvents(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime);
@@ -105,8 +113,7 @@
void* pixels;
IntRect rect;
};
- PassOwnPtr<CCThread::Task> createBeginFrameAndCommitTaskOnImplThread();
- void obtainBeginFrameAndCommitTaskFromCCThread(CCCompletionEvent*, CCThread::Task**);
+ void forceBeginFrameOnImplThread(CCCompletionEvent*);
void beginFrameCompleteOnImplThread(CCCompletionEvent*);
void requestReadbackOnImplThread(ReadbackRequest*);
void requestStartPageScaleAnimationOnImplThread(IntSize targetPosition, bool useAnchor, float scale, double durationSec);
@@ -129,11 +136,9 @@
bool m_layerRendererInitialized;
LayerRendererCapabilities m_layerRendererCapabilitiesMainThreadCopy;
bool m_started;
- int m_lastExecutedBeginFrameAndCommitSequenceNumber;
// Used on the CCThread only.
OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl;
- int m_numBeginFrameAndCommitsIssuedOnImplThread;
OwnPtr<CCInputHandler> m_inputHandlerOnImplThread;
@@ -145,6 +150,9 @@
// and initializeLayerRenderer() calls.
RefPtr<GraphicsContext3D> m_contextBeforeInitializationOnImplThread;
+ // Set when the main thread is waiting on a scheduledActionBeginFrame to be issued.
+ CCCompletionEvent* m_beginFrameCompletionEventOnImplThread;
+
// Set when the main thread is waiing on a readback.
ReadbackRequest* m_readbackRequestOnImplThread;
Modified: trunk/Source/WebKit/chromium/ChangeLog (110463 => 110464)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-03-12 20:08:20 UTC (rev 110464)
@@ -1,3 +1,31 @@
+2012-03-12 Nat Duca <[email protected]>
+
+ [Chromium] Force compositeAndReadback through regular scheduling flow
+ https://bugs.webkit.org/show_bug.cgi?id=77049
+
+ Reviewed by James Robinson.
+
+ * tests/CCFrameRateControllerTest.cpp:
+ (WebKitTests::FakeCCFrameRateControllerClient::reset):
+ (WebKitTests::FakeCCFrameRateControllerClient::vsyncTicked):
+ (WebKitTests::FakeCCFrameRateControllerClient::vsyncTick):
+ (FakeCCFrameRateControllerClient):
+ (WebKitTests::TEST):
+ * tests/CCLayerTreeHostTest.cpp:
+ (WTF):
+ (CCLayerTreeHostTestCompositeAndReadbackWhileInvisible):
+ (WTF::CCLayerTreeHostTestCompositeAndReadbackWhileInvisible::CCLayerTreeHostTestCompositeAndReadbackWhileInvisible):
+ (WTF::CCLayerTreeHostTestCompositeAndReadbackWhileInvisible::beginTest):
+ (WTF::CCLayerTreeHostTestCompositeAndReadbackWhileInvisible::didCommitAndDrawFrame):
+ (WTF::CCLayerTreeHostTestCompositeAndReadbackWhileInvisible::afterTest):
+ (WTF::TEST_F):
+ * tests/CCSchedulerStateMachineTest.cpp:
+ (WebCore::StateMachine::setNeedsForcedCommit):
+ (WebCore::StateMachine::needsForcedCommit):
+ (StateMachine):
+ (WebCore::TEST):
+ (WebCore):
+
2012-03-12 Joshua Bell <[email protected]>
IndexedDB: Handle LevelDB database corruption
Modified: trunk/Source/WebKit/chromium/tests/CCFrameRateControllerTest.cpp (110463 => 110464)
--- trunk/Source/WebKit/chromium/tests/CCFrameRateControllerTest.cpp 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebKit/chromium/tests/CCFrameRateControllerTest.cpp 2012-03-12 20:08:20 UTC (rev 110464)
@@ -39,13 +39,13 @@
public:
FakeCCFrameRateControllerClient() { reset(); }
- void reset() { m_frameBegun = false; }
- bool frameBegun() const { return m_frameBegun; }
+ void reset() { m_vsyncTicked = false; }
+ bool vsyncTicked() const { return m_vsyncTicked; }
- virtual void beginFrame() { m_frameBegun = true; }
+ virtual void vsyncTick() { m_vsyncTicked = true; }
protected:
- bool m_frameBegun;
+ bool m_vsyncTicked;
};
@@ -65,7 +65,7 @@
elapsed += thread.pendingDelay();
timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
thread.runPendingTask();
- EXPECT_TRUE(client.frameBegun());
+ EXPECT_TRUE(client.vsyncTicked());
client.reset();
// Tell the controller we drew
@@ -80,7 +80,7 @@
EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
thread.runPendingTask();
- EXPECT_TRUE(client.frameBegun());
+ EXPECT_TRUE(client.vsyncTicked());
}
TEST(CCFrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight)
@@ -100,7 +100,7 @@
elapsed += thread.pendingDelay();
timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
thread.runPendingTask();
- EXPECT_TRUE(client.frameBegun());
+ EXPECT_TRUE(client.vsyncTicked());
client.reset();
// Tell the controller we drew
@@ -111,7 +111,7 @@
EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
thread.runPendingTask();
- EXPECT_TRUE(client.frameBegun());
+ EXPECT_TRUE(client.vsyncTicked());
client.reset();
// Tell the controller we drew, again.
@@ -122,21 +122,21 @@
EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
thread.runPendingTask();
- EXPECT_FALSE(client.frameBegun());
+ EXPECT_FALSE(client.vsyncTicked());
// Tell the controller the first frame ended 5ms later
timeSource->setMonotonicallyIncreasingTimeMs(timeSource->monotonicallyIncreasingTimeMs() + 5);
controller.didFinishFrame();
// Tick should not have been called
- EXPECT_FALSE(client.frameBegun());
+ EXPECT_FALSE(client.vsyncTicked());
// Trigger yet another frame. Since one frames is pending, another vsync callback should run.
elapsed += thread.pendingDelay();
EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
thread.runPendingTask();
- EXPECT_TRUE(client.frameBegun());
+ EXPECT_TRUE(client.vsyncTicked());
}
}
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (110463 => 110464)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2012-03-12 20:08:20 UTC (rev 110464)
@@ -806,6 +806,46 @@
runTestThreaded();
}
+// A compositeAndReadback while invisible should force a normal commit without assertion.
+class CCLayerTreeHostTestCompositeAndReadbackWhileInvisible : public CCLayerTreeHostTestThreadOnly {
+public:
+ CCLayerTreeHostTestCompositeAndReadbackWhileInvisible()
+ : m_numCommits(0)
+ {
+ }
+
+ virtual void beginTest()
+ {
+ }
+
+ virtual void didCommitAndDrawFrame()
+ {
+ m_numCommits++;
+ if (m_numCommits == 1) {
+ m_layerTreeHost->setVisible(false);
+ m_layerTreeHost->setNeedsCommit();
+ m_layerTreeHost->setNeedsCommit();
+ OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4]));
+ m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get()), IntRect(0, 0, 1, 1));
+ } else
+ endTest();
+
+ }
+
+ virtual void afterTest()
+ {
+ }
+
+private:
+ int m_numCommits;
+};
+
+TEST_F(CCLayerTreeHostTestCompositeAndReadbackWhileInvisible, runMultiThread)
+{
+ runTestThreaded();
+}
+
+
// Trigger a frame with setNeedsCommit. Then, inside the resulting animate
// callback, requet another frame using setNeedsAnimate. End the test when
// animate gets called yet-again, indicating that the proxy is correctly
Modified: trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp (110463 => 110464)
--- trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp 2012-03-12 19:57:00 UTC (rev 110463)
+++ trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp 2012-03-12 20:08:20 UTC (rev 110464)
@@ -52,6 +52,9 @@
void setNeedsCommit(bool b) { m_needsCommit = b; }
bool needsCommit() const { return m_needsCommit; }
+ void setNeedsForcedCommit(bool b) { m_needsForcedCommit = b; }
+ bool needsForcedCommit() const { return m_needsForcedCommit; }
+
void setNeedsRedraw(bool b) { m_needsRedraw = b; }
bool needsRedraw() const { return m_needsRedraw; }
@@ -778,4 +781,44 @@
state.didLeaveVSync();
}
+TEST(CCSchedulerStateMachineTest, TestBeginFrameWhenInvisibleAndForceCommit)
+{
+ StateMachine state;
+ state.setVisible(true);
+ state.setNeedsCommit(true);
+ state.setNeedsForcedCommit(true);
+ EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
}
+
+TEST(CCSchedulerStateMachineTest, TestBeginFrameWhenCommitInProgress)
+{
+ StateMachine state;
+ state.setVisible(false);
+ state.setCommitState(CCSchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS);
+ state.setNeedsCommit(true);
+ state.setNeedsForcedCommit(true);
+
+ state.beginFrameComplete();
+ EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
+ state.updateState(state.nextAction());
+ EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
+ state.beginUpdateMoreResourcesComplete(false);
+ EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
+ state.updateState(state.nextAction());
+
+ EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
+
+ EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
+}
+
+TEST(CCSchedulerStateMachineTest, TestBeginFrameWhenContextLost)
+{
+ StateMachine state;
+ state.setVisible(true);
+ state.setNeedsCommit(true);
+ state.setNeedsForcedCommit(true);
+ state.didLoseContext();
+ EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
+}
+
+}