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

Side by Side Diff: cc/output/context_cache_controller.cc

Issue 2353033003: Idle cleanup for worker context (Closed)
Patch Set: Feedback and threading cleanup Created 4 years, 2 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 unified diff | Download patch
« no previous file with comments | « cc/output/context_cache_controller.h ('k') | cc/output/context_cache_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/output/context_cache_controller.h" 5 #include "cc/output/context_cache_controller.h"
6 6
7 #include "base/bind.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
8 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
9 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/lock.h"
10 #include "gpu/command_buffer/client/context_support.h" 12 #include "gpu/command_buffer/client/context_support.h"
11 #include "third_party/skia/include/gpu/GrContext.h" 13 #include "third_party/skia/include/gpu/GrContext.h"
12 14
13 namespace cc { 15 namespace cc {
14 ContextCacheController::ScopedVisibility::ScopedVisibility() = default; 16 namespace {
17 static const int kIdleCleanupDelaySeconds = 1;
18 } // namespace
15 19
16 ContextCacheController::ScopedVisibility::~ScopedVisibility() { 20 ContextCacheController::ScopedToken::ScopedToken() = default;
21
22 ContextCacheController::ScopedToken::~ScopedToken() {
17 DCHECK(released_); 23 DCHECK(released_);
18 } 24 }
19 25
20 void ContextCacheController::ScopedVisibility::Release() { 26 void ContextCacheController::ScopedToken::Release() {
21 DCHECK(!released_); 27 DCHECK(!released_);
22 released_ = true; 28 released_ = true;
23 } 29 }
24 30
25 ContextCacheController::ContextCacheController( 31 ContextCacheController::ContextCacheController(
26 gpu::ContextSupport* context_support, 32 gpu::ContextSupport* context_support,
27 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 33 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
28 : context_support_(context_support), task_runner_(std::move(task_runner)) {} 34 : context_support_(context_support),
35 task_runner_(std::move(task_runner)),
36 weak_factory_(this) {
37 weak_ptr_ = weak_factory_.GetWeakPtr();
danakj 2016/09/22 18:56:34 pls explain with comment
ericrk 2016/09/22 19:08:17 Done.
38 }
29 39
30 ContextCacheController::~ContextCacheController() = default; 40 ContextCacheController::~ContextCacheController() = default;
31 41
32 void ContextCacheController::SetGrContext(GrContext* gr_context) { 42 void ContextCacheController::SetGrContext(GrContext* gr_context) {
33 gr_context_ = gr_context; 43 gr_context_ = gr_context;
34 } 44 }
35 45
46 void ContextCacheController::SetLock(base::Lock* lock) {
47 context_lock_ = lock;
48 }
49
36 std::unique_ptr<ContextCacheController::ScopedVisibility> 50 std::unique_ptr<ContextCacheController::ScopedVisibility>
37 ContextCacheController::ClientBecameVisible() { 51 ContextCacheController::ClientBecameVisible() {
52 if (context_lock_)
53 context_lock_->AssertAcquired();
54
38 bool became_visible = num_clients_visible_ == 0; 55 bool became_visible = num_clients_visible_ == 0;
39 ++num_clients_visible_; 56 ++num_clients_visible_;
40 57
41 if (became_visible) 58 if (became_visible)
42 context_support_->SetAggressivelyFreeResources(false); 59 context_support_->SetAggressivelyFreeResources(false);
43 60
44 return base::WrapUnique(new ScopedVisibility()); 61 return base::WrapUnique(new ScopedVisibility());
45 } 62 }
46 63
47 void ContextCacheController::ClientBecameNotVisible( 64 void ContextCacheController::ClientBecameNotVisible(
48 std::unique_ptr<ScopedVisibility> scoped_visibility) { 65 std::unique_ptr<ScopedVisibility> scoped_visibility) {
49 DCHECK(scoped_visibility); 66 DCHECK(scoped_visibility);
50 scoped_visibility->Release(); 67 scoped_visibility->Release();
51 68
69 if (context_lock_)
70 context_lock_->AssertAcquired();
71
52 DCHECK_GT(num_clients_visible_, 0u); 72 DCHECK_GT(num_clients_visible_, 0u);
53 --num_clients_visible_; 73 --num_clients_visible_;
54 74
55 if (num_clients_visible_ == 0) { 75 if (num_clients_visible_ == 0) {
76 // We are freeing resources now - cancel any pending idle callbacks.
77 InvalidatePendingIdleCallbacks();
78
56 if (gr_context_) 79 if (gr_context_)
57 gr_context_->freeGpuResources(); 80 gr_context_->freeGpuResources();
58 context_support_->SetAggressivelyFreeResources(true); 81 context_support_->SetAggressivelyFreeResources(true);
59 } 82 }
60 } 83 }
61 84
62 std::unique_ptr<ContextCacheController::ScopedVisibility> 85 std::unique_ptr<ContextCacheController::ScopedBusy>
63 ContextCacheController::CreateScopedVisibilityForTesting() const { 86 ContextCacheController::ClientBecameBusy() {
64 return base::WrapUnique(new ScopedVisibility()); 87 if (context_lock_)
88 context_lock_->AssertAcquired();
89
90 ++num_clients_busy_;
91 // We are busy, cancel any pending idle callbacks.
92 InvalidatePendingIdleCallbacks();
93
94 return base::WrapUnique(new ScopedBusy());
65 } 95 }
66 96
67 void ContextCacheController::ReleaseScopedVisibilityForTesting( 97 void ContextCacheController::ClientBecameNotBusy(
68 std::unique_ptr<ScopedVisibility> scoped_visibility) const { 98 std::unique_ptr<ScopedBusy> scoped_busy) {
69 scoped_visibility->Release(); 99 DCHECK(scoped_busy);
100 scoped_busy->Release();
101
102 if (context_lock_)
103 context_lock_->AssertAcquired();
104
105 DCHECK_GT(num_clients_busy_, 0u);
106 --num_clients_busy_;
107
108 // If we have become idle and we are visible, queue a task to drop resources
109 // after a delay. If are not visible, we have already dropped resources.
110 if (num_clients_busy_ == 0 && num_clients_visible_ > 0 && task_runner_) {
111 // If we already have a callback pending, don't post a new one. The pending
112 // callback will handle posting a new callback itself. This prevents us from
113 // flooding the system with tasks.
114 if (!callback_pending_) {
115 base::AutoLock hold(current_idle_generation_lock_);
116 PostIdleCallbackWithIdleGenerationLockAcquired();
117 callback_pending_ = true;
danakj 2016/09/22 18:56:34 scoped outside the lock plz
ericrk 2016/09/22 19:08:17 Done.
118 }
119 }
120 }
121
122 void ContextCacheController::PostIdleCallbackWithIdleGenerationLockAcquired() {
danakj 2016/09/22 18:56:34 pass in the id and you dont need to claim lock is
ericrk 2016/09/22 19:08:17 Done.
123 task_runner_->PostDelayedTask(
124 FROM_HERE, base::Bind(&ContextCacheController::OnIdle, weak_ptr_,
125 current_idle_generation_),
126 base::TimeDelta::FromSeconds(kIdleCleanupDelaySeconds));
127 }
128
129 void ContextCacheController::InvalidatePendingIdleCallbacks() {
130 base::AutoLock hold(current_idle_generation_lock_);
131 ++current_idle_generation_;
132 }
133
134 void ContextCacheController::OnIdle(uint32_t idle_generation) {
135 // First check if we should run our idle callback at all. If we have become
136 // busy since scheduling, just schedule another idle callback and return.
137 {
138 base::AutoLock hold(current_idle_generation_lock_);
139 if (current_idle_generation_ != idle_generation) {
140 PostIdleCallbackWithIdleGenerationLockAcquired();
141 return;
142 }
143 }
144
145 // Try to acquire the context lock - if we can't acquire it then we've become
146 // busy since checking |current_idle_generation_| above. In this case, just
147 // re-post our idle callback and return.
148 if (context_lock_ && !context_lock_->Try()) {
149 base::AutoLock hold(current_idle_generation_lock_);
150 PostIdleCallbackWithIdleGenerationLockAcquired();
151 return;
152 }
153
154 if (gr_context_)
155 gr_context_->freeGpuResources();
156
157 // Toggle SetAggressivelyFreeResources to drop command buffer data.
158 context_support_->SetAggressivelyFreeResources(true);
159 context_support_->SetAggressivelyFreeResources(false);
160
161 callback_pending_ = false;
162
163 if (context_lock_)
164 context_lock_->Release();
70 } 165 }
71 166
72 } // namespace cc 167 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/context_cache_controller.h ('k') | cc/output/context_cache_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698