chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc

/*
 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
 * Copyright (C) 2007 Alp Toker <[email protected]>
 * 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.
 */

#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"

#include <math.h>

#include <limits>
#include <memory>
#include <utility>

#include "base/feature_list.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/gpu/gpu.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/resources/grit/blink_image_resources.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_resource_tracker.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/html/canvas/predefined_color_space.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/layout/hit_test_canvas_result.h"
#include "third_party/blink/renderer/core/layout/layout_html_canvas.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/page_animator.h"
#include "third_party/blink/renderer/core/paint/paint_auto_dark_mode.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
#include "third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_video_frame_pool.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "ui/base/resource/resource_scale_factor.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "v8/include/v8.h"

namespace blink {

namespace {

// These two constants determine if a newly created canvas starts with
// acceleration disabled. Specifically:
// 1. More than `kDisableAccelerationThreshold` canvases have been created.
// 2. The percent of canvases with acceleration disabled is >=
//    `kDisableAccelerationPercent`.
constexpr unsigned kDisableAccelerationThreshold =;
constexpr unsigned kDisableAccelerationPercent =;

BASE_FEATURE();

// Kill switch for not requesting continuous begin frame for low latency canvas.
BASE_FEATURE();

// These values come from the WhatWG spec.
constexpr int kDefaultCanvasWidth =;
constexpr int kDefaultCanvasHeight =;

// A default value of quality argument for toDataURL and toBlob
// It is in an invalid range (outside 0.0 - 1.0) so that it will not be
// misinterpreted as a user-input value
constexpr int kUndefinedQualityValue =;
constexpr int kMinimumAccelerated2dCanvasSize =;

// A default size used for canvas memory allocation when canvas size is greater
// than 2^20.
constexpr uint32_t kMaximumCanvasSize =;

// Tracks whether canvases should start out with acceleration disabled.
class DisabledAccelerationCounterSupplement final
    : public GarbageCollected<DisabledAccelerationCounterSupplement>,
      public Supplement<Document> {};

// static
const char DisabledAccelerationCounterSupplement::kSupplementName[] =;

}  // namespace

HTMLCanvasElement::HTMLCanvasElement(Document& document)
    :{}

HTMLCanvasElement::~HTMLCanvasElement() {}

void HTMLCanvasElement::Dispose() {}

void HTMLCanvasElement::ColorSchemeMayHaveChanged() {}

void HTMLCanvasElement::ParseAttribute(
    const AttributeModificationParams& params) {}

LayoutObject* HTMLCanvasElement::CreateLayoutObject(
    const ComputedStyle& style) {}

Node::InsertionNotificationRequest HTMLCanvasElement::InsertedInto(
    ContainerNode& node) {}

bool HTMLCanvasElement::SizeChangesAreAllowed(ExceptionState& exception_state) {}

void HTMLCanvasElement::setHeight(unsigned value,
                                  ExceptionState& exception_state) {}

void HTMLCanvasElement::setWidth(unsigned value,
                                 ExceptionState& exception_state) {}

void HTMLCanvasElement::SetSize(gfx::Size new_size) {}

HTMLCanvasElement::ContextFactoryVector&
HTMLCanvasElement::RenderingContextFactories() {}

CanvasRenderingContextFactory* HTMLCanvasElement::GetRenderingContextFactory(
    int rendering_api) {}

void HTMLCanvasElement::RegisterRenderingContextFactory(
    std::unique_ptr<CanvasRenderingContextFactory> rendering_context_factory) {}

void HTMLCanvasElement::RecordIdentifiabilityMetric(
    IdentifiableSurface surface,
    IdentifiableToken value) const {}

void HTMLCanvasElement::IdentifiabilityReportWithDigest(
    IdentifiableToken canvas_contents_token) const {}

CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContext(
    const String& type,
    const CanvasContextCreationAttributesCore& attributes) {}

bool HTMLCanvasElement::IsPageVisible() {}

CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal(
    const String& type,
    const CanvasContextCreationAttributesCore& attributes) {}

void HTMLCanvasElement::configureHighDynamicRange(
    const CanvasHighDynamicRangeOptions* options,
    ExceptionState& exception_state) {}

bool HTMLCanvasElement::ShouldBeDirectComposited() const {}

Settings* HTMLCanvasElement::GetSettings() const {}

bool HTMLCanvasElement::IsWebGL1Enabled() const {}

bool HTMLCanvasElement::IsWebGL2Enabled() const {}

bool HTMLCanvasElement::IsWebGLBlocked() const {}

void HTMLCanvasElement::SetContextCreationWasBlocked() {}

void HTMLCanvasElement::DidDraw(const SkIRect& rect) {}

void HTMLCanvasElement::PreFinalizeFrame() {}

void HTMLCanvasElement::PostFinalizeFrame(FlushReason reason) {}

void HTMLCanvasElement::DisableAcceleration(
    std::unique_ptr<CanvasResourceProvider> new_provider_for_testing) {}

void HTMLCanvasElement::SetNeedsCompositingUpdate() {}

void HTMLCanvasElement::DoDeferredPaintInvalidation() {}

void HTMLCanvasElement::Reset() {}

bool HTMLCanvasElement::PaintsIntoCanvasBuffer() const {}

void HTMLCanvasElement::NotifyListenersCanvasChanged() {}

// Returns an image and the image's resolution scale factor.
std::pair<blink::Image*, float> HTMLCanvasElement::BrokenCanvas(
    float device_scale_factor) {}

bool HTMLCanvasElement::LowLatencyEnabled() const {}

void HTMLCanvasElement::SetFilterQuality(
    cc::PaintFlags::FilterQuality filter_quality) {}

// In some instances we don't actually want to paint to the parent layer
// We still might want to set filter quality and MarkFirstContentfulPaint though
void HTMLCanvasElement::Paint(GraphicsContext& context,
                              const PhysicalRect& r,
                              bool flatten_composited_layers) {}

void HTMLCanvasElement::PaintInternal(GraphicsContext& context,
                                      const PhysicalRect& r) {}

bool HTMLCanvasElement::IsPrinting() const {}

UkmParameters HTMLCanvasElement::GetUkmParameters() {}

void HTMLCanvasElement::SetSurfaceSize(gfx::Size size) {}

const AtomicString HTMLCanvasElement::ImageSourceURL() const {}

scoped_refptr<StaticBitmapImage> HTMLCanvasElement::Snapshot(
    FlushReason reason,
    SourceDrawingBuffer source_buffer) const {}

String HTMLCanvasElement::ToDataURLInternal(
    const String& mime_type,
    const double& quality,
    SourceDrawingBuffer source_buffer) const {}

String HTMLCanvasElement::toDataURL(const String& mime_type,
                                    const ScriptValue& quality_argument,
                                    ExceptionState& exception_state) const {}

void HTMLCanvasElement::toBlob(V8BlobCallback* callback,
                               const String& mime_type,
                               const ScriptValue& quality_argument,
                               ExceptionState& exception_state) {}

bool HTMLCanvasElement::IsPresentationAttribute(
    const QualifiedName& name) const {}

void HTMLCanvasElement::CollectStyleForPresentationAttribute(
    const QualifiedName& name,
    const AtomicString& value,
    MutableCSSPropertyValueSet* style) {}

void HTMLCanvasElement::AddListener(CanvasDrawListener* listener) {}

void HTMLCanvasElement::RemoveListener(CanvasDrawListener* listener) {}

bool HTMLCanvasElement::OriginClean() const {}

bool HTMLCanvasElement::ShouldAccelerate2dContext() const {}

CanvasResourceDispatcher* HTMLCanvasElement::GetOrCreateResourceDispatcher() {}

bool HTMLCanvasElement::PushFrame(scoped_refptr<CanvasResource>&& image,
                                  const SkIRect& damage_rect) {}

bool HTMLCanvasElement::ShouldAccelerate() const {}

bool HTMLCanvasElement::ShouldDisableAccelerationBecauseOfReadback() const {}

std::unique_ptr<Canvas2DLayerBridge> HTMLCanvasElement::Create2DLayerBridge() {}

void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal(
    std::unique_ptr<Canvas2DLayerBridge> external_canvas2d_bridge) {}

void HTMLCanvasElement::NotifyGpuContextLost() {}

void HTMLCanvasElement::Trace(Visitor* visitor) const {}

Canvas2DLayerBridge* HTMLCanvasElement::GetOrCreateCanvas2DLayerBridge() {}

void HTMLCanvasElement::SetResourceProviderForTesting(
    std::unique_ptr<CanvasResourceProvider> provider,
    std::unique_ptr<Canvas2DLayerBridge> bridge,
    const gfx::Size& size) {}

void HTMLCanvasElement::DiscardResourceProvider() {}

void HTMLCanvasElement::UpdateSuspendOffscreenCanvasAnimation() {}

void HTMLCanvasElement::PageVisibilityChanged() {}

void HTMLCanvasElement::ContextDestroyed() {}

bool HTMLCanvasElement::StyleChangeNeedsDidDraw(
    const ComputedStyle* old_style,
    const ComputedStyle& new_style) {}

void HTMLCanvasElement::StyleDidChange(const ComputedStyle* old_style,
                                       const ComputedStyle& new_style) {}

void HTMLCanvasElement::LayoutObjectDestroyed() {}

void HTMLCanvasElement::DidMoveToNewDocument(Document& old_document) {}

void HTMLCanvasElement::DidRecalcStyle(const StyleRecalcChange change) {}

void HTMLCanvasElement::RemovedFrom(ContainerNode& insertion_point) {}

void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) {}

