Title: [94971] trunk/Source/WebKit/chromium
Revision
94971
Author
nd...@chromium.org
Date
2011-09-12 12:53:39 -0700 (Mon, 12 Sep 2011)

Log 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):

Modified Paths

Diff

Modified: trunk/Source/WebKit/chromium/ChangeLog (94970 => 94971)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-09-12 19:50:41 UTC (rev 94970)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-09-12 19:53:39 UTC (rev 94971)
@@ -1,3 +1,29 @@
+2011-09-08  Nat Duca  <nd...@chromium.org>
+
+        [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):
+
 2011-09-11  Jeremy Moskovich  <jer...@chromium.org>
 
         [Chromium] Change OOP Font loading code to use CGFont*() APIs.

Modified: trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h (94970 => 94971)


--- trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h	2011-09-12 19:50:41 UTC (rev 94970)
+++ trunk/Source/WebKit/chromium/public/WebGraphicsContext3D.h	2011-09-12 19:53:39 UTC (rev 94971)
@@ -70,7 +70,12 @@
 // GraphicsContext3D in order to implement WebGL. Nearly all of the
 // methods exposed on this interface map directly to entry points in
 // the OpenGL ES 2.0 API.
-
+//
+// Creating a WebGraphicsContext does not make it current, or guarantee
+// that the context has been created successfully. Use
+// makeContextCurrent() to complete initialization of the context, treating
+// a false return value as indication that the context could not be created
+// successfully.
 class WebGraphicsContext3D : public WebNonCopyable {
 public:
     // Return value from getActiveUniform and getActiveAttrib.

Modified: trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp (94970 => 94971)


--- trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp	2011-09-12 19:50:41 UTC (rev 94970)
+++ trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp	2011-09-12 19:53:39 UTC (rev 94971)
@@ -119,11 +119,14 @@
     return adoptPtr(new GraphicsContext3DPrivate(webViewImpl, webContext));
 }
 
-PassRefPtr<GraphicsContext3D> GraphicsContext3DPrivate::createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D> webContext, GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
+PassRefPtr<GraphicsContext3D> GraphicsContext3DPrivate::createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D> webContext, GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle, ThreadUsage threadUsage)
 {
     Chrome* chrome = static_cast<Chrome*>(hostWindow);
     WebKit::WebViewImpl* webViewImpl = chrome ? static_cast<WebKit::WebViewImpl*>(chrome->client()->webView()) : 0;
 
+    if (threadUsage == ForUseOnThisThread && !webContext->makeContextCurrent())
+        return 0;
+
     OwnPtr<GraphicsContext3DPrivate> priv = GraphicsContext3DPrivate::create(webViewImpl, webContext);
     if (!priv)
         return 0;
@@ -134,6 +137,41 @@
     return result.release();
 }
 
