diff options
author | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-12 22:07:48 +0000 |
---|---|---|
committer | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-12 22:07:48 +0000 |
commit | eabe5003b8c42a48e7072de0282c357cb347256d (patch) | |
tree | 288ca2da8467899b1e92a7f92dae3901285a6c04 /cc | |
parent | 45ad7197ae1b016fe27f795a75e62fb55de08696 (diff) | |
download | chromium_src-eabe5003b8c42a48e7072de0282c357cb347256d.zip chromium_src-eabe5003b8c42a48e7072de0282c357cb347256d.tar.gz chromium_src-eabe5003b8c42a48e7072de0282c357cb347256d.tar.bz2 |
Decouple texture upload checks, tree activation, and drawing.
This prevents us from drawing more often than we need to
when impl-side-painting is enabled.
It removes the concept of scheduling checkForCompletedSetPixels, instead
checking for completed uploads 1) before determining whether or not to make
the pending tree active and 2) before drawing.
Tree activation is handled in two places now: 1) before calculating
animations and 2) before a vsync tick.
When a pending tree is activated, a request to draw is made.
BUG=168724
Review URL: https://chromiumcodereview.appspot.com/11823043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176596 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layer_tree_host_impl.cc | 35 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.h | 2 | ||||
-rw-r--r-- | cc/scheduler.cc | 3 | ||||
-rw-r--r-- | cc/scheduler.h | 1 | ||||
-rw-r--r-- | cc/scheduler_state_machine.cc | 24 | ||||
-rw-r--r-- | cc/scheduler_state_machine.h | 4 | ||||
-rw-r--r-- | cc/scheduler_unittest.cc | 1 | ||||
-rw-r--r-- | cc/test/fake_tile_manager_client.h | 1 | ||||
-rw-r--r-- | cc/thread_proxy.cc | 7 | ||||
-rw-r--r-- | cc/thread_proxy.h | 1 | ||||
-rw-r--r-- | cc/tile_manager.cc | 15 | ||||
-rw-r--r-- | cc/tile_manager.h | 3 |
12 files changed, 55 insertions, 42 deletions
diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 0aa769b..b1c0b7b 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -89,6 +89,7 @@ public: if (!m_layerTreeHostImpl->proxy()->hasImplThread()) setImplThread.reset(new DebugScopedSetImplThread(m_layerTreeHostImpl->proxy())); + m_layerTreeHostImpl->activatePendingTreeIfNeeded(); m_layerTreeHostImpl->animate(base::TimeTicks::Now(), base::Time::Now()); } @@ -200,14 +201,6 @@ bool LayerTreeHostImpl::canDraw() // affect the result of canDraw, make sure to call m_client->onCanDrawStateChanged // in the proper places and update the notifyIfCanDrawChanged test. - // TODO(enne): Since prepareToDraw is the only place that currently does - // tree activiation, this allows prepareToDraw to be entered even if the - // active tree can't draw. This could cause flashing, though. This should - // probably be refactored such that the scheduler handles the tree - // activation rather than prepareToDrwa. - if (pendingTree()) - return true; - if (!rootLayer()) { TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::canDraw no root layer"); return false; @@ -471,6 +464,9 @@ bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame) // in the future. bool drawFrame = true; + // Make sure we have the most recent info regarding which textures have been uploaded. + checkForCompletedSetPixels(); + LayerIteratorType end = LayerIteratorType::end(frame.renderSurfaceLayerList); for (LayerIteratorType it = LayerIteratorType::begin(frame.renderSurfaceLayerList); it != end; ++it) { RenderPass::Id targetRenderPassId = it.targetRenderSurfaceLayer()->renderSurface()->renderPassId(); @@ -671,10 +667,6 @@ bool LayerTreeHostImpl::prepareToDraw(FrameData& frame) { TRACE_EVENT0("cc", "LayerTreeHostImpl::prepareToDraw"); - if (m_tileManager) - m_tileManager->CheckForCompletedSetPixels(); - - activatePendingTreeIfNeeded(); updateDrawProperties(); frame.renderSurfaceLayerList = &activeTree()->RenderSurfaceLayerList(); @@ -722,16 +714,6 @@ void LayerTreeHostImpl::ScheduleManageTiles() m_client->setNeedsManageTilesOnImplThread(); } -void LayerTreeHostImpl::ScheduleCheckForCompletedSetPixels() -{ - // CheckForCompletedSetPixels() should be called before we draw and - // preferably only once per vsync interval. For now just make sure - // a redraw is scheduled and call CheckForCompletedSetPixels() in - // prepareToDraw(). - if (m_client) - m_client->setNeedsRedrawOnImplThread(); -} - bool LayerTreeHostImpl::shouldClearRootRenderPass() const { return m_settings.shouldClearRootRenderPass; @@ -924,11 +906,19 @@ void LayerTreeHostImpl::createPendingTree() m_client->onHasPendingTreeStateChanged(pendingTree()); } +void LayerTreeHostImpl::checkForCompletedSetPixels() +{ + if (m_tileManager) + m_tileManager->CheckForCompletedSetPixels(); +} + void LayerTreeHostImpl::activatePendingTreeIfNeeded() { if (!pendingTree()) return; + checkForCompletedSetPixels(); + // It's always fine to activate to an empty tree. Otherwise, only // activate once all visible resources in pending tree are ready. if (activeTree()->RootLayer() && @@ -948,6 +938,7 @@ void LayerTreeHostImpl::activatePendingTree() m_pendingTree.reset(); m_client->onCanDrawStateChanged(canDraw()); m_client->onHasPendingTreeStateChanged(pendingTree()); + m_client->setNeedsRedrawOnImplThread(); } void LayerTreeHostImpl::setVisible(bool visible) diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h index d1019c1..d3a5858 100644 --- a/cc/layer_tree_host_impl.h +++ b/cc/layer_tree_host_impl.h @@ -122,7 +122,6 @@ public: // TileManagerClient implementation. virtual void ScheduleManageTiles() OVERRIDE; - virtual void ScheduleCheckForCompletedSetPixels() OVERRIDE; // OutputSurfaceClient implementation. virtual void OnVSyncParametersChanged(base::TimeTicks timebase, base::TimeDelta interval) OVERRIDE; @@ -156,6 +155,7 @@ public: LayerTreeImpl* pendingTree() { return m_pendingTree.get(); } const LayerTreeImpl* pendingTree() const { return m_pendingTree.get(); } void createPendingTree(); + void checkForCompletedSetPixels(); virtual void activatePendingTreeIfNeeded(); // Shortcuts to layers on the active tree. diff --git a/cc/scheduler.cc b/cc/scheduler.cc index 630d25b..6442414 100644 --- a/cc/scheduler.cc +++ b/cc/scheduler.cc @@ -168,6 +168,9 @@ void Scheduler::processScheduledActions() case SchedulerStateMachine::ACTION_COMMIT: m_client->scheduledActionCommit(); break; + case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: + m_client->scheduledActionActivatePendingTreeIfNeeded(); + break; case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: { ScheduledActionDrawAndSwapResult result = m_client->scheduledActionDrawAndSwapIfPossible(); m_stateMachine.didDrawIfPossibleCompleted(result.didDraw); diff --git a/cc/scheduler.h b/cc/scheduler.h index 93cd100..eee40ef 100644 --- a/cc/scheduler.h +++ b/cc/scheduler.h @@ -38,6 +38,7 @@ public: virtual ScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() = 0; virtual ScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapForced() = 0; virtual void scheduledActionCommit() = 0; + virtual void scheduledActionActivatePendingTreeIfNeeded() = 0; virtual void scheduledActionBeginContextRecreation() = 0; virtual void scheduledActionAcquireLayerTexturesForMainThread() = 0; virtual void didAnticipatedDrawTimeChange(base::TimeTicks) = 0; diff --git a/cc/scheduler_state_machine.cc b/cc/scheduler_state_machine.cc index c4087e78..f9d8cbc 100644 --- a/cc/scheduler_state_machine.cc +++ b/cc/scheduler_state_machine.cc @@ -13,6 +13,7 @@ SchedulerStateMachine::SchedulerStateMachine() : m_commitState(COMMIT_STATE_IDLE) , m_currentFrameNumber(0) , m_lastFrameNumberWhereDrawWasCalled(-1) + , m_lastFrameNumberWhereTreeActivationAttempted(-1) , m_consecutiveFailedDraws(0) , m_maximumNumberOfFailedDrawsBeforeDrawIsForced(3) , m_needsRedraw(false) @@ -64,6 +65,11 @@ bool SchedulerStateMachine::hasDrawnThisFrame() const return m_currentFrameNumber == m_lastFrameNumberWhereDrawWasCalled; } +bool SchedulerStateMachine::hasAttemptedTreeActivationThisFrame() const +{ + return m_currentFrameNumber == m_lastFrameNumberWhereTreeActivationAttempted; +} + bool SchedulerStateMachine::drawSuspendedUntilCommit() const { if (!m_canDraw) @@ -100,6 +106,11 @@ bool SchedulerStateMachine::shouldDraw() const return true; } +bool SchedulerStateMachine::shouldAttemptTreeActivation() const +{ + return m_hasPendingTree && m_insideVSync && !hasAttemptedTreeActivationThisFrame(); +} + bool SchedulerStateMachine::shouldAcquireLayerTexturesForMainThread() const { if (!m_mainThreadNeedsLayerTextures) @@ -120,6 +131,7 @@ SchedulerStateMachine::Action SchedulerStateMachine::nextAction() const { if (shouldAcquireLayerTexturesForMainThread()) return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; + switch (m_commitState) { case COMMIT_STATE_IDLE: if (m_outputSurfaceState != OUTPUT_SURFACE_ACTIVE && m_needsForcedRedraw) @@ -131,6 +143,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::nextAction() const return ACTION_BEGIN_OUTPUT_SURFACE_RECREATION; if (m_outputSurfaceState == OUTPUT_SURFACE_RECREATING) return ACTION_NONE; + if (shouldAttemptTreeActivation()) + return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; if (shouldDraw()) return m_needsForcedRedraw ? ACTION_DRAW_FORCED : ACTION_DRAW_IF_POSSIBLE; if (m_needsCommit && ((m_visible && m_canBeginFrame) || m_needsForcedCommit)) @@ -139,6 +153,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::nextAction() const return ACTION_NONE; case COMMIT_STATE_FRAME_IN_PROGRESS: + if (shouldAttemptTreeActivation()) + return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; if (shouldDraw()) return m_needsForcedRedraw ? ACTION_DRAW_FORCED : ACTION_DRAW_IF_POSSIBLE; return ACTION_NONE; @@ -147,6 +163,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::nextAction() const return ACTION_COMMIT; case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: { + if (shouldAttemptTreeActivation()) + return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; if (shouldDraw() || m_outputSurfaceState == OUTPUT_SURFACE_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 @@ -158,6 +176,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::nextAction() const } case COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW: + if (shouldAttemptTreeActivation()) + return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; if (m_needsForcedRedraw) return ACTION_DRAW_FORCED; return ACTION_NONE; @@ -172,6 +192,10 @@ void SchedulerStateMachine::updateState(Action action) case ACTION_NONE: return; + case ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: + m_lastFrameNumberWhereTreeActivationAttempted = m_currentFrameNumber; + return; + case ACTION_BEGIN_FRAME: DCHECK(!m_hasPendingTree); DCHECK(m_visible || m_needsForcedCommit); diff --git a/cc/scheduler_state_machine.h b/cc/scheduler_state_machine.h index 10df4df..1186827 100644 --- a/cc/scheduler_state_machine.h +++ b/cc/scheduler_state_machine.h @@ -58,6 +58,7 @@ public: ACTION_NONE, ACTION_BEGIN_FRAME, ACTION_COMMIT, + ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED, ACTION_DRAW_IF_POSSIBLE, ACTION_DRAW_FORCED, ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, @@ -143,13 +144,16 @@ protected: bool drawSuspendedUntilCommit() const; bool scheduledToDraw() const; bool shouldDraw() const; + bool shouldAttemptTreeActivation() const; bool shouldAcquireLayerTexturesForMainThread() const; bool hasDrawnThisFrame() const; + bool hasAttemptedTreeActivationThisFrame() const; CommitState m_commitState; int m_currentFrameNumber; int m_lastFrameNumberWhereDrawWasCalled; + int m_lastFrameNumberWhereTreeActivationAttempted; int m_consecutiveFailedDraws; int m_maximumNumberOfFailedDrawsBeforeDrawIsForced; bool m_needsRedraw; diff --git a/cc/scheduler_unittest.cc b/cc/scheduler_unittest.cc index 16eefeb..74384ec 100644 --- a/cc/scheduler_unittest.cc +++ b/cc/scheduler_unittest.cc @@ -50,6 +50,7 @@ public: } virtual void scheduledActionCommit() OVERRIDE { m_actions.push_back("scheduledActionCommit"); } + virtual void scheduledActionActivatePendingTreeIfNeeded() OVERRIDE { m_actions.push_back("scheduledActionActivatePendingTreeIfNeeded"); } virtual void scheduledActionBeginContextRecreation() OVERRIDE { m_actions.push_back("scheduledActionBeginContextRecreation"); } virtual void scheduledActionAcquireLayerTexturesForMainThread() OVERRIDE { m_actions.push_back("scheduledActionAcquireLayerTexturesForMainThread"); } virtual void didAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE { } diff --git a/cc/test/fake_tile_manager_client.h b/cc/test/fake_tile_manager_client.h index 118cbdd..6e94924 100644 --- a/cc/test/fake_tile_manager_client.h +++ b/cc/test/fake_tile_manager_client.h @@ -15,7 +15,6 @@ class FakeTileManagerClient : public TileManagerClient { // TileManagerClient implementation. virtual void ScheduleManageTiles() OVERRIDE {} - virtual void ScheduleCheckForCompletedSetPixels() OVERRIDE {} }; } // namespace cc diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc index 69d819b..2618400 100644 --- a/cc/thread_proxy.cc +++ b/cc/thread_proxy.cc @@ -727,6 +727,11 @@ void ThreadProxy::scheduledActionCommit() m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); } +void ThreadProxy::scheduledActionActivatePendingTreeIfNeeded() +{ + m_layerTreeHostImpl->activatePendingTreeIfNeeded(); +} + void ThreadProxy::scheduledActionBeginContextRecreation() { DCHECK(isImplThread()); @@ -755,7 +760,7 @@ ScheduledActionDrawAndSwapResult ThreadProxy::scheduledActionDrawAndSwapInternal if (m_inputHandlerOnImplThread.get()) m_inputHandlerOnImplThread->animate(monotonicTime); - // TODO(nduca): make animation happen after tree activation. + m_layerTreeHostImpl->activatePendingTreeIfNeeded(); m_layerTreeHostImpl->animate(monotonicTime, wallClockTime); // This method is called on a forced draw, regardless of whether we are able to produce a frame, diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h index 500ee1c..261d11c 100644 --- a/cc/thread_proxy.h +++ b/cc/thread_proxy.h @@ -74,6 +74,7 @@ public: virtual ScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE; virtual ScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapForced() OVERRIDE; virtual void scheduledActionCommit() OVERRIDE; + virtual void scheduledActionActivatePendingTreeIfNeeded() OVERRIDE; virtual void scheduledActionBeginContextRecreation() OVERRIDE; virtual void scheduledActionAcquireLayerTexturesForMainThread() OVERRIDE; virtual void didAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE; diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc index 3058294..9ad382b 100644 --- a/cc/tile_manager.cc +++ b/cc/tile_manager.cc @@ -78,8 +78,7 @@ TileManager::TileManager( resource_pool_(ResourcePool::Create(resource_provider)), raster_worker_pool_(RasterWorkerPool::Create(num_raster_threads)), manage_tiles_pending_(false), - manage_tiles_call_count_(0), - check_for_completed_set_pixels_pending_(false) { + manage_tiles_call_count_(0) { } TileManager::~TileManager() { @@ -145,13 +144,6 @@ void TileManager::ScheduleManageTiles() { manage_tiles_pending_ = true; } -void TileManager::ScheduleCheckForCompletedSetPixels() { - if (check_for_completed_set_pixels_pending_) - return; - client_->ScheduleCheckForCompletedSetPixels(); - check_for_completed_set_pixels_pending_ = true; -} - class BinComparator { public: bool operator() (const Tile* a, const Tile* b) const { @@ -234,8 +226,6 @@ void TileManager::ManageTiles() { } void TileManager::CheckForCompletedSetPixels() { - check_for_completed_set_pixels_pending_ = false; - while (!tiles_with_pending_set_pixels_.empty()) { Tile* tile = tiles_with_pending_set_pixels_.front(); DCHECK(tile->managed_state().resource); @@ -243,7 +233,6 @@ void TileManager::CheckForCompletedSetPixels() { // Set pixel tasks complete in the order they are posted. if (!resource_pool_->resource_provider()->didSetPixelsComplete( tile->managed_state().resource->id())) { - ScheduleCheckForCompletedSetPixels(); break; } @@ -515,8 +504,6 @@ void TileManager::OnRasterTaskCompleted( resource_pool_->resource_provider()->shallowFlushIfSupported(); managed_tile_state.resource = resource.Pass(); tiles_with_pending_set_pixels_.push(tile); - - ScheduleCheckForCompletedSetPixels(); } else { resource_pool_->resource_provider()->releasePixelBuffer(resource->id()); resource_pool_->ReleaseResource(resource.Pass()); diff --git a/cc/tile_manager.h b/cc/tile_manager.h index b03fdd7..73cae58 100644 --- a/cc/tile_manager.h +++ b/cc/tile_manager.h @@ -25,7 +25,6 @@ class TileVersion; class CC_EXPORT TileManagerClient { public: virtual void ScheduleManageTiles() = 0; - virtual void ScheduleCheckForCompletedSetPixels() = 0; protected: virtual ~TileManagerClient() {} @@ -102,7 +101,6 @@ class CC_EXPORT TileManager { void AssignGpuMemoryToTiles(); void FreeResourcesForTile(Tile* tile); void ScheduleManageTiles(); - void ScheduleCheckForCompletedSetPixels(); void DispatchMoreTasks(); void GatherPixelRefsForTile(Tile* tile); void DispatchImageDecodeTasksForTile(Tile* tile); @@ -122,7 +120,6 @@ class CC_EXPORT TileManager { scoped_ptr<RasterWorkerPool> raster_worker_pool_; bool manage_tiles_pending_; int manage_tiles_call_count_; - bool check_for_completed_set_pixels_pending_; GlobalStateThatImpactsTilePriority global_state_; |