Changeset 106700 in webkit


Ignore:
Timestamp:
Feb 3, 2012 3:18:56 PM (12 years ago)
Author:
jamesr@google.com
Message:

[chromium] Defer makeContextCurrent in compositor until first frame
https://bugs.webkit.org/show_bug.cgi?id=77269

Reviewed by Kenneth Russell.

Source/WebCore:

There are situations where we need to instantiate a compositor, but can't call makeContextCurrent() until some
initialization work completes on another thread that we cannot block for. This defers the first
makeContextCurrent() call until we need to produce the first frame at which point we know the call can succeed,
assuming that the scheduler does the right thing.

This is accomplished by splitting up proxy initialization into two pieces:
*) initializeContext() which attempts to instantiate a GraphicsContext3D. This can fail if we can't make a
context at all, in which case we abort completely and return NULL from CCLayerTreeHost::create().

*) initializeLayerRenderer() which uses the previously-created context to instantiate our compositor objects and

grab our renderer capabilities. This can fail if the context is not usable for compositing, which we report
to the client as a lost context event.

Internally this introduces a new state to the CCLayerTreeHostImpl where it has a context but does not yet have a
LayerRendererChromium, which has fairly minimal impact. One other change is that we don't instantiate the
TextureManagers until we have the renderer capabilities, but this isn't necessary until we want to start
painting so it doesn't have any impact outside of some overly intrustive unit tests.

  • platform/graphics/chromium/ContentLayerChromium.cpp:

(WebCore::ContentLayerChromium::paintContentsIfDirty):
(WebCore::ContentLayerChromium::createTextureUpdater):

  • platform/graphics/chromium/ContentLayerChromium.h:

(ContentLayerChromium):

  • platform/graphics/chromium/ImageLayerChromium.cpp:

(WebCore::ImageLayerChromium::paintContentsIfDirty):

  • platform/graphics/chromium/ImageLayerChromium.h:

(ImageLayerChromium):

  • platform/graphics/chromium/TiledLayerChromium.cpp:
  • platform/graphics/chromium/TiledLayerChromium.h:

(WebCore::TiledLayerChromium::setSampledTexelFormat):
(TiledLayerChromium):

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

(WebCore::CCLayerTreeHost::CCLayerTreeHost):
(WebCore::CCLayerTreeHost::initialize):
(WebCore::CCLayerTreeHost::initializeLayerRenderer):
(WebCore):
(WebCore::CCLayerTreeHost::beginCommitOnImplThread):
(WebCore::CCLayerTreeHost::compositeAndReadback):
(WebCore::CCLayerTreeHost::finishAllRendering):
(WebCore::CCLayerTreeHost::setViewportSize):
(WebCore::CCLayerTreeHost::setVisible):
(WebCore::CCLayerTreeHost::updateLayers):

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

(CCLayerTreeHost):
():

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

(WebCore::CCLayerTreeHostImpl::isContextLost):

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

(CCProxy):

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

(WebCore::CCSingleThreadProxy::CCSingleThreadProxy):
(WebCore::CCSingleThreadProxy::compositeAndReadback):
(WebCore::CCSingleThreadProxy::initializeContext):
(WebCore::CCSingleThreadProxy::initializeLayerRenderer):
(WebCore::CCSingleThreadProxy::layerRendererCapabilities):

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

(CCSingleThreadProxy):

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

(WebCore::CCThreadProxy::CCThreadProxy):
(WebCore::CCThreadProxy::compositeAndReadback):
(WebCore::CCThreadProxy::initializeContext):
(WebCore):
(WebCore::CCThreadProxy::initializeLayerRenderer):
(WebCore::CCThreadProxy::layerRendererCapabilities):
(WebCore::CCThreadProxy::initializeImplOnImplThread):
(WebCore::CCThreadProxy::initializeContextOnImplThread):
(WebCore::CCThreadProxy::initializeLayerRendererOnImplThread):

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

(CCThreadProxy):

Source/WebKit/chromium:

  • tests/CCLayerTreeHostTest.cpp:

(WTF::CCLayerTreeHostTestSetViewportSize::beginTest):

  • tests/TiledLayerChromiumTest.cpp:

(WTF::TEST):

