Changeset 112187 in webkit


Ignore:
Timestamp:
Mar 26, 2012 6:31:50 PM (12 years ago)
Author:
senorblanco@chromium.org
Message:

Make filters and the threaded compositor play well together.
https://bugs.webkit.org/show_bug.cgi?id=78139

Use a dedicated GraphicsContext3D instance for all filters calls in
the threaded case. Clone all FilterOperations for thread safety
in the threaded case.

Reviewed by James Robinson.

Covered by tests in LayoutTests/css3/filters.

  • platform/graphics/chromium/LayerChromium.cpp:

(WebCore::LayerChromium::setFilters):
Set a global flag if we've seen content with filters, so we know
we need to create the filter context.
(WebCore::LayerChromium::pushPropertiesTo):
Clone all filter operations if we're in the threaded case.

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

(WebCore):

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

(WebCore::CCLayerTreeHost::needsFilterContext):
(WebCore::CCLayerTreeHost::setNeedsFilterContext):
(CCLayerTreeHost):
Add flag and accessors for needsFilterContext.

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

(WebCore::CCRenderSurface::applyFilters):
Pick up the appropriate context from SharedGraphicsContext3D,
depending if we're in the threaded case or not.

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

(WebCore::CCThreadProxy::recreateContext):
For the threaded compositor re-create the filter context
alongside the main compositor context on lost context, if requested.
(WebCore::CCThreadProxy::beginFrame):
Create the filter context in beginFrame, if it was resquested and is
NULL. This handles the first-use case.

  • platform/graphics/filters/CustomFilterOperation.h:

(WebCore::CustomFilterOperation::clone):
Assert if trying to clone the custom filter operation (it has
non-threadsafe members).

  • platform/graphics/filters/FilterOperation.h:

(WebCore::DefaultFilterOperation::clone):
(WebCore::PassthroughFilterOperation::clone):
(WebCore::ReferenceFilterOperation::clone):
(WebCore::BasicColorMatrixFilterOperation::clone):
(WebCore::BasicComponentTransferFilterOperation::clone):
(WebCore::GammaFilterOperation::clone):
(WebCore::BlurFilterOperation::clone):
(WebCore::DropShadowFilterOperation::clone):
Add clone methods for all FilterOperations.

  • platform/graphics/gpu/SharedGraphicsContext3D.cpp:

(WebCore::SharedGraphicsContext3DImpl::getOrCreateContext):
(WebCore::SharedGraphicsContext3DImpl::getContext):
(WebCore::SharedGraphicsContext3DImpl::createContext):
(WebCore::SharedGraphicsContext3D::get):
(WebCore::getOrCreateContextForImplThread):
(WebCore::SharedGraphicsContext3D::getForImplThread):
(WebCore::SharedGraphicsContext3D::haveForImplThread):
(WebCore::SharedGraphicsContext3D::createForImplThread):
Split out context creation, lost context recovery, and retrieval
into separate functions, so the impl thread can use only the parts
it wants on the threads it wants (create and have on main, get on impl).
Add asserts to ensure that's how they're called.

  • platform/graphics/gpu/SharedGraphicsContext3D.h:

