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( ...@@ -159,7 +159,7 @@ blink::WebGraphicsContext3D::Attributes WebGLContextAttributes::attributes(
attrs.failIfMajorPerformanceCaveat = m_failIfMajorPerformanceCaveat; attrs.failIfMajorPerformanceCaveat = m_failIfMajorPerformanceCaveat;
attrs.noExtensions = true; attrs.noExtensions = true;
attrs.shareResources = true; attrs.shareResources = false;
attrs.preferDiscreteGPU = true; attrs.preferDiscreteGPU = true;
attrs.topDocumentURL = topDocumentURL; attrs.topDocumentURL = topDocumentURL;
......
...@@ -80,7 +80,7 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen ...@@ -80,7 +80,7 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
attrs = defaultAttrs.get(); attrs = defaultAttrs.get();
} }
blink::WebGraphicsContext3D::Attributes attributes = attrs->attributes(document.topDocument().url().string(), settings); 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()) { if (!context || !context->makeContextCurrent()) {
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;
......
...@@ -455,6 +455,22 @@ namespace { ...@@ -455,6 +455,22 @@ namespace {
} }
} // namespace anonymous } // 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 { class WebGLRenderingContextLostCallback : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_FAST_ALLOCATED;
public: public:
...@@ -831,6 +847,8 @@ void WebGLRenderingContextBase::paintRenderingResultsToCanvas() ...@@ -831,6 +847,8 @@ void WebGLRenderingContextBase::paintRenderingResultsToCanvas()
canvas()->clearCopiedImage(); canvas()->clearCopiedImage();
m_markedCanvasDirty = false; m_markedCanvasDirty = false;
ScopedTexture2DRestorer restorer(this);
m_drawingBuffer->commit(); m_drawingBuffer->commit();
if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get())) { if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get())) {
canvas()->ensureUnacceleratedImageBuffer(); canvas()->ensureUnacceleratedImageBuffer();
...@@ -3406,9 +3424,12 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in ...@@ -3406,9 +3424,12 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
return; return;
WebGLTexture* texture = validateTextureBinding("texImage2D", target, true); WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
// If possible, copy from the canvas element directly to the texture // If possible, copy from the canvas element directly to the texture
// via the GPU, without a read-back to system memory. // via the GPU, without a read-back to system memory.
if (GL_TEXTURE_2D == target && texture) { if (GL_TEXTURE_2D == target && texture) {
ScopedTexture2DRestorer restorer(this);
if (!canvas->is3D()) { if (!canvas->is3D()) {
ImageBuffer* buffer = canvas->buffer(); ImageBuffer* buffer = canvas->buffer();
if (buffer && buffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type, if (buffer && buffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
...@@ -3418,6 +3439,7 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in ...@@ -3418,6 +3439,7 @@ void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum in
} }
} else { } else {
WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext()); WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
ScopedTexture2DRestorer restorer(gl);
if (gl && gl->m_drawingBuffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type, if (gl && gl->m_drawingBuffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
level, m_unpackPremultiplyAlpha, m_unpackFlipY)) { level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type); texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
...@@ -5338,7 +5360,7 @@ void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB ...@@ -5338,7 +5360,7 @@ void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB
return; return;
blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes->attributes(canvas()->document().topDocument().url().string(), settings); 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 (!context) {
if (m_contextLostMode == RealLostContext) { if (m_contextLostMode == RealLostContext) {
m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE); m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE);
......
...@@ -356,6 +356,7 @@ protected: ...@@ -356,6 +356,7 @@ protected:
friend class WebGLCompressedTextureS3TC; friend class WebGLCompressedTextureS3TC;
friend class WebGLRenderingContextErrorMessageCallback; friend class WebGLRenderingContextErrorMessageCallback;
friend class WebGLVertexArrayObjectOES; friend class WebGLVertexArrayObjectOES;
friend class ScopedTexture2DRestorer;
WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*); WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
void initializeNewContext(); void initializeNewContext();
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "platform/image-encoders/skia/PNGImageEncoder.h" #include "platform/image-encoders/skia/PNGImageEncoder.h"
#include "platform/image-encoders/skia/WEBPImageEncoder.h" #include "platform/image-encoders/skia/WEBPImageEncoder.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "public/platform/WebExternalTextureMailbox.h"
#include "public/platform/WebGraphicsContext3D.h" #include "public/platform/WebGraphicsContext3D.h"
#include "public/platform/WebGraphicsContext3DProvider.h" #include "public/platform/WebGraphicsContext3DProvider.h"
#include "third_party/skia/include/effects/SkTableColorFilter.h" #include "third_party/skia/include/effects/SkTableColorFilter.h"
...@@ -138,22 +139,52 @@ bool ImageBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Pl ...@@ -138,22 +139,52 @@ bool ImageBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Pl
if (!m_surface->isAccelerated() || !platformLayer() || !isValid()) if (!m_surface->isAccelerated() || !platformLayer() || !isValid())
return false; return false;
if (!context->makeContextCurrent()) if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level))
return false; 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; 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. // The canvas is stored in a premultiplied format, so unpremultiply if necessary.
context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, !premultiplyAlpha); context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, !premultiplyAlpha);
// The canvas is stored in an inverted position, so the flip semantics are reversed. // The canvas is stored in an inverted position, so the flip semantics are reversed.
context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, !flipY); 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_FLIP_Y_CHROMIUM, false);
context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false);
context->bindTexture(GL_TEXTURE_2D, 0);
context->deleteTexture(sourceTexture);
context->flush(); context->flush();
sharedContext->waitSyncPoint(context->insertSyncPoint());
return true; return true;
} }
......
...@@ -108,9 +108,11 @@ public: ...@@ -108,9 +108,11 @@ public:
// FIXME: current implementations of this method have the restriction that they only work // 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 // with textures that are RGB or RGBA format, UNSIGNED_BYTE type and level 0, as specified in
// Extensions3D::canUseCopyTextureCHROMIUM(). // 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); bool copyToPlatformTexture(blink::WebGraphicsContext3D*, Platform3DObject, GLenum, GLenum, GLint, bool, bool);
Platform3DObject getBackingTexture(); Platform3DObject getBackingTexture();
bool copyRenderingResultsFromDrawingBuffer(DrawingBuffer*); bool copyRenderingResultsFromDrawingBuffer(DrawingBuffer*);
void flush(); void flush();
......
...@@ -329,14 +329,33 @@ bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, ...@@ -329,14 +329,33 @@ bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context,
} }
m_context->flush(); m_context->flush();
} }
Platform3DObject sourceTexture = m_colorBuffer;
if (!context->makeContextCurrent()) if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level))
return false; 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; 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 unpackPremultiplyAlphaNeeded = false;
bool unpackUnpremultiplyAlphaNeeded = false; bool unpackUnpremultiplyAlphaNeeded = false;
if (m_attributes.alpha && m_attributes.premultipliedAlpha && !premultiplyAlpha) if (m_attributes.alpha && m_attributes.premultipliedAlpha && !premultiplyAlpha)
...@@ -351,7 +370,12 @@ bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, ...@@ -351,7 +370,12 @@ bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context,
context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false); context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false);
context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false);
context->pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false); context->pixelStorei(GC3D_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, false);
context->bindTexture(GL_TEXTURE_2D, boundTexture);
context->deleteTexture(sourceTexture);
context->flush(); context->flush();
m_context->waitSyncPoint(context->insertSyncPoint());
return true; return true;
} }
......
...@@ -134,6 +134,7 @@ public: ...@@ -134,6 +134,7 @@ public:
virtual bool prepareMailbox(blink::WebExternalTextureMailbox*, blink::WebExternalBitmap*) OVERRIDE; virtual bool prepareMailbox(blink::WebExternalTextureMailbox*, blink::WebExternalBitmap*) OVERRIDE;
virtual void mailboxReleased(const blink::WebExternalTextureMailbox&) 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, bool copyToPlatformTexture(blink::WebGraphicsContext3D*, Platform3DObject texture, GLenum internalFormat,
GLenum destType, GLint level, bool premultiplyAlpha, bool flipY); GLenum destType, GLint level, bool premultiplyAlpha, bool flipY);
......
...@@ -554,6 +554,8 @@ public: ...@@ -554,6 +554,8 @@ public:
// //
// May return null if GPU is not supported. // May return null if GPU is not supported.
// Returns newly allocated and initialized offscreen WebGraphicsContext3D instance. // 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; } virtual WebGraphicsContext3D* createOffscreenGraphicsContext3D(const WebGraphicsContext3D::Attributes&) { return 0; }
// Returns a newly allocated and initialized offscreen context provider. The provider may return a null // 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