+namespace {
+
+PassRefPtr<GraphicsContext3D> createGraphicsContext(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle, GraphicsContext3DPrivate::ThreadUsage threadUsage)
+{
+    bool renderDirectlyToHostWindow = renderStyle == GraphicsContext3D::RenderDirectlyToHostWindow;
+
+    WebKit::WebGraphicsContext3D::Attributes webAttributes;
+    webAttributes.alpha = attrs.alpha;
+    webAttributes.depth = attrs.depth;
+    webAttributes.stencil = attrs.stencil;
+    webAttributes.antialias = attrs.antialias;
+    webAttributes.premultipliedAlpha = attrs.premultipliedAlpha;
+    webAttributes.canRecoverFromContextLoss = attrs.canRecoverFromContextLoss;
+    webAttributes.noExtensions = attrs.noExtensions;
+    webAttributes.shareResources = attrs.shareResources;
+    OwnPtr<WebKit::WebGraphicsContext3D> webContext = adoptPtr(WebKit::webKitPlatformSupport()->createGraphicsContext3D());
+    if (!webContext)
+        return 0;
+
+    Chrome* chrome = static_cast<Chrome*>(hostWindow);
+    WebKit::WebViewImpl* webViewImpl = chrome ? static_cast<WebKit::WebViewImpl*>(chrome->client()->webView()) : 0;
+
+    if (!webContext->initialize(webAttributes, webViewImpl, renderDirectlyToHostWindow))
+        return 0;
+
+    return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(webContext.release(), attrs, hostWindow, renderStyle, threadUsage);
+}
+
+} // anonymous namespace
+
+PassRefPtr<GraphicsContext3D> GraphicsContext3DPrivate::createGraphicsContextForAnotherThread(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
+{
+    return createGraphicsContext(attrs, hostWindow, renderStyle, ForUseOnAnotherThread);
+}
+
 WebKit::WebGraphicsContext3D* GraphicsContext3DPrivate::extractWebGraphicsContext3D(GraphicsContext3D* context)
 {
     if (!context)
@@ -985,28 +1023,7 @@
 
 PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
 {
-    bool renderDirectlyToHostWindow = renderStyle == RenderDirectlyToHostWindow;
-
-    WebKit::WebGraphicsContext3D::Attributes webAttributes;
-    webAttributes.alpha = attrs.alpha;
-    webAttributes.depth = attrs.depth;
-    webAttributes.stencil = attrs.stencil;
-    webAttributes.antialias = attrs.antialias;
-    webAttributes.premultipliedAlpha = attrs.premultipliedAlpha;
-    webAttributes.canRecoverFromContextLoss = attrs.canRecoverFromContextLoss;
-    webAttributes.noExtensions = attrs.noExtensions;
-    webAttributes.shareResources = attrs.shareResources;
-    OwnPtr<WebKit::WebGraphicsContext3D> webContext = adoptPtr(WebKit::webKitPlatformSupport()->createGraphicsContext3D());
-    if (!webContext)
-        return 0;
-
-    Chrome* chrome = static_cast<Chrome*>(hostWindow);
-    WebKit::WebViewImpl* webViewImpl = chrome ? static_cast<WebKit::WebViewImpl*>(chrome->client()->webView()) : 0;
-
-    if (!webContext->initialize(webAttributes, webViewImpl, renderDirectlyToHostWindow))
-        return 0;
-
-    return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(webContext.release(), attrs, hostWindow, renderStyle);
+    return createGraphicsContext(attrs, hostWindow, renderStyle, GraphicsContext3DPrivate::ForUseOnThisThread);
 }
 
 PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const

Modified: trunk/Source/WebKit/chromium/src/GraphicsContext3DPrivate.h (94970 => 94971)


--- trunk/Source/WebKit/chromium/src/GraphicsContext3DPrivate.h	2011-09-12 19:50:41 UTC (rev 94970)
+++ trunk/Source/WebKit/chromium/src/GraphicsContext3DPrivate.h	2011-09-12 19:53:39 UTC (rev 94971)
@@ -57,8 +57,20 @@
 public:
     static PassOwnPtr<GraphicsContext3DPrivate> create(WebKit::WebViewImpl*, PassOwnPtr<WebKit::WebGraphicsContext3D>);
 
+    enum ThreadUsage {
+        ForUseOnThisThread,
+        ForUseOnAnotherThread,
+    };
+
+    // createGraphicsContextForAnotherThread is equivalent to
+    // GraphicsContext3D::create, but will skip making the context
+    // current. Callers must make the context current before using it AND check
+    // that the context was created successfully via ContextLost. Once made
+    // current on a thread, the context cannot be used on any other thread.
+    static PassRefPtr<GraphicsContext3D> createGraphicsContextForAnotherThread(GraphicsContext3D::Attributes, HostWindow*, GraphicsContext3D::RenderStyle);
+
     // Used in tests to create a GraphicsContext3D from a mocked WebGraphicsContext3D.
-    static PassRefPtr<GraphicsContext3D> createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D>, GraphicsContext3D::Attributes, HostWindow*, GraphicsContext3D::RenderStyle);
+    static PassRefPtr<GraphicsContext3D> createGraphicsContextFromWebContext(PassOwnPtr<WebKit::WebGraphicsContext3D>, GraphicsContext3D::Attributes, HostWindow*, GraphicsContext3D::RenderStyle, ThreadUsage);
 
     ~GraphicsContext3DPrivate();
 

Modified: trunk/Source/WebKit/chromium/src/WebViewImpl.cpp (94970 => 94971)


--- trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2011-09-12 19:50:41 UTC (rev 94970)
+++ trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2011-09-12 19:53:39 UTC (rev 94971)
@@ -2683,7 +2683,11 @@
 {
     RefPtr<GraphicsContext3D> context = m_temporaryOnscreenGraphicsContext3D.release();
     if (!context) {
+#if USE(THREADED_COMPOSITING)
+        context = GraphicsContext3DPrivate::createGraphicsContextForAnotherThread(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
+#else
         context = GraphicsContext3D::create(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
+#endif
     }
     return context;
 }
@@ -2751,7 +2755,11 @@
             if (webContext && !webContext->isContextLost())
                 return webContext;
         }
+#if USE(THREADED_COMPOSITING)
+        m_temporaryOnscreenGraphicsContext3D = GraphicsContext3DPrivate::createGraphicsContextForAnotherThread(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
+#else
         m_temporaryOnscreenGraphicsContext3D = GraphicsContext3D::create(getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
+#endif
         return GraphicsContext3DPrivate::extractWebGraphicsContext3D(m_temporaryOnscreenGraphicsContext3D.get());
     }
 #endif

Modified: trunk/Source/WebKit/chromium/tests/MockGraphicsContext3DTest.cpp (94970 => 94971)


--- trunk/Source/WebKit/chromium/tests/MockGraphicsContext3DTest.cpp	2011-09-12 19:50:41 UTC (rev 94970)
+++ trunk/Source/WebKit/chromium/tests/MockGraphicsContext3DTest.cpp	2011-09-12 19:53:39 UTC (rev 94971)
@@ -53,10 +53,9 @@
 TEST(MockGraphicsContext3DTest, CanOverrideManually)
 {
     GraphicsContext3D::Attributes attrs;
-    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FrameCountingContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow);
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FrameCountingContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
     FrameCountingContext& mockContext = *static_cast<FrameCountingContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
 
-    context->makeContextCurrent();
     for (int i = 0; i < 10; i++) {
         context->clearColor(0, 0, 0, 1);
         context->prepareTexture();
@@ -75,7 +74,7 @@
 TEST(MockGraphicsContext3DTest, CanUseGMock)
 {
     GraphicsContext3D::Attributes attrs;
-    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new GMockContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow);
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new GMockContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
     GMockContext& mockContext = *static_cast<GMockContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
 
     EXPECT_CALL(mockContext, getError())
@@ -88,3 +87,48 @@
     for (int i = 0; i < 10; i++)
         EXPECT_EQ((int)context->getError(), 314);
 }
+
+class ContextThatCountsMakeCurrents : public MockWebGraphicsContext3D {
+public:
+    ContextThatCountsMakeCurrents() : m_makeCurrentCount(0) { }
+    virtual bool makeContextCurrent()
+    {
+        m_makeCurrentCount++;
+        return true;
+    }
+    int makeCurrentCount() { return m_makeCurrentCount; }
+private:
+    int m_makeCurrentCount;
+};
+
+
+TEST(MockGraphicsContext3DTest, ContextForThisThreadShouldMakeCurrent)
+{
+    GraphicsContext3D::Attributes attrs;
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ContextThatCountsMakeCurrents()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
+    EXPECT_TRUE(context);
+    ContextThatCountsMakeCurrents& mockContext = *static_cast<ContextThatCountsMakeCurrents*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
+    EXPECT_EQ(1, mockContext.makeCurrentCount());
+}
+
+TEST(MockGraphicsContext3DTest, ContextForAnotherThreadShouldNotMakeCurrent)
+{
+    GraphicsContext3D::Attributes attrs;
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ContextThatCountsMakeCurrents()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnAnotherThread);
+    EXPECT_TRUE(context);
+    ContextThatCountsMakeCurrents& mockContext = *static_cast<ContextThatCountsMakeCurrents*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(context.get()));
+    EXPECT_EQ(0, mockContext.makeCurrentCount());
+}
+
+class ContextWithMakeCurrentThatFails : public MockWebGraphicsContext3D {
+public:
+    ContextWithMakeCurrentThatFails() { }
+    virtual bool makeContextCurrent() { return false; }
+};
+
+TEST(MockGraphicsContext3DTest, ContextForThisThreadFailsWhenMakeCurrentFails)
+{
+    GraphicsContext3D::Attributes attrs;
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ContextWithMakeCurrentThatFails()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
+    EXPECT_FALSE(context);
+}

Modified: trunk/Source/WebKit/chromium/tests/MockWebGraphicsContext3D.h (94970 => 94971)


--- trunk/Source/WebKit/chromium/tests/MockWebGraphicsContext3D.h	2011-09-12 19:50:41 UTC (rev 94970)
+++ trunk/Source/WebKit/chromium/tests/MockWebGraphicsContext3D.h	2011-09-12 19:53:39 UTC (rev 94971)
@@ -36,7 +36,7 @@
 public:
     virtual bool initialize(Attributes, WebView*, bool renderDirectlyToWebView) { return false; }
 
-    virtual bool makeContextCurrent() { return false; }
+    virtual bool makeContextCurrent() { return true; }
 
     virtual int width() { return 0; }
     virtual int height() { return 0; }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to