(SharedGraphicsContext3D):
Reuse the SharedGraphicsContext infrastructure to create a new
context singleton for filter use in the threaded compositor.

Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r112184 r112187  
     12012-03-26  Stephen White  <senorblanco@chromium.org>
     2
     3        Make filters and the threaded compositor play well together.
     4        https://bugs.webkit.org/show_bug.cgi?id=78139
     5       
     6        Use a dedicated GraphicsContext3D instance for all filters calls in
     7        the threaded case.  Clone all FilterOperations for thread safety
     8        in the threaded case.
     9
     10        Reviewed by James Robinson.
     11       
     12        Covered by tests in LayoutTests/css3/filters.
     13
     14        * platform/graphics/chromium/LayerChromium.cpp:
     15        (WebCore::LayerChromium::setFilters):
     16        Set a global flag if we've seen content with filters, so we know
     17        we need to create the filter context.
     18        (WebCore::LayerChromium::pushPropertiesTo):
     19        Clone all filter operations if we're in the threaded case.
     20        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
     21        (WebCore):
     22        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
     23        (WebCore::CCLayerTreeHost::needsFilterContext):
     24        (WebCore::CCLayerTreeHost::setNeedsFilterContext):
     25        (CCLayerTreeHost):
     26        Add flag and accessors for needsFilterContext.
     27        * platform/graphics/chromium/cc/CCRenderSurface.cpp:
     28        (WebCore::CCRenderSurface::applyFilters):
     29        Pick up the appropriate context from SharedGraphicsContext3D,
     30        depending if we're in the threaded case or not.
     31        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
     32        (WebCore::CCThreadProxy::recreateContext):
     33        For the threaded compositor re-create the filter context
     34        alongside the main compositor context on lost context, if requested.
     35        (WebCore::CCThreadProxy::beginFrame):
     36        Create the filter context in beginFrame, if it was resquested and is
     37        NULL.  This handles the first-use case.
     38        * platform/graphics/filters/CustomFilterOperation.h:
     39        (WebCore::CustomFilterOperation::clone):
     40        Assert if trying to clone the custom filter operation (it has
     41        non-threadsafe members).
     42        * platform/graphics/filters/FilterOperation.h:
     43        (WebCore::DefaultFilterOperation::clone):
     44        (WebCore::PassthroughFilterOperation::clone):
     45        (WebCore::ReferenceFilterOperation::clone):
     46        (WebCore::BasicColorMatrixFilterOperation::clone):
     47        (WebCore::BasicComponentTransferFilterOperation::clone):
     48        (WebCore::GammaFilterOperation::clone):
     49        (WebCore::BlurFilterOperation::clone):
     50        (WebCore::DropShadowFilterOperation::clone):
     51        Add clone methods for all FilterOperations.
     52        * platform/graphics/gpu/SharedGraphicsContext3D.cpp:
     53        (WebCore::SharedGraphicsContext3DImpl::getOrCreateContext):
     54        (WebCore::SharedGraphicsContext3DImpl::getContext):
     55        (WebCore::SharedGraphicsContext3DImpl::createContext):
     56        (WebCore::SharedGraphicsContext3D::get):
     57        (WebCore::getOrCreateContextForImplThread):
     58        (WebCore::SharedGraphicsContext3D::getForImplThread):
     59        (WebCore::SharedGraphicsContext3D::haveForImplThread):
     60        (WebCore::SharedGraphicsContext3D::createForImplThread):
     61        Split out context creation, lost context recovery, and retrieval
     62        into separate functions, so the impl thread can use only the parts
     63        it wants on the threads it wants (create and have on main, get on impl).
     64        Add asserts to ensure that's how they're called.
     65        * platform/graphics/gpu/SharedGraphicsContext3D.h:
     66        (SharedGraphicsContext3D):
     67        Reuse the SharedGraphicsContext infrastructure to create a new
     68        context singleton for filter use in the threaded compositor.
     69
    1702012-03-26  Adam Barth  <abarth@webkit.org>
    271
  • trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp

    r111963 r112187  
    319319    m_filters = filters;
    320320    setNeedsCommit();
     321    CCLayerTreeHost::setNeedsFilterContext();
    321322}
    322323
     
    460461    layer->setDoubleSided(m_doubleSided);
    461462    layer->setDrawsContent(drawsContent());
     463    if (CCProxy::hasImplThread()) {
     464        // Since FilterOperations contains a vector of RefPtrs, we must deep copy the filters.
     465        FilterOperations filtersCopy;
     466        for (unsigned i = 0; i < m_filters.size(); ++i) {
     467            RefPtr<FilterOperation> clone = m_filters.at(i)->clone();
     468            if (clone)
     469                filtersCopy.operations().append(clone);
     470        }
     471        layer->setFilters(filtersCopy);
     472    } else
     473        layer->setFilters(filters());
     474
    462475    layer->setFilters(filters());
    463476    layer->setIsNonCompositedContent(m_isNonCompositedContent);
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp

    r112159 r112187  
    5050namespace WebCore {
    5151
     52bool CCLayerTreeHost::s_needsFilterContext = false;
     53
    5254bool CCLayerTreeHost::anyLayerTreeHostInstanceExists()
    5355{
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h

    r112059 r112187  
    130130    static bool anyLayerTreeHostInstanceExists();
    131131
     132    static bool needsFilterContext() { return s_needsFilterContext; }
     133    static void setNeedsFilterContext() { s_needsFilterContext = true; }
     134
    132135    // CCLayerTreeHost interface to CCProxy.
    133136    void willBeginFrame() { m_client->willBeginFrame(); }
     
    269272    TextureList m_deleteTextureAfterCommitList;
    270273    size_t m_partialTextureUpdateRequests;
     274    static bool s_needsFilterContext;
    271275};
    272276
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp

    r111909 r112187  
    224224SkBitmap CCRenderSurface::applyFilters(LayerRendererChromium* layerRenderer)
    225225{
    226     // Don't use the utility context if we have a compositor thread, since
    227     // it can race with canvas's use.
    228     if (!m_contentsTexture || !m_filters.size() || CCProxy::hasImplThread())
     226    if (!m_contentsTexture || !m_filters.size())
    229227        return SkBitmap();
    230228
     229    RefPtr<GraphicsContext3D> filterContext = CCProxy::hasImplThread() ? SharedGraphicsContext3D::getForImplThread() : SharedGraphicsContext3D::get();
     230    if (!filterContext)
     231        return SkBitmap();
     232
    231233    layerRenderer->context()->flush();
    232     return CCRenderSurfaceFilters::apply(m_filters, m_contentsTexture->textureId(), m_contentRect.size(), SharedGraphicsContext3D::get().get());
     234
     235    return CCRenderSurfaceFilters::apply(m_filters, m_contentsTexture->textureId(), m_contentRect.size(), filterContext.get());
    233236}
    234237
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp

    r112059 r112187  
    2828
    2929#include "GraphicsContext3D.h"
     30#include "SharedGraphicsContext3D.h"
    3031#include "TraceEvent.h"
    3132#include "cc/CCDelayBasedTimeSource.h"
     
    210211    if (!context)
    211212        return false;
     213    if (CCLayerTreeHost::needsFilterContext())
     214        if (!SharedGraphicsContext3D::createForImplThread())
     215            return false;
     216
    212217    ASSERT(context->hasOneRef());
    213218
     
    423428    }
    424429
     430    if (CCLayerTreeHost::needsFilterContext() && !SharedGraphicsContext3D::haveForImplThread())
     431        SharedGraphicsContext3D::createForImplThread();
     432
    425433    OwnPtr<BeginFrameAndCommitState> request(m_pendingBeginFrameRequest.release());
    426434
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h

    r108952 r112187  
    6363    }
    6464   
     65    virtual PassRefPtr<FilterOperation> clone() const
     66    {
     67        // Some member vars (e.g., m_program) are not thread-safe, so
     68        // we can't be cloned.
     69        return 0;
     70    }
     71   
    6572    CustomFilterProgram* program() const { return m_program.get(); }
    6673   
  • trunk/Source/WebCore/platform/graphics/filters/FilterOperation.h

    r108674 r112187  
    8383    virtual bool movesPixels() const { return false; }
    8484
     85    virtual PassRefPtr<FilterOperation> clone() const = 0;
     86
    8587protected:
    8688    FilterOperation(OperationType type)
     
    99101    }
    100102
     103    virtual PassRefPtr<FilterOperation> clone() const
     104    {
     105        return adoptRef(new DefaultFilterOperation(m_type));
     106    }
     107
    101108private:
    102109
     
    117124public:
    118125    static PassRefPtr<PassthroughFilterOperation> create()
     126    {
     127        return adoptRef(new PassthroughFilterOperation());
     128    }
     129
     130    virtual PassRefPtr<FilterOperation> clone() const
    119131    {
    120132        return adoptRef(new PassthroughFilterOperation());
     
    139151    {
    140152        return adoptRef(new ReferenceFilterOperation(reference, type));
     153    }
     154
     155    virtual PassRefPtr<FilterOperation> clone() const
     156    {
     157        // AtomicString is thread-hostile, so we can't be cloned.
     158        return 0;
    141159    }
    142160
     
    172190    {
    173191        return adoptRef(new BasicColorMatrixFilterOperation(amount, type));
     192    }
     193
     194    virtual PassRefPtr<FilterOperation> clone() const
     195    {
     196        return adoptRef(new BasicColorMatrixFilterOperation(m_amount, m_type));
    174197    }
    175198
     
    206229    }
    207230
     231    virtual PassRefPtr<FilterOperation> clone() const
     232    {
     233        return adoptRef(new BasicComponentTransferFilterOperation(m_amount, m_type));
     234    }
     235
    208236    double amount() const { return m_amount; }
    209237
     
    237265    {
    238266        return adoptRef(new GammaFilterOperation(amplitude, exponent, offset, type));
     267    }
     268
     269    virtual PassRefPtr<FilterOperation> clone() const
     270    {
     271        return adoptRef(new GammaFilterOperation(m_amplitude, m_exponent, m_offset, m_type));
    239272    }
    240273
     
    274307    }
    275308
     309    virtual PassRefPtr<FilterOperation> clone() const
     310    {
     311        return adoptRef(new BlurFilterOperation(m_stdDeviation, m_type));
     312    }
     313
    276314    Length stdDeviation() const { return m_stdDeviation; }
    277315
     
    304342    {
    305343        return adoptRef(new DropShadowFilterOperation(x, y, stdDeviation, color, type));
     344    }
     345
     346    virtual PassRefPtr<FilterOperation> clone() const
     347    {
     348        return adoptRef(new DropShadowFilterOperation(m_x, m_y, m_stdDeviation, m_color, m_type));
    306349    }
    307350
  • trunk/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp

    r110757 r112187  
    2929#include "SharedGraphicsContext3D.h"
    3030#include "Extensions3D.h"
     31#include "cc/CCProxy.h"
    3132
    3233namespace WebCore {
     
    3536public:
    3637    SharedGraphicsContext3DImpl() : m_context(0) { }
    37     PassRefPtr<GraphicsContext3D> get()
     38    PassRefPtr<GraphicsContext3D> getOrCreateContext()
    3839    {
    3940        // If we lost the context, or can't make it current, create a new one.
     
    4142            m_context.clear();
    4243
    43         if (!m_context) {
    44             GraphicsContext3D::Attributes attributes;
    45             attributes.depth = false;
    46             attributes.stencil = true;
    47             attributes.antialias = false;
    48             attributes.shareResources = true;
    49             attributes.preferDiscreteGPU = true;
    50             m_context = GraphicsContext3D::create(attributes, 0);
    51         }
     44        if (!m_context)
     45            createContext();
    5246
    5347        if (m_context && !m_context->makeContextCurrent())
    5448            m_context.clear();
    5549
     50        return m_context;
     51    }
     52
     53    PassRefPtr<GraphicsContext3D> getContext()
     54    {
     55        return m_context;
     56    }
     57
     58    PassRefPtr<GraphicsContext3D> createContext()
     59    {
     60        GraphicsContext3D::Attributes attributes;
     61        attributes.depth = false;
     62        attributes.stencil = true;
     63        attributes.antialias = false;
     64        attributes.shareResources = true;
     65        attributes.preferDiscreteGPU = true;
     66        m_context = GraphicsContext3D::create(attributes, 0);
    5667        return m_context;
    5768    }
     
    6374{
    6475    DEFINE_STATIC_LOCAL(SharedGraphicsContext3DImpl, impl, ());
    65     return impl.get();
     76    return impl.getOrCreateContext();
     77}
     78
     79enum ContextOperation {
     80    Get, Create
     81};
     82
     83static PassRefPtr<GraphicsContext3D> getOrCreateContextForImplThread(ContextOperation op)
     84{
     85    DEFINE_STATIC_LOCAL(SharedGraphicsContext3DImpl, impl, ());
     86    return op == Create ? impl.createContext() : impl.getContext();
     87}
     88
     89PassRefPtr<GraphicsContext3D> SharedGraphicsContext3D::getForImplThread()
     90{
     91    ASSERT(CCProxy::isImplThread());
     92    return getOrCreateContextForImplThread(Get);
     93}
     94
     95bool SharedGraphicsContext3D::haveForImplThread()
     96{
     97    ASSERT(CCProxy::isMainThread());
     98    return getOrCreateContextForImplThread(Get);
     99}
     100
     101bool SharedGraphicsContext3D::createForImplThread()
     102{
     103    ASSERT(CCProxy::isMainThread());
     104    return getOrCreateContextForImplThread(Create);
    66105}
    67106
  • trunk/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h

    r110483 r112187  
    4141    // GPU is unavailable.
    4242    static PassRefPtr<GraphicsContext3D> get();
     43    // This one returns the context, and does not touch it or re-create it.
     44    // Should only be called on the impl thread.
     45    static PassRefPtr<GraphicsContext3D> getForImplThread();
     46    // This one returns if the threaded utility context exists.
     47    // Should only be called on the main thread.
     48    static bool haveForImplThread();
     49    // This call creates the context unconditionally, but does not touch it.
     50    // Should only be called on the main thread.
     51    static bool createForImplThread();
    4352};
    4453
Note: See TracChangeset for help on using the changeset viewer.