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

Side by Side Diff: content/browser/gpu/shader_disk_cache.cc

Issue 2472473002: gpu shader cache: Clarify lifetime/ownership/threadiness of objects. (Closed)
Patch Set: iwyu Created 4 years, 1 month 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "content/browser/gpu/shader_disk_cache.h" 5 #include "content/browser/gpu/shader_disk_cache.h"
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/single_thread_task_runner.h"
8 #include "base/threading/thread_checker.h" 10 #include "base/threading/thread_checker.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "gpu/command_buffer/common/constants.h" 11 #include "gpu/command_buffer/common/constants.h"
11 #include "net/base/cache_type.h" 12 #include "net/base/cache_type.h"
12 #include "net/base/io_buffer.h" 13 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h" 14 #include "net/base/net_errors.h"
14 15
15 namespace content { 16 namespace content {
16 17
17 namespace { 18 namespace {
18 19
19 static const base::FilePath::CharType kGpuCachePath[] = 20 static const base::FilePath::CharType kGpuCachePath[] =
20 FILE_PATH_LITERAL("GPUCache"); 21 FILE_PATH_LITERAL("GPUCache");
21 22
22 void EntryCloser(disk_cache::Entry* entry) { 23 static ShaderCacheFactory* factory_instance = nullptr;
23 entry->Close();
24 }
25
26 void FreeDiskCacheIterator(
27 std::unique_ptr<disk_cache::Backend::Iterator> iterator) {}
28 24
29 } // namespace 25 } // namespace
30 26
31 // ShaderDiskCacheEntry handles the work of caching/updating the cached 27 // ShaderDiskCacheEntry handles the work of caching/updating the cached
32 // shaders. 28 // shaders.
33 class ShaderDiskCacheEntry 29 class ShaderDiskCacheEntry : public base::ThreadChecker {
34 : public base::ThreadChecker,
35 public base::RefCounted<ShaderDiskCacheEntry> {
36 public: 30 public:
37 ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache, 31 ShaderDiskCacheEntry(ShaderDiskCache* cache,
38 const std::string& key, 32 const std::string& key,
39 const std::string& shader); 33 const std::string& shader);
34 ~ShaderDiskCacheEntry();
35
40 void Cache(); 36 void Cache();
41 37
42 private: 38 private:
43 friend class base::RefCounted<ShaderDiskCacheEntry>;
44
45 enum OpType { 39 enum OpType {
46 TERMINATE,
47 OPEN_ENTRY, 40 OPEN_ENTRY,
48 WRITE_DATA, 41 WRITE_DATA,
49 CREATE_ENTRY, 42 CREATE_ENTRY,
50 }; 43 };
51 44
52 ~ShaderDiskCacheEntry();
53
54 void OnOpComplete(int rv); 45 void OnOpComplete(int rv);
55 46
56 int OpenCallback(int rv); 47 int OpenCallback(int rv);
57 int WriteCallback(int rv); 48 int WriteCallback(int rv);
58 int IOComplete(int rv); 49 int IOComplete(int rv);
59 50
60 base::WeakPtr<ShaderDiskCache> cache_; 51 ShaderDiskCache* cache_;
61 OpType op_type_; 52 OpType op_type_;
62 std::string key_; 53 std::string key_;
63 std::string shader_; 54 std::string shader_;
64 disk_cache::Entry* entry_; 55 disk_cache::Entry* entry_;
56 base::WeakPtr<ShaderDiskCacheEntry> weak_ptr_;
57 base::WeakPtrFactory<ShaderDiskCacheEntry> weak_ptr_factory_;
65 58
66 DISALLOW_COPY_AND_ASSIGN(ShaderDiskCacheEntry); 59 DISALLOW_COPY_AND_ASSIGN(ShaderDiskCacheEntry);
67 }; 60 };
68 61
69 // ShaderDiskReadHelper is used to load all of the cached shaders from the 62 // ShaderDiskReadHelper is used to load all of the cached shaders from the
70 // disk cache and send to the memory cache. 63 // disk cache and send to the memory cache.
71 class ShaderDiskReadHelper 64 class ShaderDiskReadHelper : public base::ThreadChecker {
72 : public base::ThreadChecker,
73 public base::RefCounted<ShaderDiskReadHelper> {
74 public: 65 public:
75 using ShaderLoadedCallback = ShaderDiskCache::ShaderLoadedCallback; 66 using ShaderLoadedCallback = ShaderDiskCache::ShaderLoadedCallback;
76 ShaderDiskReadHelper(base::WeakPtr<ShaderDiskCache> cache, 67 ShaderDiskReadHelper(ShaderDiskCache* cache,
77 const ShaderLoadedCallback& callback); 68 const ShaderLoadedCallback& callback);
69 ~ShaderDiskReadHelper();
70
78 void LoadCache(); 71 void LoadCache();
79 72
80 private: 73 private:
81 friend class base::RefCounted<ShaderDiskReadHelper>;
82
83 enum OpType { 74 enum OpType {
84 TERMINATE, 75 TERMINATE,
85 OPEN_NEXT, 76 OPEN_NEXT,
86 OPEN_NEXT_COMPLETE, 77 OPEN_NEXT_COMPLETE,
87 READ_COMPLETE, 78 READ_COMPLETE,
88 ITERATION_FINISHED 79 ITERATION_FINISHED
89 }; 80 };
90 81
91 82
92 ~ShaderDiskReadHelper();
93
94 void OnOpComplete(int rv); 83 void OnOpComplete(int rv);
95 84
96 int OpenNextEntry(); 85 int OpenNextEntry();
97 int OpenNextEntryComplete(int rv); 86 int OpenNextEntryComplete(int rv);
98 int ReadComplete(int rv); 87 int ReadComplete(int rv);
99 int IterationComplete(int rv); 88 int IterationComplete(int rv);
100 89
101 base::WeakPtr<ShaderDiskCache> cache_; 90 ShaderDiskCache* cache_;
102 ShaderLoadedCallback shader_loaded_callback_; 91 ShaderLoadedCallback shader_loaded_callback_;
103 OpType op_type_; 92 OpType op_type_;
104 std::unique_ptr<disk_cache::Backend::Iterator> iter_; 93 std::unique_ptr<disk_cache::Backend::Iterator> iter_;
105 scoped_refptr<net::IOBufferWithSize> buf_; 94 scoped_refptr<net::IOBufferWithSize> buf_;
106 disk_cache::Entry* entry_; 95 disk_cache::Entry* entry_;
96 base::WeakPtrFactory<ShaderDiskReadHelper> weak_ptr_factory_;
107 97
108 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper); 98 DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper);
109 }; 99 };
110 100
111 class ShaderClearHelper 101 class ShaderClearHelper : public base::RefCounted<ShaderClearHelper>,
112 : public base::RefCounted<ShaderClearHelper>, 102 public base::SupportsWeakPtr<ShaderClearHelper>,
113 public base::SupportsWeakPtr<ShaderClearHelper> { 103 public base::ThreadChecker {
114 public: 104 public:
115 ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache, 105 ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
116 const base::FilePath& path, 106 const base::FilePath& path,
117 const base::Time& delete_begin, 107 const base::Time& delete_begin,
118 const base::Time& delete_end, 108 const base::Time& delete_end,
119 const base::Closure& callback); 109 const base::Closure& callback);
120 void Clear(); 110 void Clear();
121 111
122 private: 112 private:
123 friend class base::RefCounted<ShaderClearHelper>; 113 friend class base::RefCounted<ShaderClearHelper>;
(...skipping 11 matching lines...) Expand all
135 scoped_refptr<ShaderDiskCache> cache_; 125 scoped_refptr<ShaderDiskCache> cache_;
136 OpType op_type_; 126 OpType op_type_;
137 base::FilePath path_; 127 base::FilePath path_;
138 base::Time delete_begin_; 128 base::Time delete_begin_;
139 base::Time delete_end_; 129 base::Time delete_end_;
140 base::Closure callback_; 130 base::Closure callback_;
141 131
142 DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper); 132 DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper);
143 }; 133 };
144 134
145 ShaderDiskCacheEntry::ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache, 135 ////////////////////////////////////////////////////////////////////////////////
136 // ShaderDiskCacheEntry
137
138 ShaderDiskCacheEntry::ShaderDiskCacheEntry(ShaderDiskCache* cache,
146 const std::string& key, 139 const std::string& key,
147 const std::string& shader) 140 const std::string& shader)
148 : cache_(cache), 141 : cache_(cache),
149 op_type_(OPEN_ENTRY), 142 op_type_(OPEN_ENTRY),
150 key_(key), 143 key_(key),
151 shader_(shader), 144 shader_(shader),
152 entry_(NULL) { 145 entry_(nullptr),
146 weak_ptr_factory_(this) {
147 weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
153 } 148 }
154 149
155 ShaderDiskCacheEntry::~ShaderDiskCacheEntry() { 150 ShaderDiskCacheEntry::~ShaderDiskCacheEntry() {
151 DCHECK(CalledOnValidThread());
156 if (entry_) 152 if (entry_)
157 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 153 entry_->Close();
158 base::Bind(&EntryCloser, entry_));
159 } 154 }
160 155
161 void ShaderDiskCacheEntry::Cache() { 156 void ShaderDiskCacheEntry::Cache() {
162 DCHECK(CalledOnValidThread()); 157 DCHECK(CalledOnValidThread());
163 if (!cache_.get())
164 return;
165
166 int rv = cache_->backend()->OpenEntry( 158 int rv = cache_->backend()->OpenEntry(
167 key_, 159 key_, &entry_, base::Bind(&ShaderDiskCacheEntry::OnOpComplete,
168 &entry_, 160 weak_ptr_factory_.GetWeakPtr()));
169 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this));
170 if (rv != net::ERR_IO_PENDING) 161 if (rv != net::ERR_IO_PENDING)
171 OnOpComplete(rv); 162 OnOpComplete(rv);
172 } 163 }
173 164
174 void ShaderDiskCacheEntry::OnOpComplete(int rv) { 165 void ShaderDiskCacheEntry::OnOpComplete(int rv) {
175 DCHECK(CalledOnValidThread()); 166 DCHECK(CalledOnValidThread());
176 if (!cache_.get()) 167 // The function calls inside the switch block below can end up destroying
177 return; 168 // |this|. So hold on to a WeakPtr<>, and terminate the while loop if |this|
178 169 // has been destroyed.
170 auto weak_ptr = std::move(weak_ptr_);
179 do { 171 do {
180 switch (op_type_) { 172 switch (op_type_) {
181 case OPEN_ENTRY: 173 case OPEN_ENTRY:
182 rv = OpenCallback(rv); 174 rv = OpenCallback(rv);
183 break; 175 break;
184 case CREATE_ENTRY: 176 case CREATE_ENTRY:
185 rv = WriteCallback(rv); 177 rv = WriteCallback(rv);
186 break; 178 break;
187 case WRITE_DATA: 179 case WRITE_DATA:
188 rv = IOComplete(rv); 180 rv = IOComplete(rv);
189 break; 181 break;
190 case TERMINATE:
191 rv = net::ERR_IO_PENDING; // break the loop.
192 break;
193 default:
194 NOTREACHED(); // Invalid op_type_ provided.
195 break;
196 } 182 }
197 } while (rv != net::ERR_IO_PENDING); 183 } while (rv != net::ERR_IO_PENDING && weak_ptr);
184 if (weak_ptr)
185 weak_ptr_ = std::move(weak_ptr);
198 } 186 }
199 187
200 int ShaderDiskCacheEntry::OpenCallback(int rv) { 188 int ShaderDiskCacheEntry::OpenCallback(int rv) {
201 DCHECK(CalledOnValidThread()); 189 DCHECK(CalledOnValidThread());
202 // Called through OnOpComplete, so we know |cache_| is valid.
203 if (rv == net::OK) { 190 if (rv == net::OK) {
204 cache_->backend()->OnExternalCacheHit(key_); 191 cache_->backend()->OnExternalCacheHit(key_);
205 cache_->EntryComplete(this); 192 cache_->EntryComplete(this);
206 op_type_ = TERMINATE;
207 return rv; 193 return rv;
208 } 194 }
209 195
210 op_type_ = CREATE_ENTRY; 196 op_type_ = CREATE_ENTRY;
211 return cache_->backend()->CreateEntry( 197 return cache_->backend()->CreateEntry(
212 key_, 198 key_, &entry_, base::Bind(&ShaderDiskCacheEntry::OnOpComplete,
213 &entry_, 199 weak_ptr_factory_.GetWeakPtr()));
214 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this));
215 } 200 }
216 201
217 int ShaderDiskCacheEntry::WriteCallback(int rv) { 202 int ShaderDiskCacheEntry::WriteCallback(int rv) {
218 DCHECK(CalledOnValidThread()); 203 DCHECK(CalledOnValidThread());
219 // Called through OnOpComplete, so we know |cache_| is valid.
220 if (rv != net::OK) { 204 if (rv != net::OK) {
221 LOG(ERROR) << "Failed to create shader cache entry: " << rv; 205 LOG(ERROR) << "Failed to create shader cache entry: " << rv;
222 cache_->EntryComplete(this); 206 cache_->EntryComplete(this);
223 op_type_ = TERMINATE;
224 return rv; 207 return rv;
225 } 208 }
226 209
227 op_type_ = WRITE_DATA; 210 op_type_ = WRITE_DATA;
228 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_); 211 scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_);
229 return entry_->WriteData( 212 return entry_->WriteData(1, 0, io_buf.get(), shader_.length(),
230 1, 213 base::Bind(&ShaderDiskCacheEntry::OnOpComplete,
231 0, 214 weak_ptr_factory_.GetWeakPtr()),
232 io_buf.get(), 215 false);
233 shader_.length(),
234 base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this),
235 false);
236 } 216 }
237 217
238 int ShaderDiskCacheEntry::IOComplete(int rv) { 218 int ShaderDiskCacheEntry::IOComplete(int rv) {
239 DCHECK(CalledOnValidThread()); 219 DCHECK(CalledOnValidThread());
240 // Called through OnOpComplete, so we know |cache_| is valid.
241 cache_->EntryComplete(this); 220 cache_->EntryComplete(this);
242 op_type_ = TERMINATE;
243 return rv; 221 return rv;
244 } 222 }
245 223
246 ShaderDiskReadHelper::ShaderDiskReadHelper(base::WeakPtr<ShaderDiskCache> cache, 224 ////////////////////////////////////////////////////////////////////////////////
225 // ShaderDiskReadHelper
226
227 ShaderDiskReadHelper::ShaderDiskReadHelper(ShaderDiskCache* cache,
247 const ShaderLoadedCallback& callback) 228 const ShaderLoadedCallback& callback)
248 : cache_(cache), 229 : cache_(cache),
249 shader_loaded_callback_(callback), 230 shader_loaded_callback_(callback),
250 op_type_(OPEN_NEXT), 231 op_type_(OPEN_NEXT),
251 buf_(NULL), 232 buf_(NULL),
252 entry_(NULL) {} 233 entry_(NULL),
234 weak_ptr_factory_(this) {}
235
236 ShaderDiskReadHelper::~ShaderDiskReadHelper() {
237 DCHECK(CalledOnValidThread());
238 if (entry_)
239 entry_->Close();
240 iter_ = nullptr;
241 }
253 242
254 void ShaderDiskReadHelper::LoadCache() { 243 void ShaderDiskReadHelper::LoadCache() {
255 DCHECK(CalledOnValidThread()); 244 DCHECK(CalledOnValidThread());
256 if (!cache_.get())
257 return;
258 OnOpComplete(net::OK); 245 OnOpComplete(net::OK);
259 } 246 }
260 247
261 void ShaderDiskReadHelper::OnOpComplete(int rv) { 248 void ShaderDiskReadHelper::OnOpComplete(int rv) {
262 DCHECK(CalledOnValidThread()); 249 DCHECK(CalledOnValidThread());
263 if (!cache_.get())
264 return;
265
266 do { 250 do {
267 switch (op_type_) { 251 switch (op_type_) {
268 case OPEN_NEXT: 252 case OPEN_NEXT:
269 rv = OpenNextEntry(); 253 rv = OpenNextEntry();
270 break; 254 break;
271 case OPEN_NEXT_COMPLETE: 255 case OPEN_NEXT_COMPLETE:
272 rv = OpenNextEntryComplete(rv); 256 rv = OpenNextEntryComplete(rv);
273 break; 257 break;
274 case READ_COMPLETE: 258 case READ_COMPLETE:
275 rv = ReadComplete(rv); 259 rv = ReadComplete(rv);
276 break; 260 break;
277 case ITERATION_FINISHED: 261 case ITERATION_FINISHED:
278 rv = IterationComplete(rv); 262 rv = IterationComplete(rv);
279 break; 263 break;
280 case TERMINATE: 264 case TERMINATE:
281 cache_->ReadComplete(); 265 cache_->ReadComplete();
282 rv = net::ERR_IO_PENDING; // break the loop 266 rv = net::ERR_IO_PENDING; // break the loop
283 break; 267 break;
284 default: 268 default:
285 NOTREACHED(); // Invalid state for read helper 269 NOTREACHED(); // Invalid state for read helper
286 rv = net::ERR_FAILED; 270 rv = net::ERR_FAILED;
287 break; 271 break;
288 } 272 }
289 } while (rv != net::ERR_IO_PENDING); 273 } while (rv != net::ERR_IO_PENDING);
290 } 274 }
291 275
292 int ShaderDiskReadHelper::OpenNextEntry() { 276 int ShaderDiskReadHelper::OpenNextEntry() {
293 DCHECK(CalledOnValidThread()); 277 DCHECK(CalledOnValidThread());
294 // Called through OnOpComplete, so we know |cache_| is valid.
295 op_type_ = OPEN_NEXT_COMPLETE; 278 op_type_ = OPEN_NEXT_COMPLETE;
296 if (!iter_) 279 if (!iter_)
297 iter_ = cache_->backend()->CreateIterator(); 280 iter_ = cache_->backend()->CreateIterator();
298 return iter_->OpenNextEntry( 281 return iter_->OpenNextEntry(&entry_,
299 &entry_, base::Bind(&ShaderDiskReadHelper::OnOpComplete, this)); 282 base::Bind(&ShaderDiskReadHelper::OnOpComplete,
283 weak_ptr_factory_.GetWeakPtr()));
300 } 284 }
301 285
302 int ShaderDiskReadHelper::OpenNextEntryComplete(int rv) { 286 int ShaderDiskReadHelper::OpenNextEntryComplete(int rv) {
303 DCHECK(CalledOnValidThread()); 287 DCHECK(CalledOnValidThread());
304 // Called through OnOpComplete, so we know |cache_| is valid.
305 if (rv == net::ERR_FAILED) { 288 if (rv == net::ERR_FAILED) {
306 iter_.reset(); 289 iter_.reset();
307 op_type_ = ITERATION_FINISHED; 290 op_type_ = ITERATION_FINISHED;
308 return net::OK; 291 return net::OK;
309 } 292 }
310 293
311 if (rv < 0) 294 if (rv < 0)
312 return rv; 295 return rv;
313 296
314 op_type_ = READ_COMPLETE; 297 op_type_ = READ_COMPLETE;
315 buf_ = new net::IOBufferWithSize(entry_->GetDataSize(1)); 298 buf_ = new net::IOBufferWithSize(entry_->GetDataSize(1));
316 return entry_->ReadData( 299 return entry_->ReadData(1, 0, buf_.get(), buf_->size(),
317 1, 300 base::Bind(&ShaderDiskReadHelper::OnOpComplete,
318 0, 301 weak_ptr_factory_.GetWeakPtr()));
319 buf_.get(),
320 buf_->size(),
321 base::Bind(&ShaderDiskReadHelper::OnOpComplete, this));
322 } 302 }
323 303
324 int ShaderDiskReadHelper::ReadComplete(int rv) { 304 int ShaderDiskReadHelper::ReadComplete(int rv) {
325 DCHECK(CalledOnValidThread()); 305 DCHECK(CalledOnValidThread());
326 // Called through OnOpComplete, so we know |cache_| is valid.
327 if (rv && rv == buf_->size() && !shader_loaded_callback_.is_null()) { 306 if (rv && rv == buf_->size() && !shader_loaded_callback_.is_null()) {
328 shader_loaded_callback_.Run(entry_->GetKey(), 307 shader_loaded_callback_.Run(entry_->GetKey(),
329 std::string(buf_->data(), buf_->size())); 308 std::string(buf_->data(), buf_->size()));
330 } 309 }
331 310
332 buf_ = NULL; 311 buf_ = NULL;
333 entry_->Close(); 312 entry_->Close();
334 entry_ = NULL; 313 entry_ = NULL;
335 314
336 op_type_ = OPEN_NEXT; 315 op_type_ = OPEN_NEXT;
337 return net::OK; 316 return net::OK;
338 } 317 }
339 318
340 int ShaderDiskReadHelper::IterationComplete(int rv) { 319 int ShaderDiskReadHelper::IterationComplete(int rv) {
341 DCHECK(CalledOnValidThread()); 320 DCHECK(CalledOnValidThread());
342 // Called through OnOpComplete, so we know |cache_| is valid.
343 iter_.reset(); 321 iter_.reset();
344 op_type_ = TERMINATE; 322 op_type_ = TERMINATE;
345 return net::OK; 323 return net::OK;
346 } 324 }
347 325
348 ShaderDiskReadHelper::~ShaderDiskReadHelper() { 326 ////////////////////////////////////////////////////////////////////////////////
349 if (entry_) { 327 // ShaderClearHelper
350 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
351 base::Bind(&EntryCloser, entry_));
352 }
353 if (iter_) {
354 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
355 base::Bind(&FreeDiskCacheIterator,
356 base::Passed(&iter_)));
357 }
358 }
359 328
360 ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache, 329 ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
361 const base::FilePath& path, 330 const base::FilePath& path,
362 const base::Time& delete_begin, 331 const base::Time& delete_begin,
363 const base::Time& delete_end, 332 const base::Time& delete_end,
364 const base::Closure& callback) 333 const base::Closure& callback)
365 : cache_(cache), 334 : cache_(cache),
366 op_type_(VERIFY_CACHE_SETUP), 335 op_type_(VERIFY_CACHE_SETUP),
367 path_(path), 336 path_(path),
368 delete_begin_(delete_begin), 337 delete_begin_(delete_begin),
369 delete_end_(delete_end), 338 delete_end_(delete_end),
370 callback_(callback) { 339 callback_(callback) {
371 } 340 }
372 341
373 ShaderClearHelper::~ShaderClearHelper() { 342 ShaderClearHelper::~ShaderClearHelper() {
374 DCHECK_CURRENTLY_ON(BrowserThread::IO); 343 DCHECK(CalledOnValidThread());
375 } 344 }
376 345
377 void ShaderClearHelper::Clear() { 346 void ShaderClearHelper::Clear() {
378 DCHECK_CURRENTLY_ON(BrowserThread::IO); 347 DCHECK(CalledOnValidThread());
379 DoClearShaderCache(net::OK); 348 DoClearShaderCache(net::OK);
380 } 349 }
381 350
382 void ShaderClearHelper::DoClearShaderCache(int rv) { 351 void ShaderClearHelper::DoClearShaderCache(int rv) {
383 DCHECK_CURRENTLY_ON(BrowserThread::IO); 352 DCHECK(CalledOnValidThread());
384 353
385 // Hold a ref to ourselves so when we do the CacheCleared call we don't get 354 // Hold a ref to ourselves so when we do the CacheCleared call we don't get
386 // auto-deleted when our ref count drops to zero. 355 // auto-deleted when our ref count drops to zero.
387 scoped_refptr<ShaderClearHelper> helper = this; 356 scoped_refptr<ShaderClearHelper> helper = this;
388 357
389 while (rv != net::ERR_IO_PENDING) { 358 while (rv != net::ERR_IO_PENDING) {
390 switch (op_type_) { 359 switch (op_type_) {
391 case VERIFY_CACHE_SETUP: 360 case VERIFY_CACHE_SETUP:
392 rv = cache_->SetAvailableCallback( 361 rv = cache_->SetAvailableCallback(
393 base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr())); 362 base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr()));
(...skipping 11 matching lines...) Expand all
405 rv = net::ERR_IO_PENDING; // Break the loop. 374 rv = net::ERR_IO_PENDING; // Break the loop.
406 break; 375 break;
407 default: 376 default:
408 NOTREACHED(); // Invalid state provided. 377 NOTREACHED(); // Invalid state provided.
409 op_type_ = TERMINATE; 378 op_type_ = TERMINATE;
410 break; 379 break;
411 } 380 }
412 } 381 }
413 } 382 }
414 383
384 ////////////////////////////////////////////////////////////////////////////////
385 // ShaderCacheFactory
386
387 // static
388 void ShaderCacheFactory::InitInstance(
389 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
390 scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) {
391 if (task_runner->BelongsToCurrentThread()) {
392 CreateFactoryInstance(std::move(cache_task_runner));
393 } else {
394 task_runner->PostTask(FROM_HERE,
395 base::Bind(&ShaderCacheFactory::CreateFactoryInstance,
396 std::move(cache_task_runner)));
397 }
398 }
399
415 // static 400 // static
416 ShaderCacheFactory* ShaderCacheFactory::GetInstance() { 401 ShaderCacheFactory* ShaderCacheFactory::GetInstance() {
417 return base::Singleton<ShaderCacheFactory, 402 DCHECK(!factory_instance || factory_instance->CalledOnValidThread());
418 base::LeakySingletonTraits<ShaderCacheFactory>>::get(); 403 return factory_instance;
419 } 404 }
420 405
421 ShaderCacheFactory::ShaderCacheFactory() { 406 ShaderCacheFactory::ShaderCacheFactory(
422 } 407 scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner)
408 : cache_task_runner_(std::move(cache_task_runner)) {}
423 409
424 ShaderCacheFactory::~ShaderCacheFactory() { 410 ShaderCacheFactory::~ShaderCacheFactory() {
425 } 411 }
426 412
413 // static
414 void ShaderCacheFactory::CreateFactoryInstance(
415 scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) {
416 DCHECK(!factory_instance);
417 factory_instance = new ShaderCacheFactory(std::move(cache_task_runner));
418 }
419
427 void ShaderCacheFactory::SetCacheInfo(int32_t client_id, 420 void ShaderCacheFactory::SetCacheInfo(int32_t client_id,
428 const base::FilePath& path) { 421 const base::FilePath& path) {
422 DCHECK(CalledOnValidThread());
429 client_id_to_path_map_[client_id] = path; 423 client_id_to_path_map_[client_id] = path;
430 } 424 }
431 425
432 void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) { 426 void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) {
427 DCHECK(CalledOnValidThread());
433 client_id_to_path_map_.erase(client_id); 428 client_id_to_path_map_.erase(client_id);
434 } 429 }
435 430
436 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) { 431 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) {
432 DCHECK(CalledOnValidThread());
437 ClientIdToPathMap::iterator iter = 433 ClientIdToPathMap::iterator iter =
438 client_id_to_path_map_.find(client_id); 434 client_id_to_path_map_.find(client_id);
439 if (iter == client_id_to_path_map_.end()) 435 if (iter == client_id_to_path_map_.end())
440 return NULL; 436 return NULL;
441 return ShaderCacheFactory::GetByPath(iter->second); 437 return ShaderCacheFactory::GetByPath(iter->second);
442 } 438 }
443 439
444 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath( 440 scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath(
445 const base::FilePath& path) { 441 const base::FilePath& path) {
442 DCHECK(CalledOnValidThread());
446 ShaderCacheMap::iterator iter = shader_cache_map_.find(path); 443 ShaderCacheMap::iterator iter = shader_cache_map_.find(path);
447 if (iter != shader_cache_map_.end()) 444 if (iter != shader_cache_map_.end())
448 return iter->second; 445 return iter->second;
449 446
450 ShaderDiskCache* cache = new ShaderDiskCache(path); 447 ShaderDiskCache* cache = new ShaderDiskCache(path);
451 cache->Init(); 448 cache->Init(cache_task_runner_);
452 return cache; 449 return cache;
453 } 450 }
454 451
455 void ShaderCacheFactory::AddToCache(const base::FilePath& key, 452 void ShaderCacheFactory::AddToCache(const base::FilePath& key,
456 ShaderDiskCache* cache) { 453 ShaderDiskCache* cache) {
454 DCHECK(CalledOnValidThread());
457 shader_cache_map_[key] = cache; 455 shader_cache_map_[key] = cache;
458 } 456 }
459 457
460 void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) { 458 void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) {
459 DCHECK(CalledOnValidThread());
461 shader_cache_map_.erase(key); 460 shader_cache_map_.erase(key);
462 } 461 }
463 462
464 void ShaderCacheFactory::ClearByPath(const base::FilePath& path, 463 void ShaderCacheFactory::ClearByPath(const base::FilePath& path,
465 const base::Time& delete_begin, 464 const base::Time& delete_begin,
466 const base::Time& delete_end, 465 const base::Time& delete_end,
467 const base::Closure& callback) { 466 const base::Closure& callback) {
468 DCHECK_CURRENTLY_ON(BrowserThread::IO); 467 DCHECK(CalledOnValidThread());
469 DCHECK(!callback.is_null()); 468 DCHECK(!callback.is_null());
470 469
471 scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper( 470 scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper(
472 GetByPath(path), path, delete_begin, delete_end, callback); 471 GetByPath(path), path, delete_begin, delete_end, callback);
473 472
474 // We could receive requests to clear the same path with different 473 // We could receive requests to clear the same path with different
475 // begin/end times. So, we keep a list of requests. If we haven't seen this 474 // begin/end times. So, we keep a list of requests. If we haven't seen this
476 // path before we kick off the clear and add it to the list. If we have see it 475 // path before we kick off the clear and add it to the list. If we have see it
477 // already, then we already have a clear running. We add this clear to the 476 // already, then we already have a clear running. We add this clear to the
478 // list and wait for any previous clears to finish. 477 // list and wait for any previous clears to finish.
479 ShaderClearMap::iterator iter = shader_clear_map_.find(path); 478 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
480 if (iter != shader_clear_map_.end()) { 479 if (iter != shader_clear_map_.end()) {
481 iter->second.push(helper); 480 iter->second.push(helper);
482 return; 481 return;
483 } 482 }
484 483
485 shader_clear_map_.insert( 484 shader_clear_map_.insert(
486 std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue())); 485 std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue()));
487 shader_clear_map_[path].push(helper); 486 shader_clear_map_[path].push(helper);
488 helper->Clear(); 487 helper->Clear();
489 } 488 }
490 489
491 void ShaderCacheFactory::CacheCleared(const base::FilePath& path) { 490 void ShaderCacheFactory::CacheCleared(const base::FilePath& path) {
492 DCHECK_CURRENTLY_ON(BrowserThread::IO); 491 DCHECK(CalledOnValidThread());
493 492
494 ShaderClearMap::iterator iter = shader_clear_map_.find(path); 493 ShaderClearMap::iterator iter = shader_clear_map_.find(path);
495 if (iter == shader_clear_map_.end()) { 494 if (iter == shader_clear_map_.end()) {
496 LOG(ERROR) << "Completed clear but missing clear helper."; 495 LOG(ERROR) << "Completed clear but missing clear helper.";
497 return; 496 return;
498 } 497 }
499 498
500 iter->second.pop(); 499 iter->second.pop();
501 500
502 // If there are remaining items in the list we trigger the Clear on the 501 // If there are remaining items in the list we trigger the Clear on the
503 // next one. 502 // next one.
504 if (!iter->second.empty()) { 503 if (!iter->second.empty()) {
505 iter->second.front()->Clear(); 504 iter->second.front()->Clear();
506 return; 505 return;
507 } 506 }
508 507
509 shader_clear_map_.erase(path); 508 shader_clear_map_.erase(path);
510 } 509 }
511 510
511 ////////////////////////////////////////////////////////////////////////////////
512 // ShaderDiskCache
513
512 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path) 514 ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path)
513 : cache_available_(false), 515 : cache_available_(false),
514 cache_path_(cache_path), 516 cache_path_(cache_path),
515 is_initialized_(false) { 517 is_initialized_(false) {
516 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this); 518 ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this);
517 } 519 }
518 520
519 ShaderDiskCache::~ShaderDiskCache() { 521 ShaderDiskCache::~ShaderDiskCache() {
520 ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_); 522 ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_);
521 } 523 }
522 524
523 void ShaderDiskCache::Init() { 525 void ShaderDiskCache::Init(
526 scoped_refptr<base::SingleThreadTaskRunner> cache_task_runner) {
524 if (is_initialized_) { 527 if (is_initialized_) {
525 NOTREACHED(); // can't initialize disk cache twice. 528 NOTREACHED(); // can't initialize disk cache twice.
526 return; 529 return;
527 } 530 }
528 is_initialized_ = true; 531 is_initialized_ = true;
529 532
530 int rv = disk_cache::CreateCacheBackend( 533 int rv = disk_cache::CreateCacheBackend(
531 net::SHADER_CACHE, net::CACHE_BACKEND_DEFAULT, 534 net::SHADER_CACHE, net::CACHE_BACKEND_DEFAULT,
532 cache_path_.Append(kGpuCachePath), 535 cache_path_.Append(kGpuCachePath),
533 gpu::kDefaultMaxProgramCacheMemoryBytes, true, 536 gpu::kDefaultMaxProgramCacheMemoryBytes, true, cache_task_runner, NULL,
534 BrowserThread::GetTaskRunnerForThread(BrowserThread::CACHE).get(), NULL,
535 &backend_, base::Bind(&ShaderDiskCache::CacheCreatedCallback, this)); 537 &backend_, base::Bind(&ShaderDiskCache::CacheCreatedCallback, this));
536 538
537 if (rv == net::OK) 539 if (rv == net::OK)
538 cache_available_ = true; 540 cache_available_ = true;
539 } 541 }
540 542
541 void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) { 543 void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) {
542 if (!cache_available_) 544 if (!cache_available_)
543 return; 545 return;
544 546
545 scoped_refptr<ShaderDiskCacheEntry> shim = 547 auto shim = base::MakeUnique<ShaderDiskCacheEntry>(this, key, shader);
546 new ShaderDiskCacheEntry(AsWeakPtr(), key, shader);
547 shim->Cache(); 548 shim->Cache();
548 549 auto* raw_ptr = shim.get();
549 entry_map_[shim.get()] = shim; 550 entries_.insert(std::make_pair(raw_ptr, std::move(shim)));
550 } 551 }
551 552
552 int ShaderDiskCache::Clear( 553 int ShaderDiskCache::Clear(
553 const base::Time begin_time, const base::Time end_time, 554 const base::Time begin_time, const base::Time end_time,
554 const net::CompletionCallback& completion_callback) { 555 const net::CompletionCallback& completion_callback) {
555 int rv; 556 int rv;
556 if (begin_time.is_null()) { 557 if (begin_time.is_null()) {
557 rv = backend_->DoomAllEntries(completion_callback); 558 rv = backend_->DoomAllEntries(completion_callback);
558 } else { 559 } else {
559 rv = backend_->DoomEntriesBetween(begin_time, end_time, 560 rv = backend_->DoomEntriesBetween(begin_time, end_time,
(...skipping 14 matching lines...) Expand all
574 return net::OK; 575 return net::OK;
575 available_callback_ = callback; 576 available_callback_ = callback;
576 return net::ERR_IO_PENDING; 577 return net::ERR_IO_PENDING;
577 } 578 }
578 579
579 void ShaderDiskCache::CacheCreatedCallback(int rv) { 580 void ShaderDiskCache::CacheCreatedCallback(int rv) {
580 if (rv != net::OK) { 581 if (rv != net::OK) {
581 LOG(ERROR) << "Shader Cache Creation failed: " << rv; 582 LOG(ERROR) << "Shader Cache Creation failed: " << rv;
582 return; 583 return;
583 } 584 }
584 helper_ = new ShaderDiskReadHelper(AsWeakPtr(), shader_loaded_callback_); 585 helper_ =
586 base::MakeUnique<ShaderDiskReadHelper>(this, shader_loaded_callback_);
585 helper_->LoadCache(); 587 helper_->LoadCache();
586 } 588 }
587 589
588 void ShaderDiskCache::EntryComplete(void* entry) { 590 void ShaderDiskCache::EntryComplete(ShaderDiskCacheEntry* entry) {
589 entry_map_.erase(entry); 591 entries_.erase(entry);
590 592 if (entries_.empty() && !cache_complete_callback_.is_null())
591 if (entry_map_.empty() && !cache_complete_callback_.is_null())
592 cache_complete_callback_.Run(net::OK); 593 cache_complete_callback_.Run(net::OK);
593 } 594 }
594 595
595 void ShaderDiskCache::ReadComplete() { 596 void ShaderDiskCache::ReadComplete() {
596 helper_ = NULL; 597 helper_ = nullptr;
597 598
598 // The cache is considered available after we have finished reading any 599 // The cache is considered available after we have finished reading any
599 // of the old cache values off disk. This prevents a potential race where we 600 // of the old cache values off disk. This prevents a potential race where we
600 // are reading from disk and execute a cache clear at the same time. 601 // are reading from disk and execute a cache clear at the same time.
601 cache_available_ = true; 602 cache_available_ = true;
602 if (!available_callback_.is_null()) { 603 if (!available_callback_.is_null()) {
603 available_callback_.Run(net::OK); 604 available_callback_.Run(net::OK);
604 available_callback_.Reset(); 605 available_callback_.Reset();
605 } 606 }
606 } 607 }
607 608
608 int ShaderDiskCache::SetCacheCompleteCallback( 609 int ShaderDiskCache::SetCacheCompleteCallback(
609 const net::CompletionCallback& callback) { 610 const net::CompletionCallback& callback) {
610 if (entry_map_.empty()) { 611 if (entries_.empty()) {
611 return net::OK; 612 return net::OK;
612 } 613 }
613 cache_complete_callback_ = callback; 614 cache_complete_callback_ = callback;
614 return net::ERR_IO_PENDING; 615 return net::ERR_IO_PENDING;
615 } 616 }
616 617
617 } // namespace content 618 } // namespace content
618 619
OLDNEW
« no previous file with comments | « content/browser/gpu/shader_disk_cache.h ('k') | content/browser/gpu/shader_disk_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698