Index: Source/platform/graphics/gpu/DrawingBuffer.cpp |
diff --git a/Source/platform/graphics/gpu/DrawingBuffer.cpp b/Source/platform/graphics/gpu/DrawingBuffer.cpp |
index 8927cd7eb2ea07757d87929eff452128fe81650e..d0d58ca3031a8200e51e76541b9972dc86f5e376 100644 |
--- a/Source/platform/graphics/gpu/DrawingBuffer.cpp |
+++ b/Source/platform/graphics/gpu/DrawingBuffer.cpp |
@@ -32,6 +32,7 @@ |
#include "platform/graphics/gpu/DrawingBuffer.h" |
+#include "RuntimeEnabledFeatures.h" |
#include <algorithm> |
#include "platform/TraceEvent.h" |
#include "platform/graphics/GraphicsLayer.h" |
@@ -129,8 +130,6 @@ DrawingBuffer::DrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D> context, |
, m_multisampleExtensionSupported(multisampleExtensionSupported) |
, m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) |
, m_fbo(0) |
- , m_colorBuffer(0) |
- , m_frontColorBuffer(0) |
, m_depthStencilBuffer(0) |
, m_depthBuffer(0) |
, m_stencilBuffer(0) |
@@ -228,27 +227,29 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, |
// No buffer available to recycle, create a new one. |
if (!frontColorBufferMailbox) { |
- unsigned newColorBuffer = createColorTexture(m_size); |
+ TextureInfo newTexture; |
+ newTexture.textureId = createColorTexture(); |
+ allocateTextureMemory(&newTexture, m_size); |
// Bad things happened, abandon ship. |
- if (!newColorBuffer) |
+ if (!newTexture.textureId) |
return false; |
- frontColorBufferMailbox = createNewMailbox(newColorBuffer); |
+ frontColorBufferMailbox = createNewMailbox(newTexture); |
} |
if (m_preserveDrawingBuffer == Discard) { |
- swap(frontColorBufferMailbox->textureId, m_colorBuffer); |
+ swap(frontColorBufferMailbox->textureInfo, m_colorBuffer); |
// It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a |
// WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding. |
// If this stops being true at some point, we should track the current framebuffer binding in the DrawingBuffer and restore |
// it after attaching the new back buffer here. |
m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
if (m_multisampleMode == ImplicitResolve) |
- m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0, m_sampleCount); |
+ m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount); |
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.textureId, 0); |
} else { |
- m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_colorBuffer, frontColorBufferMailbox->textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
+ m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_colorBuffer.textureId, frontColorBufferMailbox->textureInfo.textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
} |
if (m_multisampleMode != None && !m_framebufferBinding) |
@@ -258,17 +259,18 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, |
m_contentsChanged = false; |
- m_context->bindTexture(GL_TEXTURE_2D, frontColorBufferMailbox->textureId); |
+ m_context->bindTexture(GL_TEXTURE_2D, frontColorBufferMailbox->textureInfo.textureId); |
m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, frontColorBufferMailbox->mailbox.name); |
m_context->flush(); |
frontColorBufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint(); |
+ frontColorBufferMailbox->mailbox.allowOverlay = frontColorBufferMailbox->textureInfo.imageId != 0; |
markLayerComposited(); |
// set m_parentDrawingBuffer to make sure 'this' stays alive as long as it has live mailboxes |
ASSERT(!frontColorBufferMailbox->m_parentDrawingBuffer); |
frontColorBufferMailbox->m_parentDrawingBuffer = this; |
*outMailbox = frontColorBufferMailbox->mailbox; |
- m_frontColorBuffer = frontColorBufferMailbox->textureId; |
+ m_frontColorBuffer = frontColorBufferMailbox->textureInfo; |
return true; |
} |
@@ -322,19 +324,19 @@ PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox() |
} |
if (mailboxInfo->size != m_size) { |
- m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->textureId); |
- texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, m_size.width(), m_size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
+ m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->textureInfo.textureId); |
+ allocateTextureMemory(&mailboxInfo->textureInfo, m_size); |
mailboxInfo->size = m_size; |
} |
return mailboxInfo.release(); |
} |
-PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned textureId) |
+PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const TextureInfo& info) |
{ |
RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo()); |
m_context->genMailboxCHROMIUM(returnMailbox->mailbox.name); |
- returnMailbox->textureId = textureId; |
+ returnMailbox->textureInfo = info; |
returnMailbox->size = m_size; |
m_textureMailboxes.append(returnMailbox); |
return returnMailbox.release(); |
@@ -346,7 +348,10 @@ void DrawingBuffer::deleteMailbox(const blink::WebExternalTextureMailbox& mailbo |
if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) { |
if (mailbox.syncPoint) |
m_context->waitSyncPoint(mailbox.syncPoint); |
- m_context->deleteTexture(m_textureMailboxes[i]->textureId); |
+ |
+ deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); |
+ |
+ m_context->deleteTexture(m_textureMailboxes[i]->textureInfo.textureId); |
m_textureMailboxes.remove(i); |
return; |
} |
@@ -394,11 +399,11 @@ bool DrawingBuffer::initialize(const IntSize& size) |
m_fbo = m_context->createFramebuffer(); |
m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
- m_colorBuffer = createColorTexture(); |
+ m_colorBuffer.textureId = createColorTexture(); |
if (m_multisampleMode == ImplicitResolve) |
- m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0, m_sampleCount); |
+ m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount); |
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.textureId, 0); |
createSecondaryBuffers(); |
return reset(size); |
} |
@@ -424,7 +429,7 @@ bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, |
// 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->bindTexture(GL_TEXTURE_2D, m_colorBuffer.textureId); |
m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, bufferMailbox->mailbox.name); |
m_context->flush(); |
@@ -498,7 +503,7 @@ void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer) |
if (tex) { |
RefPtr<MailboxInfo> bufferMailbox = adoptRef(new MailboxInfo()); |
m_context->genMailboxCHROMIUM(bufferMailbox->mailbox.name); |
- m_context->bindTexture(GL_TEXTURE_2D, m_frontColorBuffer); |
+ m_context->bindTexture(GL_TEXTURE_2D, m_frontColorBuffer.textureId); |
m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, bufferMailbox->mailbox.name); |
m_context->flush(); |
@@ -530,8 +535,9 @@ void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer) |
// We have to make a copy of it here and bind that copy instead. |
// FIXME: That's not true any more, provided we don't change texture |
// parameters. |
- unsigned sourceTexture = createColorTexture(m_size); |
- m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer, sourceTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
+ unsigned sourceTexture = createColorTexture(); |
+ texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, m_size.width(), m_size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
+ m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer.textureId, sourceTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
// Since we're using the same context as WebGL, we have to restore any state we change (in this case, just the framebuffer binding). |
// FIXME: The WebGLRenderingContext tracks the current framebuffer binding, it would be slightly more efficient to use this value |
@@ -588,13 +594,15 @@ void DrawingBuffer::beginDestruction() |
if (m_stencilBuffer) |
m_context->deleteRenderbuffer(m_stencilBuffer); |
- if (m_colorBuffer) |
- m_context->deleteTexture(m_colorBuffer); |
+ if (m_colorBuffer.textureId) { |
+ deleteChromiumImageForTexture(&m_colorBuffer); |
+ m_context->deleteTexture(m_colorBuffer.textureId); |
+ } |
setSize(IntSize()); |
- m_colorBuffer = 0; |
- m_frontColorBuffer = 0; |
+ m_colorBuffer = TextureInfo(); |
+ m_frontColorBuffer = TextureInfo(); |
m_multisampleColorBuffer = 0; |
m_depthStencilBuffer = 0; |
m_depthBuffer = 0; |
@@ -607,7 +615,7 @@ void DrawingBuffer::beginDestruction() |
GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
} |
-unsigned DrawingBuffer::createColorTexture(const IntSize& size) |
+unsigned DrawingBuffer::createColorTexture() |
{ |
unsigned offscreenColorTexture = m_context->createTexture(); |
if (!offscreenColorTexture) |
@@ -618,8 +626,6 @@ unsigned DrawingBuffer::createColorTexture(const IntSize& size) |
m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
- if (!size.isEmpty()) |
- texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width(), size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
return offscreenColorTexture; |
} |
@@ -639,14 +645,14 @@ bool DrawingBuffer::resizeFramebuffer(const IntSize& size) |
// resize regular FBO |
m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
- m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer); |
+ m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer.textureId); |
- texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width(), size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
+ allocateTextureMemory(&m_colorBuffer, size); |
if (m_multisampleMode == ImplicitResolve) |
- m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0, m_sampleCount); |
+ m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer.textureId, 0, m_sampleCount); |
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.textureId, 0); |
m_context->bindTexture(GL_TEXTURE_2D, 0); |
@@ -1020,4 +1026,28 @@ void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in |
m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); |
} |
+void DrawingBuffer::allocateTextureMemory(TextureInfo* info, const IntSize& size) |
+{ |
+ if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) { |
+ deleteChromiumImageForTexture(info); |
+ |
+ info->imageId = m_context->createImageCHROMIUM(size.width(), size.height(), GL_RGBA8_OES, GC3D_IMAGE_SCANOUT_CHROMIUM); |
+ if (info->imageId) { |
+ m_context->bindTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); |
+ return; |
+ } |
+ } |
+ |
+ texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width(), size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); |
+} |
+ |
+void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info) |
+{ |
+ if (info->imageId) { |
+ m_context->releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, info->imageId); |
+ m_context->destroyImageCHROMIUM(info->imageId); |
+ info->imageId = 0; |
+ } |
+} |
+ |
} // namespace WebCore |