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 |