Add WTF::move()
[WebKit-https.git] / Source / WebCore / html / HTMLCanvasElement.cpp
index 062316a..13e3e93 100644 (file)
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 #include "HTMLCanvasElement.h"
 
 #include "Attribute.h"
-#include "CanvasContextAttributes.h"
 #include "CanvasGradient.h"
 #include "CanvasPattern.h"
 #include "CanvasRenderingContext2D.h"
-#include "CanvasStyle.h"
 #include "Chrome.h"
+#include "ChromeClient.h"
 #include "Document.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "GeometryUtilities.h"
 #include "GraphicsContext.h"
 #include "HTMLNames.h"
-#include "ImageBuffer.h"
 #include "ImageData.h"
 #include "MIMETypeRegistry.h"
 #include "Page.h"
 #include "RenderHTMLCanvas.h"
+#include "ScriptController.h"
 #include "Settings.h"
 #include <math.h>
-#include <stdio.h>
 
-#if USE(JSC)
+#include <runtime/JSCInlines.h>
 #include <runtime/JSLock.h>
-#endif
 
 #if ENABLE(WEBGL)    
 #include "WebGLContextAttributes.h"
 #include "WebGLRenderingContext.h"
 #endif
 
-#if PLATFORM(CHROMIUM)
-#include <public/Platform.h>
-#endif
-
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -72,89 +67,124 @@ static const int DefaultHeight = 150;
 
 // Firefox limits width/height to 32767 pixels, but slows down dramatically before it
 // reaches that limit. We limit by area instead, giving us larger maximum dimensions,
-// in exchange for a smaller maximum canvas size.
-static const float MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pixels
-
-//In Skia, we will also limit width/height to 32767.
-static const float MaxSkiaDim = 32767.0F; // Maximum width/height in CSS pixels.
+// in exchange for a smaller maximum canvas size. The maximum canvas size is in CSS pixels.
+#if PLATFORM(IOS)
+static const float MaxCanvasArea = 4580 * 1145; // 20 MB assuming 4 bytes per pixel
+#else
+static const float MaxCanvasArea = 32768 * 8192;
+#endif
 
-HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document* document)
+HTMLCanvasElement::HTMLCanvasElement(const QualifiedName& tagName, Document& document)
     : HTMLElement(tagName, document)
     , m_size(DefaultWidth, DefaultHeight)
     , m_rendererIsCanvas(false)
     , m_ignoreReset(false)
-#if ENABLE(HIGH_DPI_CANVAS)
-      // NOTE: High-DPI canvas requires the platform-specific ImageBuffer implementation to respect
-      // the resolutionScale parameter.
-    , m_deviceScaleFactor(document->frame() ? document->frame()->page()->deviceScaleFactor() : 1)
-#else
-    , m_deviceScaleFactor(1)
-#endif
+    , m_deviceScaleFactor(targetDeviceScaleFactor())
     , m_originClean(true)
     , m_hasCreatedImageBuffer(false)
     , m_didClearImageBuffer(false)
 {
     ASSERT(hasTagName(canvasTag));
+    setHasCustomStyleResolveCallbacks();
 }
 
-PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document* document)
+PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document& document)
 {
     return adoptRef(new HTMLCanvasElement(canvasTag, document));
 }
 
-PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(const QualifiedName& tagName, Document* document)
+PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(const QualifiedName& tagName, Document& document)
 {
     return adoptRef(new HTMLCanvasElement(tagName, document));
 }
 
 HTMLCanvasElement::~HTMLCanvasElement()
 {
-    HashSet<CanvasObserver*>::iterator end = m_observers.end();
-    for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
-        (*it)->canvasDestroyed(this);
+    for (auto it = m_observers.begin(), end = m_observers.end(); it != end; ++it)
+        (*it)->canvasDestroyed(*this);
 
-    m_context.clear(); // Ensure this goes away before the ImageBuffer.
+    m_context = nullptr; // Ensure this goes away before the ImageBuffer.
 }
 
-void HTMLCanvasElement::parseAttribute(const Attribute& attribute)
+void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    if (attribute.name() == widthAttr || attribute.name() == heightAttr)
+    if (name == widthAttr || name == heightAttr)
         reset();
-    HTMLElement::parseAttribute(attribute);
+    HTMLElement::parseAttribute(name, value);
 }
 
