Changeset 96066 in webkit


Ignore:
Timestamp:
Sep 26, 2011 7:18:14 PM (13 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-26
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-26
Reviewed by James Robinson.

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

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r96064 r96066  
     12011-09-26  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-26  Adam Klein  <adamk@chromium.org>
    256
  • trunk/Source/WebCore/platform/CrossThreadCopier.h

    r95702 r96066  
    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

    r95988 r96066  
    182182LayerRendererChromium::~LayerRendererChromium()
    183183{
     184    ASSERT(CCProxy::isImplThread
     185());
    184186    m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
    185187    cleanupSharedObjects();
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp

    r95901 r96066  
    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

    r95901 r96066  
    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

    r95988 r96066  
    5656    , m_visible(true)
    5757{
     58    ASSERT(CCProxy::isMainThread());
    5859}
    5960
     
    6364        // Accelerated Painting is not supported in threaded mode. Turn it off.
    6465        m_settings.acceleratePainting = false;
     66        // The HUD does not work in threaded mode. Turn it off.
     67        m_settings.showFPSCounter = false;
     68        m_settings.showPlatformLayerTree = false;
     69
    6570        m_proxy = CCThreadProxy::create(this);
    6671    } else
     
    106111}
    107112
     113// This function commits the CCLayerTreeHost to an impl tree. When modifying
     114// this function, keep in mind that the function *runs* on the impl thread! Any
     115// code that is logically a main thread operation, e.g. deletion of a LayerChromium,
     116// should be delayed until the CCLayerTreeHost::commitComplete, which will run
     117// after the commit, but on the main thread.
    108118void CCLayerTreeHost::commitTo(CCLayerTreeHostImpl* hostImpl)
    109119{
     
    116126
    117127    updateCompositorResources(m_updateList, hostImpl->context());
    118     clearPendingUpdate();
    119128
    120129    hostImpl->setVisible(m_visible);
     
    123132
    124133    hostImpl->layerRenderer()->setContentsTextureMemoryUseBytes(m_contentsTextureManager->currentMemoryUseBytes());
    125     m_contentsTextureManager->unprotectAllTextures();
    126134
    127135    // Synchronize trees, if one exists at all...
     
    132140
    133141    m_frameNumber++;
     142}
     143
     144void CCLayerTreeHost::commitComplete()
     145{
     146    clearPendingUpdate();
     147    m_contentsTextureManager->unprotectAllTextures();
    134148}
    135149
     
    210224{
    211225#if USE(THREADED_COMPOSITING)
    212     TRACE_EVENT("CCLayerTreeHost::setNeedsRedraw", this, 0);
    213226    m_proxy->setNeedsRedraw();
    214227#else
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h

    r95988 r96066  
    9898    // CCLayerTreeHost interface to CCProxy.
    9999    void animateAndLayout(double frameBeginTime);
     100    void commitComplete();
    100101    void commitTo(CCLayerTreeHostImpl*);
    101102    PassOwnPtr<CCThread> createCompositorThread();
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp

    r95988 r96066  
    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.cpp

    r95901 r96066  
    3838
    3939#ifndef NDEBUG
    40 bool CCProxy::isMainThread()
    41 {
    42     return ::isMainThread();
    43 }
    4440
    4541namespace {
    4642bool fakeImplThread = false;
    4743static WTF::ThreadIdentifier implThreadID;
     44}
     45
     46bool CCProxy::isMainThread()
     47{
     48    return ::isMainThread() && !fakeImplThread;
    4849}
    4950
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h

    r95901 r96066  
    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

    r95901 r96066  
    4343    {
    4444#ifndef NDEBUG
     45        ASSERT(CCProxy::isMainThread());
    4546        CCProxy::setImplThread(true);
    4647#endif
     
    6667{
    6768    TRACE_EVENT("CCSingleThreadProxy::CCSingleThreadProxy", this, 0);
    68     ASSERT(isMainThread());
     69    ASSERT(CCProxy::isMainThread());
    6970}
    7071
     
    7879{
    7980    TRACE_EVENT("CCSingleThreadProxy::~CCSingleThreadProxy", this, 0);
    80     ASSERT(isMainThread());
     81    ASSERT(CCProxy::isMainThread());
    8182    ASSERT(!m_layerTreeHostImpl && !m_layerTreeHost); // make sure stop() got called.
    8283}
     
    8485bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
    8586{
    86     ASSERT(isMainThread());
     87    ASSERT(CCProxy::isMainThread());
    8788
    8889    if (!recreateContextIfNeeded())
     
    104105GraphicsContext3D* CCSingleThreadProxy::context()
    105106{
    106     ASSERT(isMainThread());
     107    ASSERT(CCProxy::isMainThread());
    107108    ScopedSetImplThread impl;
    108109    return m_layerTreeHostImpl->context();
     
    111112void CCSingleThreadProxy::finishAllRendering()
    112113{
    113     ASSERT(isMainThread());
    114     ScopedSetImplThread impl;
    115     m_layerTreeHostImpl->finishAllRendering();
     114    ASSERT(CCProxy::isMainThread());
     115    {
     116        ScopedSetImplThread impl;
     117        m_layerTreeHostImpl->finishAllRendering();
     118    }
    116119}
    117120
    118121bool CCSingleThreadProxy::isStarted() const
    119122{
    120     ASSERT(isMainThread());
     123    ASSERT(CCProxy::isMainThread());
    121124    return m_layerTreeHostImpl;
    122125}
     
    124127bool CCSingleThreadProxy::initializeLayerRenderer()
    125128{
    126     ASSERT(isMainThread());
     129    ASSERT(CCProxy::isMainThread());
    127130    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D();
    128131    if (!context)
     
    132135    {
    133136        ScopedSetImplThread impl;
    134         return m_layerTreeHostImpl->initializeLayerRenderer(context);
     137        bool ok = m_layerTreeHostImpl->initializeLayerRenderer(context);
     138        if (ok)
     139            m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
     140        return ok;
    135141    }
    136142}
     
    138144const LayerRendererCapabilities& CCSingleThreadProxy::layerRendererCapabilities() const
    139145{
    140     ScopedSetImplThread impl;
    141     return m_layerTreeHostImpl->layerRendererCapabilities();
     146    // Note: this gets called during the commit by the "impl" thread
     147    return m_layerRendererCapabilitiesForMainThread;
    142148}
    143149
     
    150156void CCSingleThreadProxy::setNeedsCommit()
    151157{
    152     ASSERT(isMainThread());
     158    ASSERT(CCProxy::isMainThread());
    153159    // Commit immediately
    154160    {
     
    158164        m_layerTreeHostImpl->commitComplete();
    159165    }
     166    m_layerTreeHost->commitComplete();
    160167}
    161168
    162169void CCSingleThreadProxy::setNeedsCommitAndRedraw()
    163170{
    164     ASSERT(isMainThread());
     171    ASSERT(CCProxy::isMainThread());
    165172#if !USE(THREADED_COMPOSITING)
    166173    m_layerTreeHost->scheduleComposite();
     
    181188{
    182189    TRACE_EVENT("CCSingleThreadProxy::stop", this, 0);
    183     ASSERT(isMainThread());
     190    ASSERT(CCProxy::isMainThread());
    184191    {
    185192        ScopedSetImplThread impl;
     
    207214bool CCSingleThreadProxy::recreateContextIfNeeded()
    208215{
    209     ASSERT(isMainThread());
     216    ASSERT(CCProxy::isMainThread());
    210217    if (!m_graphicsContextLost)
    211218        return true;
     
    218225    if (context) {
    219226        ASSERT(context->hasOneRef());
    220         if (m_layerTreeHostImpl->initializeLayerRenderer(context)) {
     227        bool ok;
     228        {
     229            ScopedSetImplThread impl;
     230            ok = m_layerTreeHostImpl->initializeLayerRenderer(context);
     231            if (ok)
     232                m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
     233        }
     234        if (ok) {
    221235            m_layerTreeHost->didRecreateGraphicsContext(true);
    222236            m_graphicsContextLost = false;
     
    241255void CCSingleThreadProxy::commitIfNeeded()
    242256{
     257    ASSERT(CCProxy::isMainThread());
     258
    243259    // Update
    244260    m_layerTreeHost->updateLayers();
     
    251267        m_layerTreeHostImpl->commitComplete();
    252268    }
     269    m_layerTreeHost->commitComplete();
    253270}
    254271
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h

    r95901 r96066  
    7070    // Used on the CCThread, but checked on main thread during initialization/shutdown.
    7171    OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl;
     72    LayerRendererCapabilities m_layerRendererCapabilitiesForMainThread;
    7273
    7374    int m_numFailedRecreateAttempts;
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp

    r95901 r96066  
    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    // If a commit is pending, perform the commit first.
     91    if (m_commitRequested)  {
     92        // This bit of code is uglier than it should be because returning
     93        // pointers via the CCThread task model is really messy. Effectively, we
     94        // are making a blocking call to createBeginFrameAndCommitTaskOnCCThread,
     95        // and trying to get the CCMainThread::Task it returns so we can run it.
     96        OwnPtr<CCMainThread::Task> beginFrameAndCommitTask;
     97        {
     98            CCMainThread::Task* taskPtr = 0;
     99            CCCompletionEvent completion;
     100            ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::obtainBeginFrameAndCommitTaskFromCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&taskPtr)));
     101            completion.wait();
     102            beginFrameAndCommitTask = adoptPtr(taskPtr);
     103        }
     104
     105        beginFrameAndCommitTask->performTask();
     106    }
     107
     108    // Draw using the new tree and read back the results.
     109    bool success = false;
     110    CCCompletionEvent completion;
     111    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::drawLayersAndReadbackOnCCThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&success), AllowCrossThreadAccess(pixels), rect));
     112    completion.wait();
     113    return success;
     114}
     115
     116void CCThreadProxy::drawLayersAndReadbackOnCCThread(CCCompletionEvent* completion, bool* success, void* pixels, const IntRect& rect)
     117{
     118    ASSERT(CCProxy::isImplThread());
     119    if (!m_layerTreeHostImpl) {
     120        *success = false;
     121        completion->signal();
     122        return;
     123    }
     124    drawLayersOnCCThread();
     125    m_layerTreeHostImpl->readback(pixels, rect);
     126    *success = m_layerTreeHostImpl->isContextLost();
     127    completion->signal();
    83128}
    84129
     
    90135void CCThreadProxy::finishAllRendering()
    91136{
    92     ASSERT_NOT_REACHED();
     137    ASSERT(CCProxy::isMainThread());
     138
     139    // Make sure all GL drawing is finished on the impl thread.
     140    CCCompletionEvent completion;
     141    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::finishAllRenderingOnCCThread, AllowCrossThreadAccess(&completion)));
     142    completion.wait();
    93143}
    94144
    95145bool CCThreadProxy::isStarted() const
    96146{
    97     return m_layerTreeHostImpl;
     147    ASSERT(CCProxy::isMainThread());
     148    return m_started;
    98149}
    99150
     
    112163    // are pushed into the initializeSucceeded and capabilities local variables.
    113164    CCCompletionEvent completion;
    114     bool initializeSucceeded;
     165    bool initializeSucceeded = false;
    115166    LayerRendererCapabilities capabilities;
    116167    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnCCThread,
     
    136187{
    137188    ASSERT(isMainThread());
    138     if (m_commitPending)
     189    if (m_commitRequested)
    139190        return;
    140191
    141192    TRACE_EVENT("CCThreadProxy::setNeedsCommit", this, 0);
    142     m_commitPending = true;
    143     ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitOnCCThread));
     193    m_commitRequested = true;
     194    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, m_commitRequested, true));
    144195}
    145196
     
    147198{
    148199    ASSERT(isMainThread());
    149     if (m_commitPending)
    150         return;
     200    if (m_commitRequested)
     201        return;
     202    m_commitRequested = true;
    151203
    152204    TRACE_EVENT("CCThreadProxy::setNeedsCommitAndRedraw", this, 0);
    153     m_commitPending = true;
    154     ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsCommitAndRedrawOnCCThread));
     205    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, m_commitRequested, true));
    155206}
    156207
     
    158209{
    159210    ASSERT(isMainThread());
    160     ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setNeedsRedrawOnCCThread));
     211    if (m_commitRequested) // Implies that a commit is in flight.
     212        return;
     213    // Unlike setNeedsCommit that tracks whether a commit message has been sent,
     214    // setNeedsRedraw always sends a message to the compositor thread. This is
     215    // because the compositor thread can draw without telling the main
     216    // thread. This should not be much of a problem because calls to
     217    // setNeedsRedraw messages are uncommon (only triggered by WM_PAINT/etc),
     218    // compared to setNeedsCommitAndRedraw messages.
     219    TRACE_EVENT("CCThreadProxy::setNeedsRedraw", this, 0);
     220    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::updateSchedulerStateOnCCThread, false, true));
    161221}
    162222
    163223void CCThreadProxy::start()
    164224{
     225    ASSERT(isMainThread());
    165226    // Create LayerTreeHostImpl.
    166227    CCCompletionEvent completion;
    167228    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeImplOnCCThread, AllowCrossThreadAccess(&completion)));
    168229    completion.wait();
     230
     231    m_started = true;
    169232}
    170233
     
    173236    TRACE_EVENT("CCThreadProxy::stop", this, 0);
    174237    ASSERT(isMainThread());
     238    ASSERT(m_started);
     239
    175240    // Synchronously deletes the impl.
    176241    CCCompletionEvent completion;
     
    180245    ASSERT(!m_layerTreeHostImpl); // verify that the impl deleted.
    181246    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 {
     247    m_started = false;
     248}
     249
     250void CCThreadProxy::finishAllRenderingOnCCThread(CCCompletionEvent* completion)
     251{
     252    TRACE_EVENT("CCThreadProxy::finishAllRenderingOnCCThread", this, 0);
     253    ASSERT(isImplThread());
     254    ASSERT(!m_beginFrameAndCommitPendingOnCCThread);
     255    if (m_redrawRequestedOnCCThread) {
     256        drawLayersOnCCThread();
     257        m_layerTreeHostImpl->present();
     258        m_redrawRequestedOnCCThread = false;
     259    }
     260    m_layerTreeHostImpl->finishAllRendering();
     261    completion->signal();
     262}
     263
     264void CCThreadProxy::obtainBeginFrameAndCommitTaskFromCCThread(CCCompletionEvent* completion, CCMainThread::Task** taskPtr)
     265{
     266    OwnPtr<CCMainThread::Task> task = createBeginFrameAndCommitTaskOnCCThread();
     267    *taskPtr = task.leakPtr();
     268    completion->signal();
     269}
     270
     271PassOwnPtr<CCMainThread::Task> CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread()
     272{
     273    TRACE_EVENT("CCThreadProxy::createBeginFrameAndCommitTaskOnCCThread", this, 0);
     274    ASSERT(isImplThread());
     275    double frameBeginTime = currentTime();
     276    m_beginFrameAndCommitPendingOnCCThread = true;
     277
     278    // NOTE, it is possible to receieve a request for a
     279    // beginFrameAndCommitOnCCThread from finishAllRendering while a
     280    // beginFrameAndCommitOnCCThread is enqueued. Since CCMainThread doesn't
     281    // provide a threadsafe way to cancel tasks, it is important that
     282    // beginFrameAndCommit be structured to understand that it may get called at
     283    // a point that it shouldn't. We do this by assigning a sequence number to
     284    // every new beginFrameAndCommit task. Then, beginFrameAndCommit tracks the
     285    // last executed sequence number, dropping beginFrameAndCommit with sequence
     286    // numbers below the last executed one.
     287    int thisTaskSequenceNumber = m_numBeginFrameAndCommitsIssuedOnCCThread;
     288    m_numBeginFrameAndCommitsIssuedOnCCThread++;
     289    return createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, thisTaskSequenceNumber, frameBeginTime);
     290}
     291
     292void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTime)
     293{
     294    TRACE_EVENT("CCThreadProxy::beginFrameAndCommit", this, 0);
    194295    ASSERT(isMainThread());
    195296    if (!m_layerTreeHost)
    196297        return;
    197298
    198     TRACE_EVENT("CCThreadProxy::requestFrameAndCommit", this, 0);
     299    // Drop beginFrameAndCommit calls that occur out of sequence. See createBeginFrameAndCommitTaskOnCCThread for
     300    // an explanation of how out-of-sequence beginFrameAndCommit tasks can occur.
     301    if (sequenceNumber < m_lastExecutedBeginFrameAndCommitSequenceNumber) {
     302        TRACE_EVENT("EarlyOut_StaleBeginFrameAndCommit", this, 0);
     303        return;
     304    }
     305    m_lastExecutedBeginFrameAndCommitSequenceNumber = sequenceNumber;
     306
     307    ASSERT(m_commitRequested);
     308
     309    // FIXME: recreate the context if it was requested by the impl thread
    199310    {
    200311        TRACE_EVENT("CCLayerTreeHost::animateAndLayout", this, 0);
     
    202313    }
    203314
    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();
     315    ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);
     316
     317    // Clear the commit flag after animateAndLayout here --- objects that only
     318    // layout when painted will trigger another setNeedsCommit inside
     319    // updateLayers.
     320    m_commitRequested = false;
     321
     322    m_layerTreeHost->updateLayers();
     323
     324    {
     325        // Blocking call to CCThreadProxy::commitOnCCThread
     326        TRACE_EVENT("commit", this, 0);
     327        CCCompletionEvent completion;
     328        ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::commitOnCCThread, AllowCrossThreadAccess(&completion)));
     329        completion.wait();
     330    }
     331
     332    m_layerTreeHost->commitComplete();
     333
     334    ASSERT(m_lastExecutedBeginFrameAndCommitSequenceNumber == sequenceNumber);
    210335}
    211336
    212337void CCThreadProxy::commitOnCCThread(CCCompletionEvent* completion)
    213338{
    214     ASSERT(isImplThread());
    215     TRACE_EVENT("CCThreadProxy::commitOnCCThread", this, 0);
     339    TRACE_EVENT("CCThreadProxy::beginFrameAndCommitOnCCThread", this, 0);
     340    ASSERT(isImplThread());
     341    ASSERT(m_beginFrameAndCommitPendingOnCCThread);
     342    m_beginFrameAndCommitPendingOnCCThread = false;
     343    if (!m_layerTreeHostImpl) {
     344        completion->signal();
     345        return;
     346    }
    216347    m_layerTreeHostImpl->beginCommit();
    217     {
    218         TRACE_EVENT("CCLayerTreeHost::commit", this, 0);
    219         m_layerTreeHost->commitTo(m_layerTreeHostImpl.get());
    220     }
    221     completion->signal();
    222 
     348    m_layerTreeHost->commitTo(m_layerTreeHostImpl.get());
    223349    m_layerTreeHostImpl->commitComplete();
    224     setNeedsRedrawOnCCThread();
     350
     351    completion->signal();
     352
     353    if (m_redrawRequestedOnCCThread)
     354        scheduleDrawTaskOnCCThread();
     355}
     356
     357void CCThreadProxy::scheduleDrawTaskOnCCThread()
     358{
     359    ASSERT(isImplThread());
     360    if (m_drawTaskPostedOnCCThread)
     361        return;
     362    TRACE_EVENT("CCThreadProxy::scheduleDrawTaskOnCCThread", this, 0);
     363    ASSERT(m_layerTreeHostImpl);
     364    m_drawTaskPostedOnCCThread = true;
     365    ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::drawLayersAndPresentOnCCThread));
     366}
     367
     368void CCThreadProxy::drawLayersAndPresentOnCCThread()
     369{
     370    TRACE_EVENT("CCThreadProxy::drawLayersOnCCThread", this, 0);
     371    ASSERT(isImplThread());
     372    if (!m_layerTreeHostImpl)
     373        return;
     374
     375    drawLayersOnCCThread();
     376    m_layerTreeHostImpl->present();
     377    m_redrawRequestedOnCCThread = false;
     378    m_drawTaskPostedOnCCThread = false;
    225379}
    226380
     
    229383    TRACE_EVENT("CCThreadProxy::drawLayersOnCCThread", this, 0);
    230384    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());
    239385    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);
     386
     387    m_layerTreeHostImpl->drawLayers();
     388    ASSERT(!m_layerTreeHostImpl->isContextLost());
     389}
     390
     391void CCThreadProxy::updateSchedulerStateOnCCThread(bool commitRequested, bool redrawRequested)
     392{
     393    TRACE_EVENT("CCThreadProxy::updateSchedulerStateOnCCThread", this, 0);
    247394    ASSERT(isImplThread());
    248395    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();
     396
     397    // FIXME: use CCScheduler to decide when to manage the conversion of this
     398    // commit request into an actual createBeginFrameAndCommitTaskOnCCThread call.
     399    m_redrawRequestedOnCCThread |= redrawRequested;
     400    if (!m_beginFrameAndCommitPendingOnCCThread) {
     401        CCMainThread::postTask(createBeginFrameAndCommitTaskOnCCThread());
     402        return;
     403    }
     404
     405    // If no commit is pending, but a redraw is requested, then post a redraw right away
     406    if (m_redrawRequestedOnCCThread)
     407        scheduleDrawTaskOnCCThread();
    258408}
    259409
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h

    r95901 r96066  
    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 obtainBeginFrameAndCommitTaskFromCCThread(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

    r96054 r96066  
     12011-09-26  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-26  Joshua Bell  <jsbell@chromium.org>
    214
  • trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp

    r95901 r96066  
    171171    }
    172172
     173#if !USE(THREADED_COMPOSITING)
     174    virtual void scheduleComposite() { }
     175#endif
     176
    173177private:
    174178    explicit MockLayerTreeHostClient(TestHooks* testHooks) : m_testHooks(testHooks) { }
     
    209213        , m_endWhenBeginReturns(false)
    210214        , m_running(false)
    211         , m_timedOut(false) { }
     215        , m_timedOut(false)
     216    {
     217#if USE(THREADED_COMPOSITING)
     218        m_settings.enableCompositorThread = true;
     219#else
     220        m_settings.enableCompositorThread = false;
     221#endif
     222    }
    212223
    213224    void doBeginTest();
     
    271282    }
    272283
     284    CCSettings m_settings;
    273285    OwnPtr<MockLayerTreeHostClient> m_client;
    274286    RefPtr<CCLayerTreeHost> m_layerTreeHost;
     
    288300    m_client = MockLayerTreeHostClient::create(this);
    289301
    290     CCSettings settings;
    291     settings.enableCompositorThread = true;
    292302    RefPtr<LayerChromium> rootLayer;
    293     m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, settings);
     303    m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, m_settings);
    294304    ASSERT(m_layerTreeHost);
    295305
     
    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

    r95901 r96066  
    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.