Diff
Modified: trunk/LayoutTests/ChangeLog (139141 => 139142)
--- trunk/LayoutTests/ChangeLog 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/LayoutTests/ChangeLog 2013-01-09 02:21:57 UTC (rev 139142)
@@ -1,3 +1,14 @@
+2013-01-08 Brandon Jones <[email protected]>
+
+ Make WebGLRenderingContext inherit from ActiveDOMObject
+ https://bugs.webkit.org/show_bug.cgi?id=104733
+
+ Reviewed by Adam Barth.
+
+ * fast/canvas/webgl/context-release-upon-reload-expected.txt: Added.
+ * fast/canvas/webgl/context-release-upon-reload.html: Added.
+ * fast/canvas/webgl/resources/context-release-upon-reload-child.html: Added.
+
2013-01-08 Martin Robinson <[email protected]>
WebKitTestRunner needs support for setHandlesAuthenticationChallenges
Added: trunk/LayoutTests/fast/canvas/webgl/context-release-upon-reload-expected.txt (0 => 139142)
--- trunk/LayoutTests/fast/canvas/webgl/context-release-upon-reload-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/context-release-upon-reload-expected.txt 2013-01-09 02:21:57 UTC (rev 139142)
@@ -0,0 +1,59 @@
+
+This test ensures that WebGL contexts are released properly upon page reload
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Test 1 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 2 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 3 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 4 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 5 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 6 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 7 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 8 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 9 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+
+Test 10 of 10
+PASS context was created properly
+PASS getError was expected value: NO_ERROR : Should be no errors
+PASS Buffer was the correct size: 1680x1050
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/canvas/webgl/context-release-upon-reload.html (0 => 139142)
--- trunk/LayoutTests/fast/canvas/webgl/context-release-upon-reload.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/context-release-upon-reload.html 2013-01-09 02:21:57 UTC (rev 139142)
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL Context Release Test</title>
+<link rel="stylesheet" href=""
+<script src=""
+<script src=""
+</head>
+<body>
+<iframe id="host" style="width: 256px; height: 256px; border: 0;"></iframe>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("This test ensures that WebGL contexts are released properly upon page reload");
+
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
+var host = document.getElementById("host");
+var testIterations = 10;
+var currentIteration = 0;
+
+function refreshFrame() {
+ if(currentIteration < testIterations) {
+ currentIteration++;
+ debug("");
+ debug("Test " + currentIteration + " of " + testIterations);
+ host.src = ""
+ } else {
+ finishTest();
+ }
+}
+
+function testContext() {
+ var gl = host.contentWindow.glContext;
+ assertMsg(gl != null, "context was created properly");
+
+ glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
+
+ if(gl.canvas.width != gl.drawingBufferWidth ||
+ gl.canvas.height != gl.drawingBufferHeight) {
+ testFailed("Buffer was the wrong size: " +
+ gl.drawingBufferWidth + "x" + gl.drawingBufferHeight);
+ } else {
+ testPassed("Buffer was the correct size: " +
+ gl.drawingBufferWidth + "x" + gl.drawingBufferHeight);
+ refreshFrame();
+ }
+
+ gl = null;
+}
+
+window.addEventListener("message", function(event) {
+ if(event.data == "Ready") {
+ testContext();
+ }
+});
+
+refreshFrame();
+</script>
+
+</body>
+</html>
Added: trunk/LayoutTests/fast/canvas/webgl/resources/context-release-upon-reload-child.html (0 => 139142)
--- trunk/LayoutTests/fast/canvas/webgl/resources/context-release-upon-reload-child.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/resources/context-release-upon-reload-child.html 2013-01-09 02:21:57 UTC (rev 139142)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html style="margin: 0; padding: 0;">
+ <head>
+<meta charset="utf-8">
+ <title>Simple WebGL context</title>
+ <script src="" </script>
+</head>
+<body style="margin: 0; padding: 0; overflow: hidden;">
+ <canvas id="c"
+ width="1680" height="1050"
+ style="width: 256px; height: 256px;"> <!-- scaled to fit page better -->
+ <script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 vPosition;
+ void main()
+ {
+ gl_Position = vPosition;
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ void main()
+ {
+ gl_FragColor = vec4(1.0,0.0,0.0,1.0);
+ }
+ </script>
+
+ <script>
+ var wtu = WebGLTestUtils;
+
+ var gl = wtu.create3DContext("c", {"antialiased": false});
+ program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.75,0, -0.75,-0.75,0, 0.75,-0.75,0 ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ if(parent) {
+ window.glContext = gl;
+ parent.postMessage("Ready", "*");
+ }
+ </script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (139141 => 139142)
--- trunk/Source/WebCore/ChangeLog 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/ChangeLog 2013-01-09 02:21:57 UTC (rev 139142)
@@ -1,3 +1,77 @@
+2013-01-08 Brandon Jones <[email protected]>
+
+ Make WebGLRenderingContext inherit from ActiveDOMObject
+ https://bugs.webkit.org/show_bug.cgi?id=104733
+
+ Reviewed by Adam Barth.
+
+ When ActiveDOMObject::stop is called on the WebGLRenderingContext the
+ DrawingBuffer and GraphicsContext3D instances are forcibly released in
+ order to keep GPU memory utilization to a minimum.
+
+ Incorporated new layout test based on one just added to the WebGL
+ conformance suite. Also tested manually by reloading and
+ navigating between many WebGL apps.
+
+ Test: fast/canvas/webgl/context-release-upon-reload.html
+
+ * bindings/v8/custom/V8HTMLCanvasElementCustom.cpp:
+ (WebCore::V8HTMLCanvasElement::getContextCallback):
+ Removed garbage collection hack added in Bug 76255.
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore):
+ (WebCore::WebGLRenderingContext::create):
+ Call suspendIfNeeded per ActiveDOMObject contract.
+ (WebCore::WebGLRenderingContext::WebGLRenderingContext):
+ Call ActiveDOMObject constructor.
+ (WebCore::WebGLRenderingContext::~WebGLRenderingContext):
+ Call destroyGraphicsContext3D.
+ (WebCore::WebGLRenderingContext::destroyGraphicsContext3D):
+ Drop DrawingBuffer backing store and delete GraphicsContext3D.
+ (WebCore::WebGLRenderingContext::hasPendingActivity):
+ Always return false.
+ (WebCore::WebGLRenderingContext::stop):
+ Force lost context upon page reload or navigation.
+ * html/canvas/WebGLRenderingContext.h:
+ (WebGLRenderingContext):
+ Inherit from ActiveDOMObject and override notifications.
+ * platform/graphics/blackberry/DrawingBufferBlackBerry.cpp:
+ (WebCore):
+ (WebCore::DrawingBuffer::clearPlatformLayer):
+ Add currently no-op implementation.
+ * platform/graphics/cairo/DrawingBufferCairo.cpp:
+ (WebCore):
+ (WebCore::DrawingBuffer::clearPlatformLayer):
+ Add currently no-op implementation.
+ * platform/graphics/chromium/DrawingBufferChromium.cpp:
+ (WebCore::DrawingBufferPrivate::clearTextureId):
+ Clear texture ID from compositor's layer.
+ (DrawingBufferPrivate):
+ (WebCore::DrawingBuffer::framebuffer):
+ Moved around to reduce number of #ifdefs.
+ (WebCore):
+ (WebCore::DrawingBuffer::platformLayer):
+ (WebCore::DrawingBuffer::clearPlatformLayer):
+ Tell compositor to stop referencing DrawingBuffer's texture.
+ * platform/graphics/clutter/DrawingBufferClutter.cpp:
+ (WebCore):
+ (WebCore::DrawingBuffer::clearPlatformLayer):
+ Add currently no-op implementation.
+ * platform/graphics/gpu/DrawingBuffer.cpp:
+ (WebCore::DrawingBuffer::clear):
+ Call clearPlatformLayer before deleting OpenGL resources.
+ * platform/graphics/gpu/DrawingBuffer.h:
+ (DrawingBuffer):
+ Add clearPlatformLayer.
+ * platform/graphics/gpu/mac/DrawingBufferMac.mm:
+ (WebCore):
+ (WebCore::DrawingBuffer::clearPlatformLayer):
+ Add currently no-op implementation.
+ * platform/graphics/gpu/qt/DrawingBufferQt.cpp:
+ (WebCore):
+ (WebCore::DrawingBuffer::clearPlatformLayer):
+ Add currently no-op implementation.
+
2013-01-08 Tony Gentilcore <[email protected]>
Remove dependency on Document from HTMLConstructionSite::inQuirksMode()
Modified: trunk/Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp (139141 => 139142)
--- trunk/Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -97,12 +97,6 @@
}
#if ENABLE(WEBGL)
else if (result->is3d()) {
- // 3D canvas contexts can hold on to lots of GPU resources, and we want to take an
- // opportunity to get rid of them as soon as possible when we navigate away from pages using
- // them.
- V8PerIsolateData* perIsolateData = V8PerIsolateData::from(args.GetIsolate());
- perIsolateData->setShouldCollectGarbageSoon();
-
v8::Handle<v8::Value> v8Result = toV8(static_cast<WebGLRenderingContext*>(result), args.Holder(), args.GetIsolate());
if (InspectorInstrumentation::canvasAgentEnabled(imp->document())) {
ScriptState* scriptState = ScriptState::forContext(v8::Context::GetCurrent());
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (139141 => 139142)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -439,6 +439,7 @@
extensions->pushGroupMarkerEXT("WebGLRenderingContext");
OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context, attributes));
+ renderingContext->suspendIfNeeded();
#if PLATFORM(CHROMIUM)
if (!renderingContext->m_drawingBuffer) {
@@ -453,6 +454,7 @@
WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context,
GraphicsContext3D::Attributes attributes)
: CanvasRenderingContext(passedCanvas)
+ , ActiveDOMObject(passedCanvas->document(), this)
, m_context(context)
, m_drawingBuffer(0)
, m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
@@ -615,11 +617,24 @@
m_blackTextureCubeMap = 0;
detachAndRemoveAllObjects();
- m_context->setContextLostCallback(nullptr);
- m_context->setErrorMessageCallback(nullptr);
+ destroyGraphicsContext3D();
m_contextGroup->removeContext(this);
}
+void WebGLRenderingContext::destroyGraphicsContext3D()
+{
+ // The drawing buffer holds a context reference. It must also be destroyed
+ // in order for the context to be released.
+ if (m_drawingBuffer)
+ m_drawingBuffer.clear();
+
+ if (m_context) {
+ m_context->setContextLostCallback(nullptr);
+ m_context->setErrorMessageCallback(nullptr);
+ m_context.clear();
+ }
+}
+
void WebGLRenderingContext::markContextChanged()
{
if (m_framebufferBinding)
@@ -4584,6 +4599,19 @@
}
}
+bool WebGLRenderingContext::hasPendingActivity() const
+{
+ return false;
+}
+
+void WebGLRenderingContext::stop()
+{
+ if (!isContextLost()) {
+ forceLostContext(SyntheticLostContext);
+ destroyGraphicsContext3D();
+ }
+}
+
WebGLGetInfo WebGLRenderingContext::getBooleanParameter(GC3Denum pname)
{
GC3Dboolean value = 0;
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (139141 => 139142)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h 2013-01-09 02:21:57 UTC (rev 139142)
@@ -26,6 +26,7 @@
#ifndef WebGLRenderingContext_h
#define WebGLRenderingContext_h
+#include "ActiveDOMObject.h"
#include "CanvasRenderingContext.h"
#include "DrawingBuffer.h"
#include "GraphicsContext3D.h"
@@ -75,7 +76,7 @@
typedef int ExceptionCode;
-class WebGLRenderingContext : public CanvasRenderingContext {
+class WebGLRenderingContext : public CanvasRenderingContext, public ActiveDOMObject {
public:
static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
virtual ~WebGLRenderingContext();
@@ -317,6 +318,10 @@
unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
+ // ActiveDOMObject notifications
+ virtual bool hasPendingActivity() const;
+ virtual void stop();
+
private:
friend class WebGLFramebuffer;
friend class WebGLObject;
@@ -334,6 +339,7 @@
void addContextObject(WebGLContextObject*);
void detachAndRemoveAllObjects();
+ void destroyGraphicsContext3D();
void markContextChanged();
void cleanupAfterGraphicsCall(bool changed)
{
Modified: trunk/Source/WebCore/platform/graphics/blackberry/DrawingBufferBlackBerry.cpp (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/blackberry/DrawingBufferBlackBerry.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/blackberry/DrawingBufferBlackBerry.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -122,6 +122,10 @@
{
return colorBuffer();
}
+
+void DrawingBuffer::clearPlatformLayer()
+{
+}
#endif
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/cairo/DrawingBufferCairo.cpp (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/cairo/DrawingBufferCairo.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/cairo/DrawingBufferCairo.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -101,6 +101,10 @@
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer*)
{
}
+
+void DrawingBuffer::clearPlatformLayer()
+{
+}
#endif
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -203,6 +203,11 @@
return GraphicsContext3DPrivate::extractWebGraphicsContext3D(m_drawingBuffer->graphicsContext3D());
}
+ void clearTextureId()
+ {
+ m_layer->setTextureId(0);
+ }
+
WebKit::WebLayer* layer() { return m_layer->layer(); }
private:
@@ -210,6 +215,11 @@
OwnPtr<WebKit::WebExternalTextureLayer> m_layer;
};
+Platform3DObject DrawingBuffer::framebuffer() const
+{
+ return m_fbo;
+}
+
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* DrawingBuffer::platformLayer()
{
@@ -218,14 +228,7 @@
return m_private->layer();
}
-#endif
-Platform3DObject DrawingBuffer::framebuffer() const
-{
- return m_fbo;
-}
-
-#if USE(ACCELERATED_COMPOSITING)
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer)
{
if (!m_context->makeContextCurrent() || m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR)
@@ -249,6 +252,14 @@
m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, previousFramebuffer);
}
+
+void DrawingBuffer::clearPlatformLayer()
+{
+ if (m_private)
+ m_private->clearTextureId();
+
+ m_context->flush();
+}
#endif
}
Modified: trunk/Source/WebCore/platform/graphics/clutter/DrawingBufferClutter.cpp (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/clutter/DrawingBufferClutter.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/clutter/DrawingBufferClutter.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -74,6 +74,10 @@
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer*)
{
}
+
+void DrawingBuffer::clearPlatformLayer()
+{
+}
#endif
}
Modified: trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -76,6 +76,11 @@
return;
m_context->makeContextCurrent();
+
+#if USE(ACCELERATED_COMPOSITING)
+ clearPlatformLayer();
+#endif
+
if (!m_size.isEmpty()) {
s_currentResourceUsePixels -= m_size.width() * m_size.height();
m_size = IntSize();
Modified: trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h 2013-01-09 02:21:57 UTC (rev 139142)
@@ -129,6 +129,7 @@
bool requiresCopyFromBackToFrontBuffer() const;
unsigned frontColorBuffer() const;
void paintCompositedResultsToCanvas(ImageBuffer*);
+ void clearPlatformLayer();
#endif
GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
Modified: trunk/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm 2013-01-09 02:21:57 UTC (rev 139142)
@@ -113,6 +113,11 @@
{
return colorBuffer();
}
+
+void DrawingBuffer::clearPlatformLayer()
+{
+ // Don't need to do anything on this platform.
+}
#endif
}
Modified: trunk/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp (139141 => 139142)
--- trunk/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp 2013-01-09 01:43:54 UTC (rev 139141)
+++ trunk/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp 2013-01-09 02:21:57 UTC (rev 139142)
@@ -104,6 +104,10 @@
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer*)
{
}
+
+void DrawingBuffer::clearPlatformLayer()
+{
+}
#endif
}