-RenderObject* HTMLCanvasElement::createRenderer(RenderArena* arena, RenderStyle* style)
+RenderPtr<RenderElement> HTMLCanvasElement::createElementRenderer(PassRef<RenderStyle> style)
 {
-    Frame* frame = document()->frame();
-    if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript)) {
+    Frame* frame = document().frame();
+    if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript)) {
         m_rendererIsCanvas = true;
-        return new (arena) RenderHTMLCanvas(this);
+        return createRenderer<RenderHTMLCanvas>(*this, WTF::move(style));
     }
 
     m_rendererIsCanvas = false;
-    return HTMLElement::createRenderer(arena, style);
+    return HTMLElement::createElementRenderer(WTF::move(style));
+}
+
+void HTMLCanvasElement::willAttachRenderers()
+{
+    setIsInCanvasSubtree(true);
+}
+
+bool HTMLCanvasElement::canContainRangeEndPoint() const
+{
+    return false;
+}
+
+bool HTMLCanvasElement::canStartSelection() const
+{
+    return false;
 }
 
-void HTMLCanvasElement::addObserver(CanvasObserver* observer)
+void HTMLCanvasElement::addObserver(CanvasObserver& observer)
 {
-    m_observers.add(observer);
+    m_observers.add(&observer);
 }
 
-void HTMLCanvasElement::removeObserver(CanvasObserver* observer)
+void HTMLCanvasElement::removeObserver(CanvasObserver& observer)
 {
-    m_observers.remove(observer);
+    m_observers.remove(&observer);
 }
 
 void HTMLCanvasElement::setHeight(int value)
 {
-    setAttribute(heightAttr, String::number(value));
+    setIntegralAttribute(heightAttr, value);
 }
 
 void HTMLCanvasElement::setWidth(int value)
 {
-    setAttribute(widthAttr, String::number(value));
+    setIntegralAttribute(widthAttr, value);
 }
 
