Changeset 94971 in webkit


Ignore:
Timestamp:
Sep 12, 2011 12:53:39 PM (13 years ago)
Author:
nduca@chromium.org
Message:

[chromium] Add GraphicsContext3DPrivate:createGraphicsContextForAnotherThread
https://bugs.webkit.org/show_bug.cgi?id=67832

The compositor thread needs to create a GraphicsContext3D without
actually making it current. In previous attempts at doing this, we
modified all graphics3D creation to not make the contexts current, but
this prove to be shockingly fragile. Since this is a very
Chromium-specific behavior, this patch makes creationForAnotherThread a
method on the private GraphicsContext3D interface.
GraphicsContext3D::create behaves as usual.

Reviewed by Kenneth Russell.

  • src/GraphicsContext3DChromium.cpp:

(WebCore::GraphicsContext3DPrivate::createGraphicsContextFromWebContext):
(WebCore::GraphicsContext3DPrivate::createGraphicsContextForAnotherThread):
(WebCore::GraphicsContext3D::create):

  • src/GraphicsContext3DPrivate.h:
  • src/WebViewImpl.cpp:

(WebKit::WebViewImpl::createLayerTreeHostContext3D):
(WebKit::WebViewImpl::graphicsContext3D):

  • tests/MockGraphicsContext3DTest.cpp:

(TEST):

