| 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 =
|
|
|