| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 namespace WebCore { | 52 namespace WebCore { |
| 53 | 53 |
| 54 // Global resource ceiling (expressed in terms of pixels) for DrawingBuffer crea
tion and resize. | 54 // Global resource ceiling (expressed in terms of pixels) for DrawingBuffer crea
tion and resize. |
| 55 // When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() ca
lls that would | 55 // When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() ca
lls that would |
| 56 // exceed the global cap will instead clear the buffer. | 56 // exceed the global cap will instead clear the buffer. |
| 57 static const int s_maximumResourceUsePixels = 16 * 1024 * 1024; | 57 static const int s_maximumResourceUsePixels = 16 * 1024 * 1024; |
| 58 static int s_currentResourceUsePixels = 0; | 58 static int s_currentResourceUsePixels = 0; |
| 59 static const float s_resourceAdjustedRatio = 0.5; | 59 static const float s_resourceAdjustedRatio = 0.5; |
| 60 | 60 |
| 61 static const bool s_allowContextEvictionOnCreate = true; |
| 62 static const int s_maxScaleAttempts = 3; |
| 63 |
| 61 class ScopedTextureUnit0BindingRestorer { | 64 class ScopedTextureUnit0BindingRestorer { |
| 62 public: | 65 public: |
| 63 ScopedTextureUnit0BindingRestorer(GraphicsContext3D* context, GC3Denum activ
eTextureUnit, Platform3DObject textureUnitZeroId) | 66 ScopedTextureUnit0BindingRestorer(GraphicsContext3D* context, GC3Denum activ
eTextureUnit, Platform3DObject textureUnitZeroId) |
| 64 : m_context(context) | 67 : m_context(context) |
| 65 , m_oldActiveTextureUnit(activeTextureUnit) | 68 , m_oldActiveTextureUnit(activeTextureUnit) |
| 66 , m_oldTextureUnitZeroId(textureUnitZeroId) | 69 , m_oldTextureUnitZeroId(textureUnitZeroId) |
| 67 { | 70 { |
| 68 m_context->activeTexture(GraphicsContext3D::TEXTURE0); | 71 m_context->activeTexture(GraphicsContext3D::TEXTURE0); |
| 69 } | 72 } |
| 70 ~ScopedTextureUnit0BindingRestorer() | 73 ~ScopedTextureUnit0BindingRestorer() |
| 71 { | 74 { |
| 72 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_oldTextureUnitZe
roId); | 75 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_oldTextureUnitZe
roId); |
| 73 m_context->activeTexture(m_oldActiveTextureUnit); | 76 m_context->activeTexture(m_oldActiveTextureUnit); |
| 74 } | 77 } |
| 75 | 78 |
| 76 private: | 79 private: |
| 77 GraphicsContext3D* m_context; | 80 GraphicsContext3D* m_context; |
| 78 GC3Denum m_oldActiveTextureUnit; | 81 GC3Denum m_oldActiveTextureUnit; |
| 79 Platform3DObject m_oldTextureUnitZeroId; | 82 Platform3DObject m_oldTextureUnitZeroId; |
| 80 }; | 83 }; |
| 81 | 84 |
| 82 PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, cons
t IntSize& size, PreserveDrawingBuffer preserve) | 85 PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, cons
t IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvictionManag
er> contextEvictionManager) |
| 83 { | 86 { |
| 84 Extensions3D* extensions = context->getExtensions(); | 87 Extensions3D* extensions = context->getExtensions(); |
| 85 bool multisampleSupported = extensions->maySupportMultisampling() | 88 bool multisampleSupported = extensions->maySupportMultisampling() |
| 86 && extensions->supports("GL_ANGLE_framebuffer_blit") | 89 && extensions->supports("GL_ANGLE_framebuffer_blit") |
| 87 && extensions->supports("GL_ANGLE_framebuffer_multisample") | 90 && extensions->supports("GL_ANGLE_framebuffer_multisample") |
| 88 && extensions->supports("GL_OES_rgb8_rgba8"); | 91 && extensions->supports("GL_OES_rgb8_rgba8"); |
| 89 if (multisampleSupported) { | 92 if (multisampleSupported) { |
| 90 extensions->ensureEnabled("GL_ANGLE_framebuffer_blit"); | 93 extensions->ensureEnabled("GL_ANGLE_framebuffer_blit"); |
| 91 extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); | 94 extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); |
| 92 extensions->ensureEnabled("GL_OES_rgb8_rgba8"); | 95 extensions->ensureEnabled("GL_OES_rgb8_rgba8"); |
| 93 } | 96 } |
| 94 bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth
_stencil"); | 97 bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth
_stencil"); |
| 95 if (packedDepthStencilSupported) | 98 if (packedDepthStencilSupported) |
| 96 extensions->ensureEnabled("GL_OES_packed_depth_stencil"); | 99 extensions->ensureEnabled("GL_OES_packed_depth_stencil"); |
| 97 | 100 |
| 98 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, si
ze, multisampleSupported, packedDepthStencilSupported, preserve)); | 101 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, si
ze, multisampleSupported, packedDepthStencilSupported, preserve, contextEviction
Manager)); |
| 99 return drawingBuffer.release(); | 102 return drawingBuffer.release(); |
| 100 } | 103 } |
| 101 | 104 |
| 102 DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, | 105 DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, |
| 103 const IntSize& size, | 106 const IntSize& size, |
| 104 bool multisampleExtensionSupported, | 107 bool multisampleExtensionSupported, |
| 105 bool packedDepthStencilExtensionSupported, | 108 bool packedDepthStencilExtensionSupported, |
| 106 PreserveDrawingBuffer preserve) | 109 PreserveDrawingBuffer preserve, |
| 110 PassRefPtr<ContextEvictionManager> contextEvictionM
anager) |
| 107 : m_preserveDrawingBuffer(preserve) | 111 : m_preserveDrawingBuffer(preserve) |
| 108 , m_scissorEnabled(false) | 112 , m_scissorEnabled(false) |
| 109 , m_texture2DBinding(0) | 113 , m_texture2DBinding(0) |
| 110 , m_framebufferBinding(0) | 114 , m_framebufferBinding(0) |
| 111 , m_activeTextureUnit(GraphicsContext3D::TEXTURE0) | 115 , m_activeTextureUnit(GraphicsContext3D::TEXTURE0) |
| 112 , m_context(context) | 116 , m_context(context) |
| 113 , m_size(-1, -1) | 117 , m_size(-1, -1) |
| 114 , m_multisampleExtensionSupported(multisampleExtensionSupported) | 118 , m_multisampleExtensionSupported(multisampleExtensionSupported) |
| 115 , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupporte
d) | 119 , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupporte
d) |
| 116 , m_fbo(0) | 120 , m_fbo(0) |
| 117 , m_colorBuffer(0) | 121 , m_colorBuffer(0) |
| 118 , m_frontColorBuffer(0) | 122 , m_frontColorBuffer(0) |
| 119 , m_separateFrontTexture(false) | 123 , m_separateFrontTexture(false) |
| 120 , m_depthStencilBuffer(0) | 124 , m_depthStencilBuffer(0) |
| 121 , m_depthBuffer(0) | 125 , m_depthBuffer(0) |
| 122 , m_stencilBuffer(0) | 126 , m_stencilBuffer(0) |
| 123 , m_multisampleFBO(0) | 127 , m_multisampleFBO(0) |
| 124 , m_multisampleColorBuffer(0) | 128 , m_multisampleColorBuffer(0) |
| 125 , m_contentsChanged(true) | 129 , m_contentsChanged(true) |
| 126 , m_internalColorFormat(0) | 130 , m_internalColorFormat(0) |
| 127 , m_colorFormat(0) | 131 , m_colorFormat(0) |
| 128 , m_internalRenderbufferFormat(0) | 132 , m_internalRenderbufferFormat(0) |
| 133 , m_contextEvictionManager(contextEvictionManager) |
| 129 { | 134 { |
| 130 // Used by browser tests to detect the use of a DrawingBuffer. | 135 // Used by browser tests to detect the use of a DrawingBuffer. |
| 131 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); | 136 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); |
| 132 #if !USES_MAILBOX | 137 #if !USES_MAILBOX |
| 133 // We need a separate front and back textures if ... | 138 // We need a separate front and back textures if ... |
| 134 m_separateFrontTexture = m_preserveDrawingBuffer == Preserve // ... we have
to preserve contents after compositing, which is done with a copy or ... | 139 m_separateFrontTexture = m_preserveDrawingBuffer == Preserve // ... we have
to preserve contents after compositing, which is done with a copy or ... |
| 135 || WebKit::Platform::current()->isThreadedCompositi
ngEnabled(); // ... if we're in threaded mode and need to double buffer. | 140 || WebKit::Platform::current()->isThreadedCompositi
ngEnabled(); // ... if we're in threaded mode and need to double buffer. |
| 136 #endif // USES_MAILBOX | 141 #endif // USES_MAILBOX |
| 137 initialize(size); | 142 initialize(size); |
| 138 } | 143 } |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 setSize(IntSize()); | 449 setSize(IntSize()); |
| 445 | 450 |
| 446 m_colorBuffer = 0; | 451 m_colorBuffer = 0; |
| 447 m_frontColorBuffer = 0; | 452 m_frontColorBuffer = 0; |
| 448 m_multisampleColorBuffer = 0; | 453 m_multisampleColorBuffer = 0; |
| 449 m_depthStencilBuffer = 0; | 454 m_depthStencilBuffer = 0; |
| 450 m_depthBuffer = 0; | 455 m_depthBuffer = 0; |
| 451 m_stencilBuffer = 0; | 456 m_stencilBuffer = 0; |
| 452 m_multisampleFBO = 0; | 457 m_multisampleFBO = 0; |
| 453 m_fbo = 0; | 458 m_fbo = 0; |
| 459 m_contextEvictionManager.clear(); |
| 454 | 460 |
| 455 #if USES_MAILBOX | 461 #if USES_MAILBOX |
| 456 m_lastColorBuffer.clear(); | 462 m_lastColorBuffer.clear(); |
| 457 m_recycledMailboxes.clear(); | 463 m_recycledMailboxes.clear(); |
| 458 m_textureMailboxes.clear(); | 464 m_textureMailboxes.clear(); |
| 459 #endif // USES_MAILBOX | 465 #endif // USES_MAILBOX |
| 460 } | 466 } |
| 461 | 467 |
| 462 unsigned DrawingBuffer::createColorTexture(const IntSize& size) | 468 unsigned DrawingBuffer::createColorTexture(const IntSize& size) |
| 463 { | 469 { |
| 464 unsigned offscreenColorTexture = m_context->createTexture(); | 470 unsigned offscreenColorTexture = m_context->createTexture(); |
| 465 if (!offscreenColorTexture) | 471 if (!offscreenColorTexture) |
| 466 return 0; | 472 return 0; |
| 467 | 473 |
| 468 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, offscreenColorTexture)
; | 474 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, offscreenColorTexture)
; |
| 469 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); | 475 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); |
| 470 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); | 476 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); |
| 471 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); | 477 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); |
| 472 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); | 478 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); |
| 473 if(!size.isEmpty()) | 479 if (!size.isEmpty()) |
| 474 m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, m_in
ternalColorFormat, size.width(), size.height(), 0, m_colorFormat, GraphicsContex
t3D::UNSIGNED_BYTE); | 480 m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, m_in
ternalColorFormat, size.width(), size.height(), 0, m_colorFormat, GraphicsContex
t3D::UNSIGNED_BYTE); |
| 475 | 481 |
| 476 return offscreenColorTexture; | 482 return offscreenColorTexture; |
| 477 } | 483 } |
| 478 | 484 |
| 479 void DrawingBuffer::createSecondaryBuffers() | 485 void DrawingBuffer::createSecondaryBuffers() |
| 480 { | 486 { |
| 481 // create a multisample FBO | 487 // create a multisample FBO |
| 482 if (multisample()) { | 488 if (multisample()) { |
| 483 m_multisampleFBO = m_context->createFramebuffer(); | 489 m_multisampleFBO = m_context->createFramebuffer(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 if (multisample()) | 576 if (multisample()) |
| 571 m_context->getExtensions()->renderbufferStorageMultisample(Graph
icsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::STENCIL_INDEX8, size
.width(), size.height()); | 577 m_context->getExtensions()->renderbufferStorageMultisample(Graph
icsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::STENCIL_INDEX8, size
.width(), size.height()); |
| 572 else | 578 else |
| 573 m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER,
GraphicsContext3D::STENCIL_INDEX8, size.width(), size.height()); | 579 m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER,
GraphicsContext3D::STENCIL_INDEX8, size.width(), size.height()); |
| 574 m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, G
raphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_stencil
Buffer); | 580 m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, G
raphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_stencil
Buffer); |
| 575 } | 581 } |
| 576 } | 582 } |
| 577 m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0); | 583 m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0); |
| 578 } | 584 } |
| 579 | 585 |
| 586 |
| 587 |
| 580 void DrawingBuffer::clearFramebuffers(GC3Dbitfield clearMask) | 588 void DrawingBuffer::clearFramebuffers(GC3Dbitfield clearMask) |
| 581 { | 589 { |
| 582 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO
? m_multisampleFBO : m_fbo); | 590 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO
? m_multisampleFBO : m_fbo); |
| 583 | 591 |
| 584 m_context->clear(clearMask); | 592 m_context->clear(clearMask); |
| 585 | 593 |
| 586 // The multisample fbo was just cleared, but we also need to clear the non-m
ultisampled buffer too. | 594 // The multisample fbo was just cleared, but we also need to clear the non-m
ultisampled buffer too. |
| 587 if (m_multisampleFBO) { | 595 if (m_multisampleFBO) { |
| 588 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); | 596 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); |
| 589 m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); | 597 m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 // Clamp if the desired size is greater than the maximum texture size for th
e device. | 649 // Clamp if the desired size is greater than the maximum texture size for th
e device. |
| 642 int maxTextureSize = 0; | 650 int maxTextureSize = 0; |
| 643 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize)
; | 651 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize)
; |
| 644 if (adjustedSize.height() > maxTextureSize) | 652 if (adjustedSize.height() > maxTextureSize) |
| 645 adjustedSize.setHeight(maxTextureSize); | 653 adjustedSize.setHeight(maxTextureSize); |
| 646 | 654 |
| 647 if (adjustedSize.width() > maxTextureSize) | 655 if (adjustedSize.width() > maxTextureSize) |
| 648 adjustedSize.setWidth(maxTextureSize); | 656 adjustedSize.setWidth(maxTextureSize); |
| 649 | 657 |
| 650 // Try progressively smaller sizes until we find a size that fits or reach a
scale limit. | 658 // Try progressively smaller sizes until we find a size that fits or reach a
scale limit. |
| 659 int scaleAttempts = 0; |
| 651 while ((s_currentResourceUsePixels + pixelDelta(adjustedSize)) > s_maximumRe
sourceUsePixels) { | 660 while ((s_currentResourceUsePixels + pixelDelta(adjustedSize)) > s_maximumRe
sourceUsePixels) { |
| 661 scaleAttempts++; |
| 662 if (scaleAttempts > s_maxScaleAttempts) |
| 663 return IntSize(); |
| 664 |
| 652 adjustedSize.scale(s_resourceAdjustedRatio); | 665 adjustedSize.scale(s_resourceAdjustedRatio); |
| 653 | 666 |
| 654 if (adjustedSize.isEmpty()) | 667 if (adjustedSize.isEmpty()) |
| 655 return IntSize(); | 668 return IntSize(); |
| 656 } | 669 } |
| 670 |
| 671 return adjustedSize; |
| 672 } |
| 673 |
| 674 IntSize DrawingBuffer::adjustSizeWithContextEviction(const IntSize& size, bool&
evictContext) { |
| 675 IntSize adjustedSize = adjustSize(size); |
| 676 if (!adjustedSize.isEmpty()) { |
| 677 evictContext = false; |
| 678 return adjustedSize; // Buffer fits without evicting a context. |
| 679 } |
| 680 |
| 681 // Speculatively adjust the pixel budget to see if the buffer would fit shou
ld the oldest context be evicted. |
| 682 IntSize oldestSize = m_contextEvictionManager->oldestContextSize(); |
| 683 int pixelDelta = oldestSize.width() * oldestSize.height(); |
| 684 |
| 685 s_currentResourceUsePixels -= pixelDelta; |
| 686 adjustedSize = adjustSize(size); |
| 687 s_currentResourceUsePixels += pixelDelta; |
| 688 |
| 689 evictContext = !adjustedSize.isEmpty(); |
| 657 return adjustedSize; | 690 return adjustedSize; |
| 658 } | 691 } |
| 659 | 692 |
| 660 void DrawingBuffer::reset(const IntSize& newSize) | 693 void DrawingBuffer::reset(const IntSize& newSize) |
| 661 { | 694 { |
| 662 IntSize adjustedSize = adjustSize(newSize); | 695 IntSize adjustedSize; |
| 696 bool evictContext = false; |
| 697 bool isNewContext = m_size.isEmpty(); |
| 698 if (s_allowContextEvictionOnCreate && isNewContext) |
| 699 adjustedSize = adjustSizeWithContextEviction(newSize, evictContext); |
| 700 else |
| 701 adjustedSize = adjustSize(newSize); |
| 702 |
| 663 if (adjustedSize.isEmpty()) | 703 if (adjustedSize.isEmpty()) |
| 664 return; | 704 return; |
| 665 | 705 |
| 706 if (evictContext) |
| 707 m_contextEvictionManager->forciblyLoseOldestContext("WARNING: WebGL cont
exts have exceeded the maximum allowed backbuffer area. Oldest context will be l
ost."); |
| 708 |
| 666 if (adjustedSize != m_size) { | 709 if (adjustedSize != m_size) { |
| 667 do { | 710 do { |
| 668 // resize multisample FBO | 711 // resize multisample FBO |
| 669 if (!resizeMultisampleFramebuffer(adjustedSize) || !resizeFramebuffe
r(adjustedSize)) { | 712 if (!resizeMultisampleFramebuffer(adjustedSize) || !resizeFramebuffe
r(adjustedSize)) { |
| 670 adjustedSize.scale(s_resourceAdjustedRatio); | 713 adjustedSize.scale(s_resourceAdjustedRatio); |
| 671 continue; | 714 continue; |
| 672 } | 715 } |
| 673 | 716 |
| 674 #if OS(DARWIN) | 717 #if OS(DARWIN) |
| 675 // FIXME: This can be removed once renderbufferStorageMultisample st
arts reporting GL_OUT_OF_MEMORY properly on OSX. | 718 // FIXME: This can be removed once renderbufferStorageMultisample st
arts reporting GL_OUT_OF_MEMORY properly on OSX. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 | 795 |
| 753 void DrawingBuffer::bind() | 796 void DrawingBuffer::bind() |
| 754 { | 797 { |
| 755 if (!m_context) | 798 if (!m_context) |
| 756 return; | 799 return; |
| 757 | 800 |
| 758 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO
? m_multisampleFBO : m_fbo); | 801 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO
? m_multisampleFBO : m_fbo); |
| 759 } | 802 } |
| 760 | 803 |
| 761 } // namespace WebCore | 804 } // namespace WebCore |
| OLD | NEW |