Location:
trunk/Source/WebKit/chromium
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/chromium/ChangeLog

    r94936 r94971  
     12011-09-08  Nat Duca  <nduca@chromium.org>
     2
     3        [chromium] Add GraphicsContext3DPrivate:createGraphicsContextForAnotherThread
     4        https://bugs.webkit.org/show_bug.cgi?id=67832
     5
     6        The compositor thread needs to create a GraphicsContext3D without
     7        actually making it current. In previous attempts at doing this, we
     8        modified all graphics3D creation to not make the contexts current, but
     9        this prove to be shockingly fragile. Since this is a very
     10        Chromium-specific behavior, this patch makes creationForAnotherThread a
     11        method on the private GraphicsContext3D interface.
     12        GraphicsContext3D::create behaves as usual.
     13
     14        Reviewed by Kenneth Russell.
     15
     16        * src/GraphicsContext3DChromium.cpp:
     17        (WebCore::GraphicsContext3DPrivate::createGraphicsContextFromWebContext):
     18        (WebCore::GraphicsContext3DPrivate::createGraphicsContextForAnotherThread):
     19        (WebCore::GraphicsContext3D::create):
     20        * src/GraphicsContext3DPrivate.h:
     21        * src/WebViewImpl.cpp:
     22        (WebKit::WebViewImpl::createLayerTreeHostContext3D):
     23        (WebKit::WebViewImpl::graphicsContext3D):
     24        * tests/MockGraphicsContext3DTest.cpp:
     25        (TEST):
     26
    1272011-09-11  Jeremy Moskovich  <jeremy@chromium.org>
    228
  • trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h

    r94359 r94971  
    7171// methods exposed on this interface map directly to entry points in
    7272// the OpenGL ES 2.0 API.
    73 
     73//
     74// Creating a WebGraphicsContext does not make it current, or guarantee
     75// that the context has been created successfully. Use
     76// makeContextCurrent() to complete initialization of the context, treating
     77// a false return value as indication that the context could not be created
     78// successfully.
    7479class WebGraphicsContext3D : public WebNonCopyable {
    7580public:
  • trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp

    r94359 r94971  
    120120}
    121121
    122 PassRefPtr<GraphicsContext3D> GraphicsContext3DPrivate::createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D> webContext, GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
     122PassRefPtr<GraphicsContext3D> GraphicsContext3DPrivate::createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D> webContext, GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle, ThreadUsage threadUsage)
    123123{
    124124    Chrome* chrome = static_cast<Chrome*>(hostWindow);
    125125    WebKit::WebViewImpl* webViewImpl = chrome ? static_cast<WebKit::WebViewImpl*>(chrome->client()->webView()) : 0;
     126
     127    if (threadUsage == ForUseOnThisThread && !webContext->makeContextCurrent())
     128        return 0;
    126129
    127130    OwnPtr<GraphicsContext3DPrivate> priv = GraphicsContext3DPrivate::create(webViewImpl, webContext);
     
    133136    result->m_private = priv.release();
    134137    return result.release();
     138}
     139
     140namespace {
     141
     142PassRefPtr<GraphicsContext3D> createGraphicsContext(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle, GraphicsContext3DPrivate::ThreadUsage threadUsage)
     143{
     144    bool renderDirectlyToHostWindow = renderStyle == GraphicsContext3D::RenderDirectlyToHostWindow;
     145
     146    WebKit::WebGraphicsContext3D::Attributes webAttributes;
     147    webAttributes.alpha = attrs.alpha;
     148    webAttributes.depth = attrs.depth;
     149    webAttributes.stencil = attrs.stencil;
     150    webAttributes.antialias = attrs.antialias;
     151    webAttributes.premultipliedAlpha = attrs.premultipliedAlpha;
     152    webAttributes.canRecoverFromContextLoss = attrs.canRecoverFromContextLoss;
     153    webAttributes.noExtensions = attrs.noExtensions;
     154    webAttributes.shareResources = attrs.shareResources;
     155    OwnPtr<WebKit::WebGraphicsContext3D> webContext = adoptPtr(WebKit::webKitPlatformSupport()->createGraphicsContext3D());
     156    if (!webContext)
     157        return 0;
     158
     159    Chrome* chrome = static_cast<Chrome*>(hostWindow);
     160    WebKit::WebViewImpl* webViewImpl = chrome ? static_cast<WebKit::WebViewImpl*>(chrome->client()->webView()) : 0;
     161
     162    if (!webContext->initialize(webAttributes, webViewImpl, renderDirectlyToHostWindow))
     163        return 0;
     164
     165    return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(webContext.release(), attrs, hostWindow, renderStyle, threadUsage);
     166}
     167
     168} // anonymous namespace
     169
     170PassRefPtr<GraphicsContext3D> GraphicsContext3DPrivate::createGraphicsContextForAnotherThread(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
     171{
     172    return createGraphicsContext(attrs, hostWindow, renderStyle, ForUseOnAnotherThread);
    135173}
    136174
     
    9861024PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
    9871025{
    988     bool renderDirectlyToHostWindow = renderStyle == RenderDirectlyToHostWindow;
    989 
    990     WebKit::WebGraphicsContext3D::Attributes webAttributes;
    991     webAttributes.alpha = attrs.alpha;
    992     webAttributes.depth = attrs.depth;
    993     webAttributes.stencil = attrs.stencil;
    994     webAttributes.antialias = attrs.antialias;
    995     webAttributes.premultipliedAlpha = attrs.premultipliedAlpha;
    996     webAttributes.canRecoverFromContextLoss = attrs.canRecoverFromContextLoss;
    997     webAttributes.noExtensions = attrs.noExtensions;
    998     webAttributes.shareResources = attrs.shareResources;
    999     OwnPtr<WebKit::WebGraphicsContext3D> webContext = adoptPtr(WebKit::webKitPlatformSupport()->createGraphicsContext3D());
    1000     if (!webContext)
    1001         return 0;
    1002 
    1003     Chrome* chrome = static_cast<Chrome*>(hostWindow);
    1004     WebKit::WebViewImpl* webViewImpl = chrome ? static_cast<WebKit::WebViewImpl*>(chrome->client()->webView()) : 0;
    1005 
    1006     if (!webContext->initialize(webAttributes, webViewImpl, renderDirectlyToHostWindow))
    1007         return 0;
    1008 
    1009     return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(webContext.release(), attrs, hostWindow, renderStyle);
     1026    return createGraphicsContext(attrs, hostWindow, renderStyle, GraphicsContext3DPrivate::ForUseOnThisThread);
    10101027}
    10111028
  • trunk/Source/WebKit/chromium/src/GraphicsContext3DPrivate.h

    r94106 r94971  
    5858    static PassOwnPtr<GraphicsContext3DPrivate> create(WebKit::WebViewImpl*, PassOwnPtr<WebKit::WebGraphicsContext3D>);
    5959
     60    enum ThreadUsage {
     61        ForUseOnThisThread,
     62        ForUseOnAnotherThread,
     63    };
     64
     65    // createGraphicsContextForAnotherThread is equivalent to
     66    // GraphicsContext3D::create, but will skip making the context
     67    // current. Callers must make the context current before using it AND check
     68    // that the context was created successfully via ContextLost. Once made
     69    // current on a thread, the context cannot be used on any other thread.
     70    static PassRefPtr<GraphicsContext3D> createGraphicsContextForAnotherThread(GraphicsContext3D::Attributes, HostWindow*, GraphicsContext3D::RenderStyle);
     71
    6072    // Used in tests to create a GraphicsContext3D from a mocked WebGraphicsContext3D.
    61     static PassRefPtr<GraphicsContext3D> createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D>, GraphicsContext3D::Attributes, HostWindow*, GraphicsContext3D::RenderStyle);
     73    static PassRefPtr<GraphicsContext3D> createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D>, GraphicsContext3D::Attributes, HostWindow*, GraphicsContext3D::RenderStyle, ThreadUsage);
    6274
    6375    ~GraphicsContext3DPrivate();
  • trunk/Source/WebKit/chromium/src/WebViewImpl.cpp

    r94889 r94971  
    26842684    RefPtr<GraphicsContext3D> context = m_temporaryOnscreenGraphicsContext3D.release();
    26852685    if (!context) {
     2686#if USE(THREADED_COMPOSITING)
     2687        context = GraphicsContext3DPrivate::createGraphicsContextForAnotherThread(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
     2688#else
    26862689        context = GraphicsContext3D::create(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
     2690#endif
    26872691    }
    26882692    return context;
     
    27522756                return webContext;
    27532757        }
     2758#if USE(THREADED_COMPOSITING)
     2759        m_temporaryOnscreenGraphicsContext3D = GraphicsContext3DPrivate::createGraphicsContextForAnotherThread(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
     2760#else
    27542761        m_temporaryOnscreenGraphicsContext3D = GraphicsContext3D::create(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
     2762#endif
    27552763        return GraphicsContext3DPrivate::extractWebGraphicsContext3D(m_temporaryOnscreenGraphicsContext3D.get());
    27562764    }
  • trunk/Source/WebKit/chromium/tests/MockGraphicsContext3DTest.cpp

    r94106 r94971  
    5454{
    5555    GraphicsContext3D::Attributes attrs;
    56     RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FrameCountingContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow);
     56    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FrameCountingContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
    5757    FrameCountingContext& mockContext = *static_cast<FrameCountingContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
    5858
    59     context->makeContextCurrent();
    6059    for (int i = 0; i < 10; i++) {
    6160        context->clearColor(0, 0, 0, 1);
     
    7675{
    7776    GraphicsContext3D::Attributes attrs;
    78     RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new GMockContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow);
     77    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new GMockContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
    7978    GMockContext& mockContext = *static_cast<GMockContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
    8079
     
    8988        EXPECT_EQ((int)context->getError(), 314);
    9089}
     90
     91class ContextThatCountsMakeCurrents : public MockWebGraphicsContext3D {
     92public:
     93    ContextThatCountsMakeCurrents() : m_makeCurrentCount(0) { }
     94    virtual bool makeContextCurrent()
     95    {
     96        m_makeCurrentCount++;
     97        return true;
     98    }
     99    int makeCurrentCount() { return m_makeCurrentCount; }
     100private:
     101    int m_makeCurrentCount;
     102};
     103
     104
     105TEST(MockGraphicsContext3DTest, ContextForThisThreadShouldMakeCurrent)
     106{
     107    GraphicsContext3D::Attributes attrs;
     108    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ContextThatCountsMakeCurrents()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
     109    EXPECT_TRUE(context);
     110    ContextThatCountsMakeCurrents& mockContext = *static_cast<ContextThatCountsMakeCurrents*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
     111    EXPECT_EQ(1, mockContext.makeCurrentCount());
     112}
     113
     114TEST(MockGraphicsContext3DTest, ContextForAnotherThreadShouldNotMakeCurrent)
     115{
     116    GraphicsContext3D::Attributes attrs;
     117    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ContextThatCountsMakeCurrents()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnAnotherThread);
     118    EXPECT_TRUE(context);
     119    ContextThatCountsMakeCurrents& mockContext = *static_cast<ContextThatCountsMakeCurrents*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
     120    EXPECT_EQ(0, mockContext.makeCurrentCount());
     121}
     122
     123class ContextWithMakeCurrentThatFails : public MockWebGraphicsContext3D {
     124public:
     125    ContextWithMakeCurrentThatFails() { }
     126    virtual bool makeContextCurrent() { return false; }
     127};
     128
     129TEST(MockGraphicsContext3DTest, ContextForThisThreadFailsWhenMakeCurrentFails)
     130{
     131    GraphicsContext3D::Attributes attrs;
     132    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ContextWithMakeCurrentThatFails()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
     133    EXPECT_FALSE(context);
     134}
  • trunk/Source/WebKit/chromium/tests/MockWebGraphicsContext3D.h

    r93928 r94971  
    3737    virtual bool initialize(Attributes, WebView*, bool renderDirectlyToWebView) { return false; }
    3838
    39     virtual bool makeContextCurrent() { return false; }
     39    virtual bool makeContextCurrent() { return true; }
    4040
    4141    virtual int width() { return 0; }
Note: See TracChangeset for help on using the changeset viewer.