Chromium Code Reviews| Index: Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
| diff --git a/Source/core/platform/graphics/gpu/DrawingBuffer.cpp b/Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
| index 33855a04085adb6d95aa2ea8dc6a223ff0b7cb64..402112544be77b40a783ed43b7dc3306dd12fa85 100644 |
| --- a/Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
| +++ b/Source/core/platform/graphics/gpu/DrawingBuffer.cpp |
| @@ -58,6 +58,9 @@ static const int s_maximumResourceUsePixels = 16 * 1024 * 1024; |
| static int s_currentResourceUsePixels = 0; |
| static const float s_resourceAdjustedRatio = 0.5; |
| +static const bool s_allowContextEvictionOnCreate = true; |
| +static const int s_maxScaleAttempts = 3; |
| + |
| class ScopedTextureUnit0BindingRestorer { |
| public: |
| ScopedTextureUnit0BindingRestorer(GraphicsContext3D* context, GC3Denum activeTextureUnit, Platform3DObject textureUnitZeroId) |
| @@ -79,7 +82,7 @@ private: |
| Platform3DObject m_oldTextureUnitZeroId; |
| }; |
| -PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size, PreserveDrawingBuffer preserve) |
| +PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size, PreserveDrawingBuffer preserve, ContextEvictionManager* contextEvictionManager) |
| { |
| Extensions3D* extensions = context->getExtensions(); |
| bool multisampleSupported = extensions->maySupportMultisampling() |
| @@ -95,7 +98,7 @@ PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, cons |
| if (packedDepthStencilSupported) |
| extensions->ensureEnabled("GL_OES_packed_depth_stencil"); |
| - RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size, multisampleSupported, packedDepthStencilSupported, preserve)); |
| + RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size, multisampleSupported, packedDepthStencilSupported, preserve, contextEvictionManager)); |
| return drawingBuffer.release(); |
| } |
| @@ -103,7 +106,8 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, |
| const IntSize& size, |
| bool multisampleExtensionSupported, |
| bool packedDepthStencilExtensionSupported, |
| - PreserveDrawingBuffer preserve) |
| + PreserveDrawingBuffer preserve, |
| + ContextEvictionManager* contextEvictionManager) |
| : m_preserveDrawingBuffer(preserve) |
| , m_scissorEnabled(false) |
| , m_texture2DBinding(0) |
| @@ -126,6 +130,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, |
| , m_internalColorFormat(0) |
| , m_colorFormat(0) |
| , m_internalRenderbufferFormat(0) |
| + , m_contextEvictionManager(contextEvictionManager) |
| { |
| // Used by browser tests to detect the use of a DrawingBuffer. |
| TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); |
| @@ -451,6 +456,7 @@ void DrawingBuffer::clear() |
| m_stencilBuffer = 0; |
| m_multisampleFBO = 0; |
| m_fbo = 0; |
| + m_contextEvictionManager.clear(); |
|
Ken Russell (switch to Gerrit)
2013/04/24 01:30:57
Shouldn't the eviction manager be used across mult
bajones
2013/04/24 03:37:08
It is. clear() is only called when the DrawingBuff
|
| #if USES_MAILBOX |
| m_lastColorBuffer.clear(); |
| @@ -577,6 +583,8 @@ void DrawingBuffer::resizeDepthStencil(const IntSize& size, int sampleCount) |
| m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0); |
| } |
| + |
| + |
| void DrawingBuffer::clearFramebuffers(GC3Dbitfield clearMask) |
| { |
| m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); |
| @@ -648,21 +656,56 @@ IntSize DrawingBuffer::adjustSize(const IntSize& size) { |
| adjustedSize.setWidth(maxTextureSize); |
| // Try progressively smaller sizes until we find a size that fits or reach a scale limit. |
| + int scaleAttempts = 0; |
| while ((s_currentResourceUsePixels + pixelDelta(adjustedSize)) > s_maximumResourceUsePixels) { |
| + scaleAttempts++; |
| + if(s_maxScaleAttempts > -1 && scaleAttempts > s_maxScaleAttempts) |
|
Ken Russell (switch to Gerrit)
2013/04/24 01:30:57
Is it strictly necessary to look for s_maxScaleAtt
bajones
2013/04/24 03:37:08
I swear I WILL remember this style rule eventually
|
| + return IntSize(); |
| + |
| adjustedSize.scale(s_resourceAdjustedRatio); |
| if (adjustedSize.isEmpty()) |
| return IntSize(); |
| } |
| + |
| + return adjustedSize; |
| +} |
| + |
| +IntSize DrawingBuffer::adjustSizeWithContextEviction(const IntSize& size, bool& evictContext) { |
| + IntSize adjustedSize = adjustSize(size); |
| + if(!adjustedSize.isEmpty()) { |
| + evictContext = false; |
| + return adjustedSize; // Buffer fits without evicting a context |
|
Ken Russell (switch to Gerrit)
2013/04/24 01:30:57
Please end comments in with periods here and throu
bajones
2013/04/24 03:37:08
This one too. Years of habit working against me. *
|
| + } |
| + |
| + // Speculatively adjust the pixel budget to see if the buffer would fit should the oldest context be evicted |
| + IntSize oldestSize = m_contextEvictionManager->oldestContextSize(); |
| + int pixelDelta = oldestSize.width() * oldestSize.height(); |
| + |
| + s_currentResourceUsePixels -= pixelDelta; |
| + adjustedSize = adjustSize(size); |
| + s_currentResourceUsePixels += pixelDelta; |
| + |
| + evictContext = !adjustedSize.isEmpty(); |
| return adjustedSize; |
| } |
| void DrawingBuffer::reset(const IntSize& newSize) |
| { |
| - IntSize adjustedSize = adjustSize(newSize); |
| + IntSize adjustedSize; |
| + bool evictContext = false; |
| + bool isNewContext = m_size.isEmpty(); |
| + if (s_allowContextEvictionOnCreate && isNewContext) |
| + adjustedSize = adjustSizeWithContextEviction(newSize, evictContext); |
| + else |
| + adjustedSize = adjustSize(newSize); |
| + |
| if (adjustedSize.isEmpty()) |
| return; |
| + if (evictContext) |
| + m_contextEvictionManager->forciblyLoseOldestContext(); |
| + |
| if (adjustedSize != m_size) { |
| do { |
| // resize multisample FBO |