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

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

Issue 2280723003: Avoid making the shared main thread context if we won't use it. (Closed)
Patch Set: regress: rebase Created 4 years, 4 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 f0c6e688a144f9002dd86a67163e4d67f65f68a6..1b3c7b72d175b72ce0de97ff7e755f68f8be08a8 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -742,7 +742,7 @@ bool HTMLCanvasElement::originClean() const
return m_originClean;
}
-bool HTMLCanvasElement::shouldAccelerate(const IntSize& size, const WebGraphicsContext3DProvider* sharedMainThreadContextProvider) const
+bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
{
if (m_context && !m_context->is2d())
return false;
@@ -785,9 +785,6 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size, const WebGraphicsC
if (!settings || canvasPixelCount < settings->minimumAccelerated2dCanvasSize())
return false;
- if (sharedMainThreadContextProvider->isSoftwareRendering())
- 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 new canvases created
@@ -825,11 +822,8 @@ bool HTMLCanvasElement::shouldUseDisplayList(const IntSize& deviceSize)
return true;
}
-std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(const IntSize& deviceSize, int* msaaSampleCount, sk_sp<SkColorSpace> colorSpace)
+std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createAcceleratedImageBufferSurface(const IntSize& deviceSize, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace, int* msaaSampleCount)
{
- OpacityMode opacityMode = !m_context || m_context->creationAttributes().alpha() ? NonOpaque : Opaque;
-
- *msaaSampleCount = 0;
if (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
@@ -837,37 +831,53 @@ std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(
return wrapUnique(new AcceleratedImageBufferSurface(deviceSize, opacityMode, colorSpace));
}
- std::unique_ptr<WebGraphicsContext3DProvider> contextProvider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
+ if (!shouldAccelerate(deviceSize))
+ return nullptr;
+
+ if (document().settings())
+ *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASampleCount();
+
+ // Avoid creating |contextProvider| until we're sure we want to try use it,
+ // since it costs us GPU memory.
+ std::unique_ptr<WebGraphicsContext3DProvider> contextProvider(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
if (!contextProvider) {
CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Accelerated2DCanvasGPUContextLost);
- } else if (shouldAccelerate(deviceSize, contextProvider.get())) {
- if (document().settings())
- *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASampleCount();
- std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new Canvas2DImageBufferSurface(std::move(contextProvider), deviceSize, *msaaSampleCount, opacityMode, Canvas2DLayerBridge::EnableAcceleration, colorSpace));
- if (surface->isValid()) {
- CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCanvasImageBufferCreated);
- return surface;
- }
- CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCanvasImageBufferCreationFailed);
+ return nullptr;
}
- std::unique_ptr<RecordingImageBufferFallbackSurfaceFactory> surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory());
+ if (contextProvider->isSoftwareRendering())
Justin Novosad 2016/08/26 14:11:12 In a follow-up CL It would be nice to be able to m
+ return nullptr; // Don't use accelerated canvas with swiftshader.
+ std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new Canvas2DImageBufferSurface(std::move(contextProvider), deviceSize, *msaaSampleCount, opacityMode, Canvas2DLayerBridge::EnableAcceleration, std::move(colorSpace)));
+ if (surface->isValid()) {
+ CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCanvasImageBufferCreated);
+ return surface;
+ }
+
+ CanvasMetrics::countCanvasContextUsage(CanvasMetrics::GPUAccelerated2DCanvasImageBufferCreationFailed);
+ return nullptr;
+}
+
+std::unique_ptr<ImageBufferSurface> HTMLCanvasElement::createSoftwareImageBufferSurface(const IntSize& deviceSize, OpacityMode opacityMode, sk_sp<SkColorSpace> colorSpace)
+{
if (shouldUseDisplayList(deviceSize)) {
- std::unique_ptr<ImageBufferSurface> surface = wrapUnique(new RecordingImageBufferSurface(deviceSize, std::move(surfaceFactory), opacityMode, colorSpace));
+ auto surface = wrapUnique(new RecordingImageBufferSurface(deviceSize, wrapUnique(new UnacceleratedSurfaceFactory), opacityMode, colorSpace));
if (surface->isValid()) {
CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DCanvasImageBufferCreated);
- return surface;
+ return std::move(surface);
}
- surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory()); // recreate because previous one was released
+ // We fallback to a non-display-list surface without recording a metric here.
}
- auto surface = surfaceFactory->createSurface(deviceSize, opacityMode, colorSpace);
- if (!surface->isValid()) {
- CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCanvasImageBufferCreationFailed);
- } else {
+
+ auto surfaceFactory = wrapUnique(new UnacceleratedSurfaceFactory());
+ auto surface = surfaceFactory->createSurface(deviceSize, opacityMode, std::move(colorSpace));
+ if (surface->isValid()) {
CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCanvasImageBufferCreated);
+ return surface;
}
- return surface;
+
+ CanvasMetrics::countCanvasContextUsage(CanvasMetrics::Unaccelerated2DCanvasImageBufferCreationFailed);
+ return nullptr;
}
void HTMLCanvasElement::createImageBuffer()
@@ -887,16 +897,18 @@ void HTMLCanvasElement::createImageBufferInternal(std::unique_ptr<ImageBufferSur
if (!ImageBuffer::canCreateImageBuffer(size()))
return;
+ OpacityMode opacityMode = !m_context || m_context->creationAttributes().alpha() ? NonOpaque : Opaque;
int msaaSampleCount = 0;
- std::unique_ptr<ImageBufferSurface> surface;
- if (externalSurface) {
- surface = std::move(externalSurface);
- } else {
- surface = createImageBufferSurface(size(), &msaaSampleCount, m_context->skColorSpace());
- }
- m_imageBuffer = ImageBuffer::create(std::move(surface));
- if (!m_imageBuffer)
+ std::unique_ptr<ImageBufferSurface> surface = std::move(externalSurface);
+ if (!surface)
+ surface = createAcceleratedImageBufferSurface(size(), opacityMode, m_context->skColorSpace(), &msaaSampleCount);
+ if (!surface)
+ surface = createSoftwareImageBufferSurface(size(), opacityMode, m_context->skColorSpace());
+ if (!surface)
return;
+ DCHECK(surface->isValid());
+ m_imageBuffer = ImageBuffer::create(std::move(surface));
+ DCHECK(m_imageBuffer);
m_imageBuffer->setClient(this);
m_didFailToCreateImageBuffer = false;

Powered by Google App Engine
This is Rietveld 408576698