| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 | |
| 7 #include "CCThreadProxy.h" | |
| 8 | |
| 9 #include "CCDelayBasedTimeSource.h" | |
| 10 #include "CCDrawQuad.h" | |
| 11 #include "CCFrameRateController.h" | |
| 12 #include "CCGraphicsContext.h" | |
| 13 #include "CCInputHandler.h" | |
| 14 #include "CCLayerTreeHost.h" | |
| 15 #include "CCScheduler.h" | |
| 16 #include "CCScopedThreadProxy.h" | |
| 17 #include "CCThreadTask.h" | |
| 18 #include "TraceEvent.h" | |
| 19 #include <public/WebSharedGraphicsContext3D.h> | |
| 20 #include <wtf/CurrentTime.h> | |
| 21 | |
| 22 using namespace WTF; | |
| 23 using WebKit::WebSharedGraphicsContext3D; | |
| 24 | |
| 25 namespace { | |
| 26 | |
| 27 // Measured in seconds. | |
| 28 const double contextRecreationTickRate = 0.03; | |
| 29 | |
| 30 } // namespace | |
| 31 | |
| 32 namespace cc { | |
| 33 | |
| 34 scoped_ptr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost) | |
| 35 { | |
| 36 return make_scoped_ptr(new CCThreadProxy(layerTreeHost)).PassAs<CCProxy>(); | |
| 37 } | |
| 38 | |
| 39 CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost) | |
| 40 : m_animateRequested(false) | |
| 41 , m_commitRequested(false) | |
| 42 , m_commitRequestSentToImplThread(false) | |
| 43 , m_forcedCommitRequested(false) | |
| 44 , m_layerTreeHost(layerTreeHost) | |
| 45 , m_rendererInitialized(false) | |
| 46 , m_started(false) | |
| 47 , m_texturesAcquired(true) | |
| 48 , m_inCompositeAndReadback(false) | |
| 49 , m_mainThreadProxy(CCScopedThreadProxy::create(CCProxy::mainThread())) | |
| 50 , m_beginFrameCompletionEventOnImplThread(0) | |
| 51 , m_readbackRequestOnImplThread(0) | |
| 52 , m_commitCompletionEventOnImplThread(0) | |
| 53 , m_textureAcquisitionCompletionEventOnImplThread(0) | |
| 54 , m_resetContentsTexturesPurgedAfterCommitOnImplThread(false) | |
| 55 , m_nextFrameIsNewlyCommittedFrameOnImplThread(false) | |
| 56 , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled) | |
| 57 , m_totalCommitCount(0) | |
| 58 { | |
| 59 TRACE_EVENT0("cc", "CCThreadProxy::CCThreadProxy"); | |
| 60 ASSERT(isMainThread()); | |
| 61 } | |
| 62 | |
| 63 CCThreadProxy::~CCThreadProxy() | |
| 64 { | |
| 65 TRACE_EVENT0("cc", "CCThreadProxy::~CCThreadProxy"); | |
| 66 ASSERT(isMainThread()); | |
| 67 ASSERT(!m_started); | |
| 68 } | |
| 69 | |
| 70 bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect) | |
| 71 { | |
| 72 TRACE_EVENT0("cc", "CCThreadPRoxy::compositeAndReadback"); | |
| 73 ASSERT(isMainThread()); | |
| 74 ASSERT(m_layerTreeHost); | |
| 75 | |
| 76 if (!m_layerTreeHost->initializeRendererIfNeeded()) { | |
| 77 TRACE_EVENT0("cc", "compositeAndReadback_EarlyOut_LR_Uninitialized"); | |
| 78 return false; | |
| 79 } | |
| 80 | |
| 81 | |
| 82 // Perform a synchronous commit. | |
| 83 { | |
| 84 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 85 CCCompletionEvent beginFrameCompletion; | |
| 86 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy:
:forceBeginFrameOnImplThread, &beginFrameCompletion)); | |
| 87 beginFrameCompletion.wait(); | |
| 88 } | |
| 89 m_inCompositeAndReadback = true; | |
| 90 beginFrame(); | |
| 91 m_inCompositeAndReadback = false; | |
| 92 | |
| 93 // Perform a synchronous readback. | |
| 94 ReadbackRequest request; | |
| 95 request.rect = rect; | |
| 96 request.pixels = pixels; | |
| 97 { | |
| 98 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 99 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy:
:requestReadbackOnImplThread, &request)); | |
| 100 request.completion.wait(); | |
| 101 } | |
| 102 return request.success; | |
| 103 } | |
| 104 | |
| 105 void CCThreadProxy::requestReadbackOnImplThread(ReadbackRequest* request) | |
| 106 { | |
| 107 ASSERT(CCProxy::isImplThread()); | |
| 108 ASSERT(!m_readbackRequestOnImplThread); | |
| 109 if (!m_layerTreeHostImpl.get()) { | |
| 110 request->success = false; | |
| 111 request->completion.signal(); | |
| 112 return; | |
| 113 } | |
| 114 | |
| 115 m_readbackRequestOnImplThread = request; | |
| 116 m_schedulerOnImplThread->setNeedsRedraw(); | |
| 117 m_schedulerOnImplThread->setNeedsForcedRedraw(); | |
| 118 } | |
| 119 | |
| 120 void CCThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool
useAnchor, float scale, double duration) | |
| 121 { | |
| 122 ASSERT(CCProxy::isMainThread()); | |
| 123 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::req
uestStartPageScaleAnimationOnImplThread, targetPosition, useAnchor, scale, durat
ion)); | |
| 124 } | |
| 125 | |
| 126 void CCThreadProxy::requestStartPageScaleAnimationOnImplThread(IntSize targetPos
ition, bool useAnchor, float scale, double duration) | |
| 127 { | |
| 128 ASSERT(CCProxy::isImplThread()); | |
| 129 if (m_layerTreeHostImpl.get()) | |
| 130 m_layerTreeHostImpl->startPageScaleAnimation(targetPosition, useAnchor,
scale, monotonicallyIncreasingTime(), duration); | |
| 131 } | |
| 132 | |
| 133 void CCThreadProxy::finishAllRendering() | |
| 134 { | |
| 135 ASSERT(CCProxy::isMainThread()); | |
| 136 | |
| 137 // Make sure all GL drawing is finished on the impl thread. | |
| 138 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 139 CCCompletionEvent completion; | |
| 140 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::fin
ishAllRenderingOnImplThread, &completion)); | |
| 141 completion.wait(); | |
| 142 } | |
| 143 | |
| 144 bool CCThreadProxy::isStarted() const | |
| 145 { | |
| 146 ASSERT(CCProxy::isMainThread()); | |
| 147 return m_started; | |
| 148 } | |
| 149 | |
| 150 bool CCThreadProxy::initializeContext() | |
| 151 { | |
| 152 TRACE_EVENT0("cc", "CCThreadProxy::initializeContext"); | |
| 153 scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext(); | |
| 154 if (!context.get()) | |
| 155 return false; | |
| 156 | |
| 157 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ini
tializeContextOnImplThread, | |
| 158 context.release())); | |
| 159 return true; | |
| 160 } | |
| 161 | |
| 162 void CCThreadProxy::setSurfaceReady() | |
| 163 { | |
| 164 TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReady"); | |
| 165 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set
SurfaceReadyOnImplThread)); | |
| 166 } | |
| 167 | |
| 168 void CCThreadProxy::setSurfaceReadyOnImplThread() | |
| 169 { | |
| 170 TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReadyOnImplThread"); | |
| 171 m_schedulerOnImplThread->setCanBeginFrame(true); | |
| 172 } | |
| 173 | |
| 174 void CCThreadProxy::setVisible(bool visible) | |
| 175 { | |
| 176 TRACE_EVENT0("cc", "CCThreadProxy::setVisible"); | |
| 177 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 178 CCCompletionEvent completion; | |
| 179 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set
VisibleOnImplThread, &completion, visible)); | |
| 180 completion.wait(); | |
| 181 } | |
| 182 | |
| 183 void CCThreadProxy::setVisibleOnImplThread(CCCompletionEvent* completion, bool v
isible) | |
| 184 { | |
| 185 TRACE_EVENT0("cc", "CCThreadProxy::setVisibleOnImplThread"); | |
| 186 m_layerTreeHostImpl->setVisible(visible); | |
| 187 m_schedulerOnImplThread->setVisible(visible); | |
| 188 completion->signal(); | |
| 189 } | |
| 190 | |
| 191 bool CCThreadProxy::initializeRenderer() | |
| 192 { | |
| 193 TRACE_EVENT0("cc", "CCThreadProxy::initializeRenderer"); | |
| 194 // Make a blocking call to initializeRendererOnImplThread. The results of th
at call | |
| 195 // are pushed into the initializeSucceeded and capabilities local variables. | |
| 196 CCCompletionEvent completion; | |
| 197 bool initializeSucceeded = false; | |
| 198 RendererCapabilities capabilities; | |
| 199 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 200 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ini
tializeRendererOnImplThread, | |
| 201 &completion, | |
| 202 &initializeSucceeded, | |
| 203 &capabilities)); | |
| 204 completion.wait(); | |
| 205 | |
| 206 if (initializeSucceeded) { | |
| 207 m_rendererInitialized = true; | |
| 208 m_RendererCapabilitiesMainThreadCopy = capabilities; | |
| 209 } | |
| 210 return initializeSucceeded; | |
| 211 } | |
| 212 | |
| 213 bool CCThreadProxy::recreateContext() | |
| 214 { | |
| 215 TRACE_EVENT0("cc", "CCThreadProxy::recreateContext"); | |
| 216 ASSERT(isMainThread()); | |
| 217 | |
| 218 // Try to create the context. | |
| 219 scoped_ptr<CCGraphicsContext> context = m_layerTreeHost->createContext(); | |
| 220 if (!context.get()) | |
| 221 return false; | |
| 222 if (m_layerTreeHost->needsSharedContext()) | |
| 223 if (!WebSharedGraphicsContext3D::createCompositorThreadContext()) | |
| 224 return false; | |
| 225 | |
| 226 // Make a blocking call to recreateContextOnImplThread. The results of that | |
| 227 // call are pushed into the recreateSucceeded and capabilities local | |
| 228 // variables. | |
| 229 CCCompletionEvent completion; | |
| 230 bool recreateSucceeded = false; | |
| 231 RendererCapabilities capabilities; | |
| 232 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 233 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::rec
reateContextOnImplThread, | |
| 234 &completion, | |
| 235 context.release(), | |
| 236 &recreateSucceeded, | |
| 237 &capabilities)); | |
| 238 completion.wait(); | |
| 239 | |
| 240 if (recreateSucceeded) | |
| 241 m_RendererCapabilitiesMainThreadCopy = capabilities; | |
| 242 return recreateSucceeded; | |
| 243 } | |
| 244 | |
| 245 void CCThreadProxy::renderingStats(CCRenderingStats* stats) | |
| 246 { | |
| 247 ASSERT(isMainThread()); | |
| 248 | |
| 249 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 250 CCCompletionEvent completion; | |
| 251 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ren
deringStatsOnImplThread, | |
| 252 &completion, | |
| 253 stats)); | |
| 254 stats->totalCommitTimeInSeconds = m_totalCommitTime.InSecondsF(); | |
| 255 stats->totalCommitCount = m_totalCommitCount; | |
| 256 | |
| 257 completion.wait(); | |
| 258 } | |
| 259 | |
| 260 const RendererCapabilities& CCThreadProxy::rendererCapabilities() const | |
| 261 { | |
| 262 ASSERT(m_rendererInitialized); | |
| 263 return m_RendererCapabilitiesMainThreadCopy; | |
| 264 } | |
| 265 | |
| 266 void CCThreadProxy::loseContext() | |
| 267 { | |
| 268 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::did
LoseContextOnImplThread)); | |
| 269 } | |
| 270 | |
| 271 void CCThreadProxy::setNeedsAnimate() | |
| 272 { | |
| 273 ASSERT(isMainThread()); | |
| 274 if (m_animateRequested) | |
| 275 return; | |
| 276 | |
| 277 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsAnimate"); | |
| 278 m_animateRequested = true; | |
| 279 | |
| 280 if (m_commitRequestSentToImplThread) | |
| 281 return; | |
| 282 m_commitRequestSentToImplThread = true; | |
| 283 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set
NeedsCommitOnImplThread)); | |
| 284 } | |
| 285 | |
| 286 void CCThreadProxy::setNeedsCommit() | |
| 287 { | |
| 288 ASSERT(isMainThread()); | |
| 289 if (m_commitRequested) | |
| 290 return; | |
| 291 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsCommit"); | |
| 292 m_commitRequested = true; | |
| 293 | |
| 294 if (m_commitRequestSentToImplThread) | |
| 295 return; | |
| 296 m_commitRequestSentToImplThread = true; | |
| 297 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set
NeedsCommitOnImplThread)); | |
| 298 } | |
| 299 | |
| 300 void CCThreadProxy::didLoseContextOnImplThread() | |
| 301 { | |
| 302 ASSERT(isImplThread()); | |
| 303 TRACE_EVENT0("cc", "CCThreadProxy::didLoseContextOnImplThread"); | |
| 304 m_schedulerOnImplThread->didLoseContext(); | |
| 305 } | |
| 306 | |
| 307 void CCThreadProxy::onSwapBuffersCompleteOnImplThread() | |
| 308 { | |
| 309 ASSERT(isImplThread()); | |
| 310 TRACE_EVENT0("cc", "CCThreadProxy::onSwapBuffersCompleteOnImplThread"); | |
| 311 m_schedulerOnImplThread->didSwapBuffersComplete(); | |
| 312 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::didComp
leteSwapBuffers)); | |
| 313 } | |
| 314 | |
| 315 void CCThreadProxy::onVSyncParametersChanged(double monotonicTimebase, double in
tervalInSeconds) | |
| 316 { | |
| 317 ASSERT(isImplThread()); | |
| 318 TRACE_EVENT2("cc", "CCThreadProxy::onVSyncParametersChanged", "monotonicTime
base", monotonicTimebase, "intervalInSeconds", intervalInSeconds); | |
| 319 base::TimeTicks timebase = base::TimeTicks::FromInternalValue(monotonicTimeb
ase * base::Time::kMicrosecondsPerSecond); | |
| 320 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(intervalInSecon
ds * base::Time::kMicrosecondsPerSecond); | |
| 321 m_schedulerOnImplThread->setTimebaseAndInterval(timebase, interval); | |
| 322 } | |
| 323 | |
| 324 void CCThreadProxy::onCanDrawStateChanged(bool canDraw) | |
| 325 { | |
| 326 ASSERT(isImplThread()); | |
| 327 TRACE_EVENT1("cc", "CCThreadProxy::onCanDrawStateChanged", "canDraw", canDra
w); | |
| 328 m_schedulerOnImplThread->setCanDraw(canDraw); | |
| 329 } | |
| 330 | |
| 331 void CCThreadProxy::setNeedsCommitOnImplThread() | |
| 332 { | |
| 333 ASSERT(isImplThread()); | |
| 334 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsCommitOnImplThread"); | |
| 335 m_schedulerOnImplThread->setNeedsCommit(); | |
| 336 } | |
| 337 | |
| 338 void CCThreadProxy::setNeedsForcedCommitOnImplThread() | |
| 339 { | |
| 340 ASSERT(isImplThread()); | |
| 341 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsForcedCommitOnImplThread"); | |
| 342 m_schedulerOnImplThread->setNeedsCommit(); | |
| 343 m_schedulerOnImplThread->setNeedsForcedCommit(); | |
| 344 } | |
| 345 | |
| 346 void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAni
mationEventsVector> events, double wallClockTime) | |
| 347 { | |
| 348 ASSERT(isImplThread()); | |
| 349 TRACE_EVENT0("cc", "CCThreadProxy::postAnimationEventsToMainThreadOnImplThre
ad"); | |
| 350 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnim
ationEvents, events.release(), wallClockTime)); | |
| 351 } | |
| 352 | |
| 353 void CCThreadProxy::releaseContentsTexturesOnImplThread() | |
| 354 { | |
| 355 ASSERT(isImplThread()); | |
| 356 | |
| 357 m_layerTreeHost->reduceContentsTexturesMemoryOnImplThread(0, m_layerTreeHost
Impl->resourceProvider()); | |
| 358 | |
| 359 // Make sure that we get a new commit before drawing again. | |
| 360 m_resetContentsTexturesPurgedAfterCommitOnImplThread = false; | |
| 361 // The texture upload queue may reference textures that were just purged, cl
ear | |
| 362 // them from the queue. | |
| 363 if (m_currentTextureUpdateControllerOnImplThread.get() && m_layerTreeHost->e
victedContentsTexturesBackingsExist()) | |
| 364 m_currentTextureUpdateControllerOnImplThread->discardUploadsToEvictedRes
ources(); | |
| 365 } | |
| 366 | |
| 367 void CCThreadProxy::setNeedsRedraw() | |
| 368 { | |
| 369 ASSERT(isMainThread()); | |
| 370 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsRedraw"); | |
| 371 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set
FullRootLayerDamageOnImplThread)); | |
| 372 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::set
NeedsRedrawOnImplThread)); | |
| 373 } | |
| 374 | |
| 375 bool CCThreadProxy::commitRequested() const | |
| 376 { | |
| 377 ASSERT(isMainThread()); | |
| 378 return m_commitRequested; | |
| 379 } | |
| 380 | |
| 381 void CCThreadProxy::setNeedsRedrawOnImplThread() | |
| 382 { | |
| 383 ASSERT(isImplThread()); | |
| 384 TRACE_EVENT0("cc", "CCThreadProxy::setNeedsRedrawOnImplThread"); | |
| 385 m_schedulerOnImplThread->setNeedsRedraw(); | |
| 386 } | |
| 387 | |
| 388 void CCThreadProxy::start() | |
| 389 { | |
| 390 ASSERT(isMainThread()); | |
| 391 ASSERT(CCProxy::implThread()); | |
| 392 // Create LayerTreeHostImpl. | |
| 393 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 394 CCCompletionEvent completion; | |
| 395 scoped_ptr<CCInputHandler> handler = m_layerTreeHost->createInputHandler(); | |
| 396 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::ini
tializeImplOnImplThread, &completion, handler.release())); | |
| 397 completion.wait(); | |
| 398 | |
| 399 m_started = true; | |
| 400 } | |
| 401 | |
| 402 void CCThreadProxy::stop() | |
| 403 { | |
| 404 TRACE_EVENT0("cc", "CCThreadProxy::stop"); | |
| 405 ASSERT(isMainThread()); | |
| 406 ASSERT(m_started); | |
| 407 | |
| 408 // Synchronously deletes the impl. | |
| 409 { | |
| 410 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 411 | |
| 412 CCCompletionEvent completion; | |
| 413 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy:
:layerTreeHostClosedOnImplThread, &completion)); | |
| 414 completion.wait(); | |
| 415 } | |
| 416 | |
| 417 m_mainThreadProxy->shutdown(); // Stop running tasks posted to us. | |
| 418 | |
| 419 ASSERT(!m_layerTreeHostImpl.get()); // verify that the impl deleted. | |
| 420 m_layerTreeHost = 0; | |
| 421 m_started = false; | |
| 422 } | |
| 423 | |
| 424 void CCThreadProxy::forceSerializeOnSwapBuffers() | |
| 425 { | |
| 426 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 427 CCCompletionEvent completion; | |
| 428 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::for
ceSerializeOnSwapBuffersOnImplThread, &completion)); | |
| 429 completion.wait(); | |
| 430 } | |
| 431 | |
| 432 void CCThreadProxy::forceSerializeOnSwapBuffersOnImplThread(CCCompletionEvent* c
ompletion) | |
| 433 { | |
| 434 if (m_rendererInitialized) | |
| 435 m_layerTreeHostImpl->renderer()->doNoOp(); | |
| 436 completion->signal(); | |
| 437 } | |
| 438 | |
| 439 | |
| 440 void CCThreadProxy::finishAllRenderingOnImplThread(CCCompletionEvent* completion
) | |
| 441 { | |
| 442 TRACE_EVENT0("cc", "CCThreadProxy::finishAllRenderingOnImplThread"); | |
| 443 ASSERT(isImplThread()); | |
| 444 m_layerTreeHostImpl->finishAllRendering(); | |
| 445 completion->signal(); | |
| 446 } | |
| 447 | |
| 448 void CCThreadProxy::forceBeginFrameOnImplThread(CCCompletionEvent* completion) | |
| 449 { | |
| 450 TRACE_EVENT0("cc", "CCThreadProxy::forceBeginFrameOnImplThread"); | |
| 451 ASSERT(!m_beginFrameCompletionEventOnImplThread); | |
| 452 | |
| 453 if (m_schedulerOnImplThread->commitPending()) { | |
| 454 completion->signal(); | |
| 455 return; | |
| 456 } | |
| 457 | |
| 458 m_beginFrameCompletionEventOnImplThread = completion; | |
| 459 setNeedsForcedCommitOnImplThread(); | |
| 460 } | |
| 461 | |
| 462 void CCThreadProxy::scheduledActionBeginFrame() | |
| 463 { | |
| 464 TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionBeginFrame"); | |
| 465 ASSERT(!m_pendingBeginFrameRequest); | |
| 466 m_pendingBeginFrameRequest = adoptPtr(new BeginFrameAndCommitState()); | |
| 467 m_pendingBeginFrameRequest->monotonicFrameBeginTime = monotonicallyIncreasin
gTime(); | |
| 468 m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollD
eltas(); | |
| 469 m_pendingBeginFrameRequest->implTransform = m_layerTreeHostImpl->implTransfo
rm(); | |
| 470 m_pendingBeginFrameRequest->memoryAllocationLimitBytes = m_layerTreeHostImpl
->memoryAllocationLimitBytes(); | |
| 471 m_layerTreeHost->getEvictedContentTexturesBackings(m_pendingBeginFrameReques
t->evictedContentsTexturesBackings); | |
| 472 | |
| 473 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFr
ame)); | |
| 474 | |
| 475 if (m_beginFrameCompletionEventOnImplThread) { | |
| 476 m_beginFrameCompletionEventOnImplThread->signal(); | |
| 477 m_beginFrameCompletionEventOnImplThread = 0; | |
| 478 } | |
| 479 } | |
| 480 | |
| 481 void CCThreadProxy::beginFrame() | |
| 482 { | |
| 483 TRACE_EVENT0("cc", "CCThreadProxy::beginFrame"); | |
| 484 ASSERT(isMainThread()); | |
| 485 if (!m_layerTreeHost) | |
| 486 return; | |
| 487 | |
| 488 if (!m_pendingBeginFrameRequest) { | |
| 489 TRACE_EVENT0("cc", "EarlyOut_StaleBeginFrameMessage"); | |
| 490 return; | |
| 491 } | |
| 492 | |
| 493 if (m_layerTreeHost->needsSharedContext() && !WebSharedGraphicsContext3D::ha
veCompositorThreadContext()) | |
| 494 WebSharedGraphicsContext3D::createCompositorThreadContext(); | |
| 495 | |
| 496 OwnPtr<BeginFrameAndCommitState> request(m_pendingBeginFrameRequest.release(
)); | |
| 497 | |
| 498 // Do not notify the impl thread of commit requests that occur during | |
| 499 // the apply/animate/layout part of the beginFrameAndCommit process since | |
| 500 // those commit requests will get painted immediately. Once we have done | |
| 501 // the paint, m_commitRequested will be set to false to allow new commit | |
| 502 // requests to be scheduled. | |
| 503 m_commitRequested = true; | |
| 504 m_commitRequestSentToImplThread = true; | |
| 505 | |
| 506 // On the other hand, the animationRequested flag needs to be cleared | |
| 507 // here so that any animation requests generated by the apply or animate | |
| 508 // callbacks will trigger another frame. | |
| 509 m_animateRequested = false; | |
| 510 | |
| 511 // FIXME: technically, scroll deltas need to be applied for dropped commits
as well. | |
| 512 // Re-do the commit flow so that we don't send the scrollInfo on the BFAC me
ssage. | |
| 513 m_layerTreeHost->applyScrollAndScale(*request->scrollInfo); | |
| 514 m_layerTreeHost->setImplTransform(request->implTransform); | |
| 515 | |
| 516 if (!m_inCompositeAndReadback && !m_layerTreeHost->visible()) { | |
| 517 m_commitRequested = false; | |
| 518 m_commitRequestSentToImplThread = false; | |
| 519 m_forcedCommitRequested = false; | |
| 520 | |
| 521 TRACE_EVENT0("cc", "EarlyOut_NotVisible"); | |
| 522 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy:
:beginFrameAbortedOnImplThread)); | |
| 523 return; | |
| 524 } | |
| 525 | |
| 526 m_layerTreeHost->willBeginFrame(); | |
| 527 | |
| 528 m_layerTreeHost->updateAnimations(request->monotonicFrameBeginTime); | |
| 529 m_layerTreeHost->layout(); | |
| 530 | |
| 531 // Clear the commit flag after updating animations and layout here --- objec
ts that only | |
| 532 // layout when painted will trigger another setNeedsCommit inside | |
| 533 // updateLayers. | |
| 534 m_commitRequested = false; | |
| 535 m_commitRequestSentToImplThread = false; | |
| 536 m_forcedCommitRequested = false; | |
| 537 | |
| 538 if (!m_layerTreeHost->initializeRendererIfNeeded()) { | |
| 539 TRACE_EVENT0("cc", "EarlyOut_InitializeFailed"); | |
| 540 return; | |
| 541 } | |
| 542 | |
| 543 m_layerTreeHost->unlinkEvictedContentTexturesBackings(request->evictedConten
tsTexturesBackings); | |
| 544 | |
| 545 OwnPtr<CCTextureUpdateQueue> queue = adoptPtr(new CCTextureUpdateQueue); | |
| 546 m_layerTreeHost->updateLayers(*(queue.get()), request->memoryAllocationLimit
Bytes); | |
| 547 | |
| 548 // Once single buffered layers are committed, they cannot be modified until | |
| 549 // they are drawn by the impl thread. | |
| 550 m_texturesAcquired = false; | |
| 551 | |
| 552 m_layerTreeHost->willCommit(); | |
| 553 // Before applying scrolls and calling animate, we set m_animateRequested to | |
| 554 // false. If it is true now, it means setNeedAnimate was called again, but | |
| 555 // during a state when m_commitRequestSentToImplThread = true. We need to | |
| 556 // force that call to happen again now so that the commit request is sent to | |
| 557 // the impl thread. | |
| 558 if (m_animateRequested) { | |
| 559 // Forces setNeedsAnimate to consider posting a commit task. | |
| 560 m_animateRequested = false; | |
| 561 setNeedsAnimate(); | |
| 562 } | |
| 563 | |
| 564 // Notify the impl thread that the beginFrame has completed. This will | |
| 565 // begin the commit process, which is blocking from the main thread's | |
| 566 // point of view, but asynchronously performed on the impl thread, | |
| 567 // coordinated by the CCScheduler. | |
| 568 { | |
| 569 TRACE_EVENT0("cc", "commit"); | |
| 570 | |
| 571 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 572 | |
| 573 base::TimeTicks startTime = base::TimeTicks::HighResNow(); | |
| 574 CCCompletionEvent completion; | |
| 575 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy:
:beginFrameCompleteOnImplThread, &completion, queue.release())); | |
| 576 completion.wait(); | |
| 577 base::TimeTicks endTime = base::TimeTicks::HighResNow(); | |
| 578 | |
| 579 m_totalCommitTime += endTime - startTime; | |
| 580 m_totalCommitCount++; | |
| 581 } | |
| 582 | |
| 583 m_layerTreeHost->commitComplete(); | |
| 584 m_layerTreeHost->didBeginFrame(); | |
| 585 } | |
| 586 | |
| 587 void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion
, PassOwnPtr<CCTextureUpdateQueue> queue) | |
| 588 { | |
| 589 TRACE_EVENT0("cc", "CCThreadProxy::beginFrameCompleteOnImplThread"); | |
| 590 ASSERT(!m_commitCompletionEventOnImplThread); | |
| 591 ASSERT(isImplThread() && isMainThreadBlocked()); | |
| 592 ASSERT(m_schedulerOnImplThread); | |
| 593 ASSERT(m_schedulerOnImplThread->commitPending()); | |
| 594 | |
| 595 if (!m_layerTreeHostImpl.get()) { | |
| 596 TRACE_EVENT0("cc", "EarlyOut_NoLayerTree"); | |
| 597 completion->signal(); | |
| 598 return; | |
| 599 } | |
| 600 | |
| 601 // Clear any uploads we were making to textures linked to evicted | |
| 602 // resources | |
| 603 if (m_layerTreeHost->evictedContentsTexturesBackingsExist()) | |
| 604 queue->clearUploadsToEvictedResources(); | |
| 605 | |
| 606 // If we unlinked evicted textures on the main thread, delete them now. | |
| 607 if (m_layerTreeHost->deleteEvictedContentTexturesBackings()) { | |
| 608 // Deleting the evicted textures' backings resulted in some textures in
the | |
| 609 // layer tree being invalidated (unliked from their backings). Kick off | |
| 610 // another commit to fill them again. | |
| 611 setNeedsCommitOnImplThread(); | |
| 612 } else { | |
| 613 // The layer tree does not reference evicted textures, so mark that we | |
| 614 // can draw this tree once this commit is complete. | |
| 615 if (m_layerTreeHostImpl->contentsTexturesPurged()) | |
| 616 m_resetContentsTexturesPurgedAfterCommitOnImplThread = true; | |
| 617 } | |
| 618 | |
| 619 m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::cr
eate(this, CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider()
, m_layerTreeHostImpl->resourceProvider()->textureUploader()); | |
| 620 m_currentTextureUpdateControllerOnImplThread->performMoreUpdates( | |
| 621 m_schedulerOnImplThread->anticipatedDrawTime()); | |
| 622 | |
| 623 m_commitCompletionEventOnImplThread = completion; | |
| 624 } | |
| 625 | |
| 626 void CCThreadProxy::beginFrameAbortedOnImplThread() | |
| 627 { | |
| 628 TRACE_EVENT0("cc", "CCThreadProxy::beginFrameAbortedOnImplThread"); | |
| 629 ASSERT(isImplThread()); | |
| 630 ASSERT(m_schedulerOnImplThread); | |
| 631 ASSERT(m_schedulerOnImplThread->commitPending()); | |
| 632 | |
| 633 m_schedulerOnImplThread->beginFrameAborted(); | |
| 634 } | |
| 635 | |
| 636 void CCThreadProxy::scheduledActionCommit() | |
| 637 { | |
| 638 TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionCommit"); | |
| 639 ASSERT(isImplThread()); | |
| 640 ASSERT(m_commitCompletionEventOnImplThread); | |
| 641 ASSERT(m_currentTextureUpdateControllerOnImplThread); | |
| 642 | |
| 643 // Complete all remaining texture updates. | |
| 644 m_currentTextureUpdateControllerOnImplThread->finalize(); | |
| 645 m_currentTextureUpdateControllerOnImplThread.clear(); | |
| 646 | |
| 647 m_layerTreeHostImpl->beginCommit(); | |
| 648 | |
| 649 m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get()); | |
| 650 m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get()); | |
| 651 | |
| 652 if (m_resetContentsTexturesPurgedAfterCommitOnImplThread) { | |
| 653 m_resetContentsTexturesPurgedAfterCommitOnImplThread = false; | |
| 654 m_layerTreeHostImpl->resetContentsTexturesPurged(); | |
| 655 } | |
| 656 | |
| 657 m_layerTreeHostImpl->commitComplete(); | |
| 658 | |
| 659 m_nextFrameIsNewlyCommittedFrameOnImplThread = true; | |
| 660 | |
| 661 m_commitCompletionEventOnImplThread->signal(); | |
| 662 m_commitCompletionEventOnImplThread = 0; | |
| 663 | |
| 664 // SetVisible kicks off the next scheduler action, so this must be last. | |
| 665 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); | |
| 666 } | |
| 667 | |
| 668 void CCThreadProxy::scheduledActionBeginContextRecreation() | |
| 669 { | |
| 670 ASSERT(isImplThread()); | |
| 671 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginCo
ntextRecreation)); | |
| 672 } | |
| 673 | |
| 674 CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapInte
rnal(bool forcedDraw) | |
| 675 { | |
| 676 TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionDrawAndSwap"); | |
| 677 CCScheduledActionDrawAndSwapResult result; | |
| 678 result.didDraw = false; | |
| 679 result.didSwap = false; | |
| 680 ASSERT(isImplThread()); | |
| 681 ASSERT(m_layerTreeHostImpl.get()); | |
| 682 if (!m_layerTreeHostImpl.get()) | |
| 683 return result; | |
| 684 | |
| 685 ASSERT(m_layerTreeHostImpl->renderer()); | |
| 686 if (!m_layerTreeHostImpl->renderer()) | |
| 687 return result; | |
| 688 | |
| 689 // FIXME: compute the frame display time more intelligently | |
| 690 double monotonicTime = monotonicallyIncreasingTime(); | |
| 691 double wallClockTime = currentTime(); | |
| 692 | |
| 693 if (m_inputHandlerOnImplThread.get()) | |
| 694 m_inputHandlerOnImplThread->animate(monotonicTime); | |
| 695 m_layerTreeHostImpl->animate(monotonicTime, wallClockTime); | |
| 696 | |
| 697 // This method is called on a forced draw, regardless of whether we are able
to produce a frame, | |
| 698 // as the calling site on main thread is blocked until its request completes
, and we signal | |
| 699 // completion here. If canDraw() is false, we will indicate success=false to
the caller, but we | |
| 700 // must still signal completion to avoid deadlock. | |
| 701 | |
| 702 // We guard prepareToDraw() with canDraw() because it always returns a valid
frame, so can only | |
| 703 // be used when such a frame is possible. Since drawLayers() depends on the
result of | |
| 704 // prepareToDraw(), it is guarded on canDraw() as well. | |
| 705 | |
| 706 CCLayerTreeHostImpl::FrameData frame; | |
| 707 bool drawFrame = m_layerTreeHostImpl->canDraw() && (m_layerTreeHostImpl->pre
pareToDraw(frame) || forcedDraw); | |
| 708 if (drawFrame) { | |
| 709 m_layerTreeHostImpl->drawLayers(frame); | |
| 710 result.didDraw = true; | |
| 711 } | |
| 712 m_layerTreeHostImpl->didDrawAllLayers(frame); | |
| 713 | |
| 714 // Check for a pending compositeAndReadback. | |
| 715 if (m_readbackRequestOnImplThread) { | |
| 716 m_readbackRequestOnImplThread->success = false; | |
| 717 if (drawFrame) { | |
| 718 m_layerTreeHostImpl->readback(m_readbackRequestOnImplThread->pixels,
m_readbackRequestOnImplThread->rect); | |
| 719 m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isCon
textLost(); | |
| 720 } | |
| 721 m_readbackRequestOnImplThread->completion.signal(); | |
| 722 m_readbackRequestOnImplThread = 0; | |
| 723 } else if (drawFrame) | |
| 724 result.didSwap = m_layerTreeHostImpl->swapBuffers(); | |
| 725 | |
| 726 // Tell the main thread that the the newly-commited frame was drawn. | |
| 727 if (m_nextFrameIsNewlyCommittedFrameOnImplThread) { | |
| 728 m_nextFrameIsNewlyCommittedFrameOnImplThread = false; | |
| 729 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::did
CommitAndDrawFrame)); | |
| 730 } | |
| 731 | |
| 732 return result; | |
| 733 } | |
| 734 | |
| 735 void CCThreadProxy::acquireLayerTextures() | |
| 736 { | |
| 737 // Called when the main thread needs to modify a layer texture that is used | |
| 738 // directly by the compositor. | |
| 739 // This method will block until the next compositor draw if there is a | |
| 740 // previously committed frame that is still undrawn. This is necessary to | |
| 741 // ensure that the main thread does not monopolize access to the textures. | |
| 742 ASSERT(isMainThread()); | |
| 743 | |
| 744 if (m_texturesAcquired) | |
| 745 return; | |
| 746 | |
| 747 TRACE_EVENT0("cc", "CCThreadProxy::acquireLayerTextures"); | |
| 748 DebugScopedSetMainThreadBlocked mainThreadBlocked; | |
| 749 CCCompletionEvent completion; | |
| 750 CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::acq
uireLayerTexturesForMainThreadOnImplThread, &completion)); | |
| 751 completion.wait(); // Block until it is safe to write to layer textures from
the main thread. | |
| 752 | |
| 753 m_texturesAcquired = true; | |
| 754 } | |
| 755 | |
| 756 void CCThreadProxy::acquireLayerTexturesForMainThreadOnImplThread(CCCompletionEv
ent* completion) | |
| 757 { | |
| 758 ASSERT(isImplThread()); | |
| 759 ASSERT(!m_textureAcquisitionCompletionEventOnImplThread); | |
| 760 | |
| 761 m_textureAcquisitionCompletionEventOnImplThread = completion; | |
| 762 m_schedulerOnImplThread->setMainThreadNeedsLayerTextures(); | |
| 763 } | |
| 764 | |
| 765 void CCThreadProxy::scheduledActionAcquireLayerTexturesForMainThread() | |
| 766 { | |
| 767 ASSERT(m_textureAcquisitionCompletionEventOnImplThread); | |
| 768 m_textureAcquisitionCompletionEventOnImplThread->signal(); | |
| 769 m_textureAcquisitionCompletionEventOnImplThread = 0; | |
| 770 } | |
| 771 | |
| 772 CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapIfPo
ssible() | |
| 773 { | |
| 774 return scheduledActionDrawAndSwapInternal(false); | |
| 775 } | |
| 776 | |
| 777 CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapForc
ed() | |
| 778 { | |
| 779 return scheduledActionDrawAndSwapInternal(true); | |
| 780 } | |
| 781 | |
| 782 void CCThreadProxy::didAnticipatedDrawTimeChange(base::TimeTicks time) | |
| 783 { | |
| 784 if (!m_currentTextureUpdateControllerOnImplThread) | |
| 785 return; | |
| 786 | |
| 787 m_currentTextureUpdateControllerOnImplThread->performMoreUpdates(time); | |
| 788 } | |
| 789 | |
| 790 void CCThreadProxy::readyToFinalizeTextureUpdates() | |
| 791 { | |
| 792 ASSERT(isImplThread()); | |
| 793 m_schedulerOnImplThread->beginFrameComplete(); | |
| 794 } | |
| 795 | |
| 796 void CCThreadProxy::didCommitAndDrawFrame() | |
| 797 { | |
| 798 ASSERT(isMainThread()); | |
| 799 if (!m_layerTreeHost) | |
| 800 return; | |
| 801 m_layerTreeHost->didCommitAndDrawFrame(); | |
| 802 } | |
| 803 | |
| 804 void CCThreadProxy::didCompleteSwapBuffers() | |
| 805 { | |
| 806 ASSERT(isMainThread()); | |
| 807 if (!m_layerTreeHost) | |
| 808 return; | |
| 809 m_layerTreeHost->didCompleteSwapBuffers(); | |
| 810 } | |
| 811 | |
| 812 void CCThreadProxy::setAnimationEvents(CCAnimationEventsVector* passed_events, d
ouble wallClockTime) | |
| 813 { | |
| 814 scoped_ptr<CCAnimationEventsVector> events(make_scoped_ptr(passed_events)); | |
| 815 | |
| 816 TRACE_EVENT0("cc", "CCThreadProxy::setAnimationEvents"); | |
| 817 ASSERT(isMainThread()); | |
| 818 if (!m_layerTreeHost) | |
| 819 return; | |
| 820 m_layerTreeHost->setAnimationEvents(events.Pass(), wallClockTime); | |
| 821 } | |
| 822 | |
| 823 class CCThreadProxyContextRecreationTimer : public CCTimer, CCTimerClient { | |
| 824 public: | |
| 825 static PassOwnPtr<CCThreadProxyContextRecreationTimer> create(CCThreadProxy*
proxy) { return adoptPtr(new CCThreadProxyContextRecreationTimer(proxy)); } | |
| 826 | |
| 827 virtual void onTimerFired() OVERRIDE | |
| 828 { | |
| 829 m_proxy->tryToRecreateContext(); | |
| 830 } | |
| 831 | |
| 832 private: | |
| 833 explicit CCThreadProxyContextRecreationTimer(CCThreadProxy* proxy) | |
| 834 : CCTimer(CCProxy::mainThread(), this) | |
| 835 , m_proxy(proxy) | |
| 836 { | |
| 837 } | |
| 838 | |
| 839 CCThreadProxy* m_proxy; | |
| 840 }; | |
| 841 | |
| 842 void CCThreadProxy::beginContextRecreation() | |
| 843 { | |
| 844 TRACE_EVENT0("cc", "CCThreadProxy::beginContextRecreation"); | |
| 845 ASSERT(isMainThread()); | |
| 846 ASSERT(!m_contextRecreationTimer); | |
| 847 m_contextRecreationTimer = CCThreadProxyContextRecreationTimer::create(this)
; | |
| 848 m_layerTreeHost->didLoseContext(); | |
| 849 m_contextRecreationTimer->startOneShot(contextRecreationTickRate); | |
| 850 } | |
| 851 | |
| 852 void CCThreadProxy::tryToRecreateContext() | |
| 853 { | |
| 854 ASSERT(isMainThread()); | |
| 855 ASSERT(m_layerTreeHost); | |
| 856 CCLayerTreeHost::RecreateResult result = m_layerTreeHost->recreateContext(); | |
| 857 if (result == CCLayerTreeHost::RecreateFailedButTryAgain) | |
| 858 m_contextRecreationTimer->startOneShot(contextRecreationTickRate); | |
| 859 else if (result == CCLayerTreeHost::RecreateSucceeded) | |
| 860 m_contextRecreationTimer.clear(); | |
| 861 } | |
| 862 | |
| 863 void CCThreadProxy::initializeImplOnImplThread(CCCompletionEvent* completion, CC
InputHandler* handler) | |
| 864 { | |
| 865 TRACE_EVENT0("cc", "CCThreadProxy::initializeImplOnImplThread"); | |
| 866 ASSERT(isImplThread()); | |
| 867 m_layerTreeHostImpl = m_layerTreeHost->createLayerTreeHostImpl(this); | |
| 868 const base::TimeDelta displayRefreshInterval = base::TimeDelta::FromMicrosec
onds(base::Time::kMicrosecondsPerSecond / 60); | |
| 869 scoped_ptr<CCFrameRateController> frameRateController; | |
| 870 if (m_renderVSyncEnabled) | |
| 871 frameRateController.reset(new CCFrameRateController(CCDelayBasedTimeSour
ce::create(displayRefreshInterval, CCProxy::implThread()))); | |
| 872 else | |
| 873 frameRateController.reset(new CCFrameRateController(CCProxy::implThread(
))); | |
| 874 m_schedulerOnImplThread = CCScheduler::create(this, frameRateController.Pass
()); | |
| 875 m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible()); | |
| 876 | |
| 877 m_inputHandlerOnImplThread = scoped_ptr<CCInputHandler>(handler); | |
| 878 if (m_inputHandlerOnImplThread.get()) | |
| 879 m_inputHandlerOnImplThread->bindToClient(m_layerTreeHostImpl.get()); | |
| 880 | |
| 881 completion->signal(); | |
| 882 } | |
| 883 | |
| 884 void CCThreadProxy::initializeContextOnImplThread(CCGraphicsContext* context) | |
| 885 { | |
| 886 TRACE_EVENT0("cc", "CCThreadProxy::initializeContextOnImplThread"); | |
| 887 ASSERT(isImplThread()); | |
| 888 m_contextBeforeInitializationOnImplThread = scoped_ptr<CCGraphicsContext>(co
ntext).Pass(); | |
| 889 } | |
| 890 | |
| 891 void CCThreadProxy::initializeRendererOnImplThread(CCCompletionEvent* completion
, bool* initializeSucceeded, RendererCapabilities* capabilities) | |
| 892 { | |
| 893 TRACE_EVENT0("cc", "CCThreadProxy::initializeRendererOnImplThread"); | |
| 894 ASSERT(isImplThread()); | |
| 895 ASSERT(m_contextBeforeInitializationOnImplThread.get()); | |
| 896 *initializeSucceeded = m_layerTreeHostImpl->initializeRenderer(m_contextBefo
reInitializationOnImplThread.Pass()); | |
| 897 if (*initializeSucceeded) { | |
| 898 *capabilities = m_layerTreeHostImpl->rendererCapabilities(); | |
| 899 m_schedulerOnImplThread->setSwapBuffersCompleteSupported( | |
| 900 capabilities->usingSwapCompleteCallback); | |
| 901 } | |
| 902 | |
| 903 completion->signal(); | |
| 904 } | |
| 905 | |
| 906 void CCThreadProxy::layerTreeHostClosedOnImplThread(CCCompletionEvent* completio
n) | |
| 907 { | |
| 908 TRACE_EVENT0("cc", "CCThreadProxy::layerTreeHostClosedOnImplThread"); | |
| 909 ASSERT(isImplThread()); | |
| 910 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->res
ourceProvider()); | |
| 911 m_inputHandlerOnImplThread.reset(); | |
| 912 m_layerTreeHostImpl.reset(); | |
| 913 m_schedulerOnImplThread.clear(); | |
| 914 completion->signal(); | |
| 915 } | |
| 916 | |
| 917 void CCThreadProxy::setFullRootLayerDamageOnImplThread() | |
| 918 { | |
| 919 ASSERT(isImplThread()); | |
| 920 m_layerTreeHostImpl->setFullRootLayerDamage(); | |
| 921 } | |
| 922 | |
| 923 size_t CCThreadProxy::maxPartialTextureUpdates() const | |
| 924 { | |
| 925 return CCTextureUpdateController::maxPartialTextureUpdates(); | |
| 926 } | |
| 927 | |
| 928 void CCThreadProxy::recreateContextOnImplThread(CCCompletionEvent* completion, C
CGraphicsContext* contextPtr, bool* recreateSucceeded, RendererCapabilities* cap
abilities) | |
| 929 { | |
| 930 TRACE_EVENT0("cc", "CCThreadProxy::recreateContextOnImplThread"); | |
| 931 ASSERT(isImplThread()); | |
| 932 m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->res
ourceProvider()); | |
| 933 *recreateSucceeded = m_layerTreeHostImpl->initializeRenderer(scoped_ptr<CCGr
aphicsContext>(contextPtr).Pass()); | |
| 934 if (*recreateSucceeded) { | |
| 935 *capabilities = m_layerTreeHostImpl->rendererCapabilities(); | |
| 936 m_schedulerOnImplThread->didRecreateContext(); | |
| 937 } | |
| 938 completion->signal(); | |
| 939 } | |
| 940 | |
| 941 void CCThreadProxy::renderingStatsOnImplThread(CCCompletionEvent* completion, CC
RenderingStats* stats) | |
| 942 { | |
| 943 ASSERT(isImplThread()); | |
| 944 m_layerTreeHostImpl->renderingStats(stats); | |
| 945 completion->signal(); | |
| 946 } | |
| 947 | |
| 948 CCThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState() | |
| 949 : monotonicFrameBeginTime(0) | |
| 950 { | |
| 951 } | |
| 952 | |
| 953 CCThreadProxy::BeginFrameAndCommitState::~BeginFrameAndCommitState() | |
| 954 { | |
| 955 } | |
| 956 | |
| 957 } // namespace cc | |
| OLD | NEW |