2 * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #ifndef HTMLCanvasElement_h
29 #define HTMLCanvasElement_h
31 #include "bindings/core/v8/ScriptValue.h"
32 #include "bindings/core/v8/ScriptWrappableVisitor.h"
33 #include "core/CoreExport.h"
34 #include "core/dom/ContextLifecycleObserver.h"
35 #include "core/dom/DOMTypedArray.h"
36 #include "core/dom/Document.h"
37 #include "core/fileapi/BlobCallback.h"
38 #include "core/html/HTMLElement.h"
39 #include "core/html/canvas/CanvasDrawListener.h"
40 #include "core/html/canvas/CanvasImageSource.h"
41 #include "core/imagebitmap/ImageBitmapSource.h"
42 #include "core/page/PageVisibilityObserver.h"
43 #include "platform/geometry/FloatRect.h"
44 #include "platform/geometry/IntSize.h"
45 #include "platform/graphics/CanvasSurfaceLayerBridge.h"
46 #include "platform/graphics/GraphicsTypes.h"
47 #include "platform/graphics/GraphicsTypes3D.h"
48 #include "platform/graphics/ImageBufferClient.h"
49 #include "platform/graphics/OffscreenCanvasPlaceholder.h"
50 #include "platform/heap/Handle.h"
53 #define CanvasDefaultInterpolationQuality InterpolationLow
57 class AffineTransform;
58 class CanvasContextCreationAttributes;
59 class CanvasRenderingContext;
60 class CanvasRenderingContextFactory;
61 class GraphicsContext;
62 class HitTestCanvasResult;
63 class HTMLCanvasElement;
65 class ImageBitmapOptions;
67 class ImageBufferSurface;
72 CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext;
73 typedef CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext
76 class CORE_EXPORT HTMLCanvasElement final : public HTMLElement,
77 public ContextLifecycleObserver,
78 public PageVisibilityObserver,
79 public CanvasImageSource,
80 public ImageBufferClient,
81 public ImageBitmapSource,
82 public OffscreenCanvasPlaceholder {
83 DEFINE_WRAPPERTYPEINFO();
84 USING_GARBAGE_COLLECTED_MIXIN(HTMLCanvasElement);
85 USING_PRE_FINALIZER(HTMLCanvasElement, dispose);
88 using Node::getExecutionContext;
90 DECLARE_NODE_FACTORY(HTMLCanvasElement);
91 ~HTMLCanvasElement() override;
93 // Attributes and functions exposed to script
94 int width() const { return size().width(); }
95 int height() const { return size().height(); }
97 const IntSize& size() const { return m_size; }
99 void setWidth(int, ExceptionState&);
100 void setHeight(int, ExceptionState&);
102 void setSize(const IntSize& newSize);
104 // Called by Document::getCSSCanvasContext as well as above getContext().
105 CanvasRenderingContext* getCanvasRenderingContext(
107 const CanvasContextCreationAttributes&);
109 bool isPaintable() const;
111 String toDataURL(const String& mimeType,
112 const ScriptValue& qualityArgument,
113 ExceptionState&) const;
114 String toDataURL(const String& mimeType,
115 ExceptionState& exceptionState) const {
116 return toDataURL(mimeType, ScriptValue(), exceptionState);
119 void toBlob(BlobCallback*,
120 const String& mimeType,
121 const ScriptValue& qualityArgument,
123 void toBlob(BlobCallback* callback,
124 const String& mimeType,
125 ExceptionState& exceptionState) {
126 return toBlob(callback, mimeType, ScriptValue(), exceptionState);
129 // Used for canvas capture.
130 void addListener(CanvasDrawListener*);
131 void removeListener(CanvasDrawListener*);
133 // Used for rendering
134 void didDraw(const FloatRect&);
136 void paint(GraphicsContext&, const LayoutRect&);
138 SkCanvas* drawingCanvas() const;
139 void disableDeferral(DisableDeferralReason) const;
140 SkCanvas* existingDrawingCanvas() const;
142 CanvasRenderingContext* renderingContext() const { return m_context.get(); }
144 void ensureUnacceleratedImageBuffer();
145 ImageBuffer* buffer() const;
146 PassRefPtr<Image> copiedImage(SourceDrawingBuffer, AccelerationHint) const;
147 void clearCopiedImage();
149 SecurityOrigin* getSecurityOrigin() const;
150 bool originClean() const;
151 void setOriginTainted() { m_originClean = false; }
153 AffineTransform baseTransform() const;
156 bool isAnimated2D() const;
158 bool hasImageBuffer() const { return m_imageBuffer.get(); }
159 void discardImageBuffer();
161 bool shouldBeDirectComposited() const;
163 void prepareSurfaceForPaintingIfNeeded() const;
165 const AtomicString imageSourceURL() const override;
167 InsertionNotificationRequest insertedInto(ContainerNode*) override;
169 // ContextLifecycleObserver (and PageVisibilityObserver!!!) implementation
170 void contextDestroyed() override;
172 // PageVisibilityObserver implementation
173 void pageVisibilityChanged() override;
175 // CanvasImageSource implementation
176 PassRefPtr<Image> getSourceImageForCanvas(SourceImageStatus*,
179 const FloatSize&) const override;
180 bool wouldTaintOrigin(SecurityOrigin*) const override;
181 FloatSize elementSize(const FloatSize&) const override;
182 bool isCanvasElement() const override { return true; }
183 bool isOpaque() const override;
184 bool isAccelerated() const override;
185 int sourceWidth() override { return m_size.width(); }
186 int sourceHeight() override { return m_size.height(); }
188 // ImageBufferClient implementation
189 void notifySurfaceInvalid() override;
190 bool isDirty() override { return !m_dirtyRect.isEmpty(); }
191 void didDisableAcceleration() override;
192 void didFinalizeFrame() override;
193 void restoreCanvasMatrixClipStack(SkCanvas*) const override;
195 void doDeferredPaintInvalidation();
197 // ImageBitmapSource implementation
198 IntSize bitmapSourceSize() const override;
199 ScriptPromise createImageBitmap(ScriptState*,
201 Optional<IntRect> cropRect,
202 const ImageBitmapOptions&,
203 ExceptionState&) override;
205 DECLARE_VIRTUAL_TRACE();
207 DECLARE_VIRTUAL_TRACE_WRAPPERS();
209 void createImageBufferUsingSurfaceForTesting(
210 std::unique_ptr<ImageBufferSurface>);
212 static void registerRenderingContextFactory(
213 std::unique_ptr<CanvasRenderingContextFactory>);
214 void updateExternallyAllocatedMemory() const;
216 void styleDidChange(const ComputedStyle* oldStyle,
217 const ComputedStyle& newStyle);
219 void notifyListenersCanvasChanged();
221 // For Canvas HitRegions
222 bool isSupportedInteractiveCanvasFallback(const Element&);
223 HitTestCanvasResult* getControlAndIdIfHitRegionExists(const LayoutPoint&);
224 String getIdFromControl(const Element*);
226 // For OffscreenCanvas that controls this html canvas element
227 CanvasSurfaceLayerBridge* surfaceLayerBridge() const {
228 return m_surfaceLayerBridge.get();
230 bool createSurfaceLayer();
232 void detachContext() { m_context = nullptr; }
235 void didMoveToNewDocument(Document& oldDocument) override;
238 explicit HTMLCanvasElement(Document&);
241 using ContextFactoryVector =
242 Vector<std::unique_ptr<CanvasRenderingContextFactory>>;
243 static ContextFactoryVector& renderingContextFactories();
244 static CanvasRenderingContextFactory* getRenderingContextFactory(int);
246 bool shouldAccelerate(const IntSize&) const;
248 void parseAttribute(const QualifiedName&,
250 const AtomicString&) override;
251 LayoutObject* createLayoutObject(const ComputedStyle&) override;
252 bool areAuthorShadowsAllowed() const override { return false; }
256 std::unique_ptr<ImageBufferSurface> createWebGLImageBufferSurface(
257 const IntSize& deviceSize,
259 std::unique_ptr<ImageBufferSurface> createAcceleratedImageBufferSurface(
260 const IntSize& deviceSize,
262 int* msaaSampleCount);
263 std::unique_ptr<ImageBufferSurface> createUnacceleratedImageBufferSurface(
264 const IntSize& deviceSize,
266 void createImageBuffer();
267 void createImageBufferInternal(
268 std::unique_ptr<ImageBufferSurface> externalSurface);
269 bool shouldUseDisplayList(const IntSize& deviceSize);
271 void setSurfaceSize(const IntSize&);
273 bool paintsIntoCanvasBuffer() const;
275 ImageData* toImageData(SourceDrawingBuffer, SnapshotReason) const;
277 String toDataURLInternal(const String& mimeType,
278 const double& quality,
279 SourceDrawingBuffer) const;
281 HeapHashSet<WeakMember<CanvasDrawListener>> m_listeners;
285 TraceWrapperMember<CanvasRenderingContext> m_context;
288 FloatRect m_dirtyRect;
290 mutable intptr_t m_externallyAllocatedMemory;
294 // It prevents HTMLCanvasElement::buffer() from continuously re-attempting to
295 // allocate an imageBuffer after the first attempt failed.
296 mutable bool m_didFailToCreateImageBuffer;
297 bool m_imageBufferIsClear;
298 std::unique_ptr<ImageBuffer> m_imageBuffer;
300 // FIXME: This is temporary for platforms that have to copy the image buffer
301 // to render (and for CSSCanvasValue).
302 mutable RefPtr<Image> m_copiedImage;
304 // Used for OffscreenCanvas that controls this HTML canvas element
305 std::unique_ptr<CanvasSurfaceLayerBridge> m_surfaceLayerBridge;
307 int m_numFramesSinceLastRenderingModeSwitch;
308 bool m_pendingRenderingModeSwitch;
313 #endif // HTMLCanvasElement_h