Index: Source/core/html/canvas/WebGLRenderingContext.cpp |
diff --git a/Source/core/html/canvas/WebGLRenderingContext.cpp b/Source/core/html/canvas/WebGLRenderingContext.cpp |
index 444dd04a1d81629d1edbae5e7177348aac30cc29..ef10840f93aae4c2c4ddf64c04449dc3733e7ed3 100644 |
--- a/Source/core/html/canvas/WebGLRenderingContext.cpp |
+++ b/Source/core/html/canvas/WebGLRenderingContext.cpp |
@@ -515,7 +515,7 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen |
OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context.release(), attrs)); |
renderingContext->suspendIfNeeded(); |
- if (renderingContext->m_drawingBuffer->isZeroSized()) { |
+ if (!renderingContext->m_drawingBuffer) { |
canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context.")); |
return nullptr; |
} |
@@ -526,8 +526,8 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen |
WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<blink::WebGraphicsContext3D> context, WebGLContextAttributes* requestedAttributes) |
: CanvasRenderingContext(passedCanvas) |
, ActiveDOMObject(&passedCanvas->document()) |
- , m_context(context) |
, m_drawingBuffer(0) |
+ , m_context(context.get()) |
, m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent) |
, m_restoreAllowed(false) |
, m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext) |
@@ -555,13 +555,13 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa |
// Create the DrawingBuffer and initialize the platform layer. |
DrawingBuffer::PreserveDrawingBuffer preserve = requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard; |
- m_drawingBuffer = DrawingBuffer::create(m_context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release()); |
+ m_drawingBuffer = DrawingBuffer::create(context, clampedCanvasSize(), preserve, contextEvictionManager.release()); |
+ if (!m_drawingBuffer) |
+ return; |
- if (!m_drawingBuffer->isZeroSized()) { |
- m_drawingBuffer->bind(); |
- setupFlags(); |
- initializeNewContext(); |
- } |
+ m_drawingBuffer->bind(); |
+ setupFlags(); |
+ initializeNewContext(); |
// Register extensions. |
static const char* const webkitPrefix[] = { "WEBKIT_", 0, }; |
@@ -655,8 +655,6 @@ void WebGLRenderingContext::initializeNewContext() |
createFallbackBlackTextures1x1(); |
- m_drawingBuffer->reset(clampedCanvasSize()); |
- |
m_context->viewport(0, 0, drawingBufferWidth(), drawingBufferHeight()); |
m_context->scissor(0, 0, drawingBufferWidth(), drawingBufferHeight()); |
@@ -757,17 +755,19 @@ void WebGLRenderingContext::destroyContext() |
{ |
m_contextLost = true; |
- // The drawing buffer holds a context reference. It must also be destroyed |
- // in order for the context to be released. |
- m_drawingBuffer->releaseResources(); |
+ if (!m_context) { |
+ ASSERT(!m_drawingBuffer); |
+ return; |
+ } |
m_extensionsUtil.clear(); |
- if (m_context) { |
- m_context->setContextLostCallback(0); |
- m_context->setErrorMessageCallback(0); |
- m_context.clear(); |
- } |
+ m_context->setContextLostCallback(0); |
+ m_context->setErrorMessageCallback(0); |
+ m_context = 0; |
+ |
+ ASSERT(m_drawingBuffer); |
+ m_drawingBuffer.clear(); |
} |
void WebGLRenderingContext::markContextChanged() |
@@ -959,12 +959,12 @@ void WebGLRenderingContext::reshape(int width, int height) |
int WebGLRenderingContext::drawingBufferWidth() const |
{ |
- return m_drawingBuffer->size().width(); |
+ return isContextLost() ? 0 : m_drawingBuffer->size().width(); |
} |
int WebGLRenderingContext::drawingBufferHeight() const |
{ |
- return m_drawingBuffer->size().height(); |
+ return isContextLost() ? 0 : m_drawingBuffer->size().height(); |
} |
unsigned WebGLRenderingContext::sizeInBytes(GLenum type) |
@@ -1312,7 +1312,7 @@ void WebGLRenderingContext::clear(GLbitfield mask) |
return; |
} |
const char* reason = "framebuffer incomplete"; |
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) { |
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context, &reason)) { |
synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason); |
return; |
} |
@@ -1466,7 +1466,7 @@ void WebGLRenderingContext::copyTexImage2D(GLenum target, GLint level, GLenum in |
return; |
} |
const char* reason = "framebuffer incomplete"; |
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) { |
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context, &reason)) { |
synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason); |
return; |
} |
@@ -1509,7 +1509,7 @@ void WebGLRenderingContext::copyTexSubImage2D(GLenum target, GLint level, GLint |
return; |
} |
const char* reason = "framebuffer incomplete"; |
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) { |
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context, &reason)) { |
synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason); |
return; |
} |
@@ -1616,7 +1616,7 @@ bool WebGLRenderingContext::deleteObject(WebGLObject* object) |
if (object->object()) { |
// We need to pass in context here because we want |
// things in this context unbound. |
- object->deleteObject(m_context.get()); |
+ object->deleteObject(m_context); |
} |
return true; |
} |
@@ -1729,7 +1729,7 @@ void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* sha |
return; |
} |
m_context->detachShader(objectOrZero(program), objectOrZero(shader)); |
- shader->onDetached(m_context.get()); |
+ shader->onDetached(m_context); |
} |
void WebGLRenderingContext::disable(GLenum cap) |
@@ -2903,7 +2903,7 @@ GLboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer) |
return m_context->isBuffer(buffer->object()); |
} |
-bool WebGLRenderingContext::isContextLost() |
+bool WebGLRenderingContext::isContextLost() const |
{ |
return m_contextLost; |
} |
@@ -3070,7 +3070,7 @@ void WebGLRenderingContext::readPixels(GLint x, GLint y, GLsizei width, GLsizei |
return; |
} |
const char* reason = "framebuffer incomplete"; |
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) { |
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context, &reason)) { |
synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason); |
return; |
} |
@@ -3134,7 +3134,7 @@ void WebGLRenderingContext::renderbufferStorage(GLenum target, GLenum internalfo |
m_context->renderbufferStorage(target, internalformat, width, height); |
m_renderbufferBinding->setInternalFormat(internalformat); |
m_renderbufferBinding->setSize(width, height); |
- m_renderbufferBinding->deleteEmulatedStencilBuffer(m_context.get()); |
+ m_renderbufferBinding->deleteEmulatedStencilBuffer(m_context); |
break; |
case GL_DEPTH_STENCIL_OES: |
if (isDepthStencilSupported()) { |
@@ -3463,14 +3463,14 @@ void WebGLRenderingContext::texImage2D(GLenum target, GLint level, GLenum intern |
if (GL_TEXTURE_2D == target && texture) { |
if (!canvas->is3D()) { |
ImageBuffer* buffer = canvas->buffer(); |
- if (buffer && buffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type, |
+ if (buffer && buffer->copyToPlatformTexture(m_context, texture->object(), internalformat, type, |
level, m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type); |
return; |
} |
} else { |
WebGLRenderingContext* gl = toWebGLRenderingContext(canvas->renderingContext()); |
- if (gl && gl->m_drawingBuffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type, |
+ if (gl && gl->m_drawingBuffer->copyToPlatformTexture(m_context, texture->object(), internalformat, type, |
level, m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type); |
return; |
@@ -3510,7 +3510,7 @@ void WebGLRenderingContext::texImage2D(GLenum target, GLint level, GLenum intern |
// Otherwise, it will fall back to the normal SW path. |
WebGLTexture* texture = validateTextureBinding("texImage2D", target, true); |
if (GL_TEXTURE_2D == target && texture) { |
- if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
+ if (video->copyVideoTextureToPlatformTexture(m_context, texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type); |
return; |
} |
@@ -4004,7 +4004,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program) |
} |
if (m_currentProgram != program) { |
if (m_currentProgram) |
- m_currentProgram->onDetached(m_context.get()); |
+ m_currentProgram->onDetached(m_context); |
m_currentProgram = program; |
m_context->useProgram(objectOrZero(program)); |
if (program) |
@@ -4218,13 +4218,13 @@ void WebGLRenderingContext::forceRestoreContext() |
blink::WebLayer* WebGLRenderingContext::platformLayer() const |
{ |
- return m_drawingBuffer->platformLayer(); |
+ return isContextLost() ? 0 : m_drawingBuffer->platformLayer(); |
} |
Extensions3DUtil* WebGLRenderingContext::extensionsUtil() |
{ |
if (!m_extensionsUtil) |
- m_extensionsUtil = adoptPtr(new Extensions3DUtil(m_context.get())); |
+ m_extensionsUtil = adoptPtr(new Extensions3DUtil(m_context)); |
return m_extensionsUtil.get(); |
} |
@@ -5199,7 +5199,7 @@ bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GLenum |
} |
const char* reason = "framebuffer incomplete"; |
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) { |
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context, &reason)) { |
synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason); |
return false; |
} |
@@ -5249,7 +5249,7 @@ bool WebGLRenderingContext::validateDrawElements(const char* functionName, GLenu |
} |
const char* reason = "framebuffer incomplete"; |
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) { |
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context, &reason)) { |
synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason); |
return false; |
} |
@@ -5388,7 +5388,16 @@ void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) |
blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes->attributes(canvas()->document().topDocument()->url().string(), settings); |
OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes)); |
- if (!context) { |
+ |
+ ASSERT(!m_drawingBuffer); |
+ if (context) { |
+ RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager()); |
+ DrawingBuffer::PreserveDrawingBuffer preserve = m_requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard; |
+ m_drawingBuffer = DrawingBuffer::create(context.release(), clampedCanvasSize(), preserve, contextEvictionManager.release()); |
+ } |
+ |
+ bool failToRestore = !m_drawingBuffer; |
+ if (failToRestore) { |
if (m_contextLostMode == RealLostContext) { |
m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts); |
} else { |
@@ -5398,21 +5407,11 @@ void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) |
return; |
} |
- RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager()); |
- |
- // Construct a new drawing buffer with the new WebGraphicsContext3D. |
- m_drawingBuffer->releaseResources(); |
- DrawingBuffer::PreserveDrawingBuffer preserve = m_requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard; |
- m_drawingBuffer = DrawingBuffer::create(context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release()); |
- |
- if (m_drawingBuffer->isZeroSized()) |
- return; |
- |
m_drawingBuffer->bind(); |
m_lostContextErrors.clear(); |
- m_context = context.release(); |
+ m_context = m_drawingBuffer->context(); |
m_contextLost = false; |
setupFlags(); |