Chromium Code Reviews| Index: Source/core/html/HTMLCanvasElement.cpp |
| diff --git a/Source/core/html/HTMLCanvasElement.cpp b/Source/core/html/HTMLCanvasElement.cpp |
| index f49e813aebf51a4fde8ebc444f20f408f81d1f99..35d8301267f873fd517d672bd59efd7e1d164910 100644 |
| --- a/Source/core/html/HTMLCanvasElement.cpp |
| +++ b/Source/core/html/HTMLCanvasElement.cpp |
| @@ -45,8 +45,11 @@ |
| #include "core/page/Settings.h" |
| #include "core/rendering/RenderHTMLCanvas.h" |
| #include "platform/MIMETypeRegistry.h" |
| +#include "platform/graphics/Canvas2DImageBufferSurface.h" |
| #include "platform/graphics/GraphicsContextStateSaver.h" |
| #include "platform/graphics/ImageBuffer.h" |
| +#include "platform/graphics/UnacceleratedImageBufferSurface.h" |
| +#include "platform/graphics/gpu/WebGLImageBufferSurface.h" |
| #include "public/platform/Platform.h" |
| namespace WebCore { |
| @@ -72,7 +75,6 @@ HTMLCanvasElement::HTMLCanvasElement(Document& document) |
| , m_ignoreReset(false) |
| , m_accelerationDisabled(false) |
| , m_externallyAllocatedMemory(0) |
| - , m_deviceScaleFactor(1) |
| , m_originClean(true) |
| , m_didFailToCreateImageBuffer(false) |
| , m_didClearImageBuffer(false) |
| @@ -252,18 +254,15 @@ void HTMLCanvasElement::reset() |
| IntSize oldSize = size(); |
| IntSize newSize(w, h); |
| - float newDeviceScaleFactor = 1; |
| // If the size of an existing buffer matches, we can just clear it instead of reallocating. |
| // This optimization is only done for 2D canvases for now. |
| - if (hadImageBuffer && oldSize == newSize && m_deviceScaleFactor == newDeviceScaleFactor && m_context && m_context->is2d()) { |
| + if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d()) { |
| if (!m_didClearImageBuffer) |
| clearImageBuffer(); |
| return; |
| } |
| - m_deviceScaleFactor = newDeviceScaleFactor; |
| - |
| setSurfaceSize(newSize); |
| if (m_context && m_context->is3d() && oldSize != size()) |
| @@ -399,12 +398,6 @@ PassRefPtr<ImageData> HTMLCanvasElement::getImageData() |
| return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImageData(); |
| } |
| -IntSize HTMLCanvasElement::convertLogicalToDevice(const IntSize& logicalSize) const |
| -{ |
| - FloatSize deviceSize = logicalSize * m_deviceScaleFactor; |
| - return expandedIntSize(deviceSize); |
| -} |
| - |
| SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
| { |
| return document().securityOrigin(); |
| @@ -432,6 +425,28 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const |
| return true; |
| } |
| +PassOwnPtr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(const IntSize& deviceSize, int* msaaSampleCount) |
| +{ |
| + OwnPtr<ImageBufferSurface> surface; |
| + OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; |
| + *msaaSampleCount = 0; |
| + if (is3D()) { |
| + surface = adoptPtr(new WebGLImageBufferSurface(size(), opacityMode)); |
|
Stephen White
2013/12/09 15:33:08
Nit: I'd just do an early-return here, to save ind
|
| + } else { |
| + if (shouldAccelerate(deviceSize)) { |
| + if (document().settings()) |
| + *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASampleCount(); |
| + surface = adoptPtr(new Canvas2DImageBufferSurface(size(), opacityMode, *msaaSampleCount)); |
| + } |
| + |
| + if (!surface || !surface->isValid()) { |
| + surface = adoptPtr(new UnacceleratedImageBufferSurface(size(), opacityMode)); |
| + } |
| + } |
| + |
| + return surface.release(); |
| +} |
| + |
| void HTMLCanvasElement::createImageBuffer() |
| { |
| ASSERT(!m_imageBuffer); |
| @@ -439,7 +454,7 @@ void HTMLCanvasElement::createImageBuffer() |
| m_didFailToCreateImageBuffer = true; |
| m_didClearImageBuffer = true; |
| - IntSize deviceSize = convertLogicalToDevice(size()); |
| + IntSize deviceSize = size(); |
| if (deviceSize.width() * deviceSize.height() > MaxCanvasArea) |
| return; |
| @@ -449,28 +464,32 @@ void HTMLCanvasElement::createImageBuffer() |
| if (!deviceSize.width() || !deviceSize.height()) |
| return; |
| - RenderingMode renderingMode = is3D() ? TextureBacked : (shouldAccelerate(deviceSize) ? Accelerated : UnacceleratedNonPlatformBuffer); |
| - int msaaSampleCount = 0; |
| - if (document().settings()) |
| - msaaSampleCount = document().settings()->accelerated2dCanvasMSAASampleCount(); |
| - OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; |
| - m_imageBuffer = ImageBuffer::create(size(), m_deviceScaleFactor, renderingMode, opacityMode, msaaSampleCount); |
| + int msaaSampleCount; |
| + OwnPtr<ImageBufferSurface> surface = createImageBufferSurface(deviceSize, &msaaSampleCount); |
|
Stephen White
2013/12/09 15:33:08
Do we need to check for a NULL surface here? If it
Justin Novosad
2013/12/09 16:37:31
It was caught bey the check below, but I'll move t
|
| + m_imageBuffer = ImageBuffer::create(surface.release()); |
| if (!m_imageBuffer) |
| return; |
| + |
| m_didFailToCreateImageBuffer = false; |
| + |
| setExternallyAllocatedMemory(4 * width() * height()); |
| - m_imageBuffer->context()->setShouldClampToSourceRect(false); |
| - m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality); |
| - // 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 unaccelerated canvases. |
| - if (!msaaSampleCount && document().settings() && !document().settings()->antialiased2dCanvasEnabled()) |
| - m_imageBuffer->context()->setShouldAntialias(false); |
| - // GraphicsContext's defaults don't always agree with the 2d canvas spec. |
| - // See CanvasRenderingContext2D::State::State() for more information. |
| - m_imageBuffer->context()->setMiterLimit(10); |
| - m_imageBuffer->context()->setStrokeThickness(1); |
| - m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer->context())); |
| + |
| + if (m_imageBuffer->context()) { |
|
Stephen White
2013/12/09 15:33:08
Under what conditions does the image buffer have n
|
| + m_imageBuffer->context()->setShouldClampToSourceRect(false); |
| + m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality); |
| + // 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 unaccelerated canvases. |
| + if (!msaaSampleCount && document().settings() && !document().settings()->antialiased2dCanvasEnabled()) |
| + m_imageBuffer->context()->setShouldAntialias(false); |
| + // GraphicsContext's defaults don't always agree with the 2d canvas spec. |
| + // See CanvasRenderingContext2D::State::State() for more information. |
| + m_imageBuffer->context()->setMiterLimit(10); |
| + m_imageBuffer->context()->setStrokeThickness(1); |
| + m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer->context())); |
| + } else { |
| + m_contextStateSaver.clear(); |
| + } |
| // Recalculate compositing requirements if acceleration state changed. |
| if (m_context && m_context->is2d()) |
| @@ -539,12 +558,7 @@ void HTMLCanvasElement::clearCopiedImage() |
| AffineTransform HTMLCanvasElement::baseTransform() const |
| { |
| ASSERT(hasImageBuffer() && !m_didFailToCreateImageBuffer); |
| - IntSize unscaledSize = size(); |
| - IntSize size = convertLogicalToDevice(unscaledSize); |
| - AffineTransform transform; |
| - if (size.width() && size.height()) |
| - transform.scaleNonUniform(size.width() / unscaledSize.width(), size.height() / unscaledSize.height()); |
| - return m_imageBuffer->baseTransform() * transform; |
| + return m_imageBuffer->baseTransform(); |
| } |
| } |