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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); | 70 m_context->bindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); |
| 71 m_context->activeTexture(m_oldActiveTextureUnit); | 71 m_context->activeTexture(m_oldActiveTextureUnit); |
| 72 } | 72 } |
| 73 | 73 |
| 74 private: | 74 private: |
| 75 blink::WebGraphicsContext3D* m_context; | 75 blink::WebGraphicsContext3D* m_context; |
| 76 GLenum m_oldActiveTextureUnit; | 76 GLenum m_oldActiveTextureUnit; |
| 77 Platform3DObject m_oldTextureUnitZeroId; | 77 Platform3DObject m_oldTextureUnitZeroId; |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 PassRefPtr<DrawingBuffer> DrawingBuffer::create(blink::WebGraphicsContext3D* con text, const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvi ctionManager> contextEvictionManager) | 80 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<blink::WebGraphicsCon text3D> context, const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr <ContextEvictionManager> contextEvictionManager) |
| 81 { | 81 { |
| 82 ASSERT(context); | 82 Extensions3DUtil extensionsUtil(context.get()); |
| 83 Extensions3DUtil extensionsUtil(context); | |
| 84 bool multisampleSupported = extensionsUtil.supportsExtension("GL_CHROMIUM_fr amebuffer_multisample") | 83 bool multisampleSupported = extensionsUtil.supportsExtension("GL_CHROMIUM_fr amebuffer_multisample") |
| 85 && extensionsUtil.supportsExtension("GL_OES_rgb8_rgba8"); | 84 && extensionsUtil.supportsExtension("GL_OES_rgb8_rgba8"); |
| 86 if (multisampleSupported) { | 85 if (multisampleSupported) { |
| 87 extensionsUtil.ensureExtensionEnabled("GL_CHROMIUM_framebuffer_multisamp le"); | 86 extensionsUtil.ensureExtensionEnabled("GL_CHROMIUM_framebuffer_multisamp le"); |
| 88 extensionsUtil.ensureExtensionEnabled("GL_OES_rgb8_rgba8"); | 87 extensionsUtil.ensureExtensionEnabled("GL_OES_rgb8_rgba8"); |
| 89 } | 88 } |
| 90 bool packedDepthStencilSupported = extensionsUtil.supportsExtension("GL_OES_ packed_depth_stencil"); | 89 bool packedDepthStencilSupported = extensionsUtil.supportsExtension("GL_OES_ packed_depth_stencil"); |
| 91 if (packedDepthStencilSupported) | 90 if (packedDepthStencilSupported) |
| 92 extensionsUtil.ensureExtensionEnabled("GL_OES_packed_depth_stencil"); | 91 extensionsUtil.ensureExtensionEnabled("GL_OES_packed_depth_stencil"); |
| 93 | 92 |
| 94 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, mu ltisampleSupported, packedDepthStencilSupported, preserve, contextEvictionManage r)); | 93 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, mu ltisampleSupported, packedDepthStencilSupported, preserve, contextEvictionManage r)); |
| 95 if (!drawingBuffer->initialize(size)) | 94 if (!drawingBuffer->initialize(size)) |
| 96 return PassRefPtr<DrawingBuffer>(); | 95 return PassRefPtr<DrawingBuffer>(); |
| 97 return drawingBuffer.release(); | 96 return drawingBuffer.release(); |
| 98 } | 97 } |
| 99 | 98 |
| 100 DrawingBuffer::DrawingBuffer(blink::WebGraphicsContext3D* context, | 99 DrawingBuffer::DrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D> context, |
| 101 bool multisampleExtensionSupported, | 100 bool multisampleExtensionSupported, |
| 102 bool packedDepthStencilExtensionSupported, | 101 bool packedDepthStencilExtensionSupported, |
| 103 PreserveDrawingBuffer preserve, | 102 PreserveDrawingBuffer preserve, |
| 104 PassRefPtr<ContextEvictionManager> contextEvictionManager) | 103 PassRefPtr<ContextEvictionManager> contextEvictionManager) |
| 105 : m_preserveDrawingBuffer(preserve) | 104 : m_preserveDrawingBuffer(preserve) |
| 106 , m_scissorEnabled(false) | 105 , m_scissorEnabled(false) |
| 107 , m_texture2DBinding(0) | 106 , m_texture2DBinding(0) |
| 108 , m_framebufferBinding(0) | 107 , m_framebufferBinding(0) |
| 109 , m_activeTextureUnit(GL_TEXTURE0) | 108 , m_activeTextureUnit(GL_TEXTURE0) |
| 110 , m_context(context) | 109 , m_context(context) |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 129 , m_sampleCount(4) | 128 , m_sampleCount(4) |
| 130 , m_packAlignment(4) | 129 , m_packAlignment(4) |
| 131 , m_contextEvictionManager(contextEvictionManager) | 130 , m_contextEvictionManager(contextEvictionManager) |
| 132 { | 131 { |
| 133 // Used by browser tests to detect the use of a DrawingBuffer. | 132 // Used by browser tests to detect the use of a DrawingBuffer. |
| 134 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); | 133 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); |
| 135 } | 134 } |
| 136 | 135 |
| 137 DrawingBuffer::~DrawingBuffer() | 136 DrawingBuffer::~DrawingBuffer() |
| 138 { | 137 { |
| 139 releaseResources(); | 138 ASSERT(!m_context); |
| 140 } | 139 } |
| 141 | 140 |
| 142 void DrawingBuffer::markContentsChanged() | 141 void DrawingBuffer::markContentsChanged() |
| 143 { | 142 { |
| 144 m_contentsChanged = true; | 143 m_contentsChanged = true; |
| 145 m_contentsChangeCommitted = false; | 144 m_contentsChangeCommitted = false; |
| 146 m_layerComposited = false; | 145 m_layerComposited = false; |
| 147 } | 146 } |
| 148 | 147 |
| 149 bool DrawingBuffer::layerComposited() const | 148 bool DrawingBuffer::layerComposited() const |
| 150 { | 149 { |
| 151 return m_layerComposited; | 150 return m_layerComposited; |
| 152 } | 151 } |
| 153 | 152 |
| 154 void DrawingBuffer::markLayerComposited() | 153 void DrawingBuffer::markLayerComposited() |
| 155 { | 154 { |
| 156 m_layerComposited = true; | 155 m_layerComposited = true; |
| 157 } | 156 } |
| 158 | 157 |
| 159 blink::WebGraphicsContext3D* DrawingBuffer::context() | 158 blink::WebGraphicsContext3D* DrawingBuffer::context() |
| 160 { | 159 { |
| 161 return m_context; | 160 return m_context.get(); |
| 162 } | 161 } |
| 163 | 162 |
| 164 bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap) | 163 bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap) |
| 165 { | 164 { |
| 166 if (!m_contentsChanged) | 165 if (!m_contentsChanged) |
| 167 return false; | 166 return false; |
| 168 | 167 |
| 169 m_context->makeContextCurrent(); | 168 m_context->makeContextCurrent(); |
| 170 | 169 |
| 171 // Resolve the multisampled buffer into m_colorBuffer texture. | 170 // Resolve the multisampled buffer into m_colorBuffer texture. |
| 172 if (multisample()) | 171 if (multisample()) |
| 173 commit(); | 172 commit(); |
| 174 | 173 |
| 175 if (bitmap) { | 174 if (bitmap) { |
| 176 bitmap->setSize(size()); | 175 bitmap->setSize(size()); |
| 177 | 176 |
| 178 unsigned char* pixels = bitmap->pixels(); | 177 unsigned char* pixels = bitmap->pixels(); |
| 179 bool needPremultiply = m_attributes.alpha && !m_attributes.premultiplied Alpha; | 178 bool needPremultiply = m_attributes.alpha && !m_attributes.premultiplied Alpha; |
| 180 WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversio n::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing; | 179 WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversio n::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing; |
| 181 if (pixels) | 180 if (pixels) |
| 182 readBackFramebuffer(pixels, size().width(), size().height(), Readbac kSkia, op); | 181 readBackFramebuffer(pixels, size().width(), size().height(), Readbac kSkia, op); |
| 183 } | 182 } |
| 184 | 183 |
| 185 // We must restore the texture binding since creating new textures, | 184 // We must restore the texture binding since creating new textures, |
| 186 // consuming and producing mailboxes changes it. | 185 // consuming and producing mailboxes changes it. |
| 187 ScopedTextureUnit0BindingRestorer restorer(m_context, m_activeTextureUnit, m _texture2DBinding); | 186 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding); |
| 188 | 187 |
| 189 // First try to recycle an old buffer. | 188 // First try to recycle an old buffer. |
| 190 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); | 189 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); |
| 191 | 190 |
| 192 // No buffer available to recycle, create a new one. | 191 // No buffer available to recycle, create a new one. |
| 193 if (!frontColorBufferMailbox) { | 192 if (!frontColorBufferMailbox) { |
| 194 unsigned newColorBuffer = createColorTexture(m_size); | 193 unsigned newColorBuffer = createColorTexture(m_size); |
| 195 // Bad things happened, abandon ship. | 194 // Bad things happened, abandon ship. |
| 196 if (!newColorBuffer) | 195 if (!newColorBuffer) |
| 197 return false; | 196 return false; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 224 frontColorBufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint(); | 223 frontColorBufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint(); |
| 225 markLayerComposited(); | 224 markLayerComposited(); |
| 226 | 225 |
| 227 *outMailbox = frontColorBufferMailbox->mailbox; | 226 *outMailbox = frontColorBufferMailbox->mailbox; |
| 228 m_frontColorBuffer = frontColorBufferMailbox->textureId; | 227 m_frontColorBuffer = frontColorBufferMailbox->textureId; |
| 229 return true; | 228 return true; |
| 230 } | 229 } |
| 231 | 230 |
| 232 void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mail box) | 231 void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mail box) |
| 233 { | 232 { |
| 233 if (m_selfToWaitForMailboxes) { | |
| 234 releaseSelf(mailbox); | |
|
Justin Novosad
2014/02/18 18:07:33
naming nit: releaseSelfIfNeeded or releaseSelfIfFi
| |
| 235 return; | |
| 236 } | |
| 237 | |
| 234 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { | 238 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { |
| 235 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; | 239 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; |
| 236 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name ))) { | 240 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name ))) { |
| 237 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; | 241 mailboxInfo->mailbox.syncPoint = mailbox.syncPoint; |
| 238 m_recycledMailboxes.prepend(mailboxInfo.release()); | 242 m_recycledMailboxes.prepend(mailboxInfo.release()); |
| 239 return; | 243 return; |
| 240 } | 244 } |
| 241 } | 245 } |
| 242 ASSERT_NOT_REACHED(); | 246 ASSERT_NOT_REACHED(); |
| 243 } | 247 } |
| 244 | 248 |
| 249 | |
| 250 void DrawingBuffer::releaseSelf(const blink::WebExternalTextureMailbox& mailbox) | |
| 251 { | |
| 252 ASSERT(!m_textureMailboxes.isEmpty()); | |
| 253 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { | |
| 254 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i]; | |
| 255 if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailboxInfo- >mailbox.name))) { | |
| 256 m_context->makeContextCurrent(); | |
| 257 m_context->deleteTexture(mailboxInfo->textureId); | |
| 258 m_textureMailboxes.remove(i); | |
| 259 break; | |
| 260 } | |
| 261 } | |
| 262 if (!m_textureMailboxes.isEmpty()) | |
| 263 return; | |
| 264 | |
| 265 m_context.clear(); | |
| 266 m_layer.clear(); | |
| 267 m_selfToWaitForMailboxes.clear(); | |
| 268 } | |
| 269 | |
| 245 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox() | 270 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox() |
| 246 { | 271 { |
| 247 if (m_recycledMailboxes.isEmpty()) | 272 if (m_recycledMailboxes.isEmpty()) |
| 248 return PassRefPtr<MailboxInfo>(); | 273 return PassRefPtr<MailboxInfo>(); |
| 249 | 274 |
| 250 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); | 275 RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release(); |
| 251 m_recycledMailboxes.removeLast(); | 276 m_recycledMailboxes.removeLast(); |
| 252 | 277 |
| 253 if (mailboxInfo->mailbox.syncPoint) { | 278 if (mailboxInfo->mailbox.syncPoint) { |
| 254 m_context->waitSyncPoint(mailboxInfo->mailbox.syncPoint); | 279 m_context->waitSyncPoint(mailboxInfo->mailbox.syncPoint); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 | 434 |
| 410 m_context->flush(); | 435 m_context->flush(); |
| 411 } | 436 } |
| 412 | 437 |
| 413 void DrawingBuffer::releaseResources() | 438 void DrawingBuffer::releaseResources() |
| 414 { | 439 { |
| 415 m_context->makeContextCurrent(); | 440 m_context->makeContextCurrent(); |
| 416 | 441 |
| 417 clearPlatformLayer(); | 442 clearPlatformLayer(); |
| 418 | 443 |
| 419 for (size_t i = 0; i < m_textureMailboxes.size(); i++) | 444 for (size_t i = 0; i < m_recycledMailboxes.size(); i++) { |
| 420 m_context->deleteTexture(m_textureMailboxes[i]->textureId); | 445 m_context->deleteTexture(m_recycledMailboxes[i]->textureId); |
| 446 | |
| 447 for (size_t j = 0; j < m_textureMailboxes.size(); j++) { | |
| 448 RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[j]; | |
| 449 if (mailboxInfo->textureId == m_recycledMailboxes[i]->textureId) { | |
| 450 ASSERT(!memcmp(mailboxInfo->mailbox.name, m_recycledMailboxes[i] ->mailbox.name, sizeof(mailboxInfo->mailbox.name))); | |
| 451 m_textureMailboxes.remove(j); | |
| 452 break; | |
| 453 } | |
| 454 } | |
| 455 } | |
| 421 | 456 |
| 422 if (m_multisampleColorBuffer) | 457 if (m_multisampleColorBuffer) |
| 423 m_context->deleteRenderbuffer(m_multisampleColorBuffer); | 458 m_context->deleteRenderbuffer(m_multisampleColorBuffer); |
| 424 | 459 |
| 425 if (m_depthStencilBuffer) | 460 if (m_depthStencilBuffer) |
| 426 m_context->deleteRenderbuffer(m_depthStencilBuffer); | 461 m_context->deleteRenderbuffer(m_depthStencilBuffer); |
| 427 | 462 |
| 428 if (m_depthBuffer) | 463 if (m_depthBuffer) |
| 429 m_context->deleteRenderbuffer(m_depthBuffer); | 464 m_context->deleteRenderbuffer(m_depthBuffer); |
| 430 | 465 |
| 431 if (m_stencilBuffer) | 466 if (m_stencilBuffer) |
| 432 m_context->deleteRenderbuffer(m_stencilBuffer); | 467 m_context->deleteRenderbuffer(m_stencilBuffer); |
| 433 | 468 |
| 434 if (m_multisampleFBO) | 469 if (m_multisampleFBO) |
| 435 m_context->deleteFramebuffer(m_multisampleFBO); | 470 m_context->deleteFramebuffer(m_multisampleFBO); |
| 436 | 471 |
| 437 if (m_fbo) | 472 if (m_fbo) |
| 438 m_context->deleteFramebuffer(m_fbo); | 473 m_context->deleteFramebuffer(m_fbo); |
| 439 | 474 |
| 440 m_context = 0; | 475 setSize(IntSize()); |
| 441 | 476 |
| 442 m_colorBuffer = 0; | 477 m_colorBuffer = 0; |
| 443 m_frontColorBuffer = 0; | 478 m_frontColorBuffer = 0; |
| 444 m_multisampleColorBuffer = 0; | 479 m_multisampleColorBuffer = 0; |
| 445 m_depthStencilBuffer = 0; | 480 m_depthStencilBuffer = 0; |
| 446 m_depthBuffer = 0; | 481 m_depthBuffer = 0; |
| 447 m_stencilBuffer = 0; | 482 m_stencilBuffer = 0; |
| 448 m_multisampleFBO = 0; | 483 m_multisampleFBO = 0; |
| 449 m_fbo = 0; | 484 m_fbo = 0; |
| 450 m_contextEvictionManager.clear(); | 485 m_contextEvictionManager.clear(); |
| 451 | 486 |
| 452 m_recycledMailboxes.clear(); | 487 m_recycledMailboxes.clear(); |
| 453 m_textureMailboxes.clear(); | |
| 454 | 488 |
| 455 if (m_layer) { | 489 if (m_layer) |
| 456 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 490 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 491 | |
| 492 if (m_textureMailboxes.isEmpty()) { | |
| 493 m_context.clear(); | |
| 457 m_layer.clear(); | 494 m_layer.clear(); |
| 495 return; | |
| 458 } | 496 } |
| 497 m_selfToWaitForMailboxes = this; | |
| 459 } | 498 } |
| 460 | 499 |
| 461 unsigned DrawingBuffer::createColorTexture(const IntSize& size) | 500 unsigned DrawingBuffer::createColorTexture(const IntSize& size) |
| 462 { | 501 { |
| 463 unsigned offscreenColorTexture = m_context->createTexture(); | 502 unsigned offscreenColorTexture = m_context->createTexture(); |
| 464 if (!offscreenColorTexture) | 503 if (!offscreenColorTexture) |
| 465 return 0; | 504 return 0; |
| 466 | 505 |
| 467 m_context->bindTexture(GL_TEXTURE_2D, offscreenColorTexture); | 506 m_context->bindTexture(GL_TEXTURE_2D, offscreenColorTexture); |
| 468 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 507 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 } | 892 } |
| 854 } | 893 } |
| 855 | 894 |
| 856 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment) | 895 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment) |
| 857 { | 896 { |
| 858 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); | 897 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); |
| 859 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); | 898 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); |
| 860 } | 899 } |
| 861 | 900 |
| 862 } // namespace WebCore | 901 } // namespace WebCore |
| OLD | NEW |