Commit a6742a6b authored by junov@chromium.org's avatar junov@chromium.org

2D Canvas: disable rendering deferral in cases with a lot of overdraw

Accumulating large draw command backlogs can result in janky
performance, and in extreme cases, a GPU denial of service. This
change fixes that problem by disabling deferred rendering when
high overdraw is detected. Cases where the overdraw overwrites
the entire canvas are not affected by this change and will
stay in deferred rendering mode because overwriting the entire
canvas resets the backlog.

BUG=522764, 522972

Review URL: https://codereview.chromium.org/1308853003

git-svn-id: svn://svn.chromium.org/blink/trunk@201036 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 82c59292
...@@ -66,7 +66,7 @@ public: ...@@ -66,7 +66,7 @@ public:
void setFilterQuality(SkFilterQuality filterQuality) override { m_layerBridge->setFilterQuality(filterQuality); } void setFilterQuality(SkFilterQuality filterQuality) override { m_layerBridge->setFilterQuality(filterQuality); }
void setIsHidden(bool hidden) override { m_layerBridge->setIsHidden(hidden); } void setIsHidden(bool hidden) override { m_layerBridge->setIsHidden(hidden); }
void setImageBuffer(ImageBuffer* imageBuffer) override { m_layerBridge->setImageBuffer(imageBuffer); } void setImageBuffer(ImageBuffer* imageBuffer) override { m_layerBridge->setImageBuffer(imageBuffer); }
void didDraw(const FloatRect& rect) override { m_layerBridge->didDraw(); } void didDraw(const FloatRect& rect) override { m_layerBridge->didDraw(rect); }
void flush() override { m_layerBridge->flush(); } void flush() override { m_layerBridge->flush(); }
void flushGpu() override { m_layerBridge->flushGpu(); } void flushGpu() override { m_layerBridge->flushGpu(); }
bool writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, int x, int y) override { return m_layerBridge->writePixels(origInfo, pixels, rowBytes, x, y); } bool writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, int x, int y) override { return m_layerBridge->writePixels(origInfo, pixels, rowBytes, x, y); }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "SkSurface.h" #include "SkSurface.h"
#include "platform/TraceEvent.h" #include "platform/TraceEvent.h"
#include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
#include "platform/graphics/GraphicsLayer.h" #include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/ImageBuffer.h" #include "platform/graphics/ImageBuffer.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
...@@ -139,6 +140,7 @@ void Canvas2DLayerBridge::startRecording() ...@@ -139,6 +140,7 @@ void Canvas2DLayerBridge::startRecording()
if (m_imageBuffer) { if (m_imageBuffer) {
m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas()); m_imageBuffer->resetCanvas(m_recorder->getRecordingCanvas());
} }
m_recordingPixelCount = 0;
} }
SkCanvas* Canvas2DLayerBridge::canvas() SkCanvas* Canvas2DLayerBridge::canvas()
...@@ -489,10 +491,15 @@ WebLayer* Canvas2DLayerBridge::layer() const ...@@ -489,10 +491,15 @@ WebLayer* Canvas2DLayerBridge::layer() const
return m_layer->layer(); return m_layer->layer();
} }
void Canvas2DLayerBridge::didDraw() void Canvas2DLayerBridge::didDraw(const FloatRect& rect)
{ {
if (m_isDeferralEnabled) if (m_isDeferralEnabled) {
m_haveRecordedDrawCommands = true; m_haveRecordedDrawCommands = true;
IntRect pixelBounds = enclosingIntRect(rect);
m_recordingPixelCount += pixelBounds.width() * pixelBounds.height();
if (m_recordingPixelCount >= (m_size.width() * m_size.height() * ExpensiveCanvasHeuristicParameters::ExpensiveOverdrawThreshold))
disableDeferral();
}
} }
void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect) void Canvas2DLayerBridge::finalizeFrame(const FloatRect &dirtyRect)
......
...@@ -73,7 +73,7 @@ public: ...@@ -73,7 +73,7 @@ public:
void setFilterQuality(SkFilterQuality); void setFilterQuality(SkFilterQuality);
void setIsHidden(bool); void setIsHidden(bool);
void setImageBuffer(ImageBuffer*); void setImageBuffer(ImageBuffer*);
void didDraw(); void didDraw(const FloatRect&);
bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y); bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
void flush(); void flush();
void flushGpu(); void flushGpu();
...@@ -133,6 +133,7 @@ private: ...@@ -133,6 +133,7 @@ private:
GLenum m_lastFilter; GLenum m_lastFilter;
OpacityMode m_opacityMode; OpacityMode m_opacityMode;
IntSize m_size; IntSize m_size;
int m_recordingPixelCount;
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment