Changeset 95699 in webkit


Ignore:
Timestamp:
Sep 22, 2011, 12:22:10 AM (14 years ago)
Author:
jamesr@google.com
Message:

[chromium] Make CCThreadProxy draw
https://bugs.webkit.org/show_bug.cgi?id=67417

Source/WebCore:

Update the CCThreadProxy to correctly implement the CCProxy
interface, do all the right committing and updating steps, and
draw a picture on the screen.

Patch by Nat Duca <nduca@chromium.org> on 2011-09-22
Reviewed by James Robinson.

  • platform/graphics/IntRect.h:
  • platform/graphics/chromium/LayerRendererChromium.cpp:

(WebCore::LayerRendererChromium::~LayerRendererChromium):

  • platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp:

(WebCore::CCHeadsUpDisplay::enabled):

  • platform/graphics/chromium/cc/CCLayerImpl.cpp:

(WebCore::CCLayerImpl::CCLayerImpl):
(WebCore::CCLayerImpl::~CCLayerImpl):

  • platform/graphics/chromium/cc/CCLayerTreeHost.cpp:

(WebCore::CCLayerTreeHost::CCLayerTreeHost):
(WebCore::CCLayerTreeHost::commitTo):
(WebCore::CCLayerTreeHost::commitComplete):
(WebCore::CCLayerTreeHost::setNeedsRedraw):

  • platform/graphics/chromium/cc/CCLayerTreeHost.h:
  • platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:

(WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl):
(WebCore::CCLayerTreeHostImpl::~CCLayerTreeHostImpl):

  • platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:

(WebCore::CCSingleThreadProxy::finishAllRendering):
(WebCore::CCSingleThreadProxy::setNeedsCommit):
(WebCore::CCSingleThreadProxy::commitIfNeeded):

  • platform/graphics/chromium/cc/CCThreadProxy.cpp:

(WebCore::CCThreadProxy::CCThreadProxy):
(WebCore::CCThreadProxy::~CCThreadProxy):
(WebCore::CCThreadProxy::compositeAndReadback):
(WebCore::CCThreadProxy::drawLayersAndReadbackOnCCThread):
(WebCore::CCThreadProxy::finishAllRendering):
(WebCore::CCThreadProxy::isStarted):
(WebCore::CCThreadProxy::setNeedsCommit):
(WebCore::CCThreadProxy::setNeedsCommitAndRedraw):
(WebCore::CCThreadProxy::setNeedsRedraw):
(WebCore::CCThreadProxy::start):
(WebCore::CCThreadProxy::stop):
(WebCore::CCThreadProxy::finishAllRenderingOnCCThread):
(WebCore::CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread):
(WebCore::CCThreadProxy::beginFrameAndCommit):
(WebCore::CCThreadProxy::commitOnCCThread):
(WebCore::CCThreadProxy::scheduleDrawTaskOnCCThread):
(WebCore::CCThreadProxy::drawLayersAndPresentOnCCThread):
(WebCore::CCThreadProxy::drawLayersOnCCThread):
(WebCore::CCThreadProxy::updateSchedulerStateOnCCThread):

  • platform/graphics/chromium/cc/CCThreadProxy.h:

Source/WebKit/chromium:

Disable CCLayerTreeHostTest temporarily. Will re-enable
with https://bugs.webkit.org/show_bug.cgi?id=67418

Patch by Nat Duca <nduca@chromium.org> on 2011-09-22
Reviewed by James Robinson.

  • tests/CCLayerTreeHostTest.cpp:
