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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 , m_contentsChangeCommitted(false) | 140 , m_contentsChangeCommitted(false) |
141 , m_layerComposited(false) | 141 , m_layerComposited(false) |
142 , m_multisampleMode(None) | 142 , m_multisampleMode(None) |
143 , m_internalColorFormat(0) | 143 , m_internalColorFormat(0) |
144 , m_colorFormat(0) | 144 , m_colorFormat(0) |
145 , m_internalRenderbufferFormat(0) | 145 , m_internalRenderbufferFormat(0) |
146 , m_maxTextureSize(0) | 146 , m_maxTextureSize(0) |
147 , m_sampleCount(0) | 147 , m_sampleCount(0) |
148 , m_packAlignment(4) | 148 , m_packAlignment(4) |
149 , m_destructionInProgress(false) | 149 , m_destructionInProgress(false) |
150 #ifdef ENABLE_WEBGL_IMAGE_CHROMIUM | |
piman
2014/05/09 19:34:14
Why an ifdef? Should we, say, turn it on with a co
| |
151 , m_useImageChromium(true) | |
152 #else | |
153 , m_useImageChromium(false) | |
154 #endif | |
150 , m_contextEvictionManager(contextEvictionManager) | 155 , m_contextEvictionManager(contextEvictionManager) |
151 { | 156 { |
152 // Used by browser tests to detect the use of a DrawingBuffer. | 157 // Used by browser tests to detect the use of a DrawingBuffer. |
153 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); | 158 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); |
154 #ifndef NDEBUG | 159 #ifndef NDEBUG |
155 drawingBufferCounter.increment(); | 160 drawingBufferCounter.increment(); |
156 #endif | 161 #endif |
157 } | 162 } |
158 | 163 |
159 DrawingBuffer::~DrawingBuffer() | 164 DrawingBuffer::~DrawingBuffer() |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 | 226 |
222 // We must restore the texture binding since creating new textures, | 227 // We must restore the texture binding since creating new textures, |
223 // consuming and producing mailboxes changes it. | 228 // consuming and producing mailboxes changes it. |
224 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding); | 229 ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureU nit, m_texture2DBinding); |
225 | 230 |
226 // First try to recycle an old buffer. | 231 // First try to recycle an old buffer. |
227 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); | 232 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); |
228 | 233 |
229 // No buffer available to recycle, create a new one. | 234 // No buffer available to recycle, create a new one. |
230 if (!frontColorBufferMailbox) { | 235 if (!frontColorBufferMailbox) { |
231 unsigned newColorBuffer = createColorTexture(m_size); | 236 unsigned newColorBuffer = createColorTexture(); |
237 allocateTextureMemory(newColorBuffer, m_size); | |
232 // Bad things happened, abandon ship. | 238 // Bad things happened, abandon ship. |
233 if (!newColorBuffer) | 239 if (!newColorBuffer) |
234 return false; | 240 return false; |
235 | 241 |
236 frontColorBufferMailbox = createNewMailbox(newColorBuffer); | 242 frontColorBufferMailbox = createNewMailbox(newColorBuffer); |
237 } | 243 } |
238 | 244 |
239 if (m_preserveDrawingBuffer == Discard) { | 245 if (m_preserveDrawingBuffer == Discard) { |
240 swap(frontColorBufferMailbox->textureId, m_colorBuffer); | 246 swap(frontColorBufferMailbox->textureId, m_colorBuffer); |
241 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a | 247 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 } | 322 } |
317 ASSERT(mailboxInfo); | 323 ASSERT(mailboxInfo); |
318 | 324 |
319 if (mailboxInfo->mailbox.syncPoint) { | 325 if (mailboxInfo->mailbox.syncPoint) { |
320 m_context->waitSyncPoint(mailboxInfo->mailbox.syncPoint); | 326 m_context->waitSyncPoint(mailboxInfo->mailbox.syncPoint); |
321 mailboxInfo->mailbox.syncPoint = 0; | 327 mailboxInfo->mailbox.syncPoint = 0; |
322 } | 328 } |
323 | 329 |
324 if (mailboxInfo->size != m_size) { | 330 if (mailboxInfo->size != m_size) { |
325 m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->textureId); | 331 m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->textureId); |
326 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, m_size.w idth(), m_size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | 332 allocateTextureMemory(mailboxInfo->textureId, m_size); |
327 mailboxInfo->size = m_size; | 333 mailboxInfo->size = m_size; |
328 } | 334 } |
329 | 335 |
330 return mailboxInfo.release(); | 336 return mailboxInfo.release(); |
331 } | 337 } |
332 | 338 |
333 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned textureId) | 339 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned textureId) |
334 { | 340 { |
335 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo()); | 341 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo()); |
336 m_context->genMailboxCHROMIUM(returnMailbox->mailbox.name); | 342 m_context->genMailboxCHROMIUM(returnMailbox->mailbox.name); |
337 returnMailbox->textureId = textureId; | 343 returnMailbox->textureId = textureId; |
338 returnMailbox->size = m_size; | 344 returnMailbox->size = m_size; |
339 m_textureMailboxes.append(returnMailbox); | 345 m_textureMailboxes.append(returnMailbox); |
340 return returnMailbox.release(); | 346 return returnMailbox.release(); |
341 } | 347 } |
342 | 348 |
343 void DrawingBuffer::deleteMailbox(const blink::WebExternalTextureMailbox& mailbo x) | 349 void DrawingBuffer::deleteMailbox(const blink::WebExternalTextureMailbox& mailbo x) |
344 { | 350 { |
345 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { | 351 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { |
346 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) { | 352 if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) { |
347 if (mailbox.syncPoint) | 353 if (mailbox.syncPoint) |
348 m_context->waitSyncPoint(mailbox.syncPoint); | 354 m_context->waitSyncPoint(mailbox.syncPoint); |
355 if (m_useImageChromium) | |
356 deleteChromiumImageForTexture(m_textureMailboxes[i]->textureId); | |
357 | |
349 m_context->deleteTexture(m_textureMailboxes[i]->textureId); | 358 m_context->deleteTexture(m_textureMailboxes[i]->textureId); |
350 m_textureMailboxes.remove(i); | 359 m_textureMailboxes.remove(i); |
351 return; | 360 return; |
352 } | 361 } |
353 } | 362 } |
354 ASSERT_NOT_REACHED(); | 363 ASSERT_NOT_REACHED(); |
355 } | 364 } |
356 | 365 |
357 bool DrawingBuffer::initialize(const IntSize& size) | 366 bool DrawingBuffer::initialize(const IntSize& size) |
358 { | 367 { |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
523 context->deleteTexture(sourceTexture); | 532 context->deleteTexture(sourceTexture); |
524 context->flush(); | 533 context->flush(); |
525 m_context->waitSyncPoint(context->insertSyncPoint()); | 534 m_context->waitSyncPoint(context->insertSyncPoint()); |
526 return; | 535 return; |
527 } | 536 } |
528 | 537 |
529 // Since the m_frontColorBuffer was produced and sent to the compositor, it cannot be bound to an fbo. | 538 // Since the m_frontColorBuffer was produced and sent to the compositor, it cannot be bound to an fbo. |
530 // We have to make a copy of it here and bind that copy instead. | 539 // We have to make a copy of it here and bind that copy instead. |
531 // FIXME: That's not true any more, provided we don't change texture | 540 // FIXME: That's not true any more, provided we don't change texture |
532 // parameters. | 541 // parameters. |
533 unsigned sourceTexture = createColorTexture(m_size); | 542 unsigned sourceTexture = createColorTexture(); |
543 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, m_size.width (), m_size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | |
534 m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer, sourceText ure, 0, GL_RGBA, GL_UNSIGNED_BYTE); | 544 m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer, sourceText ure, 0, GL_RGBA, GL_UNSIGNED_BYTE); |
535 | 545 |
536 // Since we're using the same context as WebGL, we have to restore any state we change (in this case, just the framebuffer binding). | 546 // Since we're using the same context as WebGL, we have to restore any state we change (in this case, just the framebuffer binding). |
537 // FIXME: The WebGLRenderingContext tracks the current framebuffer binding, it would be slightly more efficient to use this value | 547 // FIXME: The WebGLRenderingContext tracks the current framebuffer binding, it would be slightly more efficient to use this value |
538 // rather than querying it off of the context. | 548 // rather than querying it off of the context. |
539 GLint previousFramebuffer = 0; | 549 GLint previousFramebuffer = 0; |
540 m_context->getIntegerv(GL_FRAMEBUFFER_BINDING, &previousFramebuffer); | 550 m_context->getIntegerv(GL_FRAMEBUFFER_BINDING, &previousFramebuffer); |
541 | 551 |
542 Platform3DObject framebuffer = m_context->createFramebuffer(); | 552 Platform3DObject framebuffer = m_context->createFramebuffer(); |
543 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer); | 553 m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 | 591 |
582 if (m_depthStencilBuffer) | 592 if (m_depthStencilBuffer) |
583 m_context->deleteRenderbuffer(m_depthStencilBuffer); | 593 m_context->deleteRenderbuffer(m_depthStencilBuffer); |
584 | 594 |
585 if (m_depthBuffer) | 595 if (m_depthBuffer) |
586 m_context->deleteRenderbuffer(m_depthBuffer); | 596 m_context->deleteRenderbuffer(m_depthBuffer); |
587 | 597 |
588 if (m_stencilBuffer) | 598 if (m_stencilBuffer) |
589 m_context->deleteRenderbuffer(m_stencilBuffer); | 599 m_context->deleteRenderbuffer(m_stencilBuffer); |
590 | 600 |
591 if (m_colorBuffer) | 601 if (m_colorBuffer) { |
602 if (m_useImageChromium) | |
603 deleteChromiumImageForTexture(m_colorBuffer); | |
604 | |
592 m_context->deleteTexture(m_colorBuffer); | 605 m_context->deleteTexture(m_colorBuffer); |
606 } | |
593 | 607 |
594 setSize(IntSize()); | 608 setSize(IntSize()); |
595 | 609 |
596 m_colorBuffer = 0; | 610 m_colorBuffer = 0; |
597 m_frontColorBuffer = 0; | 611 m_frontColorBuffer = 0; |
598 m_multisampleColorBuffer = 0; | 612 m_multisampleColorBuffer = 0; |
599 m_depthStencilBuffer = 0; | 613 m_depthStencilBuffer = 0; |
600 m_depthBuffer = 0; | 614 m_depthBuffer = 0; |
601 m_stencilBuffer = 0; | 615 m_stencilBuffer = 0; |
602 m_multisampleFBO = 0; | 616 m_multisampleFBO = 0; |
603 m_fbo = 0; | 617 m_fbo = 0; |
604 m_contextEvictionManager.clear(); | 618 m_contextEvictionManager.clear(); |
605 | 619 |
606 if (m_layer) | 620 if (m_layer) |
607 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 621 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
608 } | 622 } |
609 | 623 |
610 unsigned DrawingBuffer::createColorTexture(const IntSize& size) | 624 unsigned DrawingBuffer::createColorTexture() |
611 { | 625 { |
612 unsigned offscreenColorTexture = m_context->createTexture(); | 626 unsigned offscreenColorTexture = m_context->createTexture(); |
613 if (!offscreenColorTexture) | 627 if (!offscreenColorTexture) |
614 return 0; | 628 return 0; |
615 | 629 |
616 m_context->bindTexture(GL_TEXTURE_2D, offscreenColorTexture); | 630 m_context->bindTexture(GL_TEXTURE_2D, offscreenColorTexture); |
617 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 631 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
618 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 632 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
619 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ; | 633 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ; |
620 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ; | 634 m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ; |
621 if (!size.isEmpty()) | |
622 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.wid th(), size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | |
623 | 635 |
624 return offscreenColorTexture; | 636 return offscreenColorTexture; |
625 } | 637 } |
626 | 638 |
627 void DrawingBuffer::createSecondaryBuffers() | 639 void DrawingBuffer::createSecondaryBuffers() |
628 { | 640 { |
629 // create a multisample FBO | 641 // create a multisample FBO |
630 if (m_multisampleMode == ExplicitResolve) { | 642 if (m_multisampleMode == ExplicitResolve) { |
631 m_multisampleFBO = m_context->createFramebuffer(); | 643 m_multisampleFBO = m_context->createFramebuffer(); |
632 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 644 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
633 m_multisampleColorBuffer = m_context->createRenderbuffer(); | 645 m_multisampleColorBuffer = m_context->createRenderbuffer(); |
634 } | 646 } |
635 } | 647 } |
636 | 648 |
637 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) | 649 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) |
638 { | 650 { |
639 // resize regular FBO | 651 // resize regular FBO |
640 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 652 m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
641 | 653 |
642 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer); | 654 m_context->bindTexture(GL_TEXTURE_2D, m_colorBuffer); |
643 | 655 |
644 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width() , size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | 656 allocateTextureMemory(m_colorBuffer, m_size); |
645 | 657 |
646 if (m_multisampleMode == ImplicitResolve) | 658 if (m_multisampleMode == ImplicitResolve) |
647 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0, m_sampleCount); | 659 m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_A TTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0, m_sampleCount); |
648 else | 660 else |
649 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer, 0); | 661 m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL _TEXTURE_2D, m_colorBuffer, 0); |
650 | 662 |
651 m_context->bindTexture(GL_TEXTURE_2D, 0); | 663 m_context->bindTexture(GL_TEXTURE_2D, 0); |
652 | 664 |
653 if (m_multisampleMode != ExplicitResolve) | 665 if (m_multisampleMode != ExplicitResolve) |
654 resizeDepthStencil(size); | 666 resizeDepthStencil(size); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1013 memcpy(rowA, scanline, rowBytes); | 1025 memcpy(rowA, scanline, rowBytes); |
1014 } | 1026 } |
1015 } | 1027 } |
1016 | 1028 |
1017 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment) | 1029 void DrawingBuffer::texImage2DResourceSafe(GLenum target, GLint level, GLenum in ternalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint unpackAlignment) |
1018 { | 1030 { |
1019 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); | 1031 ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); |
1020 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); | 1032 m_context->texImage2D(target, level, internalformat, width, height, border, format, type, 0); |
1021 } | 1033 } |
1022 | 1034 |
1035 void DrawingBuffer::allocateTextureMemory(Platform3DObject textureId, const IntS ize& size) | |
1036 { | |
1037 if (m_useImageChromium) { | |
1038 deleteChromiumImageForTexture(textureId); | |
1039 | |
1040 blink::WGC3Duint newImage = m_context->createImageCHROMIUM(size.width(), size.height(), GL_RGBA8_OES, GC3D_IMAGE_SCANOUT_CHROMIUM); | |
1041 if (newImage) { | |
1042 m_context->bindTexImage2DCHROMIUM(GL_TEXTURE_2D, newImage); | |
1043 m_textureToImageChromiumMap.add(textureId, newImage); | |
1044 return; | |
1045 } | |
1046 } | |
1047 | |
1048 texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, size.width() , size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE); | |
1049 } | |
1050 | |
1051 void DrawingBuffer::deleteChromiumImageForTexture(Platform3DObject textureId) | |
1052 { | |
1053 HashMap<Platform3DObject, blink::WGC3Duint>::iterator imageIter = m_textureT oImageChromiumMap.find(textureId); | |
1054 // Release the old buffer if we have any. | |
1055 if (imageIter != m_textureToImageChromiumMap.end()) { | |
1056 m_context->releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, imageIter->value); | |
1057 m_context->destroyImageCHROMIUM(imageIter->value); | |
1058 m_textureToImageChromiumMap.remove(imageIter); | |
1059 } | |
1060 } | |
1061 | |
1023 } // namespace WebCore | 1062 } // namespace WebCore |
OLD | NEW |