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 21 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 #include "DrawingBuffer.h" | 33 #include "DrawingBuffer.h" |
| 34 | 34 |
| 35 #include "CanvasRenderingContext.h" | 35 #include "CanvasRenderingContext.h" |
| 36 #include "Extensions3D.h" | 36 #include "Extensions3D.h" |
| 37 #include "GraphicsContext3D.h" | 37 #include "GraphicsContext3D.h" |
| 38 #include "GraphicsContext3DPrivate.h" | 38 #include "GraphicsContext3DPrivate.h" |
| 39 #include "GraphicsLayerChromium.h" | 39 #include "GraphicsLayerChromium.h" |
| 40 #include "ImageData.h" | 40 #include "ImageData.h" |
| 41 #include "TraceEvent.h" | 41 #include "TraceEvent.h" |
| 42 #include "WebGLRenderingContext.h" | |
|
bajones
2013/04/20 05:19:59
Ken already pointed out in a different patch revie
| |
| 42 #include <algorithm> | 43 #include <algorithm> |
| 43 #include <public/Platform.h> | 44 #include <public/Platform.h> |
| 44 #include <public/WebCompositorSupport.h> | 45 #include <public/WebCompositorSupport.h> |
| 45 #include <public/WebExternalTextureLayer.h> | 46 #include <public/WebExternalTextureLayer.h> |
| 46 #include <public/WebGraphicsContext3D.h> | 47 #include <public/WebGraphicsContext3D.h> |
| 47 | 48 |
| 48 #define USES_MAILBOX 0 | 49 #define USES_MAILBOX 0 |
| 49 | 50 |
| 50 using namespace std; | 51 using namespace std; |
| 51 | 52 |
| 52 namespace WebCore { | 53 namespace WebCore { |
| 53 | 54 |
| 54 // Global resource ceiling (expressed in terms of pixels) for DrawingBuffer crea tion and resize. | 55 // 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 | 56 // When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() ca lls that would |
| 56 // exceed the global cap will instead clear the buffer. | 57 // exceed the global cap will instead clear the buffer. |
| 57 static const int s_maximumResourceUsePixels = 16 * 1024 * 1024; | 58 static const int s_maximumResourceUsePixels = 16 * 1024 * 1024; |
| 58 static int s_currentResourceUsePixels = 0; | 59 static int s_currentResourceUsePixels = 0; |
| 59 static const float s_resourceAdjustedRatio = 0.5; | 60 static const float s_resourceAdjustedRatio = 0.5; |
| 60 | 61 |
| 62 static const bool s_allowContextEvictionOnCreate = true; | |
| 63 static const int s_maxScaleAttempts = 3; | |
| 64 | |
| 61 class ScopedTextureUnit0BindingRestorer { | 65 class ScopedTextureUnit0BindingRestorer { |
| 62 public: | 66 public: |
| 63 ScopedTextureUnit0BindingRestorer(GraphicsContext3D* context, GC3Denum activ eTextureUnit, Platform3DObject textureUnitZeroId) | 67 ScopedTextureUnit0BindingRestorer(GraphicsContext3D* context, GC3Denum activ eTextureUnit, Platform3DObject textureUnitZeroId) |
| 64 : m_context(context) | 68 : m_context(context) |
| 65 , m_oldActiveTextureUnit(activeTextureUnit) | 69 , m_oldActiveTextureUnit(activeTextureUnit) |
| 66 , m_oldTextureUnitZeroId(textureUnitZeroId) | 70 , m_oldTextureUnitZeroId(textureUnitZeroId) |
| 67 { | 71 { |
| 68 m_context->activeTexture(GraphicsContext3D::TEXTURE0); | 72 m_context->activeTexture(GraphicsContext3D::TEXTURE0); |
| 69 } | 73 } |
| 70 ~ScopedTextureUnit0BindingRestorer() | 74 ~ScopedTextureUnit0BindingRestorer() |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 if (multisample()) | 574 if (multisample()) |
| 571 m_context->getExtensions()->renderbufferStorageMultisample(Graph icsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::STENCIL_INDEX8, size .width(), size.height()); | 575 m_context->getExtensions()->renderbufferStorageMultisample(Graph icsContext3D::RENDERBUFFER, sampleCount, GraphicsContext3D::STENCIL_INDEX8, size .width(), size.height()); |
| 572 else | 576 else |
| 573 m_context->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::STENCIL_INDEX8, size.width(), size.height()); | 577 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); | 578 m_context->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, G raphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_stencil Buffer); |
| 575 } | 579 } |
| 576 } | 580 } |
| 577 m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0); | 581 m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0); |
| 578 } | 582 } |
| 579 | 583 |
| 584 | |
| 585 | |
| 580 void DrawingBuffer::clearFramebuffers(GC3Dbitfield clearMask) | 586 void DrawingBuffer::clearFramebuffers(GC3Dbitfield clearMask) |
| 581 { | 587 { |
| 582 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); | 588 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); |
| 583 | 589 |
| 584 m_context->clear(clearMask); | 590 m_context->clear(clearMask); |
| 585 | 591 |
| 586 // The multisample fbo was just cleared, but we also need to clear the non-m ultisampled buffer too. | 592 // The multisample fbo was just cleared, but we also need to clear the non-m ultisampled buffer too. |
| 587 if (m_multisampleFBO) { | 593 if (m_multisampleFBO) { |
| 588 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); | 594 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); |
| 589 m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); | 595 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. | 647 // Clamp if the desired size is greater than the maximum texture size for th e device. |
| 642 int maxTextureSize = 0; | 648 int maxTextureSize = 0; |
| 643 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize) ; | 649 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize) ; |
| 644 if (adjustedSize.height() > maxTextureSize) | 650 if (adjustedSize.height() > maxTextureSize) |
| 645 adjustedSize.setHeight(maxTextureSize); | 651 adjustedSize.setHeight(maxTextureSize); |
| 646 | 652 |
| 647 if (adjustedSize.width() > maxTextureSize) | 653 if (adjustedSize.width() > maxTextureSize) |
| 648 adjustedSize.setWidth(maxTextureSize); | 654 adjustedSize.setWidth(maxTextureSize); |
| 649 | 655 |
| 650 // Try progressively smaller sizes until we find a size that fits or reach a scale limit. | 656 // Try progressively smaller sizes until we find a size that fits or reach a scale limit. |
| 657 int scaleAttempts = 0; | |
| 651 while ((s_currentResourceUsePixels + pixelDelta(adjustedSize)) > s_maximumRe sourceUsePixels) { | 658 while ((s_currentResourceUsePixels + pixelDelta(adjustedSize)) > s_maximumRe sourceUsePixels) { |
| 659 scaleAttempts++; | |
| 660 if(s_maxScaleAttempts > -1 && scaleAttempts > s_maxScaleAttempts) | |
| 661 return IntSize(); | |
| 662 | |
| 652 adjustedSize.scale(s_resourceAdjustedRatio); | 663 adjustedSize.scale(s_resourceAdjustedRatio); |
| 653 | 664 |
| 654 if (adjustedSize.isEmpty()) | 665 if (adjustedSize.isEmpty()) |
| 655 return IntSize(); | 666 return IntSize(); |
| 656 } | 667 } |
| 668 | |
| 669 return adjustedSize; | |
| 670 } | |
| 671 | |
| 672 IntSize DrawingBuffer::adjustSizeWithContextEviction(const IntSize& size, bool& evictContext) { | |
| 673 IntSize adjustedSize = adjustSize(size); | |
| 674 if(!adjustedSize.isEmpty()) { | |
| 675 evictContext = false; | |
| 676 return adjustedSize; // Buffer fits without evicting a context | |
| 677 } | |
| 678 | |
| 679 // Speculatively adjust the pixel budget to see if the buffer would fit shou ld the oldest context be evicted | |
| 680 IntSize oldestSize = WebGLRenderingContext::oldestContextSize(); | |
| 681 int pixelDelta = oldestSize.width() * oldestSize.height(); | |
| 682 | |
| 683 s_currentResourceUsePixels -= pixelDelta; | |
| 684 adjustedSize = adjustSize(size); | |
| 685 s_currentResourceUsePixels += pixelDelta; | |
| 686 | |
| 687 evictContext = !adjustedSize.isEmpty(); | |
| 657 return adjustedSize; | 688 return adjustedSize; |
| 658 } | 689 } |
| 659 | 690 |
| 660 void DrawingBuffer::reset(const IntSize& newSize) | 691 void DrawingBuffer::reset(const IntSize& newSize) |
| 661 { | 692 { |
| 662 IntSize adjustedSize = adjustSize(newSize); | 693 IntSize adjustedSize; |
| 694 bool evictContext = false; | |
| 695 bool isNewContext = m_size.isEmpty(); | |
| 696 if (s_allowContextEvictionOnCreate && isNewContext) | |
| 697 adjustedSize = adjustSizeWithContextEviction(newSize, evictContext); | |
| 698 else | |
| 699 adjustSize(newSize); | |
| 700 | |
| 663 if (adjustedSize.isEmpty()) | 701 if (adjustedSize.isEmpty()) |
| 664 return; | 702 return; |
| 665 | 703 |
| 704 if (evictContext) | |
| 705 WebGLRenderingContext::forciblyLoseOldestContext(); | |
| 706 | |
| 666 if (adjustedSize != m_size) { | 707 if (adjustedSize != m_size) { |
| 667 do { | 708 do { |
| 668 // resize multisample FBO | 709 // resize multisample FBO |
| 669 if (!resizeMultisampleFramebuffer(adjustedSize) || !resizeFramebuffe r(adjustedSize)) { | 710 if (!resizeMultisampleFramebuffer(adjustedSize) || !resizeFramebuffe r(adjustedSize)) { |
| 670 adjustedSize.scale(s_resourceAdjustedRatio); | 711 adjustedSize.scale(s_resourceAdjustedRatio); |
| 671 continue; | 712 continue; |
| 672 } | 713 } |
| 673 | 714 |
| 674 #if OS(DARWIN) | 715 #if OS(DARWIN) |
| 675 // FIXME: This can be removed once renderbufferStorageMultisample st arts reporting GL_OUT_OF_MEMORY properly on OSX. | 716 // 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 | 793 |
| 753 void DrawingBuffer::bind() | 794 void DrawingBuffer::bind() |
| 754 { | 795 { |
| 755 if (!m_context) | 796 if (!m_context) |
| 756 return; | 797 return; |
| 757 | 798 |
| 758 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); | 799 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); |
| 759 } | 800 } |
| 760 | 801 |
| 761 } // namespace WebCore | 802 } // namespace WebCore |
| OLD | NEW |