Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1475)

Unified Diff: Source/core/platform/graphics/gpu/DrawingBuffer.cpp

Issue 14217005: Limit the number of WebGL contexts that are active at any given time (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased to latest master Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/platform/graphics/gpu/DrawingBuffer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 d71fa1159cabef2d49989127fc646de848e6714a..1147e80e2f432da2b51f32c42da31a7ed44e27b8 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, PassRefPtr<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,
+ PassRefPtr<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();
#if USES_MAILBOX
m_lastColorBuffer.clear();
@@ -470,7 +476,7 @@ unsigned DrawingBuffer::createColorTexture(const IntSize& size)
m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
- if(!size.isEmpty())
+ if (!size.isEmpty())
m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, m_internalColorFormat, size.width(), size.height(), 0, m_colorFormat, GraphicsContext3D::UNSIGNED_BYTE);
return offscreenColorTexture;
@@ -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 (scaleAttempts > s_maxScaleAttempts)
+ 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.
+ }
+
+ // 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("WARNING: WebGL contexts have exceeded the maximum allowed backbuffer area. Oldest context will be lost.");
+
if (adjustedSize != m_size) {
do {
// resize multisample FBO
« no previous file with comments | « Source/core/platform/graphics/gpu/DrawingBuffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698