+#if ENABLE(WEBGL)
+static bool requiresAcceleratedCompositingForWebGL()
+{
+#if PLATFORM(GTK) || PLATFORM(EFL)
+    return false;
+#else
+    return true;
+#endif
+
+}
+static bool shouldEnableWebGL(Settings* settings)
+{
+    if (!settings)
+        return false;
+
+    if (!settings->webGLEnabled())
+        return false;
+
+    if (!requiresAcceleratedCompositingForWebGL())
+        return true;
+
+    return settings->acceleratedCompositingEnabled();
+}
+#endif
+
 CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, CanvasContextAttributes* attrs)
 {
     // A Canvas can either be "2D" or "webgl" but never both. If you request a 2D canvas and the existing
@@ -162,41 +192,32 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
     // before creating a new 2D context. Vice versa when requesting a WebGL canvas. Requesting a
     // context with any other type string will destroy any existing context.
     
-    // FIXME - The code depends on the context not going away once created, to prevent JS from
+    // FIXME: The code depends on the context not going away once created, to prevent JS from
     // seeing a dangling pointer. So for now we will disallow the context from being changed
-    // once it is created.
-    if (type == "2d") {
+    // once it is created. https://bugs.webkit.org/show_bug.cgi?id=117095
+    if (is2dType(type)) {
         if (m_context && !m_context->is2d())
-            return 0;
+            return nullptr;
         if (!m_context) {
             bool usesDashbardCompatibilityMode = false;
 #if ENABLE(DASHBOARD_SUPPORT)
-            if (Settings* settings = document()->settings())
+            if (Settings* settings = document().settings())
                 usesDashbardCompatibilityMode = settings->usesDashboardBackwardCompatibilityMode();
 #endif
-            m_context = CanvasRenderingContext2D::create(this, document()->inQuirksMode(), usesDashbardCompatibilityMode);
-#if USE(IOSURFACE_CANVAS_BACKING_STORE) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING))
-            if (m_context) {
-                // Need to make sure a RenderLayer and compositing layer get created for the Canvas
-                setNeedsStyleRecalc(SyntheticStyleChange);
-            }
+            m_context = std::make_unique<CanvasRenderingContext2D>(this, document().inQuirksMode(), usesDashbardCompatibilityMode);
+#if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
+            // Need to make sure a RenderLayer and compositing layer get created for the Canvas
+            setNeedsStyleRecalc(SyntheticStyleChange);
 #endif
         }
         return m_context.get();
     }
-#if ENABLE(WEBGL)    
-    Settings* settings = document()->settings();
-    if (settings && settings->webGLEnabled()
-#if !PLATFORM(CHROMIUM) && !PLATFORM(GTK) && !PLATFORM(EFL)
-        && settings->acceleratedCompositingEnabled()
-#endif
-        ) {
-        // Accept the legacy "webkit-3d" name as well as the provisional "experimental-webgl" name.
-        // Once ratified, we will also accept "webgl" as the context name.
-        if ((type == "webkit-3d") ||
-            (type == "experimental-webgl")) {
+#if ENABLE(WEBGL)
+    if (shouldEnableWebGL(document().settings())) {
+
+        if (is3dType(type)) {
             if (m_context && !m_context->is3d())
-                return 0;
+                return nullptr;
             if (!m_context) {
                 m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
                 if (m_context) {
@@ -210,9 +231,41 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
 #else
     UNUSED_PARAM(attrs);
 #endif
-    return 0;
+    return nullptr;
+}
+    
+bool HTMLCanvasElement::probablySupportsContext(const String& type, CanvasContextAttributes*)
+{
+    // FIXME: Provide implementation that accounts for attributes. Bugzilla bug 117093
+    // https://bugs.webkit.org/show_bug.cgi?id=117093
+
+    // FIXME: The code depends on the context not going away once created (as getContext
+    // is implemented under this assumption) https://bugs.webkit.org/show_bug.cgi?id=117095
+    if (is2dType(type))
+        return !m_context || m_context->is2d();
+
+#if ENABLE(WEBGL)
+    if (shouldEnableWebGL(document().settings())) {
+        if (is3dType(type))
+            return !m_context || m_context->is3d();
+    }
+#endif
+    return false;
+}
+
+bool HTMLCanvasElement::is2dType(const String& type)
+{
+    return type == "2d";
 }
 
+#if ENABLE(WEBGL)
+bool HTMLCanvasElement::is3dType(const String& type)
+{
+    // Retain support for the legacy "webkit-3d" name.
+    return type == "webgl" || type == "experimental-webgl" || type == "webkit-3d";
+}
+#endif
+
 void HTMLCanvasElement::didDraw(const FloatRect& rect)
 {
     clearCopiedImage();
@@ -228,9 +281,13 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect)
         ro->repaintRectangle(enclosingIntRect(m_dirtyRect));
     }
 
-    HashSet<CanvasObserver*>::iterator end = m_observers.end();
-    for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
-        (*it)->canvasChanged(this, rect);
+    notifyObserversCanvasChanged(rect);
+}
+
+void HTMLCanvasElement::notifyObserversCanvasChanged(const FloatRect& rect)
+{
+    for (auto it = m_observers.begin(), end = m_observers.end(); it != end; ++it)
+        (*it)->canvasChanged(*this, rect);
 }
 
 void HTMLCanvasElement::reset()
@@ -240,9 +297,11 @@ void HTMLCanvasElement::reset()
 
     bool ok;
     bool hadImageBuffer = hasCreatedImageBuffer();
+
     int w = getAttribute(widthAttr).toInt(&ok);
     if (!ok || w < 0)
         w = DefaultWidth;
+
     int h = getAttribute(heightAttr).toInt(&ok);
     if (!ok || h < 0)
         h = DefaultHeight;
@@ -259,37 +318,49 @@ void HTMLCanvasElement::reset()
     }
 
     IntSize oldSize = size();
+    IntSize newSize(w, h);
+    float newDeviceScaleFactor = targetDeviceScaleFactor();
+
     // 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 (m_hasCreatedImageBuffer && oldSize == IntSize(w, h) && m_context && m_context->is2d()) {
+    if (m_hasCreatedImageBuffer && oldSize == newSize && m_deviceScaleFactor == newDeviceScaleFactor && m_context && m_context->is2d()) {
         if (!m_didClearImageBuffer)
             clearImageBuffer();
         return;
     }
-    setSurfaceSize(IntSize(w, h));
+
+    m_deviceScaleFactor = newDeviceScaleFactor;
+
+    setSurfaceSize(newSize);
 
 #if ENABLE(WEBGL)
-    if (m_context && m_context->is3d() && oldSize != size())
+    if (is3D() && oldSize != size())
         static_cast<WebGLRenderingContext*>(m_context.get())->reshape(width(), height());
 #endif
 
-    if (RenderObject* renderer = this->renderer()) {
+    if (auto renderer = this->renderer()) {
         if (m_rendererIsCanvas) {
             if (oldSize != size()) {
                 toRenderHTMLCanvas(renderer)->canvasSizeChanged();
-#if USE(ACCELERATED_COMPOSITING)
                 if (renderBox() && renderBox()->hasAcceleratedCompositing())
                     renderBox()->contentChanged(CanvasChanged);
-#endif
             }
             if (hadImageBuffer)
                 renderer->repaint();
         }
     }
 
-    HashSet<CanvasObserver*>::iterator end = m_observers.end();
-    for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
-        (*it)->canvasResized(this);
+    for (auto it = m_observers.begin(), end = m_observers.end(); it != end; ++it)
+        (*it)->canvasResized(*this);
+}
+
+float HTMLCanvasElement::targetDeviceScaleFactor() const
+{
+#if ENABLE(HIGH_DPI_CANVAS)
+    return document().frame() ? document().frame()->page()->deviceScaleFactor() : 1;
+#else
+    return 1;
+#endif
 }
 
 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const
@@ -300,13 +371,12 @@ bool HTMLCanvasElement::paintsIntoCanvasBuffer() const
         return true;
 #endif
 
-#if USE(ACCELERATED_COMPOSITING)
     if (!m_context->isAccelerated())
         return true;
 
     if (renderBox() && renderBox()->hasAcceleratedCompositing())
         return false;
-#endif
+
     return true;
 }
 
@@ -320,7 +390,7 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, boo
         return;
     
     if (m_context) {
-        if (!paintsIntoCanvasBuffer() && !document()->printing())
+        if (!paintsIntoCanvasBuffer() && !document().printing())
             return;
         m_context->paintRenderingResultsToCanvas();
     }
@@ -328,10 +398,14 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, boo
     if (hasCreatedImageBuffer()) {
         ImageBuffer* imageBuffer = buffer();
         if (imageBuffer) {
-            if (m_presentedImage)
-                context->drawImage(m_presentedImage.get(), ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, DoNotRespectImageOrientation, useLowQualityScale);
-            else
-                context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, useLowQualityScale);
+            if (m_presentedImage) {
+                ImageOrientationDescription orientationDescription;
+#if ENABLE(CSS_IMAGE_ORIENTATION)
+                orientationDescription.setImageOrientationEnum(renderer()->style().imageOrientation());
+#endif 
+                context->drawImage(m_presentedImage.get(), ColorSpaceDeviceRGB, pixelSnappedIntRect(r), ImagePaintingOptions(orientationDescription, useLowQualityScale));
+            } else
+                context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, pixelSnappedIntRect(r), useLowQualityScale);
         }
     }
 
@@ -358,7 +432,7 @@ void HTMLCanvasElement::makePresentationCopy()
 {
     if (!m_presentedImage) {
         // The buffer contains the last presented data, so save a copy of it.
-        m_presentedImage = buffer()->copyImage(CopyBackingStore);
+        m_presentedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
     }
 }
 
@@ -371,8 +445,8 @@ void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
 {
     m_size = size;
     m_hasCreatedImageBuffer = false;
-    m_contextStateSaver.clear();
-    m_imageBuffer.clear();
+    m_contextStateSaver = nullptr;
+    m_imageBuffer.reset();
     clearCopiedImage();
 }
 
@@ -399,7 +473,7 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
 
     String encodingMimeType = toEncodingMimeType(mimeType);
 
-#if USE(CG) || USE(SKIA)
+#if USE(CG)
     // Try to get ImageData first, as that may avoid lossy conversions.
     RefPtr<ImageData> imageData = getImageData();
 
@@ -414,15 +488,15 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
 
 PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
 {
-    if (!m_context || !m_context->is3d())
-       return 0;
+#if ENABLE(WEBGL)
+    if (!is3D())
+        return nullptr;
 
-#if ENABLE(WEBGL)    
     WebGLRenderingContext* ctx = static_cast<WebGLRenderingContext*>(m_context.get());
 
     return ctx->paintRenderingResultsToImageData();
 #else
-    return 0;
+    return nullptr;
 #endif
 }
 
@@ -459,24 +533,19 @@ FloatSize HTMLCanvasElement::convertDeviceToLogical(const FloatSize& deviceSize)
 
 SecurityOrigin* HTMLCanvasElement::securityOrigin() const
 {
-    return document()->securityOrigin();
-}
-
-StyleResolver* HTMLCanvasElement::styleResolver()
-{
-    return document()->styleResolver();
+    return document().securityOrigin();
 }
 
 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
 {
 #if USE(IOSURFACE_CANVAS_BACKING_STORE)
     UNUSED_PARAM(size);
-    return document()->settings() && document()->settings()->canvasUsesAcceleratedDrawing();
+    return document().settings() && document().settings()->canvasUsesAcceleratedDrawing();
 #elif ENABLE(ACCELERATED_2D_CANVAS)
     if (m_context && !m_context->is2d())
         return false;
 
-    Settings* settings = document()->settings();
+    Settings* settings = document().settings();
     if (!settings || !settings->accelerated2dCanvasEnabled())
         return false;
 
@@ -484,11 +553,6 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
     if (size.width() * size.height() < settings->minimumAccelerated2dCanvasSize())
         return false;
 
-#if PLATFORM(CHROMIUM)
-    if (!WebKit::Platform::current()->canAccelerate2dCanvas())
-        return false;
-#endif
-
     return true;
 #else
     UNUSED_PARAM(size);
@@ -496,22 +560,6 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
 #endif
 }
 
-bool HTMLCanvasElement::shouldDefer() const
-{
-#if USE(SKIA)
-    if (m_context && !m_context->is2d())
-        return false;
-
-    Settings* settings = document()->settings();
-    if (!settings || !settings->deferred2dCanvasEnabled())
-        return false;
-
-    return true;
-#else
-    return false;
-#endif
-}
-
 void HTMLCanvasElement::createImageBuffer() const
 {
     ASSERT(!m_imageBuffer);
@@ -526,37 +574,27 @@ void HTMLCanvasElement::createImageBuffer() const
 
     if (deviceSize.width() * deviceSize.height() > MaxCanvasArea)
         return;
-#if USE(SKIA)
-    if (deviceSize.width() > MaxSkiaDim || deviceSize.height() > MaxSkiaDim)
-        return;
-#endif
 
     IntSize bufferSize(deviceSize.width(), deviceSize.height());
     if (!bufferSize.width() || !bufferSize.height())
         return;
 
-    RenderingMode renderingMode = shouldAccelerate(bufferSize) ? Accelerated : 
-#if USE(SKIA)
-        UnacceleratedNonPlatformBuffer;
-#else
-        Unaccelerated;
-#endif
-    DeferralMode deferralMode = shouldDefer() ? Deferred : NonDeferred;
-    m_imageBuffer = ImageBuffer::create(size(), m_deviceScaleFactor, ColorSpaceDeviceRGB, renderingMode, deferralMode);
+    RenderingMode renderingMode = shouldAccelerate(bufferSize) ? Accelerated : Unaccelerated;
+    m_imageBuffer = ImageBuffer::create(size(), m_deviceScaleFactor, ColorSpaceDeviceRGB, renderingMode);
     if (!m_imageBuffer)
         return;
     m_imageBuffer->context()->setShadowsIgnoreTransforms(true);
     m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality);
+    if (document().settings() && !document().settings()->antialiased2dCanvasEnabled())
+        m_imageBuffer->context()->setShouldAntialias(false);
     m_imageBuffer->context()->setStrokeThickness(1);
-    m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer->context()));
+    m_contextStateSaver = std::make_unique<GraphicsContextStateSaver>(*m_imageBuffer->context());
 