bool HTMLCanvasElement::EnableAcceleration() {}

bool HTMLCanvasElement::RecreateCanvasInGPURasterMode() {}

scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas(
    FlushReason reason,
    SourceImageStatus* status,
    const gfx::SizeF&,
    const AlphaDisposition alpha_disposition) {}

scoped_refptr<StaticBitmapImage>
HTMLCanvasElement::GetSourceImageForCanvasInternal(
    FlushReason reason,
    SourceImageStatus* status,
    const AlphaDisposition alpha_disposition) {}

bool HTMLCanvasElement::WouldTaintOrigin() const {}

gfx::SizeF HTMLCanvasElement::ElementSize(
    const gfx::SizeF&,
    const RespectImageOrientationEnum) const {}

gfx::Size HTMLCanvasElement::BitmapSourceSize() const {}

ScriptPromise<ImageBitmap> HTMLCanvasElement::CreateImageBitmap(
    ScriptState* script_state,
    std::optional<gfx::Rect> crop_rect,
    const ImageBitmapOptions* options,
    ExceptionState& exception_state) {}

void HTMLCanvasElement::SetOffscreenCanvasResource(
    scoped_refptr<CanvasResource>&& image,
    viz::ResourceId resource_id) {}

bool HTMLCanvasElement::IsOpaque() const {}