Location:
trunk/Source
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r95697 r95699  
     12011-09-22  Nat Duca  <nduca@chromium.org>
     2
     3        [chromium] Make CCThreadProxy draw
     4        https://bugs.webkit.org/show_bug.cgi?id=67417
     5
     6        Update the CCThreadProxy to correctly implement the CCProxy
     7        interface, do all the right committing and updating steps, and
     8        draw a picture on the screen.
     9
     10        Reviewed by James Robinson.
     11
     12        * platform/graphics/IntRect.h:
     13        * platform/graphics/chromium/LayerRendererChromium.cpp:
     14        (WebCore::LayerRendererChromium::~LayerRendererChromium):
     15        * platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp:
     16        (WebCore::CCHeadsUpDisplay::enabled):
     17        * platform/graphics/chromium/cc/CCLayerImpl.cpp:
     18        (WebCore::CCLayerImpl::CCLayerImpl):
     19        (WebCore::CCLayerImpl::~CCLayerImpl):
     20        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
     21        (WebCore::CCLayerTreeHost::CCLayerTreeHost):
     22        (WebCore::CCLayerTreeHost::commitTo):
     23        (WebCore::CCLayerTreeHost::commitComplete):
     24        (WebCore::CCLayerTreeHost::setNeedsRedraw):
     25        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
     26        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
     27        (WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl):
     28        (WebCore::CCLayerTreeHostImpl::~CCLayerTreeHostImpl):
     29        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
     30        (WebCore::CCSingleThreadProxy::finishAllRendering):
     31        (WebCore::CCSingleThreadProxy::setNeedsCommit):
     32        (WebCore::CCSingleThreadProxy::commitIfNeeded):
     33        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
     34        (WebCore::CCThreadProxy::CCThreadProxy):
     35        (WebCore::CCThreadProxy::~CCThreadProxy):
     36        (WebCore::CCThreadProxy::compositeAndReadback):
     37        (WebCore::CCThreadProxy::drawLayersAndReadbackOnCCThread):
     38        (WebCore::CCThreadProxy::finishAllRendering):
     39        (WebCore::CCThreadProxy::isStarted):
     40        (WebCore::CCThreadProxy::setNeedsCommit):
     41        (WebCore::CCThreadProxy::setNeedsCommitAndRedraw):
     42        (WebCore::CCThreadProxy::setNeedsRedraw):
     43        (WebCore::CCThreadProxy::start):
     44        (WebCore::CCThreadProxy::stop):
     45        (WebCore::CCThreadProxy::finishAllRenderingOnCCThread):
     46        (WebCore::CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread):
     47        (WebCore::CCThreadProxy::beginFrameAndCommit):
     48        (WebCore::CCThreadProxy::commitOnCCThread):
     49        (WebCore::CCThreadProxy::scheduleDrawTaskOnCCThread):
     50        (WebCore::CCThreadProxy::drawLayersAndPresentOnCCThread):
     51        (WebCore::CCThreadProxy::drawLayersOnCCThread):
     52        (WebCore::CCThreadProxy::updateSchedulerStateOnCCThread):
     53        * platform/graphics/chromium/cc/CCThreadProxy.h:
     54
    1552011-09-21  Beth Dakin  <bdakin@apple.com>
    256
  • trunk/Source/WebCore/platform/CrossThreadCopier.h

    r94986 r95699  
    4242namespace WebCore {
    4343
     44    class IntRect;
    4445    class KURL;
    4546    class ResourceError;
     
    6465    };
    6566
     67    // To allow a type to be passed across threads using its copy constructor, add a forward declaration of the type and
     68    // a CopyThreadCopierBase<false, false, TypeName> : public CrossThreadCopierPassThrough<TypeName> { }; to this file.
    6669    template<> struct CrossThreadCopierBase<false, false, ThreadableLoaderOptions> : public CrossThreadCopierPassThrough<ThreadableLoaderOptions> {
     70    };
     71
     72    template<> struct CrossThreadCopierBase<false, false, IntRect> : public CrossThreadCopierPassThrough<IntRect> {
    6773    };
    6874
  • trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp

    r95341 r95699  
    183183LayerRendererChromium::~LayerRendererChromium()
    184184{
     185    ASSERT(CCProxy::isMainThread());
    185186    m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
    186187    cleanupSharedObjects();
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp

    r95341 r95699  
    9090bool CCHeadsUpDisplay::enabled() const
    9191{
     92    // FIXME: HUD does not work in compositor thread mode.
     93    if (settings().enableCompositorThread)
     94        return false;
    9295    return settings().showPlatformLayerTree || settings().showFPSCounter;
    9396}
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp

    r95348 r95699  
    5656    , m_debugBorderWidth(0)
    5757{
     58    ASSERT(CCProxy::isImplThread());
    5859}
    5960
    6061CCLayerImpl::~CCLayerImpl()
    6162{
     63    ASSERT(CCProxy::isImplThread());
    6264}
    6365
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp

    r95256 r95699  
    5757    , m_visible(true)
    5858{
     59    ASSERT(CCProxy::isMainThread());
    5960}
    6061
     
    107108}
    108109
     110// This function commits the CCLayerTreeHost to an impl tree. When modifying
     111// this function, keep in mind that the function *runs* on the impl thread! Any
     112// code that is logically a main thread operation, e.g. deletion of a LayerChromium,
     113// should be delayed until the CCLayerTreeHost::commitComplete, which will run
     114// after the commit, but on the main thread.
    109115void CCLayerTreeHost::commitTo(CCLayerTreeHostImpl* hostImpl)
    110116{
     
    121127
    122128    updateCompositorResources(m_updateList, hostImpl->context());
    123     clearPendingUpdate();
    124129
    125130    hostImpl->setVisible(m_visible);
     
    128133
    129134    hostImpl->layerRenderer()->setContentsTextureMemoryUseBytes(m_contentsTextureManager->currentMemoryUseBytes());
    130     m_contentsTextureManager->unprotectAllTextures();
    131135
    132136    // Synchronize trees, if one exists at all...
     
    137141
    138142    m_frameNumber++;
     143}
     144
     145void CCLayerTreeHost::commitComplete()
     146{
     147    clearPendingUpdate();
     148    m_contentsTextureManager->unprotectAllTextures();
    139149}
    140150
     
    215225{
    216226#if USE(THREADED_COMPOSITING)
    217     TRACE_EVENT("CCLayerTreeHost::setNeedsRedraw", this, 0);
    218227    m_proxy->setNeedsRedraw();
    219228#else
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h

    r95320 r95699  
    6868            , showFPSCounter(false)
    6969            , showPlatformLayerTree(false) { }
     70    CCSettings(bool acceleratePainting, bool compositeOffscreen, bool enableCompositorThread, bool showFPSCounter, bool showPlatformLayerTree)
     71            : acceleratePainting(acceleratePainting)
     72            , compositeOffscreen(compositeOffscreen)
     73            , enableCompositorThread(enableCompositorThread)
     74            , showFPSCounter(showFPSCounter)
     75            , showPlatformLayerTree(showPlatformLayerTree) { }
    7076
    7177    bool acceleratePainting;
     
    97103    // CCLayerTreeHost interface to CCProxy.
    98104    void animateAndLayout(double frameBeginTime);
     105    void commitComplete();
    99106    void commitTo(CCLayerTreeHostImpl*);
    100107    PassOwnPtr<CCThread> createCompositorThread();
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp

    r95135 r95699  
    4949    , m_settings(settings)
    5050{
     51    ASSERT(CCProxy::isImplThread());
    5152}
    5253
    5354CCLayerTreeHostImpl::~CCLayerTreeHostImpl()
    5455{
     56    ASSERT(CCProxy::isImplThread());
    5557    TRACE_EVENT("CCLayerTreeHostImpl::~CCLayerTreeHostImpl()", this, 0);
    5658    if (m_layerRenderer)
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h

    r95100 r95699  
    7676#endif
    7777
     78    // Temporary hack while render_widget still does scheduling for CCLayerTreeHostMainThreadI
     79    virtual GraphicsContext3D* context() = 0;
     80
    7881    // Testing hooks
    7982    virtual void loseCompositorContext(int numTimes) = 0;
    8083
    81     // Temporary hack while render_widget still does scheduling for CCLayerTreeHostMainThreadI
    82     virtual GraphicsContext3D* context() = 0;
     84#ifndef NDEBUG
     85    static void setImplThread(bool);
     86    static void setImplThread(WTF::ThreadIdentifier);
     87#endif
    8388
    8489protected:
    8590    CCProxy() { }
    8691    friend class ScopedSetImplThread;
    87 #ifndef NDEBUG
    88     static void setImplThread(bool);
    89     static void setImplThread(WTF::ThreadIdentifier);
    90 #endif
    9192};
    9293
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp

    r95100 r95699  
    112112{
    113113    ASSERT(isMainThread());
    114     ScopedSetImplThread impl;
    115     m_layerTreeHostImpl->finishAllRendering();
     114    if (!recreateContextIfNeeded())
     115        return;
     116
     117    commitIfNeeded();
     118
     119    {
     120        ScopedSetImplThread impl;
     121        m_layerTreeHostImpl->finishAllRendering();
     122    }
    116123}
    117124
     
    158165        m_layerTreeHostImpl->commitComplete();
    159166    }
     167    m_layerTreeHost->commitComplete();
    160168}
    161169
     
    251259        m_layerTreeHostImpl->commitComplete();
    252260    }
     261    m_layerTreeHost->commitComplete();
    253262}
    254263
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp

    r95320 r95699  
    3232#include "cc/CCMainThreadTask.h"
    3333#include "cc/CCThreadTask.h"
     34#include <wtf/CurrentTime.h>
    3435#include <wtf/MainThread.h>
    3536
     
    4950
    5051CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost)
    51     : m_commitPending(false)
     52    : m_commitRequested(false)
    5253    , m_layerTreeHost(layerTreeHost)
     54    , m_started(false)
     55    , m_lastExecutedBeginFrameAndCommitSequenceNumber(-1)
     56    , m_numBeginFrameAndCommitsIssuedOnCCThread(0)
     57    , m_beginFrameAndCommitPendingOnCCThread(false)
     58    , m_drawTaskPostedOnCCThread(false)
     59    , m_redrawRequestedOnCCThread(false)
    5360{
    5461    TRACE_EVENT("CCThreadProxy::CCThreadProxy", this, 0);
     
    6774    TRACE_EVENT("CCThreadProxy::~CCThreadProxy", this, 0);
    6875    ASSERT(isMainThread());
    69     ASSERT(!m_layerTreeHostImpl); // Make sure stop() got called.
    70     ASSERT(!m_layerTreeHost); // Make sure stop() got called.
     76    ASSERT(!m_started);
    7177
    7278    numProxies--;
     
    7985bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
    8086{
    81     ASSERT_NOT_REACHED();
    82     return false;
     87    ASSERT(isMainThread());
     88    ASSERT(m_layerTreeHost);
     89
     90    finishAllRendering();
     91    bool success = false;
     92    CCCompletionEvent completion;
     93    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::drawLayersAndReadbackOnCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&success), AllowCrossThreadAccess(pixels), rect));
     94    completion.wait();
     95    return success;
     96}
     97
     98void CCThreadProxy::drawLayersAndReadbackOnCCThread(CCCompletionEvent* completion, bool* success, void* pixels, const IntRect& rect)
     99{
     100    ASSERT(CCProxy::isImplThread());
     101    if (!m_layerTreeHostImpl) {
     102        *success = false;
     103        completion->signal();
     104        return;
     105    }
     106    drawLayersOnCCThread();
     107    m_layerTreeHostImpl->readback(pixels, rect);
     108    *success = m_layerTreeHostImpl->isContextLost();
     109    completion->signal();
    83110}
    84111
     
    90117void CCThreadProxy::finishAllRendering()
    91118{
    92     ASSERT_NOT_REACHED();
     119    ASSERT(CCProxy::isMainThread());
     120    // If a commit is pending, perform the commit first.
     121    if (m_commitRequested)  {
     122        // This bit of code is uglier than it should be because returning
     123        // pointers via the CCThread task model is really messy. Effectively, we
     124        // are making a blocking call to createBeginFrameAndCommitTaskOnCCThread,
     125        // and trying to get the CCMainThread::Task it returns so we can run it.
     126        OwnPtr<CCMainThread::Task> beginFrameAndCommitTask;
     127        {
     128            CCMainThread::Task* taskPtr = 0;
     129            CCCompletionEvent completion;
     130            ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&taskPtr)));
     131            completion.wait();
     132            beginFrameAndCommitTask = adoptPtr(taskPtr);
     133        }
     134
     135        beginFrameAndCommitTask->performTask();
     136    }
     137    // Make sure all GL drawing is finished on the impl thread.
     138    CCCompletionEvent completion;
     139    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::finishAllRenderingOnCCThread, AllowCrossThreadAccess(&completion)));
     140    completion.wait();
    93141}
    94142
    95143bool CCThreadProxy::isStarted() const
    96144{
    97     return m_layerTreeHostImpl;
     145    ASSERT(CCProxy::isMainThread());
     146    return m_started;
    98147}
    99148
     
    112161    // are pushed into the initializeSucceeded and capabilities local variables.
    113162    CCCompletionEvent completion;
    114     bool initializeSucceeded;
     163    bool initializeSucceeded = false;
    115164    LayerRendererCapabilities capabilities;
    116165    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnCCThread,
     
    136185{
    137186    ASSERT(isMainThread());
    138     if (m_commitPending)
     187    if (m_commitRequested)
    139188        return;
    140189
    141190    TRACE_EVENT("CCThreadProxy::setNeedsCommit", this, 0);
    142     m_commitPending = true;
    143     ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnCCThread));
     191    m_commitRequested = true;
     192    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, m_commitRequested, true));
    144193}
    145194
     
    147196{
    148197    ASSERT(isMainThread());
    149     if (m_commitPending)
    150         return;
     198    if (m_commitRequested)
     199        return;
     200    m_commitRequested = true;
    151201
    152202    TRACE_EVENT("CCThreadProxy::setNeedsCommitAndRedraw", this, 0);
    153     m_commitPending = true;
    154     ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitAndRedrawOnCCThread));
     203    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, m_commitRequested, true));
    155204}
    156205
     
    158207{
    159208    ASSERT(isMainThread());
    160     ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsRedrawOnCCThread));
     209    if (m_commitRequested) // Implies that a commit is in flight.
     210        return;
     211    // Unlike setNeedsCommit that tracks whether a commit message has been sent,
     212    // setNeedsRedraw always sends a message to the compositor thread. This is
     213    // because the compositor thread can draw without telling the main
     214    // thread. This should not be much of a problem because calls to
     215    // setNeedsRedraw messages are uncommon (only triggered by WM_PAINT/etc),
     216    // compared to setNeedsCommitAndRedraw messages.
     217    TRACE_EVENT("CCThreadProxy::setNeedsRedraw", this, 0);
     218    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, false, true));
    161219}
    162220
    163221void CCThreadProxy::start()
    164222{
     223    ASSERT(isMainThread());
    165224    // Create LayerTreeHostImpl.
    166225    CCCompletionEvent completion;
    167226    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeImplOnCCThread, AllowCrossThreadAccess(&completion)));
    168227    completion.wait();
     228
     229    m_started = true;
    169230}
    170231
     
    173234    TRACE_EVENT("CCThreadProxy::stop", this, 0);
    174235    ASSERT(isMainThread());
     236    ASSERT(m_started);
     237
    175238    // Synchronously deletes the impl.
    176239    CCCompletionEvent completion;
     
    180243    ASSERT(!m_layerTreeHostImpl); // verify that the impl deleted.
    181244    m_layerTreeHost = 0;
    182 }
    183 
    184 void CCThreadProxy::beginFrameAndCommitOnCCThread()
    185 {
    186     TRACE_EVENT("CCThreadProxy::beginFrameAndCommitOnCCThread", this, 0);
    187     ASSERT(isImplThread());
    188     // TEMP HACK so we can exercise this code in unit tests.
    189     CCMainThread::postTask(createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, 0.0));
    190 }
    191 
    192 void CCThreadProxy::beginFrameAndCommit(double frameBeginTime)
    193 {
     245    m_started = false;
     246}
     247
     248void CCThreadProxy::finishAllRenderingOnCCThread(CCCompletionEvent* completion)
     249{
     250    TRACE_EVENT("CCThreadProxy::finishAllRenderingOnCCThread", this, 0);
     251    ASSERT(isImplThread());
     252    ASSERT(!m_beginFrameAndCommitPendingOnCCThread);
     253    if (m_redrawRequestedOnCCThread) {
     254        drawLayersOnCCThread();
     255        m_layerTreeHostImpl->present();
     256        m_redrawRequestedOnCCThread = false;
     257    }
     258    m_layerTreeHostImpl->finishAllRendering();
     259    completion->signal();
     260}
     261
     262void CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread(CCCompletionEvent* completion, CCMainThread::Task** taskPtr)
     263{
     264    OwnPtr<CCMainThread::Task> task = createBeginFrameAndCommitTaskOnCCThread();
     265    *taskPtr = task.leakPtr();
     266    completion->signal();
     267}
     268
     269PassOwnPtr<CCMainThread::Task> CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread()
     270{
     271    TRACE_EVENT("CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread", this, 0);
     272    ASSERT(isImplThread());
     273    double frameBeginTime = currentTime();
     274    m_beginFrameAndCommitPendingOnCCThread = true;
     275
     276    // NOTE, it is possible to receieve a request for a
     277    // beginFrameAndCommitOnCCThread from finishAllRendering while a
     278    // beginFrameAndCommitOnCCThread is enqueued. Since it CCMainThread doesn't
     279    // provide a threadsafe way to cancel tasks, it is important that
     280    // beginFrameAndCommit be structured to understand that it may get called at
     281    // a point that it shouldn't. We do this by assigning a sequence number to
     282    // every new beginFrameAndCommit task. Then, beginFrameAndCommit tracks the
     283    // last executed sequence number, dropping beginFrameAndCommit with sequence
     284    // numbers below the last executed one.
     285    int thisTaskSequenceNumber = m_numBeginFrameAndCommitsIssuedOnCCThread;
     286    m_numBeginFrameAndCommitsIssuedOnCCThread++;
     287    return createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, thisTaskSequenceNumber, frameBeginTime);
     288}
     289
     290void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTime)
     291{
     292    TRACE_EVENT("CCThreadProxy::beginFrameAndCommit", this, 0);
    194293    ASSERT(isMainThread());
    195294    if (!m_layerTreeHost)
    196295        return;
    197296
    198     TRACE_EVENT("CCThreadProxy::requestFrameAndCommit", this, 0);
     297    // Drop beginFrameAndCommit calls that occur out of sequence. See createBeginFrameAndCommitTaskOnCCThread for
     298    // an explanation of how out-of-sequence beginFrameAndCommit tasks can occur.
     299    if (sequenceNumber < m_lastExecutedBeginFrameAndCommitSequenceNumber) {
     300        TRACE_EVENT("EarlyOut_StaleBeginFrameAndCommit", this, 0);
     301        return;
     302    }
     303    m_lastExecutedBeginFrameAndCommitSequenceNumber = sequenceNumber;
     304
     305    ASSERT(m_commitRequested);
     306
     307    // FIXME: recreate the context if it was requested by the impl thread
    199308    {
    200309        TRACE_EVENT("CCLayerTreeHost::animateAndLayout", this, 0);
     
    202311    }
    203312
    204     m_commitPending = false;
    205 
    206     // Blocking call to CCThreadProxy::performCommit
    207     CCCompletionEvent completion;
    208     ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnCCThread, AllowCrossThreadAccess(&completion)));
    209     completion.wait();
     313    ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);
     314
     315    // Clear the commit flag after animateAndLayout here --- objects that only
     316    // layout when painted will trigger another setNeedsCommit inside
     317    // updateLayers.
     318    m_commitRequested = false;
     319
     320    m_layerTreeHost->updateLayers();
     321
     322    {
     323        // Blocking call to CCThreadProxy::commitOnCCThread
     324        TRACE_EVENT("commit", this, 0);
     325        CCCompletionEvent completion;
     326        ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnCCThread, AllowCrossThreadAccess(&completion)));
     327        completion.wait();
     328    }
     329
     330    m_layerTreeHost->commitComplete();
     331
     332    ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);
    210333}
    211334
    212335void CCThreadProxy::commitOnCCThread(CCCompletionEvent* completion)
    213336{
    214     ASSERT(isImplThread());
    215     TRACE_EVENT("CCThreadProxy::commitOnCCThread", this, 0);
     337    TRACE_EVENT("CCThreadProxy::beginFrameAndCommitOnCCThread", this, 0);
     338    ASSERT(isImplThread());
     339    ASSERT(m_beginFrameAndCommitPendingOnCCThread);
     340    m_beginFrameAndCommitPendingOnCCThread = false;
     341    if (!m_layerTreeHostImpl) {
     342        completion->signal();
     343        return;
     344    }
    216345    m_layerTreeHostImpl->beginCommit();
    217     {
    218         TRACE_EVENT("CCLayerTreeHost::commit", this, 0);
    219         m_layerTreeHost->commitTo(m_layerTreeHostImpl.get());
    220     }
    221     completion->signal();
    222 
     346    m_layerTreeHost->commitTo(m_layerTreeHostImpl.get());
    223347    m_layerTreeHostImpl->commitComplete();
    224     setNeedsRedrawOnCCThread();
     348
     349    completion->signal();
     350
     351    if (m_redrawRequestedOnCCThread)
     352        scheduleDrawTaskOnCCThread();
     353}
     354
     355void CCThreadProxy::scheduleDrawTaskOnCCThread()
     356{
     357    ASSERT(isImplThread());
     358    if (m_drawTaskPostedOnCCThread)
     359        return;
     360    TRACE_EVENT("CCThreadProxy::scheduleDrawTaskOnCCThread", this, 0);
     361    ASSERT(m_layerTreeHostImpl);
     362    m_drawTaskPostedOnCCThread = true;
     363    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::drawLayersAndPresentOnCCThread));
     364}
     365
     366void CCThreadProxy::drawLayersAndPresentOnCCThread()
     367{
     368    TRACE_EVENT("CCThreadProxy::drawLayersOnCCThread", this, 0);
     369    ASSERT(isImplThread());
     370    if (!m_layerTreeHostImpl)
     371        return;
     372
     373    drawLayersOnCCThread();
     374    m_layerTreeHostImpl->present();
     375    m_redrawRequestedOnCCThread = false;
     376    m_drawTaskPostedOnCCThread = false;
    225377}
    226378
     
    229381    TRACE_EVENT("CCThreadProxy::drawLayersOnCCThread", this, 0);
    230382    ASSERT(isImplThread());
    231     if (m_layerTreeHostImpl)
    232         m_layerTreeHostImpl->drawLayers();
    233 }
    234 
    235 void CCThreadProxy::setNeedsCommitOnCCThread()
    236 {
    237     TRACE_EVENT("CCThreadProxy::setNeedsCommitOnCCThread", this, 0);
    238     ASSERT(isImplThread());
    239383    ASSERT(m_layerTreeHostImpl);
    240     // FIXME: Not yet implemented, see https://bugs.webkit.org/show_bug.cgi?id=67417
    241     ASSERT_NOT_REACHED();
    242 }
    243 
    244 void CCThreadProxy::setNeedsCommitAndRedrawOnCCThread()
    245 {
    246     TRACE_EVENT("CCThreadProxy::setNeedsCommitAndRedrawOnCCThread", this, 0);
     384
     385    m_layerTreeHostImpl->drawLayers();
     386    ASSERT(!m_layerTreeHostImpl->isContextLost());
     387}
     388
     389void CCThreadProxy::updateSchedulerStateOnCCThread(bool commitRequested, bool redrawRequested)
     390{
     391    TRACE_EVENT("CCThreadProxy::updateSchedulerStateOnCCThread", this, 0);
    247392    ASSERT(isImplThread());
    248393    ASSERT(m_layerTreeHostImpl);
    249     // TEMP HACK so we can exercise this code in unit tests.
    250     CCMainThread::postTask(createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, 0.0));
    251 }
    252 
    253 void CCThreadProxy::setNeedsRedrawOnCCThread()
    254 {
    255     TRACE_EVENT("CCThreadProxy::setNeedsRedrawOnCCThread", this, 0);
    256     // TEMP HACK so we can exercise this code in unit tests.
    257     drawLayersOnCCThread();
     394
     395    // FIXME: use CCScheduler to decide when to manage the conversion of this
     396    // commit request into an actual createBeginFrameAndCommitTaskOnCCThread call.
     397    m_redrawRequestedOnCCThread |= redrawRequested;
     398    if (!m_beginFrameAndCommitPendingOnCCThread)
     399        CCMainThread::postTask(createBeginFrameAndCommitTaskOnCCThread());
     400
     401    // If no commit is pending, but a redraw is requested, then post a redraw right away
     402    if (!m_beginFrameAndCommitPendingOnCCThread && m_redrawRequestedOnCCThread)
     403        scheduleDrawTaskOnCCThread();
     404
    258405}
    259406
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h

    r95100 r95699  
    2828#include "cc/CCCompletionEvent.h"
    2929#include "cc/CCLayerTreeHostImpl.h"
     30#include "cc/CCMainThread.h"
    3031#include "cc/CCProxy.h"
    3132#include <wtf/OwnPtr.h>
     
    5960
    6061    // Called on CCMainThread
    61     void beginFrameAndCommit(double frameBeginTime);
     62    void beginFrameAndCommit(int sequenceNumber, double frameBeginTime);
    6263
    6364    // Called on CCThread
    64     void beginFrameAndCommitOnCCThread();
     65    PassOwnPtr<CCMainThread::Task> createBeginFrameAndCommitTaskOnCCThread();
     66    void createBeginFrameAndCommitTaskOnCCThread(CCCompletionEvent*, CCMainThread::Task**);
    6567    void commitOnCCThread(CCCompletionEvent*);
     68    void drawLayersAndPresentOnCCThread();
    6669    void drawLayersOnCCThread();
     70    void drawLayersAndReadbackOnCCThread(CCCompletionEvent*, bool* success, void* pixels, const IntRect&);
     71    void finishAllRenderingOnCCThread(CCCompletionEvent*);
    6772    void initializeImplOnCCThread(CCCompletionEvent*);
    6873    void initializeLayerRendererOnCCThread(GraphicsContext3D*, CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*);
    6974    void setNeedsCommitOnCCThread();
    70     void setNeedsCommitAndRedrawOnCCThread();
    71     void setNeedsRedrawOnCCThread();
     75    void updateSchedulerStateOnCCThread(bool commitRequested, bool redrawRequested);
    7276    void layerTreeHostClosedOnCCThread(CCCompletionEvent*);
    73 
    74     // Used on main-thread only.
    75     bool m_commitPending;
     77    void scheduleDrawTaskOnCCThread();
    7678
    7779    // Accessed on main thread only.
     80    bool m_commitRequested;
    7881    CCLayerTreeHost* m_layerTreeHost;
    7982    LayerRendererCapabilities m_layerRendererCapabilitiesMainThreadCopy;
     83    bool m_started;
     84    int m_lastExecutedBeginFrameAndCommitSequenceNumber;
    8085
    81     // Used on the CCThread, but checked on main thread during initialization/shutdown.
     86    // Used on the CCThread only
    8287    OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl;
     88    int m_numBeginFrameAndCommitsIssuedOnCCThread;
     89    bool m_beginFrameAndCommitPendingOnCCThread;
     90    bool m_drawTaskPostedOnCCThread;
     91    bool m_redrawRequestedOnCCThread;
    8392};
    8493
  • trunk/Source/WebKit/chromium/ChangeLog

    r95698 r95699  
     12011-09-22  Nat Duca  <nduca@chromium.org>
     2
     3        [chromium] Make CCThreadProxy draw
     4        https://bugs.webkit.org/show_bug.cgi?id=67417
     5
     6        Disable CCLayerTreeHostTest temporarily. Will re-enable
     7        with https://bugs.webkit.org/show_bug.cgi?id=67418
     8
     9        Reviewed by James Robinson.
     10
     11        * tests/CCLayerTreeHostTest.cpp:
     12
    1132011-09-21  Joshua Bell  <jsbell@chromium.org>
    214
  • trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp

    r95320 r95699  
    171171    }
    172172
     173#if !USE(THREADED_COMPOSITING)
     174    virtual void scheduleComposite() { }
     175#endif
     176
    173177private:
    174178    explicit MockLayerTreeHostClient(TestHooks* testHooks) : m_testHooks(testHooks) { }
     
    187191// The test continues until someone calls endTest. endTest can be called on any thread, but be aware that
    188192// ending the test is an asynchronous process.
    189 class CCLayerTreeHostTest : public testing::Test, TestHooks {
    190 public:
     193class CCLayerTreeHostTest : public testing::TestWithParam<CCSettings>, TestHooks {
     194public:
     195    virtual void SetUp()
     196    {
     197    }
    191198    virtual void afterTest() = 0;
    192199    virtual void beginTest() = 0;
     
    288295    m_client = MockLayerTreeHostClient::create(this);
    289296
    290     CCSettings settings;
    291     settings.enableCompositorThread = true;
    292297    RefPtr<LayerChromium> rootLayer;
    293     m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, settings);
     298    m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, GetParam());
    294299    ASSERT(m_layerTreeHost);
    295300
     
    300305        onEndTest(static_cast<void*>(this));
    301306}
     307INSTANTIATE_TEST_CASE_P(
     308    ProxyTests, CCLayerTreeHostTest,
     309    testing::Values(
     310        CCSettings(false, false, false, false, false),
     311        CCSettings(false, false, true, false, false)));
    302312
    303313void CCLayerTreeHostTest::endTest()
     
    546556TEST_F(CCLayerTreeHostTestSetNeedsRedraw, run)
    547557{
     558    CCSettings setings;
    548559    runTest();
    549560}
     
    551562} // namespace
    552563
    553 #endif // USE(THREADED_COMPOSITING)
     564#endif
  • trunk/Source/WebKit/chromium/tests/TreeSynchronizerTest.cpp

    r92245 r95699  
    2929#include "LayerChromium.h"
    3030#include "cc/CCLayerImpl.h"
     31#include "cc/CCProxy.h"
    3132#include <gtest/gtest.h>
    3233
     
    3435
    3536namespace {
     37
     38class ScopedSetImplThread {
     39public:
     40    ScopedSetImplThread()
     41    {
     42#ifndef NDEBUG
     43        CCProxy::setImplThread(true);
     44#endif
     45    }
     46    ~ScopedSetImplThread()
     47    {
     48#ifndef NDEBUG
     49        CCProxy::setImplThread(false);
     50#endif
     51    }
     52};
    3653
    3754class MockCCLayerImpl : public CCLayerImpl {
     
    117134TEST(TreeSynchronizerTest, syncSimpleTreeFromEmpty)
    118135{
     136    ScopedSetImplThread impl;
    119137    RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create(0);
    120138    layerTreeRoot->addChild(LayerChromium::create(0));
     
    129147TEST(TreeSynchronizerTest, syncSimpleTreeReusingLayers)
    130148{
     149    ScopedSetImplThread impl;
    131150    Vector<int> ccLayerDestructionList;
    132151
     
    154173TEST(TreeSynchronizerTest, syncSimpleTreeAndProperties)
    155174{
     175    ScopedSetImplThread impl;
    156176    RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create(0);
    157177    layerTreeRoot->addChild(LayerChromium::create(0));
     
    185205TEST(TreeSynchronizerTest, reuseCCLayersAfterStructuralChange)
    186206{
     207    ScopedSetImplThread impl;
    187208    Vector<int> ccLayerDestructionList;
    188209
     
    231252TEST(TreeSynchronizerTest, syncSimpleTreeThenDestroy)
    232253{
     254    ScopedSetImplThread impl;
    233255    Vector<int> ccLayerDestructionList;
    234256
     
    261283TEST(TreeSynchronizerTest, syncMaskReplicaAndReplicaMaskLayers)
    262284{
     285    ScopedSetImplThread impl;
    263286    RefPtr<LayerChromium> layerTreeRoot = LayerChromium::create(0);
    264287    layerTreeRoot->addChild(LayerChromium::create(0));
Note: See TracChangeset for help on using the changeset viewer.