Location:
trunk/Source
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r106699 r106700  
     12012-02-03  James Robinson  <jamesr@chromium.org>
     2
     3        [chromium] Defer makeContextCurrent in compositor until first frame
     4        https://bugs.webkit.org/show_bug.cgi?id=77269
     5
     6        Reviewed by Kenneth Russell.
     7
     8        There are situations where we need to instantiate a compositor, but can't call makeContextCurrent() until some
     9        initialization work completes on another thread that we cannot block for. This defers the first
     10        makeContextCurrent() call until we need to produce the first frame at which point we know the call can succeed,
     11        assuming that the scheduler does the right thing.
     12
     13        This is accomplished by splitting up proxy initialization into two pieces:
     14        *) initializeContext() which attempts to instantiate a GraphicsContext3D. This can fail if we can't make a
     15        context at all, in which case we abort completely and return NULL from CCLayerTreeHost::create().
     16
     17        *) initializeLayerRenderer() which uses the previously-created context to instantiate our compositor objects and
     18            grab our renderer capabilities. This can fail if the context is not usable for compositing, which we report
     19            to the client as a lost context event.
     20
     21        Internally this introduces a new state to the CCLayerTreeHostImpl where it has a context but does not yet have a
     22        LayerRendererChromium, which has fairly minimal impact. One other change is that we don't instantiate the
     23        TextureManagers until we have the renderer capabilities, but this isn't necessary until we want to start
     24        painting so it doesn't have any impact outside of some overly intrustive unit tests.
     25
     26        * platform/graphics/chromium/ContentLayerChromium.cpp:
     27        (WebCore::ContentLayerChromium::paintContentsIfDirty):
     28        (WebCore::ContentLayerChromium::createTextureUpdater):
     29        * platform/graphics/chromium/ContentLayerChromium.h:
     30        (ContentLayerChromium):
     31        * platform/graphics/chromium/ImageLayerChromium.cpp:
     32        (WebCore::ImageLayerChromium::paintContentsIfDirty):
     33        * platform/graphics/chromium/ImageLayerChromium.h:
     34        (ImageLayerChromium):
     35        * platform/graphics/chromium/TiledLayerChromium.cpp:
     36        * platform/graphics/chromium/TiledLayerChromium.h:
     37        (WebCore::TiledLayerChromium::setSampledTexelFormat):
     38        (TiledLayerChromium):
     39        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
     40        (WebCore::CCLayerTreeHost::CCLayerTreeHost):
     41        (WebCore::CCLayerTreeHost::initialize):
     42        (WebCore::CCLayerTreeHost::initializeLayerRenderer):
     43        (WebCore):
     44        (WebCore::CCLayerTreeHost::beginCommitOnImplThread):
     45        (WebCore::CCLayerTreeHost::compositeAndReadback):
     46        (WebCore::CCLayerTreeHost::finishAllRendering):
     47        (WebCore::CCLayerTreeHost::setViewportSize):
     48        (WebCore::CCLayerTreeHost::setVisible):
     49        (WebCore::CCLayerTreeHost::updateLayers):
     50        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
     51        (CCLayerTreeHost):
     52        ():
     53        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
     54        (WebCore::CCLayerTreeHostImpl::isContextLost):
     55        * platform/graphics/chromium/cc/CCProxy.h:
     56        (CCProxy):
     57        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
     58        (WebCore::CCSingleThreadProxy::CCSingleThreadProxy):
     59        (WebCore::CCSingleThreadProxy::compositeAndReadback):
     60        (WebCore::CCSingleThreadProxy::initializeContext):
     61        (WebCore::CCSingleThreadProxy::initializeLayerRenderer):
     62        (WebCore::CCSingleThreadProxy::layerRendererCapabilities):
     63        * platform/graphics/chromium/cc/CCSingleThreadProxy.h:
     64        (CCSingleThreadProxy):
     65        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
     66        (WebCore::CCThreadProxy::CCThreadProxy):
     67        (WebCore::CCThreadProxy::compositeAndReadback):
     68        (WebCore::CCThreadProxy::initializeContext):
     69        (WebCore):
     70        (WebCore::CCThreadProxy::initializeLayerRenderer):
     71        (WebCore::CCThreadProxy::layerRendererCapabilities):
     72        (WebCore::CCThreadProxy::initializeImplOnImplThread):
     73        (WebCore::CCThreadProxy::initializeContextOnImplThread):
     74        (WebCore::CCThreadProxy::initializeLayerRendererOnImplThread):
     75        * platform/graphics/chromium/cc/CCThreadProxy.h:
     76        (CCThreadProxy):
     77
    1782012-02-03  James Robinson  <jamesr@chromium.org>
    279
  • trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp

    r106383 r106700  
    9797{
    9898    updateTileSizeAndTilingOption();
     99    createTextureUpdaterIfNeeded();
    99100
    100101    IntRect layerRect;
     
    123124}
    124125
    125 void ContentLayerChromium::createTextureUpdater(const CCLayerTreeHost* host)
     126void ContentLayerChromium::createTextureUpdaterIfNeeded()
    126127{
     128    if (m_textureUpdater)
     129        return;
    127130#if USE(SKIA)
    128     if (host->settings().acceleratePainting)
     131    if (layerTreeHost()->settings().acceleratePainting)
    129132        m_textureUpdater = FrameBufferSkPictureCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate));
    130     else if (host->settings().perTilePainting)
    131         m_textureUpdater = BitmapSkPictureCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate), host->layerRendererCapabilities().usingMapSub);
     133    else if (layerTreeHost()->settings().perTilePainting)
     134        m_textureUpdater = BitmapSkPictureCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate), layerTreeHost()->layerRendererCapabilities().usingMapSub);
    132135    else
    133136#endif // USE(SKIA)
    134         m_textureUpdater = BitmapCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate), host->layerRendererCapabilities().usingMapSub);
     137        m_textureUpdater = BitmapCanvasLayerTextureUpdater::create(ContentLayerPainter::create(m_delegate), layerTreeHost()->layerRendererCapabilities().usingMapSub);
    135138    m_textureUpdater->setOpaque(opaque());
     139
     140    GC3Denum textureFormat = layerTreeHost()->layerRendererCapabilities().bestTextureFormat;
     141    setTextureFormat(textureFormat);
     142    setSampledTexelFormat(textureUpdater()->sampledTexelFormat(textureFormat));
    136143}
    137144
  • trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h

    r106383 r106700  
    7070
    7171private:
    72     virtual void createTextureUpdater(const CCLayerTreeHost*);
    7372    virtual LayerTextureUpdater* textureUpdater() const { return m_textureUpdater.get(); }
     73    virtual void createTextureUpdaterIfNeeded();
    7474
    7575    ContentLayerDelegate* m_delegate;
  • trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp

    r106383 r106700  
    161161void ImageLayerChromium::paintContentsIfDirty(const Region& /* occludedScreenSpace */)
    162162{
     163    createTextureUpdaterIfNeeded();
    163164    if (m_needsDisplay) {
    164165        m_textureUpdater->updateFromImage(m_contents->nativeImageForCurrentFrame());
     
    171172}
    172173
     174void ImageLayerChromium::createTextureUpdaterIfNeeded()
     175{
     176    if (m_textureUpdater)
     177        return;
     178
     179    m_textureUpdater = ImageLayerTextureUpdater::create(layerTreeHost()->layerRendererCapabilities().usingMapSub);
     180    GC3Denum textureFormat = layerTreeHost()->layerRendererCapabilities().bestTextureFormat;
     181    setTextureFormat(textureFormat);
     182    setSampledTexelFormat(textureUpdater()->sampledTexelFormat(textureFormat));
     183}
     184
    173185LayerTextureUpdater* ImageLayerChromium::textureUpdater() const
    174186{
     
    188200}
    189201
    190 void ImageLayerChromium::createTextureUpdater(const CCLayerTreeHost* host)
    191 {
    192     // Avoid creating a new texture updater which would not have a valid copy of the current image.
    193     if (!m_textureUpdater)
    194         m_textureUpdater = ImageLayerTextureUpdater::create(host->layerRendererCapabilities().usingMapSub);
    195 }
    196 
    197202bool ImageLayerChromium::needsContentsScale() const
    198203{
  • trunk/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h

    r106383 r106700  
    6363    ImageLayerChromium();
    6464
    65     virtual void createTextureUpdater(const CCLayerTreeHost*);
    6665    void setTilingOption(TilingOption);
    6766
    6867    virtual LayerTextureUpdater* textureUpdater() const;
     68    virtual void createTextureUpdaterIfNeeded();
    6969    virtual IntSize contentBounds() const;
    7070
  • trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp

    r106383 r106700  
    175175}
    176176
    177 void TiledLayerChromium::setLayerTreeHost(CCLayerTreeHost* host)
    178 {
    179     if (host == layerTreeHost())
    180         return;
    181 
    182     LayerChromium::setLayerTreeHost(host);
    183 
    184     if (!host)
    185         return;
    186 
    187     createTextureUpdater(host);
    188     setTextureFormat(host->layerRendererCapabilities().bestTextureFormat);
    189     m_sampledTexelFormat = textureUpdater()->sampledTexelFormat(m_textureFormat);
    190 }
    191 
    192177void TiledLayerChromium::updateCompositorResources(GraphicsContext3D*, CCTextureUpdater& updater)
    193178{
     
    371356        tile->m_updateRect = IntRect();
    372357    }
     358
     359    createTextureUpdaterIfNeeded();
    373360
    374361    // Create tiles as needed, expanding a dirty rect to contain all
     
    474461    m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom);
    475462
     463    createTextureUpdaterIfNeeded();
    476464    for (int j = top; j <= bottom; ++j) {
    477465        for (int i = left; i <= right; ++i) {
  • trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h

    r106383 r106700  
    7878    void setTextureFormat(GC3Denum textureFormat) { m_textureFormat = textureFormat; }
    7979    void setBorderTexelOption(CCLayerTilingData::BorderTexelOption);
     80    void setSampledTexelFormat(LayerTextureUpdater::SampledTexelFormat sampledTexelFormat) { m_sampledTexelFormat = sampledTexelFormat; }
    8081
    81     virtual void createTextureUpdater(const CCLayerTreeHost*) = 0;
    8282    virtual LayerTextureUpdater* textureUpdater() const = 0;
     83    virtual void createTextureUpdaterIfNeeded() = 0;
    8384
    8485    // Set invalidations to be potentially repainted during update().
     
    102103private:
    103104    virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
    104 
    105     virtual void setLayerTreeHost(CCLayerTreeHost*);
    106105
    107106    void createTilerIfNeeded();
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp

    r106383 r106700  
    6464    , m_client(client)
    6565    , m_frameNumber(0)
     66    , m_layerRendererInitialized(false)
    6667    , m_settings(settings)
    6768    , m_visible(true)
     
    8990    m_proxy->start();
    9091
    91     if (!m_proxy->initializeLayerRenderer())
     92    if (!m_proxy->initializeContext())
    9293        return false;
    9394
    9495    m_compositorIdentifier = m_proxy->compositorIdentifier();
    95 
    96     // Update m_settings based on capabilities that we got back from the renderer.
    97     m_settings.acceleratePainting = m_proxy->layerRendererCapabilities().usingAcceleratedPainting;
    98 
    99     // Update m_settings based on partial update capability.
    100     m_settings.partialTextureUpdates = m_settings.partialTextureUpdates && m_proxy->partialTextureUpdateCapability();
    101 
    102     m_contentsTextureManager = TextureManager::create(TextureManager::highLimitBytes(viewportSize()),
    103                                                       TextureManager::reclaimLimitBytes(viewportSize()),
    104                                                       m_proxy->layerRendererCapabilities().maxTextureSize);
    10596    return true;
    10697}
     
    117108}
    118109
     110void CCLayerTreeHost::initializeLayerRenderer()
     111{
     112    TRACE_EVENT("CCLayerTreeHost::initializeLayerRenderer", this, 0);
     113    if (!m_proxy->initializeLayerRenderer()) {
     114        // Uh oh, better tell the client that we can't do anything with this context.
     115        m_client->didRecreateGraphicsContext(false);
     116        return;
     117    }
     118
     119    // Update m_settings based on capabilities that we got back from the renderer.
     120    m_settings.acceleratePainting = m_proxy->layerRendererCapabilities().usingAcceleratedPainting;
     121
     122    // Update m_settings based on partial update capability.
     123    m_settings.partialTextureUpdates = m_settings.partialTextureUpdates && m_proxy->partialTextureUpdateCapability();
     124
     125    m_contentsTextureManager = TextureManager::create(TextureManager::highLimitBytes(viewportSize()),
     126                                                      TextureManager::reclaimLimitBytes(viewportSize()),
     127                                                      m_proxy->layerRendererCapabilities().maxTextureSize);
     128
     129    m_layerRendererInitialized = true;
     130}
     131
     132
    119133void CCLayerTreeHost::deleteContentsTexturesOnImplThread(TextureAllocator* allocator)
    120134{
     
    141155    TRACE_EVENT("CCLayerTreeHost::commitTo", this, 0);
    142156
    143     contentsTextureManager()->reduceMemoryToLimit(TextureManager::reclaimLimitBytes(viewportSize()));
    144     contentsTextureManager()->deleteEvictedTextures(hostImpl->contentsTextureAllocator());
     157    m_contentsTextureManager->reduceMemoryToLimit(TextureManager::reclaimLimitBytes(viewportSize()));
     158    m_contentsTextureManager->deleteEvictedTextures(hostImpl->contentsTextureAllocator());
    145159}
    146160
     
    199213bool CCLayerTreeHost::compositeAndReadback(void *pixels, const IntRect& rect)
    200214{
     215    if (!m_layerRendererInitialized) {
     216        initializeLayerRenderer();
     217        if (!m_layerRendererInitialized)
     218            return false;
     219    }
    201220    m_triggerIdlePaints = false;
    202221    bool ret = m_proxy->compositeAndReadback(pixels, rect);
     
    207226void CCLayerTreeHost::finishAllRendering()
    208227{
     228    if (!m_layerRendererInitialized)
     229        return;
    209230    m_proxy->finishAllRendering();
    210231}
     
    255276        return;
    256277
    257     contentsTextureManager()->setMaxMemoryLimitBytes(TextureManager::highLimitBytes(viewportSize));
    258     contentsTextureManager()->setPreferredMemoryLimitBytes(TextureManager::reclaimLimitBytes(viewportSize));
     278    if (m_contentsTextureManager) {
     279        m_contentsTextureManager->setMaxMemoryLimitBytes(TextureManager::highLimitBytes(viewportSize));
     280        m_contentsTextureManager->setPreferredMemoryLimitBytes(TextureManager::reclaimLimitBytes(viewportSize));
     281    }
    259282    m_viewportSize = viewportSize;
    260283    setNeedsCommit();
     
    286309
    287310    m_visible = visible;
     311
     312    if (!m_layerRendererInitialized)
     313        return;
     314
    288315    if (!visible) {
    289316        m_contentsTextureManager->reduceMemoryToLimit(TextureManager::lowLimitBytes(viewportSize()));
     
    347374void CCLayerTreeHost::updateLayers()
    348375{
     376    if (!m_layerRendererInitialized) {
     377        initializeLayerRenderer();
     378        // If we couldn't initialize, then bail since we're returning to software mode.
     379        if (!m_layerRendererInitialized)
     380            return;
     381    }
     382
    349383    if (!rootLayer())
    350384        return;
     
    389423    size_t preferredLimitBytes = TextureManager::reclaimLimitBytes(m_viewportSize);
    390424    size_t maxLimitBytes = TextureManager::highLimitBytes(m_viewportSize);
    391     contentsTextureManager()->reduceMemoryToLimit(preferredLimitBytes);
    392     if (contentsTextureManager()->currentMemoryUseBytes() >= preferredLimitBytes)
     425    m_contentsTextureManager->reduceMemoryToLimit(preferredLimitBytes);
     426    if (m_contentsTextureManager->currentMemoryUseBytes() >= preferredLimitBytes)
    393427        return;
    394428
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h

    r106601 r106700  
    155155    const LayerRendererCapabilities& layerRendererCapabilities() const;
    156156
    157     // Test-only hook
     157    // Test only hook
    158158    void loseCompositorContext(int numTimes);
    159159
     
    202202    typedef Vector<OwnPtr<ManagedTexture> > TextureList;
    203203
     204    void initializeLayerRenderer();
     205
    204206    enum PaintType { PaintVisible, PaintIdle };
    205207    static void paintContentsIfDirty(LayerChromium*, PaintType, const Region& occludedScreenSpace);
     
    221223
    222224    OwnPtr<CCProxy> m_proxy;
     225    bool m_layerRendererInitialized;
    223226
    224227    RefPtr<LayerChromium> m_rootLayer;
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp

    r106607 r106700  
    286286bool CCLayerTreeHostImpl::isContextLost()
    287287{
    288     ASSERT(m_layerRenderer);
    289     return m_layerRenderer->isContextLost();
     288    return m_layerRenderer && m_layerRenderer->isContextLost();
    290289}
    291290
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h

    r106601 r106700  
    6262    virtual bool isStarted() const = 0;
    6363
     64    // Attempts to initialize a context to use for rendering. Returns false if the context could not be created.
     65    // The context will not be used and no frames may be produced until initializeLayerRenderer() is called.
     66    virtual bool initializeContext() = 0;
     67
     68    // Attempts to initialize the layer renderer. Returns false if the context isn't usable for compositing.
    6469    virtual bool initializeLayerRenderer() = 0;
    6570
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp

    r100984 r106700  
    4646    : m_layerTreeHost(layerTreeHost)
    4747    , m_compositorIdentifier(-1)
     48    , m_layerRendererInitialized(false)
    4849    , m_numFailedRecreateAttempts(0)
    4950    , m_graphicsContextLost(false)
     
    7071bool CCSingleThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
    7172{
    72     ASSERT(CCProxy::isMainThread());
    73 
    74     if (!recreateContextIfNeeded())
    75         return false;
     73    TRACE_EVENT("CCSingleThreadProxy::compositeAndReadback", this, 0);
     74    ASSERT(CCProxy::isMainThread());
     75
     76    if (!recreateContextIfNeeded()) {
     77        TRACE_EVENT("compositeAndReadback_EarlyOut_ContextLost", this, 0);
     78        return false;
     79    }
    7680
    7781    commitIfNeeded();
     
    110114}
    111115
    112 bool CCSingleThreadProxy::initializeLayerRenderer()
     116bool CCSingleThreadProxy::initializeContext()
    113117{
    114118    ASSERT(CCProxy::isMainThread());
     
    117121        return false;
    118122    ASSERT(context->hasOneRef());
    119 
    120     {
    121         DebugScopedSetImplThread impl;
    122         bool ok = m_layerTreeHostImpl->initializeLayerRenderer(context);
    123         if (ok)
     123    m_contextBeforeInitialization = context;
     124    return true;
     125}
     126
     127bool CCSingleThreadProxy::initializeLayerRenderer()
     128{
     129    ASSERT(CCProxy::isMainThread());
     130    ASSERT(m_contextBeforeInitialization);
     131    {
     132        DebugScopedSetImplThread impl;
     133        bool ok = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitialization.release());
     134        if (ok) {
     135            m_layerRendererInitialized = true;
    124136            m_layerRendererCapabilitiesForMainThread = m_layerTreeHostImpl->layerRendererCapabilities();
     137        }
    125138        return ok;
    126139    }
     
    129142const LayerRendererCapabilities& CCSingleThreadProxy::layerRendererCapabilities() const
    130143{
     144    ASSERT(m_layerRendererInitialized);
    131145    // Note: this gets called during the commit by the "impl" thread
    132146    return m_layerRendererCapabilitiesForMainThread;
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h

    r105583 r106700  
    4545    virtual void finishAllRendering();
    4646    virtual bool isStarted() const;
     47    virtual bool initializeContext();
    4748    virtual bool initializeLayerRenderer();
    4849    virtual int compositorIdentifier() const { return m_compositorIdentifier; }
     
    7677    int m_compositorIdentifier;
    7778
     79    // Holds on to the context between initializeContext() and initializeLayerRenderer() calls. Shouldn't
     80    // be used for anything else.
     81    RefPtr<GraphicsContext3D> m_contextBeforeInitialization;
     82
    7883    // Used on the CCThread, but checked on main thread during initialization/shutdown.
    7984    OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl;
     85    bool m_layerRendererInitialized;
    8086    LayerRendererCapabilities m_layerRendererCapabilitiesForMainThread;
    8187
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp

    r105961 r106700  
    6060    , m_layerTreeHost(layerTreeHost)
    6161    , m_compositorIdentifier(-1)
     62    , m_layerRendererInitialized(false)
    6263    , m_started(false)
    6364    , m_lastExecutedBeginFrameAndCommitSequenceNumber(-1)
     
    8586    ASSERT(isMainThread());
    8687    ASSERT(m_layerTreeHost);
     88
     89    if (!m_layerRendererInitialized) {
     90        TRACE_EVENT("compositeAndReadback_EarlyOut_LR_Uninitialized", this, 0);
     91        return false;
     92    }
    8793
    8894    // If a commit is pending, perform the commit first.
     
    147153}
    148154
    149 bool CCThreadProxy::initializeLayerRenderer()
    150 {
    151     TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0);
     155bool CCThreadProxy::initializeContext()
     156{
     157    TRACE_EVENT("CCThreadProxy::initializeContext", this, 0);
    152158    RefPtr<GraphicsContext3D> context = m_layerTreeHost->createLayerTreeHostContext3D();
    153159    if (!context)
     
    159165    ASSERT(contextPtr->hasOneRef());
    160166
     167    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeContextOnImplThread,
     168                                                       AllowCrossThreadAccess(contextPtr)));
     169    return true;
     170}
     171
     172bool CCThreadProxy::initializeLayerRenderer()
     173{
     174    TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0);
    161175    // Make a blocking call to initializeLayerRendererOnImplThread. The results of that call
    162176    // are pushed into the initializeSucceeded and capabilities local variables.
     
    165179    LayerRendererCapabilities capabilities;
    166180    CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnImplThread,
    167                                           AllowCrossThreadAccess(contextPtr), AllowCrossThreadAccess(&completion),
    168                                           AllowCrossThreadAccess(&initializeSucceeded), AllowCrossThreadAccess(&capabilities),
    169                                           AllowCrossThreadAccess(&m_compositorIdentifier)));
     181                                          AllowCrossThreadAccess(&completion),
     182                                          AllowCrossThreadAccess(&initializeSucceeded),
     183                                          AllowCrossThreadAccess(&capabilities)));
    170184    completion.wait();
    171185
    172     if (initializeSucceeded)
     186    if (initializeSucceeded) {
     187        m_layerRendererInitialized = true;
    173188        m_layerRendererCapabilitiesMainThreadCopy = capabilities;
     189    }
    174190    return initializeSucceeded;
    175191}
     
    183199const LayerRendererCapabilities& CCThreadProxy::layerRendererCapabilities() const
    184200{
     201    ASSERT(m_layerRendererInitialized);
    185202    return m_layerRendererCapabilitiesMainThreadCopy;
    186203}
     
    538555    m_schedulerOnImplThread = CCScheduler::create(this, frameRateController.release());
    539556    m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible());
     557
     558    m_inputHandlerOnImplThread = CCInputHandler::create(m_layerTreeHostImpl.get());
     559    m_compositorIdentifier = m_inputHandlerOnImplThread->identifier();
     560
    540561    completion->signal();
    541562}
    542563
    543 void CCThreadProxy::initializeLayerRendererOnImplThread(GraphicsContext3D* contextPtr, CCCompletionEvent* completion, bool* initializeSucceeded, LayerRendererCapabilities* capabilities, int* compositorIdentifier)
     564void CCThreadProxy::initializeContextOnImplThread(GraphicsContext3D* context)
     565{
     566    TRACE_EVENT("CCThreadProxy::initializeContextOnImplThread", this, 0);
     567    ASSERT(isImplThread());
     568    m_contextBeforeInitializationOnImplThread = adoptRef(context);
     569}
     570
     571void CCThreadProxy::initializeLayerRendererOnImplThread(CCCompletionEvent* completion, bool* initializeSucceeded, LayerRendererCapabilities* capabilities)
    544572{
    545573    TRACE_EVENT("CCThreadProxy::initializeLayerRendererOnImplThread", this, 0);
    546574    ASSERT(isImplThread());
    547     RefPtr<GraphicsContext3D> context(adoptRef(contextPtr));
    548     *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(context);
     575    ASSERT(m_contextBeforeInitializationOnImplThread);
     576    *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(m_contextBeforeInitializationOnImplThread.release());
    549577    if (*initializeSucceeded) {
    550578        *capabilities = m_layerTreeHostImpl->layerRendererCapabilities();
    551579        if (capabilities->usingSwapCompleteCallback)
    552580            m_schedulerOnImplThread->setMaxFramesPending(2);
    553 
    554         m_inputHandlerOnImplThread = CCInputHandler::create(m_layerTreeHostImpl.get());
    555         *compositorIdentifier = m_inputHandlerOnImplThread->identifier();
    556581    }
    557582
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h

    r105583 r106700  
    5353    virtual void finishAllRendering();
    5454    virtual bool isStarted() const;
     55    virtual bool initializeContext();
    5556    virtual bool initializeLayerRenderer();
    5657    virtual int compositorIdentifier() const;
     
    99100    void finishAllRenderingOnImplThread(CCCompletionEvent*);
    100101    void initializeImplOnImplThread(CCCompletionEvent*);
    101     void initializeLayerRendererOnImplThread(GraphicsContext3D*, CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*, int* compositorIdentifier);
     102    void initializeContextOnImplThread(GraphicsContext3D*);
     103    void initializeLayerRendererOnImplThread(CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*);
    102104    void setVisibleOnImplThread(CCCompletionEvent*, bool visible);
    103105    void layerTreeHostClosedOnImplThread(CCCompletionEvent*);
     
    108110    CCLayerTreeHost* m_layerTreeHost;
    109111    int m_compositorIdentifier;
     112    bool m_layerRendererInitialized;
    110113    LayerRendererCapabilities m_layerRendererCapabilitiesMainThreadCopy;
    111114    bool m_started;
     
    121124
    122125    RefPtr<CCScopedThreadProxy> m_mainThreadProxy;
     126
     127    // Holds on to the GraphicsContext3D we might use for compositing in between initializeContext()
     128    // and initializeLayerRenderer() calls.
     129    RefPtr<GraphicsContext3D> m_contextBeforeInitializationOnImplThread;
    123130
    124131    // Set when the main thread is waiing on a readback.
  • trunk/Source/WebKit/chromium/ChangeLog

    r106678 r106700  
     12012-02-03  James Robinson  <jamesr@chromium.org>
     2
     3        [chromium] Defer makeContextCurrent in compositor until first frame
     4        https://bugs.webkit.org/show_bug.cgi?id=77269
     5
     6        Reviewed by Kenneth Russell.
     7
     8        * tests/CCLayerTreeHostTest.cpp:
     9        (WTF::CCLayerTreeHostTestSetViewportSize::beginTest):
     10        * tests/TiledLayerChromiumTest.cpp:
     11        (WTF::TEST):
     12
    1132012-02-03  Beth Dakin  <bdakin@apple.com>
    214
  • trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp

    r106371 r106700  
    124124    WebKit::WebViewImpl* webViewImpl = chrome ? static_cast<WebKit::WebViewImpl*>(chrome->client()->webView()) : 0;
    125125
    126     if (threadUsage == ForUseOnThisThread && !webContext->makeContextCurrent())
    127         return 0;
    128 
    129126    OwnPtr<GraphicsContext3DPrivate> priv = GraphicsContext3DPrivate::create(webViewImpl, webContext, attrs);
    130127    if (!priv)
  • trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp

    r106383 r106700  
    11031103        IntSize viewportSize(10, 10);
    11041104        layerTreeHost()->setViewportSize(viewportSize);
     1105
     1106        layerTreeHost()->updateLayers();
     1107
    11051108        EXPECT_EQ(viewportSize, layerTreeHost()->viewportSize());
    11061109        EXPECT_EQ(TextureManager::highLimitBytes(viewportSize), layerTreeHost()->contentsTextureManager()->maxMemoryLimitBytes());
  • trunk/Source/WebKit/chromium/tests/FakeGraphicsContext3DTest.cpp

    r103293 r106700  
    102102
    103103
    104 TEST(FakeGraphicsContext3DTest, ContextForThisThreadShouldMakeCurrent)
     104TEST(FakeGraphicsContext3DTest, ContextForThisThreadShouldNotMakeCurrent)
    105105{
    106106    GraphicsContext3D::Attributes attrs;
     
    108108    EXPECT_TRUE(context);
    109109    ContextThatCountsMakeCurrents& mockContext = *static_cast<ContextThatCountsMakeCurrents*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
    110     EXPECT_EQ(1, mockContext.makeCurrentCount());
     110    EXPECT_EQ(0, mockContext.makeCurrentCount());
    111111}
    112112
     
    120120}
    121121
    122 class ContextWithMakeCurrentThatFails : public FakeWebGraphicsContext3D {
    123 public:
    124     ContextWithMakeCurrentThatFails() { }
    125     virtual bool makeContextCurrent() { return false; }
    126 };
    127 
    128 TEST(FakeGraphicsContext3DTest, ContextForThisThreadFailsWhenMakeCurrentFails)
    129 {
    130     GraphicsContext3D::Attributes attrs;
    131     RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ContextWithMakeCurrentThatFails()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
    132     EXPECT_FALSE(context);
    133 }
  • trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp

    r106383 r106700  
    163163    }
    164164
     165    virtual void createTextureUpdaterIfNeeded() { }
     166
    165167    RefPtr<FakeLayerTextureUpdater> m_fakeTextureUpdater;
    166168    TextureManager* m_textureManager;
     
    429431    IntRect contentRect(IntPoint::zero(), contentBounds);
    430432
    431     RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
    432     RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
     433    // We have enough memory for only one of the two layers.
     434    int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel.
     435    OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit, memoryLimit);
     436
     437    RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
     438    RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
    433439    rootLayer->addChild(childLayer);
    434440
     
    440446    childLayer->invalidateRect(contentRect);
    441447
    442     // We have enough memory for only one of the two layers.
    443     int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel.
    444 
    445448    FakeTextureAllocator textureAllocator;
    446449    CCTextureUpdater updater(&textureAllocator);
     
    448451    ccLayerTreeHost->setRootLayer(rootLayer);
    449452    ccLayerTreeHost->setViewportSize(IntSize(300, 300));
    450     ccLayerTreeHost->contentsTextureManager()->setMaxMemoryLimitBytes(memoryLimit);
     453    textureManager->setMaxMemoryLimitBytes(memoryLimit);
    451454    ccLayerTreeHost->updateLayers();
    452455    ccLayerTreeHost->updateCompositorResources(ccLayerTreeHost->context(), updater);
     
    461464    rootLayer->removeAllChildren();
    462465
    463     // Need to set the max limit again as it gets overwritten by updateLayers().
    464     ccLayerTreeHost->contentsTextureManager()->setMaxMemoryLimitBytes(memoryLimit);
    465466    ccLayerTreeHost->updateLayers();
    466467    EXPECT_FALSE(rootLayer->skipsDraw());
Note: See TracChangeset for help on using the changeset viewer.