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

Side by Side Diff: cc/thread_proxy.cc

Issue 11362054: Use message passing for BeginFrameAndCommitState and clean up forced commit logic (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix windows signed/unsigned warning Created 8 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 | Annotate | Revision Log
« no previous file with comments | « cc/thread_proxy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 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/thread_proxy.h" 5 #include "cc/thread_proxy.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "cc/delay_based_time_source.h" 9 #include "cc/delay_based_time_source.h"
10 #include "cc/draw_quad.h" 10 #include "cc/draw_quad.h"
(...skipping 20 matching lines...) Expand all
31 scoped_ptr<Proxy> ThreadProxy::create(LayerTreeHost* layerTreeHost, scoped_ptr<T hread> implThread) 31 scoped_ptr<Proxy> ThreadProxy::create(LayerTreeHost* layerTreeHost, scoped_ptr<T hread> implThread)
32 { 32 {
33 return make_scoped_ptr(new ThreadProxy(layerTreeHost, implThread.Pass())).Pa ssAs<Proxy>(); 33 return make_scoped_ptr(new ThreadProxy(layerTreeHost, implThread.Pass())).Pa ssAs<Proxy>();
34 } 34 }
35 35
36 ThreadProxy::ThreadProxy(LayerTreeHost* layerTreeHost, scoped_ptr<Thread> implTh read) 36 ThreadProxy::ThreadProxy(LayerTreeHost* layerTreeHost, scoped_ptr<Thread> implTh read)
37 : Proxy(implThread.Pass()) 37 : Proxy(implThread.Pass())
38 , m_animateRequested(false) 38 , m_animateRequested(false)
39 , m_commitRequested(false) 39 , m_commitRequested(false)
40 , m_commitRequestSentToImplThread(false) 40 , m_commitRequestSentToImplThread(false)
41 , m_forcedCommitRequested(false)
42 , m_layerTreeHost(layerTreeHost) 41 , m_layerTreeHost(layerTreeHost)
43 , m_rendererInitialized(false) 42 , m_rendererInitialized(false)
44 , m_started(false) 43 , m_started(false)
45 , m_texturesAcquired(true) 44 , m_texturesAcquired(true)
46 , m_inCompositeAndReadback(false) 45 , m_inCompositeAndReadback(false)
47 , m_mainThreadProxy(ScopedThreadProxy::create(Proxy::mainThread())) 46 , m_mainThreadProxy(ScopedThreadProxy::create(Proxy::mainThread()))
48 , m_beginFrameCompletionEventOnImplThread(0) 47 , m_beginFrameCompletionEventOnImplThread(0)
49 , m_readbackRequestOnImplThread(0) 48 , m_readbackRequestOnImplThread(0)
50 , m_commitCompletionEventOnImplThread(0) 49 , m_commitCompletionEventOnImplThread(0)
51 , m_textureAcquisitionCompletionEventOnImplThread(0) 50 , m_textureAcquisitionCompletionEventOnImplThread(0)
52 , m_nextFrameIsNewlyCommittedFrameOnImplThread(false) 51 , m_nextFrameIsNewlyCommittedFrameOnImplThread(false)
53 , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled) 52 , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled)
54 , m_totalCommitCount(0) 53 , m_totalCommitCount(0)
55 , m_deferCommits(false) 54 , m_deferCommits(false)
56 , m_deferredCommitPending(false)
57 { 55 {
58 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); 56 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
59 DCHECK(isMainThread()); 57 DCHECK(isMainThread());
60 } 58 }
61 59
62 ThreadProxy::~ThreadProxy() 60 ThreadProxy::~ThreadProxy()
63 { 61 {
64 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy"); 62 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
65 DCHECK(isMainThread()); 63 DCHECK(isMainThread());
66 DCHECK(!m_started); 64 DCHECK(!m_started);
67 } 65 }
68 66
69 bool ThreadProxy::compositeAndReadback(void *pixels, const gfx::Rect& rect) 67 bool ThreadProxy::compositeAndReadback(void *pixels, const gfx::Rect& rect)
70 { 68 {
71 TRACE_EVENT0("cc", "ThreadPRoxy::compositeAndReadback"); 69 TRACE_EVENT0("cc", "ThreadProxy::compositeAndReadback");
72 DCHECK(isMainThread()); 70 DCHECK(isMainThread());
73 DCHECK(m_layerTreeHost); 71 DCHECK(m_layerTreeHost);
74 DCHECK(!m_deferCommits); 72 DCHECK(!m_deferCommits);
75 73
76 if (!m_layerTreeHost->initializeRendererIfNeeded()) { 74 if (!m_layerTreeHost->initializeRendererIfNeeded()) {
77 TRACE_EVENT0("cc", "compositeAndReadback_EarlyOut_LR_Uninitialized"); 75 TRACE_EVENT0("cc", "compositeAndReadback_EarlyOut_LR_Uninitialized");
78 return false; 76 return false;
79 } 77 }
80 78
81 79
82 // Perform a synchronous commit. 80 // Perform a synchronous commit.
83 { 81 {
84 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); 82 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
85 CompletionEvent beginFrameCompletion; 83 CompletionEvent beginFrameCompletion;
86 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::forceBeginFrameOn ImplThread, base::Unretained(this), &beginFrameCompletion)); 84 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::forceBeginFrameOn ImplThread, base::Unretained(this), &beginFrameCompletion));
87 beginFrameCompletion.wait(); 85 beginFrameCompletion.wait();
88 } 86 }
89 m_inCompositeAndReadback = true; 87 m_inCompositeAndReadback = true;
90 beginFrame(); 88 beginFrame(scoped_ptr<BeginFrameAndCommitState>());
91 m_inCompositeAndReadback = false; 89 m_inCompositeAndReadback = false;
92 90
93 // Perform a synchronous readback. 91 // Perform a synchronous readback.
94 ReadbackRequest request; 92 ReadbackRequest request;
95 request.rect = rect; 93 request.rect = rect;
96 request.pixels = pixels; 94 request.pixels = pixels;
97 { 95 {
98 DebugScopedSetMainThreadBlocked mainThreadBlocked(this); 96 DebugScopedSetMainThreadBlocked mainThreadBlocked(this);
99 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::requestReadbackOn ImplThread, base::Unretained(this), &request)); 97 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::requestReadbackOn ImplThread, base::Unretained(this), &request));
100 request.completion.wait(); 98 request.completion.wait();
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 { 329 {
332 DCHECK(isImplThread()); 330 DCHECK(isImplThread());
333 TRACE_EVENT0("cc", "ThreadProxy::setNeedsCommitOnImplThread"); 331 TRACE_EVENT0("cc", "ThreadProxy::setNeedsCommitOnImplThread");
334 m_schedulerOnImplThread->setNeedsCommit(); 332 m_schedulerOnImplThread->setNeedsCommit();
335 } 333 }
336 334
337 void ThreadProxy::setNeedsForcedCommitOnImplThread() 335 void ThreadProxy::setNeedsForcedCommitOnImplThread()
338 { 336 {
339 DCHECK(isImplThread()); 337 DCHECK(isImplThread());
340 TRACE_EVENT0("cc", "ThreadProxy::setNeedsForcedCommitOnImplThread"); 338 TRACE_EVENT0("cc", "ThreadProxy::setNeedsForcedCommitOnImplThread");
341 m_schedulerOnImplThread->setNeedsCommit();
342 m_schedulerOnImplThread->setNeedsForcedCommit(); 339 m_schedulerOnImplThread->setNeedsForcedCommit();
343 } 340 }
344 341
345 void ThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<Animati onEventsVector> events, base::Time wallClockTime) 342 void ThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<Animati onEventsVector> events, base::Time wallClockTime)
346 { 343 {
347 DCHECK(isImplThread()); 344 DCHECK(isImplThread());
348 TRACE_EVENT0("cc", "ThreadProxy::postAnimationEventsToMainThreadOnImplThread "); 345 TRACE_EVENT0("cc", "ThreadProxy::postAnimationEventsToMainThreadOnImplThread ");
349 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::setAnimation Events, base::Unretained(this), base::Passed(events.Pass()), wallClockTime)); 346 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::setAnimation Events, base::Unretained(this), base::Passed(events.Pass()), wallClockTime));
350 } 347 }
351 348
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 { 392 {
396 DCHECK(isMainThread()); 393 DCHECK(isMainThread());
397 DCHECK_NE(m_deferCommits, deferCommits); 394 DCHECK_NE(m_deferCommits, deferCommits);
398 m_deferCommits = deferCommits; 395 m_deferCommits = deferCommits;
399 396
400 if (m_deferCommits) 397 if (m_deferCommits)
401 TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::setDeferCommits", this); 398 TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::setDeferCommits", this);
402 else 399 else
403 TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::setDeferCommits", this); 400 TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::setDeferCommits", this);
404 401
405 if (!m_deferCommits && m_deferredCommitPending) { 402 if (!m_deferCommits && m_pendingDeferredCommit)
406 m_deferredCommitPending = false; 403 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFra me, base::Unretained(this), base::Passed(m_pendingDeferredCommit.Pass())));
407 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFra me, base::Unretained(this)));
408 }
409 } 404 }
410 405
411 bool ThreadProxy::commitRequested() const 406 bool ThreadProxy::commitRequested() const
412 { 407 {
413 DCHECK(isMainThread()); 408 DCHECK(isMainThread());
414 return m_commitRequested; 409 return m_commitRequested;
415 } 410 }
416 411
417 void ThreadProxy::setNeedsRedrawOnImplThread() 412 void ThreadProxy::setNeedsRedrawOnImplThread()
418 { 413 {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 DCHECK(isImplThread()); 474 DCHECK(isImplThread());
480 m_layerTreeHostImpl->finishAllRendering(); 475 m_layerTreeHostImpl->finishAllRendering();
481 completion->signal(); 476 completion->signal();
482 } 477 }
483 478
484 void ThreadProxy::forceBeginFrameOnImplThread(CompletionEvent* completion) 479 void ThreadProxy::forceBeginFrameOnImplThread(CompletionEvent* completion)
485 { 480 {
486 TRACE_EVENT0("cc", "ThreadProxy::forceBeginFrameOnImplThread"); 481 TRACE_EVENT0("cc", "ThreadProxy::forceBeginFrameOnImplThread");
487 DCHECK(!m_beginFrameCompletionEventOnImplThread); 482 DCHECK(!m_beginFrameCompletionEventOnImplThread);
488 483
484 setNeedsForcedCommitOnImplThread();
489 if (m_schedulerOnImplThread->commitPending()) { 485 if (m_schedulerOnImplThread->commitPending()) {
490 completion->signal(); 486 completion->signal();
491 return; 487 return;
492 } 488 }
493 489
494 m_beginFrameCompletionEventOnImplThread = completion; 490 m_beginFrameCompletionEventOnImplThread = completion;
495 setNeedsForcedCommitOnImplThread();
496 } 491 }
497 492
498 void ThreadProxy::scheduledActionBeginFrame() 493 void ThreadProxy::scheduledActionBeginFrame()
499 { 494 {
500 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionBeginFrame"); 495 TRACE_EVENT0("cc", "ThreadProxy::scheduledActionBeginFrame");
501 DCHECK(!m_pendingBeginFrameRequest); 496 scoped_ptr<BeginFrameAndCommitState> beginFrameState(new BeginFrameAndCommit State);
502 m_pendingBeginFrameRequest = make_scoped_ptr(new BeginFrameAndCommitState()) ; 497 beginFrameState->monotonicFrameBeginTime = base::TimeTicks::Now();
503 m_pendingBeginFrameRequest->monotonicFrameBeginTime = base::TimeTicks::Now() ; 498 beginFrameState->scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
504 m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollD eltas(); 499 beginFrameState->implTransform = m_layerTreeHostImpl->implTransform();
505 m_pendingBeginFrameRequest->implTransform = m_layerTreeHostImpl->implTransfo rm(); 500 DCHECK_GT(m_layerTreeHostImpl->memoryAllocationLimitBytes(), 0u);
506 m_pendingBeginFrameRequest->memoryAllocationLimitBytes = m_layerTreeHostImpl ->memoryAllocationLimitBytes(); 501 beginFrameState->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAll ocationLimitBytes();
507 if (m_layerTreeHost->contentsTextureManager()) 502 if (m_layerTreeHost->contentsTextureManager())
508 m_layerTreeHost->contentsTextureManager()->getEvictedBackings(m_pending BeginFrameRequest->evictedContentsTexturesBackings); 503 m_layerTreeHost->contentsTextureManager()->getEvictedBackings(beginFram eState->evictedContentsTexturesBackings);
509 504
510 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFrame, base::Unretained(this))); 505 m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadProxy::beginFrame, base::Unretained(this), base::Passed(beginFrameState.Pass())));
511 506
512 if (m_beginFrameCompletionEventOnImplThread) { 507 if (m_beginFrameCompletionEventOnImplThread) {
513 m_beginFrameCompletionEventOnImplThread->signal(); 508 m_beginFrameCompletionEventOnImplThread->signal();
514 m_beginFrameCompletionEventOnImplThread = 0; 509 m_beginFrameCompletionEventOnImplThread = 0;
515 } 510 }
516 } 511 }
517 512
518 void ThreadProxy::beginFrame() 513 void ThreadProxy::beginFrame(scoped_ptr<BeginFrameAndCommitState> beginFrameStat e)
519 { 514 {
520 TRACE_EVENT0("cc", "ThreadProxy::beginFrame"); 515 TRACE_EVENT0("cc", "ThreadProxy::beginFrame");
521 DCHECK(isMainThread()); 516 DCHECK(isMainThread());
522 if (!m_layerTreeHost) 517 if (!m_layerTreeHost)
523 return; 518 return;
524 519
525 if (m_deferCommits) { 520 if (m_deferCommits) {
526 m_deferredCommitPending = true; 521 m_pendingDeferredCommit = beginFrameState.Pass();
527 m_layerTreeHost->didDeferCommit(); 522 m_layerTreeHost->didDeferCommit();
528 TRACE_EVENT0("cc", "EarlyOut_DeferCommits"); 523 TRACE_EVENT0("cc", "EarlyOut_DeferCommits");
529 return; 524 return;
530 } 525 }
531 526
532 if (!m_pendingBeginFrameRequest) {
533 TRACE_EVENT0("cc", "EarlyOut_StaleBeginFrameMessage");
534 return;
535 }
536
537 if (m_layerTreeHost->needsSharedContext() && !WebSharedGraphicsContext3D::ha veCompositorThreadContext()) 527 if (m_layerTreeHost->needsSharedContext() && !WebSharedGraphicsContext3D::ha veCompositorThreadContext())
538 WebSharedGraphicsContext3D::createCompositorThreadContext(); 528 WebSharedGraphicsContext3D::createCompositorThreadContext();
539 529
540 scoped_ptr<BeginFrameAndCommitState> request(m_pendingBeginFrameRequest.Pass ());
541
542 // Do not notify the impl thread of commit requests that occur during 530 // Do not notify the impl thread of commit requests that occur during
543 // the apply/animate/layout part of the beginFrameAndCommit process since 531 // the apply/animate/layout part of the beginFrameAndCommit process since
544 // those commit requests will get painted immediately. Once we have done 532 // those commit requests will get painted immediately. Once we have done
545 // the paint, m_commitRequested will be set to false to allow new commit 533 // the paint, m_commitRequested will be set to false to allow new commit
546 // requests to be scheduled. 534 // requests to be scheduled.
547 m_commitRequested = true; 535 m_commitRequested = true;
548 m_commitRequestSentToImplThread = true; 536 m_commitRequestSentToImplThread = true;
549 537
550 // On the other hand, the animationRequested flag needs to be cleared 538 // On the other hand, the animationRequested flag needs to be cleared
551 // here so that any animation requests generated by the apply or animate 539 // here so that any animation requests generated by the apply or animate
552 // callbacks will trigger another frame. 540 // callbacks will trigger another frame.
553 m_animateRequested = false; 541 m_animateRequested = false;
554 542
555 // FIXME: technically, scroll deltas need to be applied for dropped commits as well. 543 if (beginFrameState) {
556 // Re-do the commit flow so that we don't send the scrollInfo on the BFAC me ssage. 544 m_layerTreeHost->applyScrollAndScale(*beginFrameState->scrollInfo);
557 m_layerTreeHost->applyScrollAndScale(*request->scrollInfo); 545 m_layerTreeHost->setImplTransform(beginFrameState->implTransform);
558 m_layerTreeHost->setImplTransform(request->implTransform); 546 }
559 547
560 if (!m_inCompositeAndReadback && !m_layerTreeHost->visible()) { 548 if (!m_inCompositeAndReadback && !m_layerTreeHost->visible()) {
561 m_commitRequested = false; 549 m_commitRequested = false;
562 m_commitRequestSentToImplThread = false; 550 m_commitRequestSentToImplThread = false;
563 m_forcedCommitRequested = false;
564 551
565 TRACE_EVENT0("cc", "EarlyOut_NotVisible"); 552 TRACE_EVENT0("cc", "EarlyOut_NotVisible");
566 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::beginFrameAborted OnImplThread, base::Unretained(this))); 553 Proxy::implThread()->postTask(base::Bind(&ThreadProxy::beginFrameAborted OnImplThread, base::Unretained(this)));
567 return; 554 return;
568 } 555 }
569 556
570 m_layerTreeHost->willBeginFrame(); 557 m_layerTreeHost->willBeginFrame();
571 558
572 m_layerTreeHost->updateAnimations(request->monotonicFrameBeginTime); 559 if (beginFrameState)
560 m_layerTreeHost->updateAnimations(beginFrameState->monotonicFrameBeginTi me);
573 m_layerTreeHost->layout(); 561 m_layerTreeHost->layout();
574 562
575 // Clear the commit flag after updating animations and layout here --- objec ts that only 563 // Clear the commit flag after updating animations and layout here --- objec ts that only
576 // layout when painted will trigger another setNeedsCommit inside 564 // layout when painted will trigger another setNeedsCommit inside
577 // updateLayers. 565 // updateLayers.
578 m_commitRequested = false; 566 m_commitRequested = false;
579 m_commitRequestSentToImplThread = false; 567 m_commitRequestSentToImplThread = false;
580 m_forcedCommitRequested = false;
581 568
582 if (!m_layerTreeHost->initializeRendererIfNeeded()) { 569 if (!m_layerTreeHost->initializeRendererIfNeeded()) {
583 TRACE_EVENT0("cc", "EarlyOut_InitializeFailed"); 570 TRACE_EVENT0("cc", "EarlyOut_InitializeFailed");
584 return; 571 return;
585 } 572 }
586 573
587 m_layerTreeHost->contentsTextureManager()->unlinkEvictedBackings(request->ev ictedContentsTexturesBackings); 574 if (beginFrameState)
575 m_layerTreeHost->contentsTextureManager()->unlinkEvictedBackings(beginFr ameState->evictedContentsTexturesBackings);
588 576
589 scoped_ptr<ResourceUpdateQueue> queue = make_scoped_ptr(new ResourceUpdateQu eue); 577 scoped_ptr<ResourceUpdateQueue> queue = make_scoped_ptr(new ResourceUpdateQu eue);
590 m_layerTreeHost->updateLayers(*(queue.get()), request->memoryAllocationLimit Bytes); 578 m_layerTreeHost->updateLayers(*(queue.get()), beginFrameState ? beginFrameSt ate->memoryAllocationLimitBytes : 0);
591 579
592 // Once single buffered layers are committed, they cannot be modified until 580 // Once single buffered layers are committed, they cannot be modified until
593 // they are drawn by the impl thread. 581 // they are drawn by the impl thread.
594 m_texturesAcquired = false; 582 m_texturesAcquired = false;
595 583
596 m_layerTreeHost->willCommit(); 584 m_layerTreeHost->willCommit();
597 // Before applying scrolls and calling animate, we set m_animateRequested to 585 // Before applying scrolls and calling animate, we set m_animateRequested to
598 // false. If it is true now, it means setNeedAnimate was called again, but 586 // false. If it is true now, it means setNeedAnimate was called again, but
599 // during a state when m_commitRequestSentToImplThread = true. We need to 587 // during a state when m_commitRequestSentToImplThread = true. We need to
600 // force that call to happen again now so that the commit request is sent to 588 // force that call to happen again now so that the commit request is sent to
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 } 947 }
960 948
961 void ThreadProxy::renderingStatsOnImplThread(CompletionEvent* completion, Render ingStats* stats) 949 void ThreadProxy::renderingStatsOnImplThread(CompletionEvent* completion, Render ingStats* stats)
962 { 950 {
963 DCHECK(isImplThread()); 951 DCHECK(isImplThread());
964 m_layerTreeHostImpl->renderingStats(stats); 952 m_layerTreeHostImpl->renderingStats(stats);
965 completion->signal(); 953 completion->signal();
966 } 954 }
967 955
968 ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState() 956 ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState()
957 : memoryAllocationLimitBytes(0)
969 { 958 {
970 } 959 }
971 960
972 ThreadProxy::BeginFrameAndCommitState::~BeginFrameAndCommitState() 961 ThreadProxy::BeginFrameAndCommitState::~BeginFrameAndCommitState()
973 { 962 {
974 } 963 }
975 964
976 } // namespace cc 965 } // namespace cc
OLDNEW
« no previous file with comments | « cc/thread_proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698