Commit f41ff6a0 authored by bajones@chromium.org's avatar bajones@chromium.org

Share Group plumbing in Blink; Remove WebGL from default share group

BUG=127940

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

git-svn-id: svn://svn.chromium.org/blink/trunk@169525 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 7b34804c
......@@ -159,7 +159,7 @@ blink::WebGraphicsContext3D::Attributes WebGLContextAttributes::attributes(
attrs.failIfMajorPerformanceCaveat = m_failIfMajorPerformanceCaveat;
attrs.noExtensions = true;
attrs.shareResources = true;
attrs.shareResources = false;
attrs.preferDiscreteGPU = true;
attrs.topDocumentURL = topDocumentURL;
......
......@@ -80,7 +80,7 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
attrs = defaultAttrs.get();
}
blink::WebGraphicsContext3D::Attributes attributes = attrs->attributes(document.topDocument().url().string(), settings);
OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes));
OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes, 0));
if (!context || !context->makeContextCurrent()) {
canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context."));
return nullptr;
......
......@@ -455,6 +455,22 @@ namespace {
}
} // namespace anonymous
class ScopedTexture2DRestorer {
public:
ScopedTexture2DRestorer(WebGLRenderingContextBase* context)
: m_context(context)
{
}
~ScopedTexture2DRestorer()
{
m_context->restoreCurrentTexture2D();
}
private:
WebGLRenderingContextBase* m_context;
};
class WebGLRenderingContextLostCallback : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
WTF_MAKE_FAST_ALLOCATED;
public:
......@@ -831,6 +847,8 @@ void WebGLRenderingContextBase::paintRenderingResultsToCanvas()
canvas()->clearCopiedImage();
m_markedCanvasDirty = false;
ScopedTexture2DRestorer restorer(this);
m_drawingBuffer->commit();
if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get())) {
canvas()->ensureUnacceleratedImageBuffer();
......@@ -3406,9 +3424,12 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
return;
WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
// If possible, copy from the canvas element directly to the texture
// via the GPU, without a read-back to system memory.
if (GL_TEXTURE_2D == target && texture) {
ScopedTexture2DRestorer restorer(this);
if (!canvas->is3D()) {
ImageBuffer* buffer = canvas->buffer();
if (buffer && buffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
......@@ -3418,6 +3439,7 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
}
} else {
WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
ScopedTexture2DRestorer restorer(gl);
if (gl && gl->m_drawingBuffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
......@@ -5338,7 +5360,7 @@ void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB
return;
blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes->attributes(canvas()->document().topDocument().url().string(), settings);
OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes));
OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes, 0));
if (!context) {
if (m_contextLostMode == RealLostContext) {
m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE);
......
......@@ -356,6 +356,7 @@ protected:
friend class WebGLCompressedTextureS3TC;
friend class WebGLRenderingContextErrorMessageCallback;
friend class WebGLVertexArrayObjectOES;
friend class ScopedTexture2DRestorer;
WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
void initializeNewContext();
......
......@@ -47,6 +47,7 @@
#include "platform/image-encoders/skia/PNGImageEncoder.h"
#include "platform/image-encoders/skia/WEBPImageEncoder.h"
#include "public/platform/Platform.h"
#include "public/platform/WebExternalTextureMailbox.h"
#include "public/platform/WebGraphicsContext3D.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "third_party/skia/include/effects/SkTableColorFilter.h"
......@@ -138,22 +139,52 @@ bool ImageBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Pl
if (!m_surface->isAccelerated() || !platformLayer() || !isValid())
return false;
if (!context->makeContextCurrent())
if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level))
return false;
if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level))
OwnPtr<blink::WebGraphicsContext3DProvider> provider = adoptPtr(blink::Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
if (!provider)
return false;
blink::WebGraphicsContext3D* sharedContext = provider->context3d();
if (!sharedContext || !sharedContext->makeContextCurrent())
return false;
OwnPtr<blink::WebExternalTextureMailbox> mailbox = adoptPtr(new blink::WebExternalTextureMailbox);
// Contexts may be in a different share group. We must transfer the texture through a mailbox first
sharedContext->genMailboxCHROMIUM(mailbox->name);
sharedContext->bindTexture(GL_TEXTURE_2D, getBackingTexture());
sharedContext->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox->name);
sharedContext->flush();
mailbox->syncPoint = sharedContext->insertSyncPoint();
if (!context->makeContextCurrent())
return false;
Platform3DObject sourceTexture = context->createTexture();
context->bindTexture(GL_TEXTURE_2D, sourceTexture);
context->waitSyncPoint(mailbox->syncPoint);
context->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox->name);
// The canvas is stored in a premultiplied format, so unpremultiply if necessary.
context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, !premultiplyAlpha);
// The canvas is stored in an inverted position, so the flip semantics are reversed.
context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, !flipY);
context->copyTextureCHROMIUM(GL_TEXTURE_2D, getBackingTexture(), texture, level, internalFormat, destType);
context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, texture, level, internalFormat, destType);
context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false);
context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false);
context->bindTexture(GL_TEXTURE_2D, 0);
context->deleteTexture(sourceTexture);
context->flush();
sharedContext->waitSyncPoint(context->insertSyncPoint());
return true;
}
......
......@@ -108,9 +108,11 @@ public:
// FIXME: current implementations of this method have the restriction that they only work
// with textures that are RGB or RGBA format, UNSIGNED_BYTE type and level 0, as specified in
// Extensions3D::canUseCopyTextureCHROMIUM().
// Destroys the TEXTURE_2D binding for the active texture unit of the passed context
bool copyToPlatformTexture(blink::WebGraphicsContext3D*, Platform3DObject, GLenum, GLenum, GLint, bool, bool);
Platform3DObject getBackingTexture();
bool copyRenderingResultsFromDrawingBuffer(DrawingBuffer*);
void flush();
......
......@@ -329,14 +329,33 @@ bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context,
}
m_context->flush();
}
Platform3DObject sourceTexture = m_colorBuffer;
if (!context->makeContextCurrent())
if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level))
return false;
if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level))
// Contexts may be in a different share group. We must transfer the texture through a mailbox first
RefPtr<MailboxInfo> bufferMailbox = adoptRef(new MailboxInfo());
m_context->genMailboxCHROMIUM(bufferMailbox->mailbox.name);
m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer);
m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, bufferMailbox->mailbox.name);
m_context->flush();
bufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
if (!context->makeContextCurrent())
return false;
Platform3DObject sourceTexture = context->createTexture();
// TODO(bajones): Should be able to change the texture bindings here without reverting but
// something else in the system is depending on it. Failing to revert causes WebGL
// tests to fail. We should find out why and fix it.
GLint boundTexture = 0;
context->getIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
context->bindTexture(GL_TEXTURE_2D, sourceTexture);
context->waitSyncPoint(bufferMailbox->mailbox.syncPoint);
context->consumeTextureCHROMIUM(GL_TEXTURE_2D, bufferMailbox->mailbox.name);
bool unpackPremultiplyAlphaNeeded = false;
bool unpackUnpremultiplyAlphaNeeded = false;
if (m_attributes.alpha && m_attributes.premultipliedAlpha && !premultiplyAlpha)
......@@ -351,7 +370,12 @@ bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context,
context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false);
context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false);
context->pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false);
context->bindTexture(GL_TEXTURE_2D, boundTexture);
context->deleteTexture(sourceTexture);
context->flush();
m_context->waitSyncPoint(context->insertSyncPoint());
return true;
}
......
......@@ -134,6 +134,7 @@ public:
virtual bool prepareMailbox(blink::WebExternalTextureMailbox*, blink::WebExternalBitmap*) OVERRIDE;
virtual void mailboxReleased(const blink::WebExternalTextureMailbox&) OVERRIDE;
// Destroys the TEXTURE_2D binding for the owned context
bool copyToPlatformTexture(blink::WebGraphicsContext3D*, Platform3DObject texture, GLenum internalFormat,
GLenum destType, GLint level, bool premultiplyAlpha, bool flipY);
......
......@@ -554,6 +554,8 @@ public:
//
// May return null if GPU is not supported.
// Returns newly allocated and initialized offscreen WebGraphicsContext3D instance.
// Passing an existing context to shareContext will create the new context in the same share group as the passed context.
virtual WebGraphicsContext3D* createOffscreenGraphicsContext3D(const WebGraphicsContext3D::Attributes&, WebGraphicsContext3D* shareContext) { return 0; }
virtual WebGraphicsContext3D* createOffscreenGraphicsContext3D(const WebGraphicsContext3D::Attributes&) { return 0; }
// Returns a newly allocated and initialized offscreen context provider. The provider may return a null
......
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