Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Unified Diff: ui/cc/cc/CCSchedulerStateMachine.cpp

Issue 10701016: Initial import attempt, just to play with. Many things disabled/removed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/cc/cc/CCSchedulerStateMachine.h ('k') | ui/cc/cc/CCScopedThreadProxy.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/cc/cc/CCSchedulerStateMachine.cpp
diff --git a/ui/cc/cc/CCSchedulerStateMachine.cpp b/ui/cc/cc/CCSchedulerStateMachine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c729d504b2a9257a98c81a0ce193126d13f85fc7
--- /dev/null
+++ b/ui/cc/cc/CCSchedulerStateMachine.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "cc/CCSchedulerStateMachine.h"
+
+#include <stdio.h>
+
+namespace WebCore {
+
+CCSchedulerStateMachine::CCSchedulerStateMachine()
+ : m_commitState(COMMIT_STATE_IDLE)
+ , m_currentFrameNumber(0)
+ , m_lastFrameNumberWhereDrawWasCalled(-1)
+ , m_consecutiveFailedDraws(0)
+ , m_maximumNumberOfFailedDrawsBeforeDrawIsForced(3)
+ , m_needsRedraw(false)
+ , m_needsForcedRedraw(false)
+ , m_needsForcedRedrawAfterNextCommit(false)
+ , m_needsCommit(false)
+ , m_needsForcedCommit(false)
+ , m_mainThreadNeedsLayerTextures(false)
+ , m_updateMoreResourcesPending(false)
+ , m_insideVSync(false)
+ , m_visible(false)
+ , m_canBeginFrame(false)
+ , m_canDraw(true)
+ , m_drawIfPossibleFailed(false)
+ , m_textureState(LAYER_TEXTURE_STATE_UNLOCKED)
+ , m_contextState(CONTEXT_ACTIVE)
+{
+}
+
+bool CCSchedulerStateMachine::hasDrawnThisFrame() const
+{
+ return m_currentFrameNumber == m_lastFrameNumberWhereDrawWasCalled;
+}
+
+bool CCSchedulerStateMachine::drawSuspendedUntilCommit() const
+{
+ if (!m_canDraw)
+ return true;
+ if (!m_visible)
+ return true;
+ if (m_textureState == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD)
+ return true;
+ return false;
+}
+
+bool CCSchedulerStateMachine::scheduledToDraw() const
+{
+ if (!m_needsRedraw)
+ return false;
+ if (drawSuspendedUntilCommit())
+ return false;
+ return true;
+}
+
+bool CCSchedulerStateMachine::shouldDraw() const
+{
+ if (m_needsForcedRedraw)
+ return true;
+
+ if (!scheduledToDraw())
+ return false;
+ if (!m_insideVSync)
+ return false;
+ if (hasDrawnThisFrame())
+ return false;
+ if (m_contextState != CONTEXT_ACTIVE)
+ return false;
+ return true;
+}
+
+bool CCSchedulerStateMachine::shouldAcquireLayerTexturesForMainThread() const
+{
+ if (!m_mainThreadNeedsLayerTextures)
+ return false;
+ if (m_textureState == LAYER_TEXTURE_STATE_UNLOCKED)
+ return true;
+ ASSERT(m_textureState == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD);
+ // Transfer the lock from impl thread to main thread immediately if the
+ // impl thread is not even scheduled to draw. Guards against deadlocking.
+ if (!scheduledToDraw())
+ return true;
+ if (!vsyncCallbackNeeded())
+ return true;
+ return false;
+}
+
+CCSchedulerStateMachine::Action CCSchedulerStateMachine::nextAction() const
+{
+ if (shouldAcquireLayerTexturesForMainThread())
+ return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD;
+ switch (m_commitState) {
+ case COMMIT_STATE_IDLE:
+ if (m_contextState != CONTEXT_ACTIVE && m_needsForcedRedraw)
+ return ACTION_DRAW_FORCED;
+ 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 m_needsForcedRedraw ? ACTION_DRAW_FORCED : ACTION_DRAW_IF_POSSIBLE;
+ if (m_needsCommit && ((m_visible && m_canBeginFrame) || m_needsForcedCommit))
+ return ACTION_BEGIN_FRAME;
+ return ACTION_NONE;
+
+ case COMMIT_STATE_FRAME_IN_PROGRESS:
+ if (shouldDraw())
+ return m_needsForcedRedraw ? ACTION_DRAW_FORCED : ACTION_DRAW_IF_POSSIBLE;
+ return ACTION_NONE;
+
+ case COMMIT_STATE_UPDATING_RESOURCES:
+ if (shouldDraw())
+ return m_needsForcedRedraw ? ACTION_DRAW_FORCED : ACTION_DRAW_IF_POSSIBLE;
+ if (!m_updateMoreResourcesPending)
+ return ACTION_BEGIN_UPDATE_MORE_RESOURCES;
+ return ACTION_NONE;
+
+ case COMMIT_STATE_READY_TO_COMMIT:
+ return ACTION_COMMIT;
+
+ case COMMIT_STATE_WAITING_FOR_FIRST_DRAW:
+ if (shouldDraw() || m_contextState == CONTEXT_LOST)
+ return m_needsForcedRedraw ? ACTION_DRAW_FORCED : ACTION_DRAW_IF_POSSIBLE;
+ // COMMIT_STATE_WAITING_FOR_FIRST_DRAW wants to enforce a draw. If m_canDraw is false
+ // or textures are not available, proceed to the next step (similar as in COMMIT_STATE_IDLE).
+ bool canCommit = m_visible || m_needsForcedCommit;
+ if (m_needsCommit && canCommit && drawSuspendedUntilCommit())
+ return ACTION_BEGIN_FRAME;
+ return ACTION_NONE;
+ }
+ ASSERT_NOT_REACHED();
+ return ACTION_NONE;
+}
+
+void CCSchedulerStateMachine::updateState(Action action)
+{
+ switch (action) {
+ case ACTION_NONE:
+ return;
+
+ case ACTION_BEGIN_FRAME:
+ 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:
+ ASSERT(m_commitState == COMMIT_STATE_UPDATING_RESOURCES);
+ m_updateMoreResourcesPending = true;
+ return;
+
+ case ACTION_COMMIT:
+ if ((m_needsCommit || !m_visible) && !m_needsForcedCommit)
+ m_commitState = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
+ else
+ m_commitState = COMMIT_STATE_IDLE;
+
+ m_needsRedraw = true;
+ if (m_drawIfPossibleFailed)
+ m_lastFrameNumberWhereDrawWasCalled = -1;
+
+ if (m_needsForcedRedrawAfterNextCommit) {
+ m_needsForcedRedrawAfterNextCommit = false;
+ m_needsForcedRedraw = true;
+ }
+
+ m_textureState = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
+ return;
+
+ case ACTION_DRAW_FORCED:
+ case ACTION_DRAW_IF_POSSIBLE:
+ m_needsRedraw = false;
+ m_needsForcedRedraw = false;
+ m_drawIfPossibleFailed = false;
+ if (m_insideVSync)
+ m_lastFrameNumberWhereDrawWasCalled = m_currentFrameNumber;
+ if (m_commitState == COMMIT_STATE_WAITING_FOR_FIRST_DRAW)
+ m_commitState = COMMIT_STATE_IDLE;
+ if (m_textureState == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD)
+ m_textureState = LAYER_TEXTURE_STATE_UNLOCKED;
+ return;
+
+ case ACTION_BEGIN_CONTEXT_RECREATION:
+ ASSERT(m_commitState == COMMIT_STATE_IDLE);
+ ASSERT(m_contextState == CONTEXT_LOST);
+ m_contextState = CONTEXT_RECREATING;
+ return;
+
+ case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
+ m_textureState = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD;
+ m_mainThreadNeedsLayerTextures = false;
+ if (m_commitState != COMMIT_STATE_FRAME_IN_PROGRESS)
+ m_needsCommit = true;
+ return;
+ }
+}
+
+void CCSchedulerStateMachine::setMainThreadNeedsLayerTextures()
+{
+ ASSERT(!m_mainThreadNeedsLayerTextures);
+ ASSERT(m_textureState != LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
+ m_mainThreadNeedsLayerTextures = true;
+}
+
+bool CCSchedulerStateMachine::vsyncCallbackNeeded() const
+{
+ if (!m_visible || m_contextState != CONTEXT_ACTIVE) {
+ if (m_needsForcedRedraw || m_commitState == COMMIT_STATE_UPDATING_RESOURCES)
+ return true;
+
+ return false;
+ }
+
+ return m_needsRedraw || m_needsForcedRedraw || m_commitState == COMMIT_STATE_UPDATING_RESOURCES;
+}
+
+void CCSchedulerStateMachine::didEnterVSync()
+{
+ m_insideVSync = true;
+}
+
+void CCSchedulerStateMachine::didLeaveVSync()
+{
+ m_currentFrameNumber++;
+ m_insideVSync = false;
+}
+
+void CCSchedulerStateMachine::setVisible(bool visible)
+{
+ m_visible = visible;
+}
+
+void CCSchedulerStateMachine::setNeedsRedraw()
+{
+ m_needsRedraw = true;
+}
+
+void CCSchedulerStateMachine::setNeedsForcedRedraw()
+{
+ m_needsForcedRedraw = true;
+}
+
+void CCSchedulerStateMachine::didDrawIfPossibleCompleted(bool success)
+{
+ m_drawIfPossibleFailed = !success;
+ if (m_drawIfPossibleFailed) {
+ m_needsRedraw = true;
+ m_needsCommit = true;
+ m_consecutiveFailedDraws++;
+ if (m_consecutiveFailedDraws >= m_maximumNumberOfFailedDrawsBeforeDrawIsForced) {
+ m_consecutiveFailedDraws = 0;
+ // We need to force a draw, but it doesn't make sense to do this until
+ // we've committed and have new textures.
+ m_needsForcedRedrawAfterNextCommit = true;
+ }
+ } else
+ m_consecutiveFailedDraws = 0;
+}
+
+void CCSchedulerStateMachine::setNeedsCommit()
+{
+ m_needsCommit = true;
+}
+
+void CCSchedulerStateMachine::setNeedsForcedCommit()
+{
+ m_needsForcedCommit = true;
+}
+
+void CCSchedulerStateMachine::beginFrameComplete()
+{
+ ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS);
+ m_commitState = COMMIT_STATE_UPDATING_RESOURCES;
+}
+
+void CCSchedulerStateMachine::beginFrameAborted()
+{
+ ASSERT(m_commitState == COMMIT_STATE_FRAME_IN_PROGRESS);
+ m_commitState = COMMIT_STATE_IDLE;
+}
+
+void CCSchedulerStateMachine::beginUpdateMoreResourcesComplete(bool morePending)
+{
+ ASSERT(m_commitState == COMMIT_STATE_UPDATING_RESOURCES);
+ ASSERT(m_updateMoreResourcesPending);
+ m_updateMoreResourcesPending = false;
+ if (!morePending)
+ m_commitState = COMMIT_STATE_READY_TO_COMMIT;
+}
+
+void CCSchedulerStateMachine::didLoseContext()
+{
+ if (m_contextState == CONTEXT_LOST || m_contextState == CONTEXT_RECREATING)
+ return;
+ m_contextState = CONTEXT_LOST;
+}
+
+void CCSchedulerStateMachine::didRecreateContext()
+{
+ ASSERT(m_contextState == CONTEXT_RECREATING);
+ m_contextState = CONTEXT_ACTIVE;
+ setNeedsCommit();
+}
+
+void CCSchedulerStateMachine::setMaximumNumberOfFailedDrawsBeforeDrawIsForced(int numDraws)
+{
+ m_maximumNumberOfFailedDrawsBeforeDrawIsForced = numDraws;
+}
+
+}
« no previous file with comments | « ui/cc/cc/CCSchedulerStateMachine.h ('k') | ui/cc/cc/CCScopedThreadProxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698