WebGL: Transfer ownership of WebGraphicsContext3D from WebGLRenderingContext to DrawingBuffer.

Currently, the lifecycle of DrawingBuffer is different from it of
WebGraphicsContext3D, so there is so many checks if the context is valid.
This complexity is not necessary because DrawingBuffer does not own any
objects when the context is lost or impossible to be created.

To be clear the lifecycle, this CL makes DrawingBuffer take ownership of WebGraphicsContext3D.

The DrawingBuffer creation or resize can fail if the memory is not enough. This
logic is preserved.
In detail,
1. If it occurs during WebGLRenderingContext creation, we give up creating
WebGLRenderingContext.
2. If it occurs during restoration of lost context, we will try again.
3. If it occurs during resizing DrawingBuffer, we slightly ignore, because we
can reuse different size FBO in this case.

In addition, this CL fixes two bugs.
1. maybeRestoreContext() pretends to success to restore although creating FBO in
DrawingBuffer fails. As mentioned earlier, we will try again.
2. WebGLRenderingContext calls DrawingBuffer::reset() twice during creation,
because the constructor of DrawingBuffer internally calls reset().

BUG=344393

Review URL: https://codereview.chromium.org/163773007

git-svn-id: svn://svn.chromium.org/blink/trunk@168457 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent c5993552
...@@ -72,7 +72,7 @@ void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* array ...@@ -72,7 +72,7 @@ void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* array
if (!arrayObject->isDefaultObject() && arrayObject == m_context->m_boundVertexArrayObject) if (!arrayObject->isDefaultObject() && arrayObject == m_context->m_boundVertexArrayObject)
m_context->setBoundVertexArrayObject(nullptr); m_context->setBoundVertexArrayObject(nullptr);
arrayObject->deleteObject(m_context->webGraphicsContext3D()); arrayObject->deleteObject(m_context->webContext());
} }
GLboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject) GLboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
...@@ -83,7 +83,7 @@ GLboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arra ...@@ -83,7 +83,7 @@ GLboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arra
if (!arrayObject->hasEverBeenBound()) if (!arrayObject->hasEverBeenBound())
return 0; return 0;
return m_context->webGraphicsContext3D()->isVertexArrayOES(arrayObject->object()); return m_context->webContext()->isVertexArrayOES(arrayObject->object());
} }
void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject) void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
...@@ -92,17 +92,17 @@ void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayOb ...@@ -92,17 +92,17 @@ void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayOb
return; return;
if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, context()))) { if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, context()))) {
m_context->webGraphicsContext3D()->synthesizeGLError(GL_INVALID_OPERATION); m_context->webContext()->synthesizeGLError(GL_INVALID_OPERATION);
return; return;
} }
if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) { if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
m_context->webGraphicsContext3D()->bindVertexArrayOES(arrayObject->object()); m_context->webContext()->bindVertexArrayOES(arrayObject->object());
arrayObject->setHasEverBeenBound(); arrayObject->setHasEverBeenBound();
m_context->setBoundVertexArrayObject(arrayObject); m_context->setBoundVertexArrayObject(arrayObject);
} else { } else {
m_context->webGraphicsContext3D()->bindVertexArrayOES(0); m_context->webContext()->bindVertexArrayOES(0);
m_context->setBoundVertexArrayObject(nullptr); m_context->setBoundVertexArrayObject(nullptr);
} }
} }
......
...@@ -41,7 +41,7 @@ WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase* ctx) ...@@ -41,7 +41,7 @@ WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase* ctx)
, m_target(0) , m_target(0)
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
setObject(ctx->webGraphicsContext3D()->createBuffer()); setObject(ctx->webContext()->createBuffer());
} }
WebGLBuffer::~WebGLBuffer() WebGLBuffer::~WebGLBuffer()
......
...@@ -50,7 +50,7 @@ blink::WebGraphicsContext3D* WebGLContextGroup::getAWebGraphicsContext3D() ...@@ -50,7 +50,7 @@ blink::WebGraphicsContext3D* WebGLContextGroup::getAWebGraphicsContext3D()
{ {
ASSERT(!m_contexts.isEmpty()); ASSERT(!m_contexts.isEmpty());
HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin(); HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin();
return (*it)->webGraphicsContext3D(); return (*it)->webContext();
} }
void WebGLContextGroup::addContext(WebGLRenderingContextBase* context) void WebGLContextGroup::addContext(WebGLRenderingContextBase* context)
......
...@@ -47,7 +47,7 @@ void WebGLContextObject::detachContext() ...@@ -47,7 +47,7 @@ void WebGLContextObject::detachContext()
{ {
detach(); detach();
if (m_context) { if (m_context) {
deleteObject(m_context->webGraphicsContext3D()); deleteObject(m_context->webContext());
m_context->removeContextObject(this); m_context->removeContextObject(this);
m_context = 0; m_context = 0;
} }
...@@ -55,7 +55,7 @@ void WebGLContextObject::detachContext() ...@@ -55,7 +55,7 @@ void WebGLContextObject::detachContext()
blink::WebGraphicsContext3D* WebGLContextObject::getAWebGraphicsContext3D() const blink::WebGraphicsContext3D* WebGLContextObject::getAWebGraphicsContext3D() const
{ {
return m_context ? m_context->webGraphicsContext3D() : 0; return m_context ? m_context->webContext() : 0;
} }
} }
...@@ -58,7 +58,7 @@ String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader) ...@@ -58,7 +58,7 @@ String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader)
return String(); return String();
if (!m_context->validateWebGLObject("getTranslatedShaderSource", shader)) if (!m_context->validateWebGLObject("getTranslatedShaderSource", shader))
return ""; return "";
return m_context->webGraphicsContext3D()->getTranslatedShaderSourceANGLE(shader->object()); return m_context->webContext()->getTranslatedShaderSourceANGLE(shader->object());
} }
bool WebGLDebugShaders::supported(WebGLRenderingContextBase* context) bool WebGLDebugShaders::supported(WebGLRenderingContextBase* context)
......
...@@ -79,7 +79,7 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GLenum>& buffers) ...@@ -79,7 +79,7 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GLenum>& buffers)
} }
// Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0. // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
GLenum value = (bufs[0] == GL_BACK) ? GL_COLOR_ATTACHMENT0 : GL_NONE; GLenum value = (bufs[0] == GL_BACK) ? GL_COLOR_ATTACHMENT0 : GL_NONE;
m_context->webGraphicsContext3D()->drawBuffersEXT(1, &value); m_context->webContext()->drawBuffersEXT(1, &value);
m_context->setBackDrawBuffer(bufs[0]); m_context->setBackDrawBuffer(bufs[0]);
} else { } else {
if (n > m_context->maxDrawBuffers()) { if (n > m_context->maxDrawBuffers()) {
...@@ -99,7 +99,7 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GLenum>& buffers) ...@@ -99,7 +99,7 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GLenum>& buffers)
// static // static
bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase* webglContext) bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase* webglContext)
{ {
blink::WebGraphicsContext3D* context = webglContext->webGraphicsContext3D(); blink::WebGraphicsContext3D* context = webglContext->webContext();
Extensions3DUtil* extensionsUtil = webglContext->extensionsUtil(); Extensions3DUtil* extensionsUtil = webglContext->extensionsUtil();
// This is called after we make sure GL_EXT_draw_buffers is supported. // This is called after we make sure GL_EXT_draw_buffers is supported.
......
...@@ -263,7 +263,7 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx) ...@@ -263,7 +263,7 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx)
, m_hasEverBeenBound(false) , m_hasEverBeenBound(false)
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
setObject(ctx->webGraphicsContext3D()->createFramebuffer()); setObject(ctx->webContext()->createFramebuffer());
} }
WebGLFramebuffer::~WebGLFramebuffer() WebGLFramebuffer::~WebGLFramebuffer()
...@@ -302,7 +302,7 @@ void WebGLFramebuffer::attach(GLenum attachment, GLenum attachmentPoint) ...@@ -302,7 +302,7 @@ void WebGLFramebuffer::attach(GLenum attachment, GLenum attachmentPoint)
ASSERT(isBound()); ASSERT(isBound());
WebGLAttachment* attachmentObject = getAttachment(attachment); WebGLAttachment* attachmentObject = getAttachment(attachment);
if (attachmentObject) if (attachmentObject)
attachmentObject->attach(context()->webGraphicsContext3D(), attachmentPoint); attachmentObject->attach(context()->webContext(), attachmentPoint);
} }
WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) const WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) const
...@@ -413,7 +413,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum attachment) ...@@ -413,7 +413,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum attachment)
WebGLAttachment* attachmentObject = getAttachment(attachment); WebGLAttachment* attachmentObject = getAttachment(attachment);
if (attachmentObject) { if (attachmentObject) {
attachmentObject->onDetached(context()->webGraphicsContext3D()); attachmentObject->onDetached(context()->webContext());
m_attachments.remove(attachment); m_attachments.remove(attachment);
drawBuffersIfNecessary(false); drawBuffersIfNecessary(false);
switch (attachment) { switch (attachment) {
...@@ -446,7 +446,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a ...@@ -446,7 +446,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
WebGLAttachment* attachmentObject = it->value.get(); WebGLAttachment* attachmentObject = it->value.get();
if (attachmentObject->isSharedObject(attachment)) { if (attachmentObject->isSharedObject(attachment)) {
GLenum attachmentType = it->key; GLenum attachmentType = it->key;
attachmentObject->unattach(context()->webGraphicsContext3D(), attachmentType); attachmentObject->unattach(context()->webContext(), attachmentType);
removeAttachmentFromBoundFramebuffer(attachmentType); removeAttachmentFromBoundFramebuffer(attachmentType);
checkMore = true; checkMore = true;
break; break;
...@@ -601,7 +601,7 @@ void WebGLFramebuffer::drawBuffersIfNecessary(bool force) ...@@ -601,7 +601,7 @@ void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
} }
} }
if (reset) { if (reset) {
context()->webGraphicsContext3D()->drawBuffersEXT( context()->webContext()->drawBuffersEXT(
m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data()); m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
} }
} }
......
...@@ -43,7 +43,7 @@ WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx) ...@@ -43,7 +43,7 @@ WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx)
, m_infoValid(true) , m_infoValid(true)
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
setObject(ctx->webGraphicsContext3D()->createProgram()); setObject(ctx->webContext()->createProgram());
} }
WebGLProgram::~WebGLProgram() WebGLProgram::~WebGLProgram()
......
...@@ -49,7 +49,7 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase* ctx) ...@@ -49,7 +49,7 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase* ctx)
, m_hasEverBeenBound(false) , m_hasEverBeenBound(false)
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
setObject(ctx->webGraphicsContext3D()->createRenderbuffer()); setObject(ctx->webContext()->createRenderbuffer());
} }
void WebGLRenderbuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object) void WebGLRenderbuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
......
...@@ -94,7 +94,7 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen ...@@ -94,7 +94,7 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
renderingContext->registerContextExtensions(); renderingContext->registerContextExtensions();
renderingContext->suspendIfNeeded(); 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.")); canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context."));
return nullptr; return nullptr;
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "platform/Timer.h" #include "platform/Timer.h"
#include "platform/graphics/GraphicsTypes3D.h" #include "platform/graphics/GraphicsTypes3D.h"
#include "platform/graphics/ImageBuffer.h" #include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/gpu/DrawingBuffer.h"
#include "platform/graphics/gpu/Extensions3DUtil.h" #include "platform/graphics/gpu/Extensions3DUtil.h"
#include "platform/graphics/gpu/WebGLImageConversion.h" #include "platform/graphics/gpu/WebGLImageConversion.h"
#include "public/platform/WebGraphicsContext3D.h" #include "public/platform/WebGraphicsContext3D.h"
...@@ -49,7 +50,6 @@ class WebLayer; ...@@ -49,7 +50,6 @@ class WebLayer;
namespace WebCore { namespace WebCore {
class ANGLEInstancedArrays; class ANGLEInstancedArrays;
class DrawingBuffer;
class EXTFragDepth; class EXTFragDepth;
class EXTTextureFilterAnisotropic; class EXTTextureFilterAnisotropic;
class ExceptionState; class ExceptionState;
...@@ -204,7 +204,7 @@ public: ...@@ -204,7 +204,7 @@ public:
void hint(GLenum target, GLenum mode); void hint(GLenum target, GLenum mode);
GLboolean isBuffer(WebGLBuffer*); GLboolean isBuffer(WebGLBuffer*);
bool isContextLost(); bool isContextLost() const;
GLboolean isEnabled(GLenum cap); GLboolean isEnabled(GLenum cap);
GLboolean isFramebuffer(WebGLFramebuffer*); GLboolean isFramebuffer(WebGLFramebuffer*);
GLboolean isProgram(WebGLProgram*); GLboolean isProgram(WebGLProgram*);
...@@ -323,7 +323,7 @@ public: ...@@ -323,7 +323,7 @@ public:
void forceRestoreContext(); void forceRestoreContext();
void loseContextImpl(LostContextMode); void loseContextImpl(LostContextMode);
blink::WebGraphicsContext3D* webGraphicsContext3D() const { return m_context.get(); } blink::WebGraphicsContext3D* webContext() const { return m_drawingBuffer->context(); }
WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); } WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
virtual blink::WebLayer* platformLayer() const OVERRIDE; virtual blink::WebLayer* platformLayer() const OVERRIDE;
Extensions3DUtil* extensionsUtil(); Extensions3DUtil* extensionsUtil();
...@@ -390,12 +390,10 @@ protected: ...@@ -390,12 +390,10 @@ protected:
WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*); WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*);
OwnPtr<blink::WebGraphicsContext3D> m_context;
RefPtr<WebGLContextGroup> m_contextGroup;
// Structure for rendering to a DrawingBuffer, instead of directly // Structure for rendering to a DrawingBuffer, instead of directly
// to the back-buffer of m_context. // to the back-buffer of m_context.
RefPtr<DrawingBuffer> m_drawingBuffer; RefPtr<DrawingBuffer> m_drawingBuffer;
RefPtr<WebGLContextGroup> m_contextGroup;
// Dispatches a context lost event once it is determined that one is needed. // Dispatches a context lost event once it is determined that one is needed.
// This is used both for synthetic and real context losses. For real ones, it's // This is used both for synthetic and real context losses. For real ones, it's
......
...@@ -42,7 +42,7 @@ WebGLShader::WebGLShader(WebGLRenderingContextBase* ctx, GLenum type) ...@@ -42,7 +42,7 @@ WebGLShader::WebGLShader(WebGLRenderingContextBase* ctx, GLenum type)
, m_source("") , m_source("")
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
setObject(ctx->webGraphicsContext3D()->createShader(type)); setObject(ctx->webContext()->createShader(type));
} }
WebGLShader::~WebGLShader() WebGLShader::~WebGLShader()
......
...@@ -51,7 +51,7 @@ WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx) ...@@ -51,7 +51,7 @@ WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
, m_isHalfFloatType(false) , m_isHalfFloatType(false)
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
setObject(ctx->webGraphicsContext3D()->createTexture()); setObject(ctx->webContext()->createTexture());
} }
WebGLTexture::~WebGLTexture() WebGLTexture::~WebGLTexture()
......
...@@ -49,7 +49,7 @@ WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase* ...@@ -49,7 +49,7 @@ WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase*
case VaoTypeDefault: case VaoTypeDefault:
break; break;
default: default:
setObject(context()->webGraphicsContext3D()->createVertexArrayOES()); setObject(context()->webContext()->createVertexArrayOES());
break; break;
} }
} }
...@@ -65,7 +65,7 @@ void WebGLVertexArrayObjectOES::deleteObjectImpl(blink::WebGraphicsContext3D* co ...@@ -65,7 +65,7 @@ void WebGLVertexArrayObjectOES::deleteObjectImpl(blink::WebGraphicsContext3D* co
case VaoTypeDefault: case VaoTypeDefault:
break; break;
default: default:
context()->webGraphicsContext3D()->deleteVertexArrayOES(object); context()->webContext()->deleteVertexArrayOES(object);
break; break;
} }
...@@ -84,7 +84,7 @@ void WebGLVertexArrayObjectOES::setElementArrayBuffer(PassRefPtr<WebGLBuffer> bu ...@@ -84,7 +84,7 @@ void WebGLVertexArrayObjectOES::setElementArrayBuffer(PassRefPtr<WebGLBuffer> bu
if (buffer) if (buffer)
buffer->onAttached(); buffer->onAttached();
if (m_boundElementArrayBuffer) if (m_boundElementArrayBuffer)
m_boundElementArrayBuffer->onDetached(context()->webGraphicsContext3D()); m_boundElementArrayBuffer->onDetached(context()->webContext());
m_boundElementArrayBuffer = buffer; m_boundElementArrayBuffer = buffer;
} }
...@@ -99,7 +99,7 @@ void WebGLVertexArrayObjectOES::setVertexAttribState( ...@@ -99,7 +99,7 @@ void WebGLVertexArrayObjectOES::setVertexAttribState(
if (buffer) if (buffer)
buffer->onAttached(); buffer->onAttached();
if (state.bufferBinding) if (state.bufferBinding)
state.bufferBinding->onDetached(context()->webGraphicsContext3D()); state.bufferBinding->onDetached(context()->webContext());
state.bufferBinding = buffer; state.bufferBinding = buffer;
state.bytesPerElement = bytesPerElement; state.bytesPerElement = bytesPerElement;
...@@ -114,14 +114,14 @@ void WebGLVertexArrayObjectOES::setVertexAttribState( ...@@ -114,14 +114,14 @@ void WebGLVertexArrayObjectOES::setVertexAttribState(
void WebGLVertexArrayObjectOES::unbindBuffer(PassRefPtr<WebGLBuffer> buffer) void WebGLVertexArrayObjectOES::unbindBuffer(PassRefPtr<WebGLBuffer> buffer)
{ {
if (m_boundElementArrayBuffer == buffer) { if (m_boundElementArrayBuffer == buffer) {
m_boundElementArrayBuffer->onDetached(context()->webGraphicsContext3D()); m_boundElementArrayBuffer->onDetached(context()->webContext());
m_boundElementArrayBuffer = nullptr; m_boundElementArrayBuffer = nullptr;
} }
for (size_t i = 0; i < m_vertexAttribState.size(); ++i) { for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
VertexAttribState& state = m_vertexAttribState[i]; VertexAttribState& state = m_vertexAttribState[i];
if (state.bufferBinding == buffer) { if (state.bufferBinding == buffer) {
buffer->onDetached(context()->webGraphicsContext3D()); buffer->onDetached(context()->webContext());
state.bufferBinding = nullptr; state.bufferBinding = nullptr;
} }
} }
......
...@@ -77,9 +77,10 @@ private: ...@@ -77,9 +77,10 @@ private:
Platform3DObject m_oldTextureUnitZeroId; Platform3DObject m_oldTextureUnitZeroId;
}; };
PassRefPtr<DrawingBuffer> DrawingBuffer::create(blink::WebGraphicsContext3D* context, const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvictionManager> contextEvictionManager) PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<blink::WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvictionManager> contextEvictionManager)
{ {
Extensions3DUtil extensionsUtil(context); ASSERT(context);
Extensions3DUtil extensionsUtil(context.get());
bool multisampleSupported = extensionsUtil.supportsExtension("GL_CHROMIUM_framebuffer_multisample") bool multisampleSupported = extensionsUtil.supportsExtension("GL_CHROMIUM_framebuffer_multisample")
&& extensionsUtil.supportsExtension("GL_OES_rgb8_rgba8"); && extensionsUtil.supportsExtension("GL_OES_rgb8_rgba8");
if (multisampleSupported) { if (multisampleSupported) {
...@@ -90,12 +91,13 @@ PassRefPtr<DrawingBuffer> DrawingBuffer::create(blink::WebGraphicsContext3D* con ...@@ -90,12 +91,13 @@ PassRefPtr<DrawingBuffer> DrawingBuffer::create(blink::WebGraphicsContext3D* con
if (packedDepthStencilSupported) if (packedDepthStencilSupported)
extensionsUtil.ensureExtensionEnabled("GL_OES_packed_depth_stencil"); extensionsUtil.ensureExtensionEnabled("GL_OES_packed_depth_stencil");
RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size, multisampleSupported, packedDepthStencilSupported, preserve, contextEvictionManager)); RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, multisampleSupported, packedDepthStencilSupported, preserve, contextEvictionManager));
if (!drawingBuffer->initialize(size))
return PassRefPtr<DrawingBuffer>();
return drawingBuffer.release(); return drawingBuffer.release();
} }
DrawingBuffer::DrawingBuffer(blink::WebGraphicsContext3D* context, DrawingBuffer::DrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D> context,
const IntSize& size,
bool multisampleExtensionSupported, bool multisampleExtensionSupported,
bool packedDepthStencilExtensionSupported, bool packedDepthStencilExtensionSupported,
PreserveDrawingBuffer preserve, PreserveDrawingBuffer preserve,
...@@ -124,12 +126,12 @@ DrawingBuffer::DrawingBuffer(blink::WebGraphicsContext3D* context, ...@@ -124,12 +126,12 @@ DrawingBuffer::DrawingBuffer(blink::WebGraphicsContext3D* context,
, m_colorFormat(0) , m_colorFormat(0)
, m_internalRenderbufferFormat(0) , m_internalRenderbufferFormat(0)
, m_maxTextureSize(0) , m_maxTextureSize(0)
, m_sampleCount(0)
, m_packAlignment(4) , m_packAlignment(4)
, m_contextEvictionManager(contextEvictionManager) , m_contextEvictionManager(contextEvictionManager)
{ {
// Used by browser tests to detect the use of a DrawingBuffer. // Used by browser tests to detect the use of a DrawingBuffer.
TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation");
initialize(size);
} }
DrawingBuffer::~DrawingBuffer() DrawingBuffer::~DrawingBuffer()
...@@ -156,12 +158,12 @@ void DrawingBuffer::markLayerComposited() ...@@ -156,12 +158,12 @@ void DrawingBuffer::markLayerComposited()
blink::WebGraphicsContext3D* DrawingBuffer::context() blink::WebGraphicsContext3D* DrawingBuffer::context()
{ {
return m_context; return m_context.get();
} }
bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap) bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap)
{ {
if (!m_context || !m_contentsChanged) if (!m_contentsChanged)
return false; return false;
m_context->makeContextCurrent(); m_context->makeContextCurrent();
...@@ -182,7 +184,7 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, ...@@ -182,7 +184,7 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox,
// We must restore the texture binding since creating new textures, // We must restore the texture binding since creating new textures,
// consuming and producing mailboxes changes it. // consuming and producing mailboxes changes it.
ScopedTextureUnit0BindingRestorer restorer(m_context, m_activeTextureUnit, m_texture2DBinding); ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureUnit, m_texture2DBinding);
// First try to recycle an old buffer. // First try to recycle an old buffer.
RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox();
...@@ -245,7 +247,7 @@ void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mail ...@@ -245,7 +247,7 @@ void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mail
PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox() PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox()
{ {
if (!m_context || m_recycledMailboxes.isEmpty()) if (m_recycledMailboxes.isEmpty())
return PassRefPtr<MailboxInfo>(); return PassRefPtr<MailboxInfo>();
RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release();
...@@ -275,11 +277,10 @@ PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned ...@@ -275,11 +277,10 @@ PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned
return returnMailbox.release(); return returnMailbox.release();
} }
void DrawingBuffer::initialize(const IntSize& size) bool DrawingBuffer::initialize(const IntSize& size)
{ {
ASSERT(m_context);
m_attributes = m_context->getContextAttributes(); m_attributes = m_context->getContextAttributes();
Extensions3DUtil extensionsUtil(m_context); Extensions3DUtil extensionsUtil(m_context.get());
if (m_attributes.alpha) { if (m_attributes.alpha) {
m_internalColorFormat = GL_RGBA; m_internalColorFormat = GL_RGBA;
...@@ -312,12 +313,12 @@ void DrawingBuffer::initialize(const IntSize& size) ...@@ -312,12 +313,12 @@ void DrawingBuffer::initialize(const IntSize& size)
else else
m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0); m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
createSecondaryBuffers(); createSecondaryBuffers();
reset(size); return reset(size);
} }
bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY) bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY)
{ {
if (!m_context || !m_context->makeContextCurrent()) if (!m_context->makeContextCurrent())
return false; return false;
if (m_contentsChanged) { if (m_contentsChanged) {
if (m_multisampleMode != None) { if (m_multisampleMode != None) {
...@@ -363,9 +364,6 @@ Platform3DObject DrawingBuffer::framebuffer() const ...@@ -363,9 +364,6 @@ Platform3DObject DrawingBuffer::framebuffer() const
blink::WebLayer* DrawingBuffer::platformLayer() blink::WebLayer* DrawingBuffer::platformLayer()
{ {
if (!m_context)
return 0;
if (!m_layer) { if (!m_layer) {
m_layer = adoptPtr(blink::Platform::current()->compositorSupport()->createExternalTextureLayer(this)); m_layer = adoptPtr(blink::Platform::current()->compositorSupport()->createExternalTextureLayer(this));
...@@ -380,7 +378,7 @@ blink::WebLayer* DrawingBuffer::platformLayer() ...@@ -380,7 +378,7 @@ blink::WebLayer* DrawingBuffer::platformLayer()
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer) void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer)
{ {
if (!m_context || !m_context->makeContextCurrent() || m_context->getGraphicsResetStatusARB() != GL_NO_ERROR) if (!m_context->makeContextCurrent() || m_context->getGraphicsResetStatusARB() != GL_NO_ERROR)
return; return;
if (!imageBuffer) if (!imageBuffer)
...@@ -421,40 +419,37 @@ void DrawingBuffer::clearPlatformLayer() ...@@ -421,40 +419,37 @@ void DrawingBuffer::clearPlatformLayer()
if (m_layer) if (m_layer)
m_layer->clearTexture(); m_layer->clearTexture();
if (m_context) m_context->flush();
m_context->flush();
} }
void DrawingBuffer::releaseResources() void DrawingBuffer::releaseResources()
{ {
if (m_context) { m_context->makeContextCurrent();
m_context->makeContextCurrent();
clearPlatformLayer(); clearPlatformLayer();
for (size_t i = 0; i < m_textureMailboxes.size(); i++) for (size_t i = 0; i < m_textureMailboxes.size(); i++)
m_context->deleteTexture(m_textureMailboxes[i]->textureId); m_context->deleteTexture(m_textureMailboxes[i]->textureId);
if (m_multisampleColorBuffer) if (m_multisampleColorBuffer)
m_context->deleteRenderbuffer(m_multisampleColorBuffer); m_context->deleteRenderbuffer(m_multisampleColorBuffer);
if (m_depthStencilBuffer) if (m_depthStencilBuffer)
m_context->deleteRenderbuffer(m_depthStencilBuffer); m_context->deleteRenderbuffer(m_depthStencilBuffer);
if (m_depthBuffer) if (m_depthBuffer)
m_context->deleteRenderbuffer(m_depthBuffer); m_context->deleteRenderbuffer(m_depthBuffer);
if (m_stencilBuffer) if (m_stencilBuffer)
m_context->deleteRenderbuffer(m_stencilBuffer); m_context->deleteRenderbuffer(m_stencilBuffer);
if (m_multisampleFBO) if (m_multisampleFBO)
m_context->deleteFramebuffer(m_multisampleFBO); m_context->deleteFramebuffer(m_multisampleFBO);
if (m_fbo) if (m_fbo)
m_context->deleteFramebuffer(m_fbo); m_context->deleteFramebuffer(m_fbo);
m_context = 0; m_context.clear();
}
setSize(IntSize()); setSize(IntSize());
...@@ -479,9 +474,6 @@ void DrawingBuffer::releaseResources() ...@@ -479,9 +474,6 @@ void DrawingBuffer::releaseResources()
unsigned DrawingBuffer::createColorTexture(const IntSize& size) unsigned DrawingBuffer::createColorTexture(const IntSize& size)
{ {
if (!m_context)
return 0;
unsigned offscreenColorTexture = m_context->createTexture(); unsigned offscreenColorTexture = m_context->createTexture();
if (!offscreenColorTexture) if (!offscreenColorTexture)
return 0; return 0;
...@@ -598,9 +590,6 @@ void DrawingBuffer::resizeDepthStencil(const IntSize& size) ...@@ -598,9 +590,6 @@ void DrawingBuffer::resizeDepthStencil(const IntSize& size)
void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) void DrawingBuffer::clearFramebuffers(GLbitfield clearMask)
{ {
if (!m_context)
return;
// We will clear the multisample FBO, but we also need to clear the non-multisampled buffer. // We will clear the multisample FBO, but we also need to clear the non-multisampled buffer.
if (m_multisampleFBO) { if (m_multisampleFBO) {
m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
...@@ -668,11 +657,9 @@ IntSize DrawingBuffer::adjustSizeWithContextEviction(const IntSize& size, bool& ...@@ -668,11 +657,9 @@ IntSize DrawingBuffer::adjustSizeWithContextEviction(const IntSize& size, bool&
return adjustedSize; return adjustedSize;
} }
void DrawingBuffer::reset(const IntSize& newSize) bool DrawingBuffer::reset(const IntSize& newSize)
{ {
if (!m_context) ASSERT(!newSize.isEmpty());
return;
IntSize adjustedSize; IntSize adjustedSize;
bool evictContext = false; bool evictContext = false;
bool isNewContext = m_size.isEmpty(); bool isNewContext = m_size.isEmpty();
...@@ -682,7 +669,7 @@ void DrawingBuffer::reset(const IntSize& newSize) ...@@ -682,7 +669,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
adjustedSize = adjustSize(newSize); adjustedSize = adjustSize(newSize);
if (adjustedSize.isEmpty()) if (adjustedSize.isEmpty())
return; return false;
if (evictContext) if (evictContext)
m_contextEvictionManager->forciblyLoseOldestContext("WARNING: WebGL contexts have exceeded the maximum allowed backbuffer area. Oldest context will be lost."); m_contextEvictionManager->forciblyLoseOldestContext("WARNING: WebGL contexts have exceeded the maximum allowed backbuffer area. Oldest context will be lost.");
...@@ -700,7 +687,7 @@ void DrawingBuffer::reset(const IntSize& newSize) ...@@ -700,7 +687,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
setSize(adjustedSize); setSize(adjustedSize);
if (adjustedSize.isEmpty()) if (adjustedSize.isEmpty())
return; return false;
} }
m_context->disable(GL_SCISSOR_TEST); m_context->disable(GL_SCISSOR_TEST);
...@@ -720,13 +707,11 @@ void DrawingBuffer::reset(const IntSize& newSize) ...@@ -720,13 +707,11 @@ void DrawingBuffer::reset(const IntSize& newSize)
} }
clearFramebuffers(clearMask); clearFramebuffers(clearMask);
return true;
} }
void DrawingBuffer::commit(long x, long y, long width, long height) void DrawingBuffer::commit(long x, long y, long width, long height)
{ {
if (!m_context)
return;
if (width < 0) if (width < 0)
width = m_size.width(); width = m_size.width();
if (height < 0) if (height < 0)
...@@ -754,7 +739,7 @@ void DrawingBuffer::commit(long x, long y, long width, long height) ...@@ -754,7 +739,7 @@ void DrawingBuffer::commit(long x, long y, long width, long height)
void DrawingBuffer::restoreFramebufferBinding() void DrawingBuffer::restoreFramebufferBinding()
{ {
if (!m_context || !m_framebufferBinding) if (!m_framebufferBinding)
return; return;
m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding); m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding);
...@@ -767,9 +752,6 @@ bool DrawingBuffer::multisample() const ...@@ -767,9 +752,6 @@ bool DrawingBuffer::multisample() const
void DrawingBuffer::bind() void DrawingBuffer::bind()
{ {
if (!m_context)
return;
m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo);
} }
......
...@@ -79,24 +79,19 @@ public: ...@@ -79,24 +79,19 @@ public:
Discard Discard
}; };
static PassRefPtr<DrawingBuffer> create(blink::WebGraphicsContext3D*, const IntSize&, PreserveDrawingBuffer, PassRefPtr<ContextEvictionManager>); static PassRefPtr<DrawingBuffer> create(PassOwnPtr<blink::WebGraphicsContext3D>, const IntSize&, PreserveDrawingBuffer, PassRefPtr<ContextEvictionManager>);
virtual ~DrawingBuffer(); virtual ~DrawingBuffer();
// Clear all resources from this object, as well as context. Called when context is destroyed
// to prevent invalid accesses to the resources.
void releaseResources();
// Issues a glClear() on all framebuffers associated with this DrawingBuffer. The caller is responsible for // Issues a glClear() on all framebuffers associated with this DrawingBuffer. The caller is responsible for
// making the context current and setting the clear values and masks. Modifies the framebuffer binding. // making the context current and setting the clear values and masks. Modifies the framebuffer binding.
void clearFramebuffers(GLbitfield clearMask); void clearFramebuffers(GLbitfield clearMask);
// Given the desired buffer size, provides the largest dimensions that will fit in the pixel budget. // Given the desired buffer size, provides the largest dimensions that will fit in the pixel budget.
IntSize adjustSize(const IntSize&); IntSize adjustSize(const IntSize&);
void reset(const IntSize&); bool reset(const IntSize&);
void bind(); void bind();
IntSize size() const { return m_size; } IntSize size() const { return m_size; }
bool isZeroSized() const { return m_size.isEmpty(); }
// Copies the multisample color buffer to the normal color buffer and leaves m_fbo bound. // Copies the multisample color buffer to the normal color buffer and leaves m_fbo bound.
void commit(long x = 0, long y = 0, long width = -1, long height = -1); void commit(long x = 0, long y = 0, long width = -1, long height = -1);
...@@ -143,10 +138,11 @@ public: ...@@ -143,10 +138,11 @@ public:
PassRefPtr<Uint8ClampedArray> paintRenderingResultsToImageData(int&, int&); PassRefPtr<Uint8ClampedArray> paintRenderingResultsToImageData(int&, int&);
private: private:
DrawingBuffer(blink::WebGraphicsContext3D*, const IntSize&, bool multisampleExtensionSupported, DrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D>, bool multisampleExtensionSupported,
bool packedDepthStencilExtensionSupported, PreserveDrawingBuffer, PassRefPtr<ContextEvictionManager>); bool packedDepthStencilExtensionSupported, PreserveDrawingBuffer, PassRefPtr<ContextEvictionManager>);
void initialize(const IntSize&); bool initialize(const IntSize&);
void releaseResources();
unsigned createColorTexture(const IntSize& size = IntSize()); unsigned createColorTexture(const IntSize& size = IntSize());
// Create the depth/stencil and multisample buffers, if needed. // Create the depth/stencil and multisample buffers, if needed.
...@@ -198,7 +194,7 @@ private: ...@@ -198,7 +194,7 @@ private:
Platform3DObject m_framebufferBinding; Platform3DObject m_framebufferBinding;
GLenum m_activeTextureUnit; GLenum m_activeTextureUnit;
blink::WebGraphicsContext3D* m_context; OwnPtr<blink::WebGraphicsContext3D> m_context;
IntSize m_size; IntSize m_size;
bool m_multisampleExtensionSupported; bool m_multisampleExtensionSupported;
bool m_packedDepthStencilExtensionSupported; bool m_packedDepthStencilExtensionSupported;
......
...@@ -112,16 +112,17 @@ protected: ...@@ -112,16 +112,17 @@ protected:
virtual void SetUp() virtual void SetUp()
{ {
RefPtr<FakeContextEvictionManager> contextEvictionManager = adoptRef(new FakeContextEvictionManager()); RefPtr<FakeContextEvictionManager> contextEvictionManager = adoptRef(new FakeContextEvictionManager());
m_context = adoptPtr(new WebGraphicsContext3DForTests); OwnPtr<WebGraphicsContext3DForTests> context = adoptPtr(new WebGraphicsContext3DForTests);
m_drawingBuffer = DrawingBuffer::create(m_context.get(), IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve, contextEvictionManager.release()); m_context = context.get();
m_drawingBuffer = DrawingBuffer::create(context.release(), IntSize(initialWidth, initialHeight), DrawingBuffer::Preserve, contextEvictionManager.release());
} }
WebGraphicsContext3DForTests* webContext() WebGraphicsContext3DForTests* webContext()
{ {
return m_context.get(); return m_context;
} }
OwnPtr<WebGraphicsContext3DForTests> m_context; WebGraphicsContext3DForTests* m_context;
RefPtr<DrawingBuffer> m_drawingBuffer; RefPtr<DrawingBuffer> m_drawingBuffer;
}; };
...@@ -141,16 +142,6 @@ TEST_F(DrawingBufferTest, testPaintRenderingResultsToCanvas) ...@@ -141,16 +142,6 @@ TEST_F(DrawingBufferTest, testPaintRenderingResultsToCanvas)
EXPECT_FALSE(imageBuffer->bitmap().isNull()); EXPECT_FALSE(imageBuffer->bitmap().isNull());
} }
TEST_F(DrawingBufferTest, verifyNoNewBuffersAfterContextLostWithMailboxes)
{
// Tell the buffer its contents changed and context was lost.
m_drawingBuffer->markContentsChanged();
m_drawingBuffer->releaseResources();
blink::WebExternalTextureMailbox mailbox;
EXPECT_FALSE(m_drawingBuffer->prepareMailbox(&mailbox, 0));
}
TEST_F(DrawingBufferTest, verifyResizingProperlyAffectsMailboxes) TEST_F(DrawingBufferTest, verifyResizingProperlyAffectsMailboxes)
{ {
blink::WebExternalTextureMailbox mailbox; blink::WebExternalTextureMailbox mailbox;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment