Index: Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
diff --git a/Source/core/platform/graphics/gpu/DrawingBuffer.cpp b/Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
index 5940b06e7cd3d5cea867b30fbcc6f362f075d436..4ca8b0fa727e3aedbce5cab54f775f5a99bd2bc2 100644 |
--- a/Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
+++ b/Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
@@ -176,7 +176,7 @@ WebKit::WebGraphicsContext3D* DrawingBuffer::context() |
return m_context->webContext(); |
} |
-bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox) |
+bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox, bool bitmap) |
{ |
if (!m_context || !m_contentsChanged || !m_lastColorBuffer) |
return false; |
@@ -187,6 +187,32 @@ bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox |
if (multisample()) |
commit(); |
+ if (bitmap) { |
+ SkBitmap* bitmap = &m_lastColorBuffer->mailbox.bitmap; |
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); |
+ if (bitmap->width() != size().width() |
+ || bitmap->height() != size().height()) { |
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, size().width(), size().height(), 0); |
+ bitmap->allocPixels(); |
+ } |
+ m_lastColorBuffer->mailbox.size = size(); |
+ |
+ SkAutoLockPixels bitmapLock(*bitmap); |
+ |
+ unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); |
+ m_context->readPixels(0, 0, size().width(), size().height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels); |
Ken Russell (switch to Gerrit)
2013/06/27 13:41:02
We'd better be careful that the user hasn't set th
|
+ for (int i = 0; i < size().width() * size().height() * 4; i += 4) |
+ swap(pixels[i + 0], pixels[i + 2]); |
Ken Russell (switch to Gerrit)
2013/06/27 13:41:02
I'm pretty sure this needs to be conditional depen
|
+ |
+ if (m_attributes.alpha && !m_attributes.premultipliedAlpha) { |
+ for (int i = 0; i < size().width() * size().height() * 4; i += 4) { |
+ pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); |
+ pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); |
+ pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); |
+ } |
+ } |
+ } |
+ |
// We must restore the texture binding since creating new textures, |
// consuming and producing mailboxes changes it. |
ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureUnit, m_texture2DBinding); |
@@ -216,6 +242,10 @@ bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox |
} else { |
Extensions3D* extensions = m_context->getExtensions(); |
extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_colorBuffer, nextFrontColorBuffer->textureId, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE); |
+ SkBitmap nextBitmap = nextFrontColorBuffer->mailbox.bitmap; |
+ nextFrontColorBuffer->mailbox.bitmap = m_lastColorBuffer->mailbox.bitmap; |
+ nextFrontColorBuffer->mailbox.size = m_lastColorBuffer->mailbox.size; |
+ m_lastColorBuffer->mailbox.bitmap = nextBitmap; |
} |
if (multisample() && !m_framebufferBinding) |
@@ -231,6 +261,7 @@ bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox |
m_context->markLayerComposited(); |
*outMailbox = nextFrontColorBuffer->mailbox; |
+ |
m_frontColorBuffer = nextFrontColorBuffer->textureId; |
return true; |
} |
@@ -238,12 +269,13 @@ bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox |
void DrawingBuffer::mailboxReleased(const WebKit::WebExternalTextureMailbox& mailbox) |
{ |
for (size_t i = 0; i < m_textureMailboxes.size(); i++) { |
- RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; |
- if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name))) { |
- mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; |
- m_recycledMailboxes.append(mailboxInfo.release()); |
- return; |
- } |
+ RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; |
+ if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name))) { |
+ mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; |
+ mailboxInfo->mailbox.bitmap = mailbox.bitmap; |
+ m_recycledMailboxes.append(mailboxInfo.release()); |
+ return; |
+ } |
} |
ASSERT_NOT_REACHED(); |
} |