-#if USE(JSC)
-    JSC::JSLock lock(JSC::SilenceAssertionsOnly);
+    JSC::JSLockHolder lock(scriptExecutionContext()->vm());
     size_t numBytes = 4 * m_imageBuffer->internalSize().width() * m_imageBuffer->internalSize().height();
-    scriptExecutionContext()->globalData()->heap.reportExtraMemoryCost(numBytes);
-#endif
+    scriptExecutionContext()->vm().heap.reportExtraMemoryCost(numBytes);
 
-#if USE(IOSURFACE_CANVAS_BACKING_STORE) || (ENABLE(ACCELERATED_2D_CANVAS) && USE(ACCELERATED_COMPOSITING))
+#if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
     if (m_context && m_context->is2d())
         // Recalculate compositing requirements if acceleration state changed.
         const_cast<HTMLCanvasElement*>(this)->setNeedsStyleRecalc(SyntheticStyleChange);
@@ -565,13 +603,13 @@ void HTMLCanvasElement::createImageBuffer() const
 
 GraphicsContext* HTMLCanvasElement::drawingContext() const
 {
-    return buffer() ? m_imageBuffer->context() : 0;
+    return buffer() ? m_imageBuffer->context() : nullptr;
 }
 
 GraphicsContext* HTMLCanvasElement::existingDrawingContext() const
 {
     if (!m_hasCreatedImageBuffer)
-        return 0;
+        return nullptr;
 
     return drawingContext();
 }
@@ -588,7 +626,7 @@ Image* HTMLCanvasElement::copiedImage() const
     if (!m_copiedImage && buffer()) {
         if (m_context)
             m_context->paintRenderingResultsToCanvas();
-        m_copiedImage = buffer()->copyImage(CopyBackingStore);
+        m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
     }
     return m_copiedImage.get();
 }