Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010, Google Inc. All rights reserved. | 2 * Copyright (c) 2010, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 return textureId; | 169 return textureId; |
| 170 } | 170 } |
| 171 | 171 |
| 172 WebKit::WebGraphicsContext3D* DrawingBuffer::context() | 172 WebKit::WebGraphicsContext3D* DrawingBuffer::context() |
| 173 { | 173 { |
| 174 if (!m_context) | 174 if (!m_context) |
| 175 return 0; | 175 return 0; |
| 176 return m_context->webContext(); | 176 return m_context->webContext(); |
| 177 } | 177 } |
| 178 | 178 |
| 179 bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox ) | 179 bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox , bool bitmap) |
| 180 { | 180 { |
| 181 if (!m_context || !m_contentsChanged || !m_lastColorBuffer) | 181 if (!m_context || !m_contentsChanged || !m_lastColorBuffer) |
| 182 return false; | 182 return false; |
| 183 | 183 |
| 184 m_context->makeContextCurrent(); | 184 m_context->makeContextCurrent(); |
| 185 | 185 |
| 186 // Resolve the multisampled buffer into the texture referenced by m_lastColo rBuffer mailbox. | 186 // Resolve the multisampled buffer into the texture referenced by m_lastColo rBuffer mailbox. |
| 187 if (multisample()) | 187 if (multisample()) |
| 188 commit(); | 188 commit(); |
| 189 | 189 |
| 190 if (bitmap) { | |
| 191 SkBitmap* bitmap = &m_lastColorBuffer->mailbox.bitmap; | |
| 192 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); | |
| 193 if (bitmap->width() != size().width() | |
| 194 || bitmap->height() != size().height()) { | |
| 195 bitmap->setConfig(SkBitmap::kARGB_8888_Config, size().width(), size( ).height(), 0); | |
| 196 bitmap->allocPixels(); | |
| 197 } | |
| 198 m_lastColorBuffer->mailbox.size = size(); | |
| 199 | |
| 200 SkAutoLockPixels bitmapLock(*bitmap); | |
| 201 | |
| 202 unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()) ; | |
| 203 m_context->readPixels(0, 0, size().width(), size().height(), GraphicsCon text3D::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
| |
| 204 for (int i = 0; i < size().width() * size().height() * 4; i += 4) | |
| 205 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
| |
| 206 | |
| 207 if (m_attributes.alpha && !m_attributes.premultipliedAlpha) { | |
| 208 for (int i = 0; i < size().width() * size().height() * 4; i += 4) { | |
| 209 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 25 5); | |
| 210 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 25 5); | |
| 211 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 25 5); | |
| 212 } | |
| 213 } | |
| 214 } | |
| 215 | |
| 190 // We must restore the texture binding since creating new textures, | 216 // We must restore the texture binding since creating new textures, |
| 191 // consuming and producing mailboxes changes it. | 217 // consuming and producing mailboxes changes it. |
| 192 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding); | 218 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding); |
| 193 | 219 |
| 194 // First try to recycle an old buffer. | 220 // First try to recycle an old buffer. |
| 195 RefPtr<MailboxInfo> nextFrontColorBuffer = getRecycledMailbox(); | 221 RefPtr<MailboxInfo> nextFrontColorBuffer = getRecycledMailbox(); |
| 196 | 222 |
| 197 // No buffer available to recycle, create a new one. | 223 // No buffer available to recycle, create a new one. |
| 198 if (!nextFrontColorBuffer) { | 224 if (!nextFrontColorBuffer) { |
| 199 unsigned newColorBuffer = createColorTexture(m_size); | 225 unsigned newColorBuffer = createColorTexture(m_size); |
| 200 // Bad things happened, abandon ship. | 226 // Bad things happened, abandon ship. |
| 201 if (!newColorBuffer) | 227 if (!newColorBuffer) |
| 202 return false; | 228 return false; |
| 203 | 229 |
| 204 nextFrontColorBuffer = createNewMailbox(newColorBuffer); | 230 nextFrontColorBuffer = createNewMailbox(newColorBuffer); |
| 205 } | 231 } |
| 206 | 232 |
| 207 if (m_preserveDrawingBuffer == Discard) { | 233 if (m_preserveDrawingBuffer == Discard) { |
| 208 m_colorBuffer = nextFrontColorBuffer->textureId; | 234 m_colorBuffer = nextFrontColorBuffer->textureId; |
| 209 swap(nextFrontColorBuffer, m_lastColorBuffer); | 235 swap(nextFrontColorBuffer, m_lastColorBuffer); |
| 210 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a | 236 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a |
| 211 // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding. | 237 // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding. |
| 212 // If this stops being true at some point, we should track the current f ramebuffer binding in the DrawingBuffer and restore | 238 // If this stops being true at some point, we should track the current f ramebuffer binding in the DrawingBuffer and restore |
| 213 // it after attaching the new back buffer here. | 239 // it after attaching the new back buffer here. |
| 214 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); | 240 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); |
| 215 m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, Graphics Context3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0); | 241 m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, Graphics Context3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0); |
| 216 } else { | 242 } else { |
| 217 Extensions3D* extensions = m_context->getExtensions(); | 243 Extensions3D* extensions = m_context->getExtensions(); |
| 218 extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_colorBu ffer, nextFrontColorBuffer->textureId, 0, GraphicsContext3D::RGBA, GraphicsConte xt3D::UNSIGNED_BYTE); | 244 extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_colorBu ffer, nextFrontColorBuffer->textureId, 0, GraphicsContext3D::RGBA, GraphicsConte xt3D::UNSIGNED_BYTE); |
| 245 SkBitmap nextBitmap = nextFrontColorBuffer->mailbox.bitmap; | |
| 246 nextFrontColorBuffer->mailbox.bitmap = m_lastColorBuffer->mailbox.bitmap ; | |
| 247 nextFrontColorBuffer->mailbox.size = m_lastColorBuffer->mailbox.size; | |
| 248 m_lastColorBuffer->mailbox.bitmap = nextBitmap; | |
| 219 } | 249 } |
| 220 | 250 |
| 221 if (multisample() && !m_framebufferBinding) | 251 if (multisample() && !m_framebufferBinding) |
| 222 bind(); | 252 bind(); |
| 223 else | 253 else |
| 224 restoreFramebufferBinding(); | 254 restoreFramebufferBinding(); |
| 225 | 255 |
| 226 m_contentsChanged = false; | 256 m_contentsChanged = false; |
| 227 | 257 |
| 228 context()->bindTexture(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer-> textureId); | 258 context()->bindTexture(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer-> textureId); |
| 229 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, nextFrontCo lorBuffer->mailbox.name); | 259 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, nextFrontCo lorBuffer->mailbox.name); |
| 230 context()->flush(); | 260 context()->flush(); |
| 231 m_context->markLayerComposited(); | 261 m_context->markLayerComposited(); |
| 232 | 262 |
| 233 *outMailbox = nextFrontColorBuffer->mailbox; | 263 *outMailbox = nextFrontColorBuffer->mailbox; |
| 264 | |
| 234 m_frontColorBuffer = nextFrontColorBuffer->textureId; | 265 m_frontColorBuffer = nextFrontColorBuffer->textureId; |
| 235 return true; | 266 return true; |
| 236 } | 267 } |
| 237 | 268 |
| 238 void DrawingBuffer::mailboxReleased(const WebKit::WebExternalTextureMailbox& mai lbox) | 269 void DrawingBuffer::mailboxReleased(const WebKit::WebExternalTextureMailbox& mai lbox) |
| 239 { | 270 { |
| 240 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { | 271 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { |
| 241 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; | 272 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; |
| 242 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.nam e))) { | 273 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name ))) { |
| 243 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; | 274 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; |
| 244 m_recycledMailboxes.append(mailboxInfo.release()); | 275 mailboxInfo->mailbox.bitmap = mailbox.bitmap; |
| 245 return; | 276 m_recycledMailboxes.append(mailboxInfo.release()); |
| 246 } | 277 return; |
| 278 } | |
| 247 } | 279 } |
| 248 ASSERT_NOT_REACHED(); | 280 ASSERT_NOT_REACHED(); |
| 249 } | 281 } |
| 250 | 282 |
| 251 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::getRecycledMailbox() | 283 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::getRecycledMailbox() |
| 252 { | 284 { |
| 253 if (!m_context || m_recycledMailboxes.isEmpty()) | 285 if (!m_context || m_recycledMailboxes.isEmpty()) |
| 254 return PassRefPtr<MailboxInfo>(); | 286 return PassRefPtr<MailboxInfo>(); |
| 255 | 287 |
| 256 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); | 288 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 814 | 846 |
| 815 void DrawingBuffer::bind() | 847 void DrawingBuffer::bind() |
| 816 { | 848 { |
| 817 if (!m_context) | 849 if (!m_context) |
| 818 return; | 850 return; |
| 819 | 851 |
| 820 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); | 852 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); |
| 821 } | 853 } |
| 822 | 854 |
| 823 } // namespace WebCore | 855 } // namespace WebCore |
| OLD | NEW |