Пример #1
0
void CCThreadProxy::setNeedsRedraw()
{
    ASSERT(isMainThread());
    TRACE_EVENT("CCThreadProxy::setNeedsRedraw", this, 0);
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setFullRootLayerDamageOnImplThread));
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsRedrawOnImplThread));
}
Пример #2
0
bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
{
    TRACE_EVENT("CCThreadPRoxy::compositeAndReadback", this, 0);
    ASSERT(isMainThread());
    ASSERT(m_layerTreeHost);

    if (!m_layerRendererInitialized) {
        TRACE_EVENT("compositeAndReadback_EarlyOut_LR_Uninitialized", this, 0);
        return false;
    }


    // Perform a synchronous commit.
    CCCompletionEvent beginFrameCompletion;
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::forceBeginFrameOnImplThread, AllowCrossThreadAccess(&beginFrameCompletion)));
    beginFrameCompletion.wait();
    beginFrame();

    // Perform a synchronous readback.
    ReadbackRequest request;
    request.rect = rect;
    request.pixels = pixels;
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::requestReadbackOnImplThread, AllowCrossThreadAccess(&request)));
    request.completion.wait();
    return request.success;
}
Пример #3
0
bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
{
    TRACE_EVENT("CCThreadPRoxy::compositeAndReadback", this, 0);
    ASSERT(isMainThread());
    ASSERT(m_layerTreeHost);

    // If a commit is pending, perform the commit first.
    if (m_commitRequested)  {
        // This bit of code is uglier than it should be because returning
        // pointers via the CCThread task model is really messy. Effectively, we
        // are making a blocking call to createBeginFrameAndCommitTaskOnImplThread,
        // and trying to get the CCMainThread::Task it returns so we can run it.
        OwnPtr<CCMainThread::Task> beginFrameAndCommitTask;
        {
            CCMainThread::Task* taskPtr = 0;
            CCCompletionEvent completion;
            s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::obtainBeginFrameAndCommitTaskFromCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&taskPtr)));
            completion.wait();
            beginFrameAndCommitTask = adoptPtr(taskPtr);
        }

        beginFrameAndCommitTask->performTask();
    }

    // Draw using the new tree and read back the results.
    bool success = false;
    CCCompletionEvent completion;
    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::drawLayersAndReadbackOnImplThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&success), AllowCrossThreadAccess(pixels), rect));
    completion.wait();
    return success;
}
Пример #4
0
void CCThreadProxy::onSwapBuffersCompleteOnImplThread()
{
    ASSERT(isImplThread());
    TRACE_EVENT("CCThreadProxy::onSwapBuffersCompleteOnImplThread", this, 0);
    m_schedulerOnImplThread->didSwapBuffersComplete();
    m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::didCompleteSwapBuffers));
}
Пример #5
0
bool CCThreadProxy::recreateContext()
{
    TRACE_EVENT0("cc", "CCThreadProxy::recreateContext");
    ASSERT(isMainThread());

    // Try to create the context.
    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
    if (!context)
        return false;
    ASSERT(context->hasOneRef());

    // Leak the context pointer so we can transfer ownership of it to the other side...
    GraphicsContext3D* contextPtr = context.release().leakRef();
    ASSERT(contextPtr->hasOneRef());

    // Make a blocking call to recreateContextOnImplThread. The results of that
    // call are pushed into the recreateSucceeded and capabilities local
    // variables.
    CCCompletionEvent completion;
    bool recreateSucceeded = false;
    LayerRendererCapabilities capabilities;
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::recreateContextOnImplThread,
                                                       AllowCrossThreadAccess(&completion),
                                                       AllowCrossThreadAccess(contextPtr),
                                                       AllowCrossThreadAccess(&recreateSucceeded),
                                                       AllowCrossThreadAccess(&capabilities)));
    completion.wait();

    if (recreateSucceeded)
        m_layerRendererCapabilitiesMainThreadCopy = capabilities;
    return recreateSucceeded;
}
Пример #6
0
bool CCThreadProxy::initializeLayerRenderer()
{
    TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0);
    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D();
    if (!context)
        return false;
    ASSERT(context->hasOneRef());

    // Leak the context pointer so we can transfer ownership of it to the other side...
    GraphicsContext3D* contextPtr = context.release().leakRef();
    ASSERT(contextPtr->hasOneRef());

    // Make a blocking call to initializeLayerRendererOnImplThread. The results of that call
    // are pushed into the initializeSucceeded and capabilities local variables.
    CCCompletionEvent completion;
    bool initializeSucceeded = false;
    LayerRendererCapabilities capabilities;
    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnImplThread,
                                          AllowCrossThreadAccess(contextPtr), AllowCrossThreadAccess(&completion),
                                          AllowCrossThreadAccess(&initializeSucceeded), AllowCrossThreadAccess(&capabilities),
                                          AllowCrossThreadAccess(&m_compositorIdentifier)));
    completion.wait();

    if (initializeSucceeded)
        m_layerRendererCapabilitiesMainThreadCopy = capabilities;
    return initializeSucceeded;
}
Пример #7
0
void CCThreadProxy::start()
{
    // Create LayerTreeHostImpl.
    CCCompletionEvent completion;
    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeImplOnCCThread, AllowCrossThreadAccess(&completion)));
    completion.wait();
}
Пример #8
0
void CCThreadProxy::setVisible(bool visible)
{
    ASSERT(isMainThread());
    CCCompletionEvent completion;
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setVisibleOnImplThread, AllowCrossThreadAccess(&completion), visible));
    completion.wait();
}
Пример #9
0
void CCThreadProxy::finishAllRendering()
{
    ASSERT(CCProxy::isMainThread());

    // Make sure all GL drawing is finished on the impl thread.
    CCCompletionEvent completion;
    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::finishAllRenderingOnImplThread, AllowCrossThreadAccess(&completion)));
    completion.wait();
}
Пример #10
0
void CCThreadProxy::setNeedsCommitAndRedraw()
{
    ASSERT(isMainThread());
    if (m_commitPending)
        return;

    TRACE_EVENT("CCThreadProxy::setNeedsCommitAndRedraw", this, 0);
    m_commitPending = true;
    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitAndRedrawOnCCThread));
}
Пример #11
0
void CCThreadProxy::setNeedsCommit()
{
    ASSERT(isMainThread());
    if (m_commitRequested)
        return;

    TRACE_EVENT("CCThreadProxy::setNeedsCommit", this, 0);
    m_commitRequested = true;
    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnImplThread));
}
Пример #12
0
void CCThreadProxy::start()
{
    ASSERT(isMainThread());
    ASSERT(s_ccThread);
    // Create LayerTreeHostImpl.
    CCCompletionEvent completion;
    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeImplOnImplThread, AllowCrossThreadAccess(&completion)));
    completion.wait();

    m_started = true;
}
Пример #13
0
void CCThreadProxy::stop()
{
    TRACE_EVENT("CCThreadProxy::stop", this, 0);
    ASSERT(isMainThread());
    // Synchronously deletes the impl.
    CCCompletionEvent completion;
    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::layerTreeHostClosedOnCCThread, AllowCrossThreadAccess(&completion)));
    completion.wait();

    ASSERT(!m_layerTreeHostImpl); // verify that the impl deleted.
    m_layerTreeHost = 0;
}
Пример #14
0
CCScheduledActionDrawAndSwapResult CCThreadProxy::scheduledActionDrawAndSwapInternal(bool forcedDraw)
{
    TRACE_EVENT("CCThreadProxy::scheduledActionDrawAndSwap", this, 0);
    CCScheduledActionDrawAndSwapResult result;
    result.didDraw = false;
    result.didSwap = false;
    ASSERT(isImplThread());
    ASSERT(m_layerTreeHostImpl);
    if (!m_layerTreeHostImpl)
        return result;

    // FIXME: compute the frame display time more intelligently
    double monotonicTime = monotonicallyIncreasingTime();
    double wallClockTime = currentTime();

    m_inputHandlerOnImplThread->animate(monotonicTime);
    m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
    CCLayerTreeHostImpl::FrameData frame;
    bool drawFrame = m_layerTreeHostImpl->prepareToDraw(frame) || forcedDraw;
    if (drawFrame) {
        m_layerTreeHostImpl->drawLayers(frame);
        result.didDraw = true;
    }

    // Check for a pending compositeAndReadback.
    if (m_readbackRequestOnImplThread) {
        ASSERT(drawFrame); // This should be a forcedDraw
        m_layerTreeHostImpl->readback(m_readbackRequestOnImplThread->pixels, m_readbackRequestOnImplThread->rect);
        m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isContextLost();
        m_readbackRequestOnImplThread->completion.signal();
        m_readbackRequestOnImplThread = 0;
    }

    if (drawFrame)
        result.didSwap = m_layerTreeHostImpl->swapBuffers();

    // Process any finish request
    if (m_finishAllRenderingCompletionEventOnImplThread) {
        ASSERT(drawFrame); // This should be a forcedDraw
        m_layerTreeHostImpl->finishAllRendering();
        m_finishAllRenderingCompletionEventOnImplThread->signal();
        m_finishAllRenderingCompletionEventOnImplThread = 0;
    }

    // Tell the main thread that the the newly-commited frame was drawn.
    if (m_nextFrameIsNewlyCommittedFrameOnImplThread) {
        m_nextFrameIsNewlyCommittedFrameOnImplThread = false;
        m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::didCommitAndDrawFrame));
    }

    ASSERT(drawFrame || (!drawFrame && !forcedDraw));
    return result;
}
Пример #15
0
void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTime, PassOwnPtr<CCScrollUpdateSet> scrollInfo)
{
    TRACE_EVENT("CCThreadProxy::beginFrameAndCommit", this, 0);
    ASSERT(isMainThread());
    if (!m_layerTreeHost)
        return;

    // Scroll deltas need to be applied even if the commit will be dropped.
    m_layerTreeHost->applyScrollDeltas(*scrollInfo.get());

    // Drop beginFrameAndCommit calls that occur out of sequence. See createBeginFrameAndCommitTaskOnImplThread for
    // an explanation of how out-of-sequence beginFrameAndCommit tasks can occur.
    if (sequenceNumber < m_lastExecutedBeginFrameAndCommitSequenceNumber) {
        TRACE_EVENT("EarlyOut_StaleBeginFrameAndCommit", this, 0);
        return;
    }
    m_lastExecutedBeginFrameAndCommitSequenceNumber = sequenceNumber;

    // FIXME: recreate the context if it was requested by the impl thread
    {
        TRACE_EVENT("CCLayerTreeHost::animateAndLayout", this, 0);
        m_layerTreeHost->animateAndLayout(frameBeginTime);
    }

    ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);

    // Clear the commit flag after animateAndLayout here --- objects that only
    // layout when painted will trigger another setNeedsCommit inside
    // updateLayers.
    m_commitRequested = false;

    m_layerTreeHost->updateLayers();

    {
        // Blocking call to CCThreadProxy::commitOnImplThread
        TRACE_EVENT("commit", this, 0);
        CCCompletionEvent completion;
        s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnImplThread, AllowCrossThreadAccess(&completion)));
        completion.wait();
    }

    m_layerTreeHost->commitComplete();

    if (m_redrawAfterCommit)
        setNeedsRedraw();
    m_redrawAfterCommit = false;

    ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);
}
Пример #16
0
void CCThreadProxy::scheduledActionBeginFrame()
{
    TRACE_EVENT0("cc", "CCThreadProxy::scheduledActionBeginFrame");
    ASSERT(!m_pendingBeginFrameRequest);
    m_pendingBeginFrameRequest = adoptPtr(new BeginFrameAndCommitState());
    m_pendingBeginFrameRequest->frameBeginTime = 0;
    m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollDeltas();

    m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrame));

    if (m_beginFrameCompletionEventOnImplThread) {
        m_beginFrameCompletionEventOnImplThread->signal();
        m_beginFrameCompletionEventOnImplThread = 0;
    }
}
Пример #17
0
bool CCThreadProxy::initializeContext()
{
    TRACE_EVENT("CCThreadProxy::initializeContext", this, 0);
    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createContext();
    if (!context)
        return false;
    ASSERT(context->hasOneRef());

    // Leak the context pointer so we can transfer ownership of it to the other side...
    GraphicsContext3D* contextPtr = context.release().leakRef();
    ASSERT(contextPtr->hasOneRef());

    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeContextOnImplThread,
                                                       AllowCrossThreadAccess(contextPtr)));
    return true;
}
Пример #18
0
void CCThreadProxy::stop()
{
    TRACE_EVENT("CCThreadProxy::stop", this, 0);
    ASSERT(isMainThread());
    ASSERT(m_started);

    // Synchronously deletes the impl.
    CCCompletionEvent completion;
    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::layerTreeHostClosedOnImplThread, AllowCrossThreadAccess(&completion)));
    completion.wait();

    m_mainThreadProxy->shutdown(); // Stop running tasks posted to us.

    ASSERT(!m_layerTreeHostImpl); // verify that the impl deleted.
    m_layerTreeHost = 0;
    m_started = false;
}
Пример #19
0
void CCThreadProxy::beginFrameAndCommit(double frameBeginTime)
{
    ASSERT(isMainThread());
    if (!m_layerTreeHost)
        return;

    TRACE_EVENT("CCThreadProxy::requestFrameAndCommit", this, 0);
    {
        TRACE_EVENT("CCLayerTreeHost::animateAndLayout", this, 0);
        m_layerTreeHost->animateAndLayout(frameBeginTime);
    }

    m_commitPending = false;

    // Blocking call to CCThreadProxy::performCommit
    CCCompletionEvent completion;
    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnCCThread, AllowCrossThreadAccess(&completion)));
    completion.wait();
}
Пример #20
0
bool CCThreadProxy::initializeLayerRenderer()
{
    TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0);
    // Make a blocking call to initializeLayerRendererOnImplThread. The results of that call
    // are pushed into the initializeSucceeded and capabilities local variables.
    CCCompletionEvent completion;
    bool initializeSucceeded = false;
    LayerRendererCapabilities capabilities;
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnImplThread,
                                                       AllowCrossThreadAccess(&completion),
                                                       AllowCrossThreadAccess(&initializeSucceeded),
                                                       AllowCrossThreadAccess(&capabilities)));
    completion.wait();

    if (initializeSucceeded) {
        m_layerRendererInitialized = true;
        m_layerRendererCapabilitiesMainThreadCopy = capabilities;
    }
    return initializeSucceeded;
}
Пример #21
0
void CCThreadProxy::scheduledActionDrawAndSwap()
{
    TRACE_EVENT("CCThreadProxy::scheduledActionDrawAndSwap", this, 0);
    ASSERT(isImplThread());
    if (!m_layerTreeHostImpl)
        return;

    // FIXME: compute the frame display time more intelligently
    double monotonicTime = monotonicallyIncreasingTime();
    double wallClockTime = currentTime();

    m_inputHandlerOnImplThread->willDraw(monotonicTime);
    m_layerTreeHostImpl->animate(monotonicTime, wallClockTime);
    m_layerTreeHostImpl->drawLayers();

    // Check for a pending compositeAndReadback.
    if (m_readbackRequestOnImplThread) {
        m_layerTreeHostImpl->readback(m_readbackRequestOnImplThread->pixels, m_readbackRequestOnImplThread->rect);
        m_readbackRequestOnImplThread->success = !m_layerTreeHostImpl->isContextLost();
        m_readbackRequestOnImplThread->completion.signal();
        m_readbackRequestOnImplThread = 0;
    }

    m_layerTreeHostImpl->swapBuffers();

    // Process any finish request
    if (m_finishAllRenderingCompletionEventOnImplThread) {
        m_layerTreeHostImpl->finishAllRendering();
        m_finishAllRenderingCompletionEventOnImplThread->signal();
        m_finishAllRenderingCompletionEventOnImplThread = 0;
    }

    // Tell the main thread that the the newly-commited frame was drawn.
    if (m_nextFrameIsNewlyCommittedFrameOnImplThread) {
        m_nextFrameIsNewlyCommittedFrameOnImplThread = false;
        m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::didCommitAndDrawFrame));
    }
}
Пример #22
0
void CCThreadProxy::setNeedsRedraw()
{
    ASSERT(isMainThread());
    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsRedrawOnCCThread));
}
Пример #23
0
void CCThreadProxy::setNeedsRedraw()
{
    ASSERT(isMainThread());
    TRACE_EVENT("CCThreadProxy::setNeedsRedraw", this, 0);
    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsRedrawOnImplThread));
}
Пример #24
0
void CCThreadProxy::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double duration)
{
    ASSERT(CCProxy::isMainThread());
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::requestStartPageScaleAnimationOnImplThread, targetPosition, useAnchor, scale, duration));
}
Пример #25
0
void CCThreadProxy::loseContext()
{
    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::didLoseContextOnImplThread));
}
Пример #26
0
void CCThreadProxy::scheduledActionBeginContextRecreation()
{
    ASSERT(isImplThread());
    m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginContextRecreation));
}
Пример #27
0
void CCThreadProxy::beginFrame()
{
    TRACE_EVENT0("cc", "CCThreadProxy::beginFrame");
    ASSERT(isMainThread());
    if (!m_layerTreeHost)
        return;

    if (!m_pendingBeginFrameRequest) {
        TRACE_EVENT0("cc", "EarlyOut_StaleBeginFrameMessage");
        return;
    }

    OwnPtr<BeginFrameAndCommitState> request(m_pendingBeginFrameRequest.release());

    // Do not notify the impl thread of commit requests that occur during
    // the apply/animate/layout part of the beginFrameAndCommit process since
    // those commit requests will get painted immediately. Once we have done
    // the paint, m_commitRequested will be set to false to allow new commit
    // requests to be scheduled.
    m_commitRequested = true;

    // On the other hand, the animationRequested flag needs to be cleared
    // here so that any animation requests generated by the apply or animate
    // callbacks will trigger another frame.
    m_animateRequested = false;

    // FIXME: technically, scroll deltas need to be applied for dropped commits as well.
    // Re-do the commit flow so that we don't send the scrollInfo on the BFAC message.
    m_layerTreeHost->applyScrollAndScale(*request->scrollInfo);

    // FIXME: recreate the context if it was requested by the impl thread.
    m_layerTreeHost->updateAnimations(request->frameBeginTime);
    m_layerTreeHost->layout();

    // Clear the commit flag after updating animations and layout here --- objects that only
    // layout when painted will trigger another setNeedsCommit inside
    // updateLayers.
    m_commitRequested = false;

    if (!m_layerTreeHost->updateLayers())
        return;

    // Before applying scrolls and calling animate, we set m_animateRequested to false.
    // If it is true now, it means setNeedAnimate was called again. Call setNeedsCommit
    // now so that we get begin frame when this one is done.
    if (m_animateRequested)
        setNeedsCommit();

    // Notify the impl thread that the beginFrame has completed. This will
    // begin the commit process, which is blocking from the main thread's
    // point of view, but asynchronously performed on the impl thread,
    // coordinated by the CCScheduler.
    {
        TRACE_EVENT("commit", this, 0);
        CCCompletionEvent completion;
        CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameCompleteOnImplThread, AllowCrossThreadAccess(&completion)));
        completion.wait();
    }

    m_layerTreeHost->commitComplete();
}
Пример #28
0
void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector> events, double wallClockTime)
{
    ASSERT(isImplThread());
    TRACE_EVENT("CCThreadProxy::postAnimationEventsToMainThreadOnImplThread", this, 0);
    m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnimationEvents, events, wallClockTime));
}