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

Unified Diff: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp

Issue 1482363004: Fixing laggy chrome on a multitude of accelerated canvases (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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
Index: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index e04ea2b304f96f0bc3e3c80e013ff43918bbac47..a1ca43ac74803667a4fe19914b9fd0fa9467534d 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -80,6 +80,10 @@ const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
// In Skia, we will also limit width/height to 32767.
const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels.
+// Max Limit of Externally Allocated Memory
danakj 2015/11/30 23:07:03 comments are sentences, please add periods, and do
+// Equivalent to memory used by 80 accelerated canvases, each has a size of 1000*500 and 2d context
+const int MaxTotalExternallyAllocatedMemory = 6000000 * 80;
danakj 2015/11/30 23:07:03 also, naming for contants is kNameOfConstant. but
danakj 2015/11/30 23:07:03 can you write it as like 1000*500*4.. i'm not sure
xlai (Olivia) 2015/12/01 21:50:25 Refactored all the constants in this file to fit t
+
// A default value of quality argument for toDataURL and toBlob
// It is in an invalid range (outside 0.0 - 1.0) so that it will not be misinterpreted as a user-input value
const int UndefinedQualityValue = -1.0;
@@ -124,9 +128,13 @@ inline HTMLCanvasElement::HTMLCanvasElement(Document& document)
DEFINE_NODE_FACTORY(HTMLCanvasElement)
+intptr_t HTMLCanvasElement::s_totalMemoryForAcceleratedCanvases = 0;
+
HTMLCanvasElement::~HTMLCanvasElement()
{
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory);
+ if (m_imageBuffer && m_imageBuffer->isAccelerated())
+ updateTotalMemoryForAcceleratedCanvases(-m_externallyAllocatedMemory);
#if !ENABLE(OILPAN)
// Ensure these go away before the ImageBuffer.
m_context.clear();
@@ -605,7 +613,7 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
return false;
#endif
// If the GPU resources would be very expensive, prefer a display list.
- if (canvasPixelCount > ExpensiveCanvasHeuristicParameters::PreferDisplayListOverGpuSizeThreshold)
+ if (canvasPixelCount >= ExpensiveCanvasHeuristicParameters::PreferDisplayListOverGpuSizeThreshold)
danakj 2015/11/30 23:07:03 This looks like a separate CL, cuz it's an unrelat
xlai (Olivia) 2015/12/01 21:50:25 Sorry that's a careless mistake. Had corrected it.
return false;
}
@@ -616,6 +624,19 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
if (!Platform::current()->canAccelerate2dCanvas())
return false;
+ // When GPU allocated memory runs low (due to having created too many accelerated canvases), the
+ // compositor starves and browser becomes laggy. Thus, we should stop allocating more GPU memory to
danakj 2015/11/30 23:07:03 don't indent comments extra, all lines get the sam
+ // new canvases created when the current memory usage exceeds the threshold.
+ if (s_totalMemoryForAcceleratedCanvases >= MaxTotalExternallyAllocatedMemory)
danakj 2015/11/30 23:07:03 You'll go over the budget before you start rejecti
xlai (Olivia) 2015/12/01 21:50:25 I think the max limit here is more like a soft lim
+ return false;
+#if defined(OS_ANDROID)
danakj 2015/11/30 23:07:03 I think you can do this ifdefing around what the l
xlai (Olivia) 2015/12/01 21:50:25 Acknowledged. Moved the code to the front in setti
+ // We estimate that the max limit for android phones is half of that for desktops
+ // based on local experimental results on Android One
+ // (though a very slight lagginess on Android One is still expected, other devices should work fine)
+ if (s_totalMemoryForAcceleratedCanvases >= MaxTotalExternallyAllocatedMemory / 2)
+ return false;
+#endif
+
return true;
}
@@ -776,8 +797,25 @@ void HTMLCanvasElement::updateExternallyAllocatedMemory() const
externallyAllocatedMemory = std::numeric_limits<intptr_t>::max();
// Subtracting two intptr_t that are known to be positive will never underflow.
- v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyAllocatedMemory - m_externallyAllocatedMemory);
+ intptr_t diffFromCurrAllocatedMemory = externallyAllocatedMemory - m_externallyAllocatedMemory;
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(diffFromCurrAllocatedMemory);
m_externallyAllocatedMemory = externallyAllocatedMemory;
+
+ if (m_imageBuffer && m_imageBuffer->isAccelerated())
+ updateTotalMemoryForAcceleratedCanvases(diffFromCurrAllocatedMemory);
+}
+
+void HTMLCanvasElement::updateTotalMemoryForAcceleratedCanvases(intptr_t diffFromCurrAllocatedMemory)
+{
+ ASSERT(isMainThread());
+
+ Checked<intptr_t, RecordOverflow> checkedExternallyAllocatedMemory = s_totalMemoryForAcceleratedCanvases;
+ checkedExternallyAllocatedMemory += diffFromCurrAllocatedMemory;
+ intptr_t externallyAllocatedMemory;
+ if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == CheckedState::DidOverflow)
+ externallyAllocatedMemory = std::numeric_limits<intptr_t>::max();
+
+ s_totalMemoryForAcceleratedCanvases = externallyAllocatedMemory;
}
SkCanvas* HTMLCanvasElement::drawingCanvas() const

Powered by Google App Engine
This is Rietveld 408576698