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 |