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

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

Issue 2625873005: Add an heuristic for promoting canvases to GPU acceleration (Closed)
Patch Set: webgl test fix Created 3 years, 11 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
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 e92835562605d818ede0727559587e2cb8dcbd4b..392d7ceb2f45ff6bd466db066d8ccfd9bdb38bdb 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -792,7 +792,7 @@ bool HTMLCanvasElement::originClean() const {
return m_originClean;
}
-bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const {
+bool HTMLCanvasElement::shouldAccelerate(AccelerationCriteria criteria) const {
if (m_context && !m_context->is2d())
return false;
@@ -808,8 +808,8 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const {
if (layoutBox() && !layoutBox()->hasAcceleratedCompositing())
return false;
- CheckedNumeric<int> checkedCanvasPixelCount = size.width();
- checkedCanvasPixelCount *= size.height();
+ CheckedNumeric<int> checkedCanvasPixelCount = size().width();
+ checkedCanvasPixelCount *= size().height();
if (!checkedCanvasPixelCount.IsValid())
return false;
int canvasPixelCount = checkedCanvasPixelCount.ValueOrDie();
@@ -831,10 +831,12 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const {
}
// Do not use acceleration for small canvas.
- Settings* settings = document().settings();
- if (!settings ||
- canvasPixelCount < settings->getMinimumAccelerated2dCanvasSize())
- return false;
+ if (criteria != IgnoreCanvasSizeAccelerationCriteria) {
+ Settings* settings = document().settings();
+ if (!settings ||
+ canvasPixelCount < settings->getMinimumAccelerated2dCanvasSize())
+ return false;
+ }
// When GPU allocated memory runs low (due to having created too many
// accelerated canvases), the compositor starves and browser becomes laggy.
@@ -872,7 +874,7 @@ class UnacceleratedSurfaceFactory
} // namespace
-bool HTMLCanvasElement::shouldUseDisplayList(const IntSize& deviceSize) {
+bool HTMLCanvasElement::shouldUseDisplayList() {
if (m_context->colorSpace() != kLegacyCanvasColorSpace)
return false;
@@ -886,15 +888,13 @@ bool HTMLCanvasElement::shouldUseDisplayList(const IntSize& deviceSize) {
}
std::unique_ptr<ImageBufferSurface>
-HTMLCanvasElement::createWebGLImageBufferSurface(const IntSize& deviceSize,
- OpacityMode opacityMode) {
+HTMLCanvasElement::createWebGLImageBufferSurface(OpacityMode opacityMode) {
DCHECK(is3D());
// If 3d, but the use of the canvas will be for non-accelerated content
// then make a non-accelerated ImageBuffer. This means copying the internal
// Image will require a pixel readback, but that is unavoidable in this case.
auto surface = WTF::wrapUnique(new AcceleratedImageBufferSurface(
- deviceSize, opacityMode, m_context->skColorSpace(),
- m_context->colorType()));
+ size(), opacityMode, m_context->skColorSpace(), m_context->colorType()));
if (surface->isValid())
return std::move(surface);
return nullptr;
@@ -902,12 +902,8 @@ HTMLCanvasElement::createWebGLImageBufferSurface(const IntSize& deviceSize,
std::unique_ptr<ImageBufferSurface>
HTMLCanvasElement::createAcceleratedImageBufferSurface(
- const IntSize& deviceSize,
OpacityMode opacityMode,
int* msaaSampleCount) {
- if (!shouldAccelerate(deviceSize))
- return nullptr;
-
if (document().settings()) {
*msaaSampleCount =
document().settings()->getAccelerated2dCanvasMSAASampleCount();
@@ -928,7 +924,7 @@ HTMLCanvasElement::createAcceleratedImageBufferSurface(
std::unique_ptr<ImageBufferSurface> surface =
WTF::wrapUnique(new Canvas2DImageBufferSurface(
- std::move(contextProvider), deviceSize, *msaaSampleCount, opacityMode,
+ std::move(contextProvider), size(), *msaaSampleCount, opacityMode,
Canvas2DLayerBridge::EnableAcceleration, m_context->skColorSpace(),
m_context->colorType()));
if (!surface->isValid()) {
@@ -944,12 +940,11 @@ HTMLCanvasElement::createAcceleratedImageBufferSurface(
std::unique_ptr<ImageBufferSurface>
HTMLCanvasElement::createUnacceleratedImageBufferSurface(
- const IntSize& deviceSize,
OpacityMode opacityMode) {
- if (shouldUseDisplayList(deviceSize)) {
+ if (shouldUseDisplayList()) {
auto surface = WTF::wrapUnique(new RecordingImageBufferSurface(
- deviceSize, WTF::wrapUnique(new UnacceleratedSurfaceFactory),
- opacityMode, m_context->skColorSpace(), m_context->colorType()));
+ size(), WTF::wrapUnique(new UnacceleratedSurfaceFactory), opacityMode,
+ m_context->skColorSpace(), m_context->colorType()));
if (surface->isValid()) {
CanvasMetrics::countCanvasContextUsage(
CanvasMetrics::DisplayList2DCanvasImageBufferCreated);
@@ -960,9 +955,8 @@ HTMLCanvasElement::createUnacceleratedImageBufferSurface(
}
auto surfaceFactory = WTF::makeUnique<UnacceleratedSurfaceFactory>();
- auto surface = surfaceFactory->createSurface(deviceSize, opacityMode,
- m_context->skColorSpace(),
- m_context->colorType());
+ auto surface = surfaceFactory->createSurface(
+ size(), opacityMode, m_context->skColorSpace(), m_context->colorType());
if (surface->isValid()) {
CanvasMetrics::countCanvasContextUsage(
CanvasMetrics::Unaccelerated2DCanvasImageBufferCreated);
@@ -999,12 +993,14 @@ void HTMLCanvasElement::createImageBufferInternal(
if (externalSurface->isValid())
surface = std::move(externalSurface);
} else if (is3D()) {
- surface = createWebGLImageBufferSurface(size(), opacityMode);
+ surface = createWebGLImageBufferSurface(opacityMode);
} else {
- surface = createAcceleratedImageBufferSurface(size(), opacityMode,
- &msaaSampleCount);
+ if (shouldAccelerate(NormalAccelerationCriteria)) {
+ surface =
+ createAcceleratedImageBufferSurface(opacityMode, &msaaSampleCount);
+ }
if (!surface) {
- surface = createUnacceleratedImageBufferSurface(size(), opacityMode);
+ surface = createUnacceleratedImageBufferSurface(opacityMode);
}
}
if (!surface)
@@ -1023,7 +1019,6 @@ void HTMLCanvasElement::createImageBufferInternal(
return;
}
- m_imageBuffer->setClient(this);
// Enabling MSAA overrides a request to disable antialiasing. This is true
// regardless of whether the rendering mode is accelerated or not. For
// consistency, we don't want to apply AA in accelerated canvases but not in
@@ -1071,9 +1066,10 @@ void HTMLCanvasElement::updateExternallyAllocatedMemory() const {
// Four bytes per pixel per buffer.
CheckedNumeric<intptr_t> checkedExternallyAllocatedMemory = 4 * bufferCount;
- if (is3D())
+ if (is3D()) {
checkedExternallyAllocatedMemory +=
m_context->externallyAllocatedBytesPerPixel();
+ }
checkedExternallyAllocatedMemory *= width();
checkedExternallyAllocatedMemory *= height();
@@ -1213,6 +1209,21 @@ void HTMLCanvasElement::didMoveToNewDocument(Document& oldDocument) {
HTMLElement::didMoveToNewDocument(oldDocument);
}
+void HTMLCanvasElement::willDrawImageTo2DContext(CanvasImageSource* source) {
+ if (ExpensiveCanvasHeuristicParameters::EnableAccelerationToAvoidReadbacks &&
+ source->isAccelerated() && !buffer()->isAccelerated() &&
+ shouldAccelerate(IgnoreCanvasSizeAccelerationCriteria)) {
+ OpacityMode opacityMode =
+ m_context->creationAttributes().alpha() ? NonOpaque : Opaque;
+ int msaaSampleCount = 0;
+ std::unique_ptr<ImageBufferSurface> surface =
+ createAcceleratedImageBufferSurface(opacityMode, &msaaSampleCount);
+ if (surface) {
+ buffer()->setSurface(std::move(surface));
+ }
+ }
+}
+
PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(
SourceImageStatus* status,
AccelerationHint hint,
@@ -1260,8 +1271,9 @@ PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(
DisableAccelerationToAvoidReadbacks &&
!RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() &&
hint == PreferNoAcceleration && m_context->isAccelerated() &&
- hasImageBuffer())
+ hasImageBuffer()) {
buffer()->disableAcceleration();
+ }
RefPtr<Image> image = renderingContext()->getImage(hint, reason);
if (image) {
skImage =

Powered by Google App Engine
This is Rietveld 408576698