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; }