bool HTMLCanvasElement::CreateLayer() {}

void HTMLCanvasElement::OnWebLayerUpdated() {}

void HTMLCanvasElement::RegisterContentsLayer(cc::Layer* layer) {}

void HTMLCanvasElement::UnregisterContentsLayer(cc::Layer* layer) {}

FontSelector* HTMLCanvasElement::GetFontSelector() {}

void HTMLCanvasElement::UpdateMemoryUsage() {}

size_t HTMLCanvasElement::GetMemoryUsage() const {}

void HTMLCanvasElement::ReplaceExisting2dLayerBridge(
    std::unique_ptr<Canvas2DLayerBridge> new_layer_bridge,
    std::unique_ptr<CanvasResourceProvider> new_provider_for_testing) {}

CanvasResourceProvider* HTMLCanvasElement::GetOrCreateCanvasResourceProvider(
    RasterModeHint hint) {}

scoped_refptr<StaticBitmapImage> HTMLCanvasElement::GetTransparentImage() {}

cc::Layer* HTMLCanvasElement::ContentsCcLayer() const {}

RespectImageOrientationEnum HTMLCanvasElement::RespectImageOrientation() const {}

// Temporary plumbing
bool HTMLCanvasElement::IsHibernating() const {}

bool HTMLCanvasElement::IsAccelerated() const {}

}  // namespace blink