Chromium Code Reviews| 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 |