blob: 23675df1be5013e1972dffc4168ca1927e6c997c [file] [log] [blame]
/*
* Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* 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
* 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
* 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
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HTMLCanvasElement_h
#define HTMLCanvasElement_h
#include <memory>
#include "bindings/core/v8/ScriptValue.h"
#include "core/CoreExport.h"
#include "core/dom/ContextLifecycleObserver.h"
#include "core/dom/DOMTypedArray.h"
#include "core/dom/Document.h"
#include "core/fileapi/BlobCallback.h"
#include "core/html/HTMLElement.h"
#include "core/html/canvas/CanvasDrawListener.h"
#include "core/html/canvas/CanvasImageSource.h"
#include "core/html/canvas/CanvasRenderingContextHost.h"
#include "core/imagebitmap/ImageBitmapSource.h"
#include "core/page/PageVisibilityObserver.h"
#include "platform/bindings/ScriptWrappableVisitor.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntSize.h"
#include "platform/graphics/CanvasSurfaceLayerBridge.h"
#include "platform/graphics/GraphicsTypes.h"
#include "platform/graphics/GraphicsTypes3D.h"
#include "platform/graphics/ImageBufferClient.h"
#include "platform/graphics/OffscreenCanvasPlaceholder.h"
#include "platform/heap/Handle.h"
#define CanvasDefaultInterpolationQuality kInterpolationLow
namespace blink {
class AffineTransform;
class CanvasContextCreationAttributes;
class CanvasRenderingContext;
class CanvasRenderingContextFactory;
class GraphicsContext;
class HitTestCanvasResult;
class HTMLCanvasElement;
class Image;
class ImageBitmapOptions;
class ImageBuffer;
class ImageBufferSurface;
class ImageData;
class IntSize;
class
CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext;
typedef CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext
RenderingContext;
class CORE_EXPORT HTMLCanvasElement final
: public HTMLElement,
public ContextLifecycleObserver,
public PageVisibilityObserver,
public CanvasImageSource,
public CanvasRenderingContextHost,
public CanvasSurfaceLayerBridgeObserver,
public ImageBufferClient,
public ImageBitmapSource,
public OffscreenCanvasPlaceholder {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HTMLCanvasElement);
USING_PRE_FINALIZER(HTMLCanvasElement, Dispose);
public:
using Node::GetExecutionContext;
DECLARE_NODE_FACTORY(HTMLCanvasElement);
~HTMLCanvasElement() override;
// Attributes and functions exposed to script
int width() const { return Size().Width(); }
int height() const { return Size().Height(); }
const IntSize& Size() const override { return size_; }
void setWidth(int, ExceptionState&);
void setHeight(int, ExceptionState&);
void SetSize(const IntSize& new_size);
// Called by Document::getCSSCanvasContext as well as above getContext().
CanvasRenderingContext* GetCanvasRenderingContext(
const String&,
const CanvasContextCreationAttributes&);
bool IsPaintable() const;
String toDataURL(const String& mime_type,
const ScriptValue& quality_argument,
ExceptionState&) const;
String toDataURL(const String& mime_type,
ExceptionState& exception_state) const {
return toDataURL(mime_type, ScriptValue(), exception_state);
}
void toBlob(BlobCallback*,
const String& mime_type,
const ScriptValue& quality_argument,
ExceptionState&);
void toBlob(BlobCallback* callback,
const String& mime_type,
ExceptionState& exception_state) {
return toBlob(callback, mime_type, ScriptValue(), exception_state);
}
// Used for canvas capture.
void AddListener(CanvasDrawListener*);
void RemoveListener(CanvasDrawListener*);
// Used for rendering
void DidDraw(const FloatRect&) override;
void DidDraw() override;
void Paint(GraphicsContext&, const LayoutRect&);
PaintCanvas* DrawingCanvas();
void DisableDeferral(DisableDeferralReason);
PaintCanvas* ExistingDrawingCanvas() const;
CanvasRenderingContext* RenderingContext() const { return context_.Get(); }
void EnsureUnacceleratedImageBuffer();
PassRefPtr<Image> CopiedImage(SourceDrawingBuffer,
AccelerationHint,
SnapshotReason);
void ClearCopiedImage();
bool OriginClean() const;
void SetOriginTainted() { origin_clean_ = false; }
AffineTransform BaseTransform() const;
bool Is3d() const;
bool Is2d() const;
bool IsAnimated2d() const;
void DiscardImageBuffer() override;
ImageBuffer* GetImageBuffer() const override { return image_buffer_.get(); }
ImageBuffer* GetOrCreateImageBuffer() override;
bool ShouldBeDirectComposited() const;
void PrepareSurfaceForPaintingIfNeeded();
const AtomicString ImageSourceURL() const override;
InsertionNotificationRequest InsertedInto(ContainerNode*) override;
bool IsDirty() { return !dirty_rect_.IsEmpty(); }
void DoDeferredPaintInvalidation();
void FinalizeFrame() override;
// ContextLifecycleObserver and PageVisibilityObserver implementation
void ContextDestroyed(ExecutionContext*) override;
// PageVisibilityObserver implementation
void PageVisibilityChanged() override;
// CanvasImageSource implementation
PassRefPtr<Image> GetSourceImageForCanvas(SourceImageStatus*,
AccelerationHint,
SnapshotReason,
const FloatSize&) override;
bool WouldTaintOrigin(SecurityOrigin*) const override;
FloatSize ElementSize(const FloatSize&) const override;
bool IsCanvasElement() const override { return true; }
bool IsOpaque() const override;
bool IsAccelerated() const override;
int SourceWidth() override { return size_.Width(); }
int SourceHeight() override { return size_.Height(); }
// CanvasSurfaceLayerBridgeObserver implementation
void OnWebLayerReplaced() override;
// ImageBufferClient implementation
void NotifySurfaceInvalid() override;
void DidDisableAcceleration() override;
void RestoreCanvasMatrixClipStack(PaintCanvas*) const override;
void SetNeedsCompositingUpdate() override;
// ImageBitmapSource implementation
IntSize BitmapSourceSize() const override;
ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
Optional<IntRect> crop_rect,
const ImageBitmapOptions&,
ExceptionState&) override;
// OffscreenCanvasPlaceholder implementation.
void SetPlaceholderFrame(RefPtr<StaticBitmapImage>,
WeakPtr<OffscreenCanvasFrameDispatcher>,
RefPtr<WebTaskRunner>,
unsigned resource_id) override;
DECLARE_VIRTUAL_TRACE();
DECLARE_VIRTUAL_TRACE_WRAPPERS();
void CreateImageBufferUsingSurfaceForTesting(
std::unique_ptr<ImageBufferSurface>);
static void RegisterRenderingContextFactory(
std::unique_ptr<CanvasRenderingContextFactory>);
void UpdateExternallyAllocatedMemory() const;
void StyleDidChange(const ComputedStyle* old_style,
const ComputedStyle& new_style);
void NotifyListenersCanvasChanged();
// For Canvas HitRegions
bool IsSupportedInteractiveCanvasFallback(const Element&);
HitTestCanvasResult* GetControlAndIdIfHitRegionExists(const LayoutPoint&);
String GetIdFromControl(const Element*);
// For OffscreenCanvas that controls this html canvas element
CanvasSurfaceLayerBridge* SurfaceLayerBridge() const {
return surface_layer_bridge_.get();
}
void CreateLayer();
void DetachContext() override { context_ = nullptr; }
void WillDrawImageTo2DContext(CanvasImageSource*);
ExecutionContext* GetTopExecutionContext() const override {
return GetDocument().GetExecutionContext();
}
const KURL& GetExecutionContextUrl() const override {
return GetDocument().TopDocument().Url();
}
DispatchEventResult HostDispatchEvent(Event* event) override {
return DispatchEvent(event);
}
bool IsWebGLAllowed() const override;
protected:
void DidMoveToNewDocument(Document& old_document) override;
private:
explicit HTMLCanvasElement(Document&);
void Dispose();
using ContextFactoryVector =
Vector<std::unique_ptr<CanvasRenderingContextFactory>>;
static ContextFactoryVector& RenderingContextFactories();
static CanvasRenderingContextFactory* GetRenderingContextFactory(int);
enum AccelerationCriteria {
kNormalAccelerationCriteria,
kIgnoreResourceLimitCriteria,
};
bool ShouldAccelerate(AccelerationCriteria) const;
void ParseAttribute(const AttributeModificationParams&) override;
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
bool AreAuthorShadowsAllowed() const override { return false; }
void Reset();
std::unique_ptr<ImageBufferSurface> CreateWebGLImageBufferSurface(
OpacityMode);
std::unique_ptr<ImageBufferSurface> CreateAcceleratedImageBufferSurface(
OpacityMode,
int* msaa_sample_count);
std::unique_ptr<ImageBufferSurface> CreateUnacceleratedImageBufferSurface(
OpacityMode);
void CreateImageBuffer();
void CreateImageBufferInternal(
std::unique_ptr<ImageBufferSurface> external_surface);
bool ShouldUseDisplayList();
void SetSurfaceSize(const IntSize&);
bool PaintsIntoCanvasBuffer() const;
ImageData* ToImageData(SourceDrawingBuffer, SnapshotReason) const;
String ToDataURLInternal(const String& mime_type,
const double& quality,
SourceDrawingBuffer) const;
HeapHashSet<WeakMember<CanvasDrawListener>> listeners_;
IntSize size_;
TraceWrapperMember<CanvasRenderingContext> context_;
bool ignore_reset_;
FloatRect dirty_rect_;
mutable intptr_t externally_allocated_memory_;
bool origin_clean_;
// It prevents HTMLCanvasElement::buffer() from continuously re-attempting to
// allocate an imageBuffer after the first attempt failed.
mutable bool did_fail_to_create_image_buffer_;
bool image_buffer_is_clear_;
std::unique_ptr<ImageBuffer> image_buffer_;
// FIXME: This is temporary for platforms that have to copy the image buffer
// to render (and for CSSCanvasValue).
mutable RefPtr<Image> copied_image_;
// Used for OffscreenCanvas that controls this HTML canvas element
std::unique_ptr<CanvasSurfaceLayerBridge> surface_layer_bridge_;
bool did_notify_listeners_for_current_frame_ = false;
};
} // namespace blink
#endif // HTMLCanvasElement_h