diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-16 11:45:35 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-17 08:59:23 +0000 |
commit | 552906b0f222c5d5dd11b9fd73829d510980461a (patch) | |
tree | 3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/third_party/blink/renderer/core/html/canvas | |
parent | 1b05827804eaf047779b597718c03e7d38344261 (diff) | |
download | qtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz |
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/html/canvas')
22 files changed, 491 insertions, 428 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc index 3d8b51d9113..98297281a3b 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc @@ -20,7 +20,6 @@ #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h" -#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" @@ -310,8 +309,10 @@ void CanvasAsyncBlobCreator::ScheduleAsyncBlobCreation(const double& quality) { // deadlines (6.7s or 13s) bypass the web test running deadline (6s) // and result in timeouts on different tests. We use // enforce_idle_encoding_for_test_ to test idle encoding in unit tests. + // We also don't use idle tasks in workers because there's no proper idle + // queue there and tasks can take too long without requestAnimationFrame. bool use_idle_encoding = - (mime_type_ != kMimeTypeWebp) && + WTF::IsMainThread() && (mime_type_ != kMimeTypeWebp) && (enforce_idle_encoding_for_test_ || !RuntimeEnabledFeatures::NoIdleEncodingForWebTestsEnabled()); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h index fe400b9bc00..9a2c289975a 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h @@ -11,8 +11,8 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_blob_callback.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/html/canvas/image_encode_options.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" @@ -50,8 +50,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator enum ToBlobFunctionType { kHTMLCanvasToBlobCallback, kHTMLCanvasConvertToBlobPromise, - kOffscreenCanvasConvertToBlobPromise, - kNumberOfToBlobFunctionTypes + kOffscreenCanvasConvertToBlobPromise }; void ScheduleAsyncBlobCreation(const double& quality); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc index 3d0c1185640..32388eb43c1 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc @@ -7,6 +7,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/html/canvas/image_data.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h" @@ -33,7 +34,7 @@ class MockCanvasAsyncBlobCreator : public CanvasAsyncBlobCreator { kHTMLCanvasToBlobCallback, nullptr, base::TimeTicks(), - document, + document->GetExecutionContext(), nullptr) { if (fail_encoder_initialization) fail_encoder_initialization_for_test_ = true; @@ -293,7 +294,7 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) { source_bitmap_image, options, CanvasAsyncBlobCreator::ToBlobFunctionType:: kHTMLCanvasConvertToBlobPromise, - base::TimeTicks(), &GetDocument(), nullptr); + base::TimeTicks(), GetFrame().DomWindow(), nullptr); ASSERT_TRUE(async_blob_creator->EncodeImageForConvertToBlobTest()); sk_sp<SkData> sk_data = SkData::MakeWithCopy( diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h index e745c09b710..7a0266b3868 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h @@ -9,10 +9,8 @@ #include "base/memory/weak_ptr.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/skia/include/core/SkRefCnt.h" - -class SkImage; namespace blink { @@ -22,7 +20,7 @@ class CORE_EXPORT CanvasDrawListener : public GarbageCollectedMixin { public: virtual ~CanvasDrawListener(); virtual void SendNewFrame( - sk_sp<SkImage>, + scoped_refptr<StaticBitmapImage>, base::WeakPtr<WebGraphicsContext3DProviderWrapper>) = 0; virtual bool NeedsNewFrame() const = 0; virtual void RequestFrame() = 0; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc index da84ab47e1c..c86e35e067b 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc @@ -37,8 +37,6 @@ CanvasFontCache::CanvasFontCache(Document& document) default_font_description.SetComputedSize(defaultFontSize); default_font_style_ = ComputedStyle::Create(); default_font_style_->SetFontDescription(default_font_description); - default_font_style_->GetFont().Update( - default_font_style_->GetFont().GetFontSelector()); } CanvasFontCache::~CanvasFontCache() { diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc index 09e5055466e..12047018871 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc @@ -42,7 +42,7 @@ CanvasRenderingContext* CanvasFontCacheTest::Context2D() const { void CanvasFontCacheTest::SetUp() { PageTestBase::SetUp(); - GetDocument().documentElement()->SetInnerHTMLFromString( + GetDocument().documentElement()->setInnerHTML( "<body><canvas id='c'></canvas></body>"); UpdateAllLifecyclePhasesForTest(); canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c")); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h index 86478c5c04d..8e8782b0461 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h @@ -31,11 +31,11 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" +#include "third_party/blink/renderer/platform/graphics/image_orientation.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" namespace blink { -class FloatRect; class Image; enum SourceImageStatus { @@ -67,16 +67,12 @@ class CORE_EXPORT CanvasImageSource { virtual bool IsImageBitmap() const { return false; } virtual bool IsOffscreenCanvas() const { return false; } - // Adjusts the source and destination rectangles for cases where the actual - // source image is a subregion of the image returned by - // getSourceImageForCanvas. - virtual void AdjustDrawRects(FloatRect* src_rect, FloatRect* dst_rect) const { - } - - virtual FloatSize ElementSize(const FloatSize& default_object_size) const = 0; + virtual FloatSize ElementSize(const FloatSize& default_object_size, + const RespectImageOrientationEnum) const = 0; virtual FloatSize DefaultDestinationSize( - const FloatSize& default_object_size) const { - return ElementSize(default_object_size); + const FloatSize& default_object_size, + const RespectImageOrientationEnum respect_orientation) const { + return ElementSize(default_object_size, respect_orientation); } virtual const KURL& SourceURL() const { return BlankURL(); } virtual bool IsOpaque() const { return false; } diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc index 51de8c31002..2793b17d823 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc @@ -40,9 +40,8 @@ CanvasRenderingContext::CanvasRenderingContext( const CanvasContextCreationAttributesCore& attrs) : host_(host), color_params_(CanvasColorSpace::kSRGB, - CanvasPixelFormat::kRGBA8, - kNonOpaque, - CanvasForceRGBA::kNotForced), + CanvasColorParams::GetNativeCanvasPixelFormat(), + kNonOpaque), creation_attributes_(attrs) { // Supported color spaces and pixel formats: sRGB in uint8, e-sRGB in f16, // linear sRGB and p3 and rec2020 with linear gamma transfer function in f16. @@ -89,6 +88,8 @@ WTF::String CanvasRenderingContext::PixelFormatAsString() const { return kRGBA8CanvasPixelFormatName; case CanvasPixelFormat::kF16: return kF16CanvasPixelFormatName; + case CanvasPixelFormat::kBGRA8: + return kBGRA8CanvasPixelFormatName; }; CHECK(false); return ""; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h index 787de816804..e14dd738e8c 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h @@ -51,6 +51,7 @@ constexpr const char* kRec2020CanvasColorSpaceName = "rec2020"; constexpr const char* kP3CanvasColorSpaceName = "p3"; constexpr const char* kRGBA8CanvasPixelFormatName = "uint8"; +constexpr const char* kBGRA8CanvasPixelFormatName = "uint8"; constexpr const char* kF16CanvasPixelFormatName = "float16"; class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable, diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc index 116d2026856..6e4763718ca 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc @@ -5,8 +5,11 @@ #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h" #include "base/feature_list.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h" #include "third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h" @@ -15,7 +18,6 @@ #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/skia/include/core/SkSurface.h" namespace blink { @@ -97,97 +99,9 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl( : nullptr; if (Is3d()) { - CanvasResourceProvider::ResourceUsage usage; - if (SharedGpuContext::IsGpuCompositingEnabled()) { - if (LowLatencyEnabled()) { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedDirect3DResourceUsage; - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedCompositedResourceUsage; - } - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kSoftwareCompositedResourceUsage; - } - - uint8_t presentation_mode = - CanvasResourceProvider::kDefaultPresentationMode; - if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { - presentation_mode |= - CanvasResourceProvider::kAllowImageChromiumPresentationMode; - } - if (RenderingContext() && RenderingContext()->UsingSwapChain()) { - DCHECK(LowLatencyEnabled()); - // Allow swap chain presentation only if 3d context is using a swap - // chain since we'll be importing it as a passthrough texture. - presentation_mode |= - CanvasResourceProvider::kAllowSwapChainPresentationMode; - } - - ReplaceResourceProvider(CanvasResourceProvider::CreateForCanvas( - Size(), usage, SharedGpuContext::ContextProviderWrapper(), - 0 /* msaa_sample_count */, FilterQuality(), ColorParams(), - presentation_mode, std::move(dispatcher), - RenderingContext()->IsOriginTopLeft())); + CreateCanvasResourceProvider3D(hint, dispatcher); } else { - DCHECK(Is2d()); - const bool want_acceleration = - hint == kPreferAcceleration && ShouldAccelerate2dContext(); - - CanvasResourceProvider::ResourceUsage usage; - if (want_acceleration) { - if (LowLatencyEnabled()) { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedDirect2DResourceUsage; - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedCompositedResourceUsage; - } - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kSoftwareCompositedResourceUsage; - } - - uint8_t presentation_mode = - CanvasResourceProvider::kDefaultPresentationMode; - // Allow GMB image resources if the runtime feature is enabled or if - // we want to use it for low latency mode. - if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() || - (base::FeatureList::IsEnabled( - features::kLowLatencyCanvas2dImageChromium) && - LowLatencyEnabled() && want_acceleration)) { - presentation_mode |= - CanvasResourceProvider::kAllowImageChromiumPresentationMode; - } - // Allow swap chains only if the runtime feature is enabled and we're - // in low latency mode too. - if (base::FeatureList::IsEnabled( - features::kLowLatencyCanvas2dSwapChain) && - LowLatencyEnabled() && want_acceleration) { - presentation_mode |= - CanvasResourceProvider::kAllowSwapChainPresentationMode; - } - - // It is important to not use the context's IsOriginTopLeft() here - // because that denotes the current state and could change after the - // new resource provider is created e.g. due to switching between - // unaccelerated and accelerated modes during tab switching. - const bool is_origin_top_left = - !want_acceleration || LowLatencyEnabled(); - - ReplaceResourceProvider(CanvasResourceProvider::CreateForCanvas( - Size(), usage, SharedGpuContext::ContextProviderWrapper(), - GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(), - presentation_mode, std::move(dispatcher), is_origin_top_left)); - - if (ResourceProvider()) { - // Always save an initial frame, to support resetting the top level - // matrix and clip. - ResourceProvider()->Canvas()->save(); - ResourceProvider()->SetFilterQuality(FilterQuality()); - ResourceProvider()->SetResourceRecyclingEnabled(true); - } + CreateCanvasResourceProvider2D(hint, dispatcher); } } if (!ResourceProvider()) @@ -196,6 +110,117 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl( return ResourceProvider(); } +void CanvasRenderingContextHost::CreateCanvasResourceProvider3D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher) { + DCHECK(Is3d()); + + uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode; + if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { + presentation_mode |= + CanvasResourceProvider::kAllowImageChromiumPresentationMode; + } + if (RenderingContext() && RenderingContext()->UsingSwapChain()) { + DCHECK(LowLatencyEnabled()); + // Allow swap chain presentation only if 3d context is using a swap + // chain since we'll be importing it as a passthrough texture. + presentation_mode |= + CanvasResourceProvider::kAllowSwapChainPresentationMode; + } + CanvasResourceProvider::ResourceUsage usage; + + if (SharedGpuContext::IsGpuCompositingEnabled()) { + if (LowLatencyEnabled() && RenderingContext()) { + // Allow swap chain presentation only if 3d context is using a swap + // chain since we'll be importing it as a passthrough texture. + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedDirect3DResourceUsage; + } else { + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedCompositedResourceUsage; + } + } else { + usage = + CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage; + } + + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", usage); + ReplaceResourceProvider(CanvasResourceProvider::Create( + Size(), usage, SharedGpuContext::ContextProviderWrapper(), + 0 /* msaa_sample_count */, FilterQuality(), ColorParams(), + presentation_mode, std::move(dispatcher), + RenderingContext()->IsOriginTopLeft())); + if (ResourceProvider() && ResourceProvider()->IsValid()) { + base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated", + ResourceProvider()->IsAccelerated()); + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType", + ResourceProvider()->GetType()); + } +} + +void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher) { + DCHECK(Is2d()); + const bool want_acceleration = + hint == kPreferAcceleration && ShouldAccelerate2dContext(); + + uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode; + // Allow GMB image resources if the runtime feature is enabled or if + // we want to use it for low latency mode. + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() || + (base::FeatureList::IsEnabled( + features::kLowLatencyCanvas2dImageChromium) && + LowLatencyEnabled() && want_acceleration)) { + presentation_mode |= + CanvasResourceProvider::kAllowImageChromiumPresentationMode; + } + if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain) && + LowLatencyEnabled() && want_acceleration) { + presentation_mode |= + CanvasResourceProvider::kAllowSwapChainPresentationMode; + } + + CanvasResourceProvider::ResourceUsage usage; + if (want_acceleration) { + if (LowLatencyEnabled()) { + // Allow swap chains only if the runtime feature is enabled and we're + // in low latency mode too. + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedDirect2DResourceUsage; + } else { + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedCompositedResourceUsage; + } + } else { + usage = + CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage; + } + + // It is important to not use the context's IsOriginTopLeft() here + // because that denotes the current state and could change after the + // new resource provider is created e.g. due to switching between + // unaccelerated and accelerated modes during tab switching. + const bool is_origin_top_left = !want_acceleration || LowLatencyEnabled(); + + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", usage); + ReplaceResourceProvider(CanvasResourceProvider::Create( + Size(), usage, SharedGpuContext::ContextProviderWrapper(), + GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(), + presentation_mode, std::move(dispatcher), is_origin_top_left)); + + if (ResourceProvider()) { + if (ResourceProvider()->IsValid()) { + base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated", + ResourceProvider()->IsAccelerated()); + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType", + ResourceProvider()->GetType()); + } + ResourceProvider()->SetFilterQuality(FilterQuality()); + ResourceProvider()->SetResourceRecyclingEnabled(true); + } +} + CanvasColorParams CanvasRenderingContextHost::ColorParams() const { if (RenderingContext()) return RenderingContext()->ColorParams(); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h index 851de57833e..e0503886bc6 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h @@ -10,7 +10,6 @@ #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h" -#include "third_party/blink/renderer/core/html/canvas/image_encode_options.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" @@ -25,6 +24,7 @@ class CanvasRenderingContext; class CanvasResource; class CanvasResourceDispatcher; class FontSelector; +class ImageEncodeOptions; class KURL; class StaticBitmapImage; @@ -110,6 +110,13 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost, scoped_refptr<StaticBitmapImage> CreateTransparentImage(const IntSize&) const; + void CreateCanvasResourceProvider2D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher); + void CreateCanvasResourceProvider3D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher); + bool did_fail_to_create_resource_provider_ = false; bool did_record_canvas_size_to_uma_ = false; HostType host_type_ = kNone; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index 727f95a161e..487efcdd8ba 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc @@ -42,6 +42,8 @@ #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" @@ -66,19 +68,17 @@ #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/imagebitmap/image_bitmap_options.h" #include "third_party/blink/renderer/core/input_type_names.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/paint/compositing/paint_layer_compositor.h" +#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_timing.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_heuristic_parameters.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" @@ -108,7 +108,7 @@ constexpr int kMinimumAccelerated2dCanvasSize = 128 * 129; HTMLCanvasElement::HTMLCanvasElement(Document& document) : HTMLElement(html_names::kCanvasTag, document), - ContextLifecycleObserver(&document), + ExecutionContextLifecycleObserver(GetExecutionContext()), PageVisibilityObserver(document.GetPage()), CanvasRenderingContextHost( CanvasRenderingContextHost::HostType::kCanvasHost), @@ -140,11 +140,11 @@ void HTMLCanvasElement::Dispose() { if (context_) { UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.HasRendered", bool(ResourceProvider())); - if (ResourceProvider()) { + if (context_->Host()) { UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.IsComposited", context_->IsComposited()); + context_->DetachHost(); } - context_->DetachHost(); context_ = nullptr; } @@ -154,10 +154,6 @@ void HTMLCanvasElement::Dispose() { } if (surface_layer_bridge_) { - if (surface_layer_bridge_->GetCcLayer()) { - GraphicsLayer::UnregisterContentsLayer( - surface_layer_bridge_->GetCcLayer()); - } // Observer has to be cleared out at this point. Otherwise the // SurfaceLayerBridge may call back into the observer which is undefined // behavior. In the worst case, the dead canvas element re-adds itself into @@ -301,7 +297,7 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal( // If this context is cross-origin, it should prefer to use the low-power GPU LocalFrame* frame = GetDocument().GetFrame(); CanvasContextCreationAttributesCore recomputed_attributes = attributes; - if (frame && frame->IsCrossOriginSubframe()) + if (frame && frame->IsCrossOriginToMainFrame()) recomputed_attributes.power_preference = "low-power"; context_ = factory->Create(this, recomputed_attributes); @@ -387,7 +383,12 @@ bool HTMLCanvasElement::IsWebGL2Enabled() const { bool HTMLCanvasElement::IsWebGLBlocked() const { Document& document = GetDocument(); LocalFrame* frame = document.GetFrame(); - return frame && frame->Client()->ShouldBlockWebGL(); + if (!frame) + return false; + + bool blocked = false; + frame->GetLocalFrameHostRemote().Are3DAPIsBlocked(&blocked); + return blocked; } void HTMLCanvasElement::DidDraw(const FloatRect& rect) { @@ -490,13 +491,23 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() { return; } LayoutBox* layout_box = GetLayoutBox(); + + FloatRect content_rect; + if (layout_box) { + if (layout_box->IsLayoutReplaced()) { + content_rect = + FloatRect(ToLayoutReplaced(layout_box)->ReplacedContentRect()); + } else { + content_rect = FloatRect(layout_box->PhysicalContentBoxRect()); + } + } + if (Is2d()) { FloatRect src_rect(0, 0, Size().Width(), Size().Height()); dirty_rect_.Intersect(src_rect); FloatRect invalidation_rect; if (layout_box) { - FloatRect content_rect(layout_box->PhysicalContentBoxRect()); FloatRect mapped_dirty_rect = MapRect(dirty_rect_, src_rect, content_rect); if (context_->IsComposited()) { @@ -532,7 +543,6 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() { // being stretched, so we need to account for color bleeding caused by the // interpolation filter. FloatRect src_rect(0, 0, Size().Width(), Size().Height()); - FloatRect content_rect(layout_box->PhysicalContentBoxRect()); if (content_rect.Width() > src_rect.Width() || content_rect.Height() > src_rect.Height()) { dirty_rect_.Inflate(0.5); @@ -541,9 +551,6 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() { dirty_rect_.Intersect(src_rect); PhysicalRect mapped_dirty_rect( EnclosingIntRect(MapRect(dirty_rect_, src_rect, content_rect))); - // For querying PaintLayer::GetCompositingState() - // FIXME: is this invalidation using the correct compositing state? - DisableCompositingQueryAsserts disabler; layout_box->InvalidatePaintRectangle(mapped_dirty_rect); } dirty_rect_ = FloatRect(); @@ -602,7 +609,7 @@ void HTMLCanvasElement::Reset() { if (layout_object->IsCanvas()) { if (old_size != Size()) { ToLayoutHTMLCanvas(layout_object)->CanvasSizeChanged(); - if (GetLayoutBox() && GetLayoutBox()->HasAcceleratedCompositing()) + if (GetDocument().GetSettings()->GetAcceleratedCompositingEnabled()) GetLayoutBox()->ContentChanged(kCanvasChanged); } if (had_resource_provider) @@ -617,7 +624,8 @@ bool HTMLCanvasElement::PaintsIntoCanvasBuffer() const { DCHECK(context_); if (!context_->IsComposited()) return true; - if (GetLayoutBox() && GetLayoutBox()->HasAcceleratedCompositing()) + auto* settings = GetDocument().GetSettings(); + if (settings && settings->GetAcceleratedCompositingEnabled()) return false; return true; @@ -640,15 +648,15 @@ void HTMLCanvasElement::NotifyListenersCanvasChanged() { if (listener_needs_new_frame_capture) { SourceImageStatus status; - scoped_refptr<Image> source_image = - GetSourceImageForCanvas(&status, kPreferNoAcceleration, FloatSize()); + scoped_refptr<StaticBitmapImage> source_image = + GetSourceImageForCanvasInternal(&status, kPreferNoAcceleration); if (status != kNormalSourceImageStatus) return; - sk_sp<SkImage> image = - source_image->PaintImageForCurrentFrame().GetSkImage(); for (CanvasDrawListener* listener : listeners_) { - if (listener->NeedsNewFrame()) - listener->SendNewFrame(image, source_image->ContextProviderWrapper()); + if (listener->NeedsNewFrame()) { + listener->SendNewFrame(source_image, + source_image->ContextProviderWrapper()); + } } } } @@ -747,53 +755,51 @@ void HTMLCanvasElement::PaintInternal(GraphicsContext& context, const PhysicalRect& r) { context_->PaintRenderingResultsToCanvas(kFrontBuffer); if (HasResourceProvider()) { - if (!context.ContextDisabled()) { - const ComputedStyle* style = GetComputedStyle(); - // For 2D Canvas, there are two ways of render Canvas for printing: - // display list or image snapshot. Display list allows better PDF printing - // and we prefer this method. - // Here are the requirements for display list to be used: - // 1. We must have had a full repaint of the Canvas after beginprint - // event has been fired. Otherwise, we don't have a PaintRecord. - // 2. CSS property 'image-rendering' must not be 'pixelated'. - - // display list rendering: we replay the last full PaintRecord, if Canvas - // has been redraw since beginprint happened. - if (IsPrinting() && !Is3d() && canvas2d_bridge_) { - canvas2d_bridge_->FlushRecording(); - if (canvas2d_bridge_->getLastRecord()) { - if (style && style->ImageRendering() != EImageRendering::kPixelated) { - context.Canvas()->save(); - context.Canvas()->translate(r.X(), r.Y()); - context.Canvas()->scale(r.Width() / Size().Width(), - r.Height() / Size().Height()); - context.Canvas()->drawPicture(canvas2d_bridge_->getLastRecord()); - context.Canvas()->restore(); - UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", true); - return; - } + const ComputedStyle* style = GetComputedStyle(); + // For 2D Canvas, there are two ways of render Canvas for printing: + // display list or image snapshot. Display list allows better PDF printing + // and we prefer this method. + // Here are the requirements for display list to be used: + // 1. We must have had a full repaint of the Canvas after beginprint + // event has been fired. Otherwise, we don't have a PaintRecord. + // 2. CSS property 'image-rendering' must not be 'pixelated'. + + // display list rendering: we replay the last full PaintRecord, if Canvas + // has been redraw since beginprint happened. + if (IsPrinting() && !Is3d() && canvas2d_bridge_) { + canvas2d_bridge_->FlushRecording(); + if (canvas2d_bridge_->getLastRecord()) { + if (style && style->ImageRendering() != EImageRendering::kPixelated) { + context.Canvas()->save(); + context.Canvas()->translate(r.X(), r.Y()); + context.Canvas()->scale(r.Width() / Size().Width(), + r.Height() / Size().Height()); + context.Canvas()->drawPicture(canvas2d_bridge_->getLastRecord()); + context.Canvas()->restore(); + UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", true); + return; } - UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", false); - } - // or image snapshot rendering: grab a snapshot and raster it. - SkBlendMode composite_operator = - !context_ || context_->CreationAttributes().alpha - ? SkBlendMode::kSrcOver - : SkBlendMode::kSrc; - FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size())); - scoped_refptr<StaticBitmapImage> snapshot = - canvas2d_bridge_ - ? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration) - : (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr); - if (snapshot) { - // GraphicsContext cannot handle gpu resource serialization. - snapshot = snapshot->MakeUnaccelerated(); - DCHECK(!snapshot->IsTextureBacked()); - context.DrawImage(snapshot.get(), Image::kSyncDecode, - FloatRect(PixelSnappedIntRect(r)), &src_rect, - style && style->HasFilterInducingProperty(), - composite_operator); } + UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", false); + } + // or image snapshot rendering: grab a snapshot and raster it. + SkBlendMode composite_operator = + !context_ || context_->CreationAttributes().alpha + ? SkBlendMode::kSrcOver + : SkBlendMode::kSrc; + FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size())); + scoped_refptr<StaticBitmapImage> snapshot = + canvas2d_bridge_ + ? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration) + : (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr); + if (snapshot) { + // GraphicsContext cannot handle gpu resource serialization. + snapshot = snapshot->MakeUnaccelerated(); + DCHECK(!snapshot->IsTextureBacked()); + context.DrawImage(snapshot.get(), Image::kSyncDecode, + FloatRect(PixelSnappedIntRect(r)), &src_rect, + style && style->HasFilterInducingProperty(), + composite_operator); } } else { // When alpha is false, we should draw to opaque black. @@ -977,7 +983,7 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback, async_creator = MakeGarbageCollected<CanvasAsyncBlobCreator>( image_bitmap, options, CanvasAsyncBlobCreator::kHTMLCanvasToBlobCallback, callback, start_time, - &GetDocument()); + GetExecutionContext()); } if (async_creator) { @@ -1050,7 +1056,8 @@ bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const { // The following is necessary for handling the special case of canvases in // the dev tools overlay, which run in a process that supports accelerated // 2d canvas but in a special compositing context that does not. - if (GetLayoutBox() && !GetLayoutBox()->HasAcceleratedCompositing()) + auto* settings = GetDocument().GetSettings(); + if (settings && !settings->GetAcceleratedCompositingEnabled()) return false; // Avoid creating |contextProvider| until we're sure we want to try use it, @@ -1140,7 +1147,7 @@ void HTMLCanvasElement::NotifyGpuContextLost() { void HTMLCanvasElement::Trace(Visitor* visitor) { visitor->Trace(listeners_); visitor->Trace(context_); - ContextLifecycleObserver::Trace(visitor); + ExecutionContextLifecycleObserver::Trace(visitor); PageVisibilityObserver::Trace(visitor); HTMLElement::Trace(visitor); } @@ -1184,7 +1191,7 @@ void HTMLCanvasElement::PageVisibilityChanged() { DiscardResourceProvider(); } -void HTMLCanvasElement::ContextDestroyed(ExecutionContext*) { +void HTMLCanvasElement::ContextDestroyed() { if (context_) context_->Stop(); } @@ -1203,14 +1210,13 @@ void HTMLCanvasElement::LayoutObjectDestroyed() { } void HTMLCanvasElement::DidMoveToNewDocument(Document& old_document) { - ContextLifecycleObserver::SetContext(&GetDocument()); - PageVisibilityObserver::SetContext(GetDocument().GetPage()); + SetExecutionContext(GetExecutionContext()); + SetPage(GetDocument().GetPage()); HTMLElement::DidMoveToNewDocument(old_document); } void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) { - if (canvas_heuristic_parameters::kEnableAccelerationToAvoidReadbacks && - SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() && + if (SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() && source->IsAccelerated() && GetOrCreateCanvas2DLayerBridge() && !canvas2d_bridge_->IsAccelerated() && ShouldAccelerate(kIgnoreResourceLimitCriteria)) { @@ -1226,6 +1232,12 @@ scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas( SourceImageStatus* status, AccelerationHint hint, const FloatSize&) { + return GetSourceImageForCanvasInternal(status, hint); +} + +scoped_refptr<StaticBitmapImage> +HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status, + AccelerationHint hint) { if (!width() || !height()) { *status = kZeroSizeCanvasSourceImageStatus; return nullptr; @@ -1242,21 +1254,21 @@ scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas( } if (!context_) { - scoped_refptr<Image> result = GetTransparentImage(); + scoped_refptr<StaticBitmapImage> result = GetTransparentImage(); *status = result ? kNormalSourceImageStatus : kInvalidSourceImageStatus; return result; } if (HasImageBitmapContext()) { *status = kNormalSourceImageStatus; - scoped_refptr<Image> result = context_->GetImage(hint); + scoped_refptr<StaticBitmapImage> result = context_->GetImage(hint); if (!result) result = GetTransparentImage(); *status = result ? kNormalSourceImageStatus : kInvalidSourceImageStatus; return result; } - scoped_refptr<Image> image; + scoped_refptr<StaticBitmapImage> image; // TODO(ccameron): Canvas should produce sRGB images. // https://crbug.com/672299 if (Is3d()) { @@ -1285,7 +1297,9 @@ bool HTMLCanvasElement::WouldTaintOrigin() const { return !OriginClean(); } -FloatSize HTMLCanvasElement::ElementSize(const FloatSize&) const { +FloatSize HTMLCanvasElement::ElementSize( + const FloatSize&, + const RespectImageOrientationEnum) const { if (context_ && HasImageBitmapContext()) { scoped_refptr<Image> image = context_->GetImage(kPreferNoAcceleration); if (image) @@ -1305,11 +1319,13 @@ ScriptPromise HTMLCanvasElement::CreateImageBitmap( ScriptState* script_state, EventTarget& event_target, base::Optional<IntRect> crop_rect, - const ImageBitmapOptions* options) { + const ImageBitmapOptions* options, + ExceptionState& exception_state) { DCHECK(event_target.ToLocalDOMWindow()); return ImageBitmapSource::FulfillImageBitmap( - script_state, ImageBitmap::Create(this, crop_rect, options)); + script_state, MakeGarbageCollected<ImageBitmap>(this, crop_rect, options), + exception_state); } void HTMLCanvasElement::SetOffscreenCanvasResource( @@ -1425,12 +1441,10 @@ void HTMLCanvasElement::OnWebLayerUpdated() { } void HTMLCanvasElement::RegisterContentsLayer(cc::Layer* layer) { - GraphicsLayer::RegisterContentsLayer(layer); OnContentsCcLayerChanged(); } void HTMLCanvasElement::UnregisterContentsLayer(cc::Layer* layer) { - GraphicsLayer::UnregisterContentsLayer(layer); OnContentsCcLayerChanged(); } @@ -1493,20 +1507,30 @@ void HTMLCanvasElement::ReplaceExisting2dLayerBridge( if (canvas2d_bridge_) { image = canvas2d_bridge_->NewImageSnapshot(kPreferNoAcceleration); // image can be null if allocation failed in which case we should just - // abort the surface switch to reatain the old surface which is still + // abort the surface switch to retain the old surface which is still // functional. if (!image) return; } - new_layer_bridge->SetCanvasResourceHost(this); ReplaceResourceProvider(nullptr); canvas2d_bridge_ = std::move(new_layer_bridge); + canvas2d_bridge_->SetCanvasResourceHost(this); + + cc::PaintCanvas* canvas = canvas2d_bridge_->GetPaintCanvas(); + // Paint canvas automatically has the clip re-applied. Since image already + // contains clip, it needs to be drawn before the clip stack is re-applied. + // Remove clip from canvas and restore it after the image is drawn. + canvas->restoreToCount(1); + canvas->save(); + + // TODO(jochin): Consider using ResourceProvider()->RestoreBackBuffer() here + // to avoid all of this clip stack manipulation. if (image) canvas2d_bridge_->DrawFullImage(image->PaintImageForCurrentFrame()); - RestoreCanvasMatrixClipStack(canvas2d_bridge_->DrawingCanvas()); - canvas2d_bridge_->DidRestoreCanvasMatrixClipStack( - canvas2d_bridge_->DrawingCanvas()); + RestoreCanvasMatrixClipStack(canvas); + canvas2d_bridge_->DidRestoreCanvasMatrixClipStack(canvas); + UpdateMemoryUsage(); } @@ -1525,7 +1549,7 @@ bool HTMLCanvasElement::HasImageBitmapContext() const { return (type == CanvasRenderingContext::kContextImageBitmap); } -scoped_refptr<Image> HTMLCanvasElement::GetTransparentImage() { +scoped_refptr<StaticBitmapImage> HTMLCanvasElement::GetTransparentImage() { if (!transparent_image_ || transparent_image_.get()->Size() != Size()) transparent_image_ = CreateTransparentImage(Size()); return transparent_image_; @@ -1547,4 +1571,8 @@ void HTMLCanvasElement::OnContentsCcLayerChanged() { GetLayoutBoxModelObject()->Layer()->SetNeedsRepaint(); } +RespectImageOrientationEnum HTMLCanvasElement::RespectImageOrientation() const { + return LayoutObject::ShouldRespectImageOrientation(GetLayoutObject()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h index f1c64559b81..c929303ec30 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h @@ -36,9 +36,8 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_blob_callback.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h" -#include "third_party/blink/renderer/core/html/canvas/image_encode_options.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" #include "third_party/blink/renderer/core/page/page_visibility_observer.h" @@ -49,8 +48,8 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/graphics_types_3d.h" -#include "third_party/blink/renderer/platform/graphics/image.h" #include "third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h" +#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/surface_layer_bridge.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -97,7 +96,7 @@ typedef CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextO // this class and without overcomplicating context. class CORE_EXPORT HTMLCanvasElement final : public HTMLElement, - public ContextLifecycleObserver, + public ExecutionContextLifecycleObserver, public PageVisibilityObserver, public CanvasRenderingContextHost, public WebSurfaceLayerBridgeObserver, @@ -193,8 +192,8 @@ class CORE_EXPORT HTMLCanvasElement final bool PushFrame(scoped_refptr<CanvasResource> image, const SkIRect& damage_rect) override; - // ContextLifecycleObserver and PageVisibilityObserver implementation - void ContextDestroyed(ExecutionContext*) override; + // ExecutionContextLifecycleObserver and PageVisibilityObserver implementation + void ContextDestroyed() override; // PageVisibilityObserver implementation void PageVisibilityChanged() override; @@ -204,7 +203,8 @@ class CORE_EXPORT HTMLCanvasElement final AccelerationHint, const FloatSize&) override; bool WouldTaintOrigin() const override; - FloatSize ElementSize(const FloatSize&) const override; + FloatSize ElementSize(const FloatSize&, + const RespectImageOrientationEnum) const override; bool IsCanvasElement() const override { return true; } bool IsOpaque() const override; bool IsAccelerated() const override; @@ -234,7 +234,8 @@ class CORE_EXPORT HTMLCanvasElement final ScriptPromise CreateImageBitmap(ScriptState*, EventTarget&, base::Optional<IntRect> crop_rect, - const ImageBitmapOptions*) override; + const ImageBitmapOptions*, + ExceptionState&) override; // OffscreenCanvasPlaceholder implementation. void SetOffscreenCanvasResource(scoped_refptr<CanvasResource>, @@ -302,6 +303,11 @@ class CORE_EXPORT HTMLCanvasElement final // composited. cc::Layer* ContentsCcLayer() const; + // Return the image orientation setting from the layout object, if available. + // In the absence of a layout object, kRespectImageOrientation will be + // returned. + RespectImageOrientationEnum RespectImageOrientation() const; + protected: void DidMoveToNewDocument(Document& old_document) override; @@ -344,12 +350,16 @@ class CORE_EXPORT HTMLCanvasElement final bool HasImageBitmapContext() const; // Returns the transparent image resource for this canvas. - scoped_refptr<Image> GetTransparentImage(); + scoped_refptr<StaticBitmapImage> GetTransparentImage(); CanvasRenderingContext* GetCanvasRenderingContextInternal( const String&, const CanvasContextCreationAttributesCore&); + scoped_refptr<StaticBitmapImage> GetSourceImageForCanvasInternal( + SourceImageStatus*, + AccelerationHint); + void OnContentsCcLayerChanged(); HeapHashSet<WeakMember<CanvasDrawListener>> listeners_; @@ -391,7 +401,7 @@ class CORE_EXPORT HTMLCanvasElement final // GPU Memory Management mutable intptr_t externally_allocated_memory_; - scoped_refptr<Image> transparent_image_ = nullptr; + scoped_refptr<StaticBitmapImage> transparent_image_ = nullptr; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl index 27b54f80beb..d8f04c404a2 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl +++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl @@ -40,7 +40,7 @@ [HighEntropy, MeasureAs=CanvasToBlob, RaisesException] void toBlob(BlobCallback _callback, optional DOMString type = "image/png", optional any quality); - [HighEntropy, RuntimeEnabled=CanvasColorManagement, MeasureAs=CanvasConvertToBlob, RaisesException, CallWith=ScriptState] Promise<Blob> convertToBlob(optional ImageEncodeOptions options); + [HighEntropy, RuntimeEnabled=CanvasColorManagement, MeasureAs=CanvasConvertToBlob, RaisesException, CallWith=ScriptState] Promise<Blob> convertToBlob(optional ImageEncodeOptions options = {}); }; // https://html.spec.whatwg.org/C/#blobcallback diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc index 50256d97b59..eb28b745ed9 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc @@ -29,10 +29,10 @@ #include "third_party/blink/renderer/core/html/canvas/image_data.h" #include "base/sys_byteorder.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_uint8_clamped_array.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" -#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h" #include "third_party/blink/renderer/platform/graphics/color_behavior.h" #include "third_party/skia/include/third_party/skcms/skcms.h" #include "v8/include/v8.h" @@ -56,7 +56,7 @@ bool ImageData::ValidateConstructorArguments( const IntSize* size, const unsigned& width, const unsigned& height, - const DOMArrayBufferView* data, + const NotShared<DOMArrayBufferView> data, const ImageDataColorSettings* color_settings, ExceptionState* exception_state) { // We accept all the combinations of colorSpace and storageFormat in an @@ -163,23 +163,26 @@ bool ImageData::ValidateConstructorArguments( return true; } -DOMArrayBufferView* ImageData::AllocateAndValidateDataArray( +NotShared<DOMArrayBufferView> ImageData::AllocateAndValidateDataArray( const unsigned& length, ImageDataStorageFormat storage_format, ExceptionState* exception_state) { if (!length) - return nullptr; + return NotShared<DOMArrayBufferView>(); - DOMArrayBufferView* data_array = nullptr; + NotShared<DOMArrayBufferView> data_array; switch (storage_format) { case kUint8ClampedArrayStorageFormat: - data_array = DOMUint8ClampedArray::CreateOrNull(length); + data_array = NotShared<DOMArrayBufferView>( + DOMUint8ClampedArray::CreateOrNull(length)); break; case kUint16ArrayStorageFormat: - data_array = DOMUint16Array::CreateOrNull(length); + data_array = + NotShared<DOMArrayBufferView>(DOMUint16Array::CreateOrNull(length)); break; case kFloat32ArrayStorageFormat: - data_array = DOMFloat32Array::CreateOrNull(length); + data_array = + NotShared<DOMArrayBufferView>(DOMFloat32Array::CreateOrNull(length)); break; default: NOTREACHED(); @@ -191,62 +194,51 @@ DOMArrayBufferView* ImageData::AllocateAndValidateDataArray( expected_size != data_array->byteLengthAsSizeT())) { if (exception_state) exception_state->ThrowRangeError("Out of memory at ImageData creation"); - return nullptr; + return NotShared<DOMArrayBufferView>(); } return data_array; } -DOMUint8ClampedArray* ImageData::AllocateAndValidateUint8ClampedArray( +NotShared<DOMUint8ClampedArray> ImageData::AllocateAndValidateUint8ClampedArray( const unsigned& length, ExceptionState* exception_state) { - DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray( + NotShared<DOMUint8ClampedArray> buffer_view; + buffer_view = AllocateAndValidateDataArray( length, kUint8ClampedArrayStorageFormat, exception_state); - if (!buffer_view) - return nullptr; - DOMUint8ClampedArray* u8_array = const_cast<DOMUint8ClampedArray*>( - static_cast<const DOMUint8ClampedArray*>(buffer_view)); - DCHECK(u8_array); - return u8_array; + return buffer_view; } -DOMUint16Array* ImageData::AllocateAndValidateUint16Array( +NotShared<DOMUint16Array> ImageData::AllocateAndValidateUint16Array( const unsigned& length, ExceptionState* exception_state) { - DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray( - length, kUint16ArrayStorageFormat, exception_state); - if (!buffer_view) - return nullptr; - DOMUint16Array* u16_array = const_cast<DOMUint16Array*>( - static_cast<const DOMUint16Array*>(buffer_view)); - DCHECK(u16_array); - return u16_array; + NotShared<DOMUint16Array> buffer_view; + buffer_view = AllocateAndValidateDataArray(length, kUint16ArrayStorageFormat, + exception_state); + return buffer_view; } -DOMFloat32Array* ImageData::AllocateAndValidateFloat32Array( +NotShared<DOMFloat32Array> ImageData::AllocateAndValidateFloat32Array( const unsigned& length, ExceptionState* exception_state) { - DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray( - length, kFloat32ArrayStorageFormat, exception_state); - if (!buffer_view) - return nullptr; - DOMFloat32Array* f32_array = const_cast<DOMFloat32Array*>( - static_cast<const DOMFloat32Array*>(buffer_view)); - DCHECK(f32_array); - return f32_array; + NotShared<DOMFloat32Array> buffer_view; + buffer_view = AllocateAndValidateDataArray(length, kFloat32ArrayStorageFormat, + exception_state); + return buffer_view; } ImageData* ImageData::Create(const IntSize& size, const ImageDataColorSettings* color_settings) { - if (!ImageData::ValidateConstructorArguments(kParamSize, &size, 0, 0, nullptr, - color_settings)) + if (!ValidateConstructorArguments(kParamSize, &size, 0, 0, + NotShared<DOMArrayBufferView>(), + color_settings)) return nullptr; ImageDataStorageFormat storage_format = kUint8ClampedArrayStorageFormat; if (color_settings) { storage_format = ImageData::GetImageDataStorageFormat(color_settings->storageFormat()); } - DOMArrayBufferView* data_array = + NotShared<DOMArrayBufferView> data_array = AllocateAndValidateDataArray(4 * static_cast<unsigned>(size.Width()) * static_cast<unsigned>(size.Height()), storage_format); @@ -322,12 +314,10 @@ ImageData* ImageData::Create(const IntSize& size, ImageData* ImageData::Create(const IntSize& size, NotShared<DOMArrayBufferView> data_array, const ImageDataColorSettings* color_settings) { - if (!ImageData::ValidateConstructorArguments(kParamSize | kParamData, &size, - 0, 0, data_array.View(), - color_settings)) + if (!ImageData::ValidateConstructorArguments( + kParamSize | kParamData, &size, 0, 0, data_array, color_settings)) return nullptr; - return MakeGarbageCollected<ImageData>(size, data_array.View(), - color_settings); + return MakeGarbageCollected<ImageData>(size, data_array, color_settings); } static SkImageInfo GetImageInfo(scoped_refptr<StaticBitmapImage> image) { @@ -373,7 +363,7 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image, if (!area.IsValid()) return nullptr; // Create image data with f32 storage - DOMFloat32Array* f32_array = + NotShared<DOMFloat32Array> f32_array = ImageData::AllocateAndValidateFloat32Array(area.ValueOrDie(), nullptr); if (!f32_array) return nullptr; @@ -382,20 +372,20 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image, image_info.minRowBytes(), 0, 0); ImageDataColorSettings* color_settings = CanvasColorParamsToImageDataColorSettings(color_params); - return Create(image->Size(), NotShared<blink::DOMArrayBufferView>(f32_array), - color_settings); + return Create(image->Size(), f32_array, color_settings); } ImageData* ImageData::Create(unsigned width, unsigned height, ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments(kParamWidth | kParamHeight, - nullptr, width, height, nullptr, - nullptr, &exception_state)) + if (!ImageData::ValidateConstructorArguments( + kParamWidth | kParamHeight, nullptr, width, height, + NotShared<DOMArrayBufferView>(), nullptr, &exception_state)) return nullptr; - DOMArrayBufferView* byte_array = AllocateAndValidateDataArray( - 4 * width * height, kUint8ClampedArrayStorageFormat, &exception_state); + NotShared<DOMUint8ClampedArray> byte_array = + AllocateAndValidateUint8ClampedArray(4 * width * height, + &exception_state); return byte_array ? MakeGarbageCollected<ImageData>(IntSize(width, height), byte_array) : nullptr; @@ -405,13 +395,13 @@ ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data, unsigned width, ExceptionState& exception_state) { if (!ImageData::ValidateConstructorArguments(kParamData | kParamWidth, - nullptr, width, 0, data.View(), - nullptr, &exception_state)) + nullptr, width, 0, data, nullptr, + &exception_state)) return nullptr; unsigned height = - base::checked_cast<unsigned>(data.View()->lengthAsSizeT()) / (width * 4); - return MakeGarbageCollected<ImageData>(IntSize(width, height), data.View()); + base::checked_cast<unsigned>(data->lengthAsSizeT()) / (width * 4); + return MakeGarbageCollected<ImageData>(IntSize(width, height), data); } ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data, @@ -419,11 +409,11 @@ ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data, unsigned height, ExceptionState& exception_state) { if (!ImageData::ValidateConstructorArguments( - kParamData | kParamWidth | kParamHeight, nullptr, width, height, - data.View(), nullptr, &exception_state)) + kParamData | kParamWidth | kParamHeight, nullptr, width, height, data, + nullptr, &exception_state)) return nullptr; - return MakeGarbageCollected<ImageData>(IntSize(width, height), data.View()); + return MakeGarbageCollected<ImageData>(IntSize(width, height), data); } ImageData* ImageData::CreateImageData( @@ -432,13 +422,13 @@ ImageData* ImageData::CreateImageData( const ImageDataColorSettings* color_settings, ExceptionState& exception_state) { if (!ImageData::ValidateConstructorArguments( - kParamWidth | kParamHeight, nullptr, width, height, nullptr, - color_settings, &exception_state)) + kParamWidth | kParamHeight, nullptr, width, height, + NotShared<DOMArrayBufferView>(), color_settings, &exception_state)) return nullptr; ImageDataStorageFormat storage_format = ImageData::GetImageDataStorageFormat(color_settings->storageFormat()); - DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray( + NotShared<DOMArrayBufferView> buffer_view = AllocateAndValidateDataArray( 4 * width * height, storage_format, &exception_state); if (!buffer_view) @@ -453,7 +443,7 @@ ImageData* ImageData::CreateImageData(ImageDataArray& data, unsigned height, ImageDataColorSettings* color_settings, ExceptionState& exception_state) { - DOMArrayBufferView* buffer_view = nullptr; + NotShared<DOMArrayBufferView> buffer_view; // When pixels data is provided, we need to override the storage format of // ImageDataColorSettings with the one that matches the data type of the @@ -461,13 +451,13 @@ ImageData* ImageData::CreateImageData(ImageDataArray& data, String storage_format_name; if (data.IsUint8ClampedArray()) { - buffer_view = data.GetAsUint8ClampedArray().View(); + buffer_view = data.GetAsUint8ClampedArray(); storage_format_name = kUint8ClampedArrayStorageFormatName; } else if (data.IsUint16Array()) { - buffer_view = data.GetAsUint16Array().View(); + buffer_view = data.GetAsUint16Array(); storage_format_name = kUint16ArrayStorageFormatName; } else if (data.IsFloat32Array()) { - buffer_view = data.GetAsFloat32Array().View(); + buffer_view = data.GetAsFloat32Array(); storage_format_name = kFloat32ArrayStorageFormatName; } else { NOTREACHED(); @@ -495,8 +485,8 @@ ImageData* ImageData::CreateForTest(const IntSize& size) { data_size.ValueOrDie() > v8::TypedArray::kMaxLength) return nullptr; - DOMUint8ClampedArray* byte_array = - DOMUint8ClampedArray::CreateOrNull(data_size.ValueOrDie()); + NotShared<DOMUint8ClampedArray> byte_array( + DOMUint8ClampedArray::CreateOrNull(data_size.ValueOrDie())); if (!byte_array) return nullptr; @@ -507,7 +497,7 @@ ImageData* ImageData::CreateForTest(const IntSize& size) { // to be validated on the call site. ImageData* ImageData::CreateForTest( const IntSize& size, - DOMArrayBufferView* buffer_view, + NotShared<DOMArrayBufferView> buffer_view, const ImageDataColorSettings* color_settings) { return MakeGarbageCollected<ImageData>(size, buffer_view, color_settings); } @@ -527,7 +517,7 @@ ImageData* ImageData::CropRect(const IntRect& crop_rect, bool flip_y) { return nullptr; unsigned data_size = 4 * dst_rect.Width() * dst_rect.Height(); - DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray( + NotShared<DOMArrayBufferView> buffer_view = AllocateAndValidateDataArray( data_size, ImageData::GetImageDataStorageFormat(color_settings_->storageFormat())); if (!buffer_view) @@ -562,15 +552,16 @@ ImageData* ImageData::CropRect(const IntRect& crop_rect, bool flip_y) { ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state, EventTarget& event_target, base::Optional<IntRect> crop_rect, - const ImageBitmapOptions* options) { + const ImageBitmapOptions* options, + ExceptionState& exception_state) { if (BufferBase()->IsDetached()) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "The source data has been detached.")); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "The source data has been detached."); + return ScriptPromise(); } return ImageBitmapSource::FulfillImageBitmap( - script_state, ImageBitmap::Create(this, crop_rect, options)); + script_state, MakeGarbageCollected<ImageBitmap>(this, crop_rect, options), + exception_state); } v8::Local<v8::Object> ImageData::AssociateWithWrapper( @@ -685,19 +676,19 @@ unsigned ImageData::StorageFormatDataSize( return 1; } -DOMArrayBufferView* +NotShared<DOMArrayBufferView> ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( ArrayBufferContents& content, CanvasPixelFormat pixel_format, ImageDataStorageFormat storage_format) { if (!content.DataLength()) - return nullptr; + return NotShared<DOMArrayBufferView>(); - if (pixel_format == CanvasPixelFormat::kRGBA8 && + if (pixel_format == CanvasColorParams::GetNativeCanvasPixelFormat() && storage_format == kUint8ClampedArrayStorageFormat) { DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(content); - return DOMUint8ClampedArray::Create(array_buffer, 0, - array_buffer->ByteLengthAsSizeT()); + return NotShared<DOMArrayBufferView>(DOMUint8ClampedArray::Create( + array_buffer, 0, array_buffer->ByteLengthAsSizeT())); } skcms_PixelFormat src_format = skcms_PixelFormat_RGBA_8888; @@ -709,10 +700,10 @@ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul; if (storage_format == kUint8ClampedArrayStorageFormat) { - DOMUint8ClampedArray* u8_array = + NotShared<DOMUint8ClampedArray> u8_array = AllocateAndValidateUint8ClampedArray(num_pixels * 4); if (!u8_array) - return nullptr; + return NotShared<DOMArrayBufferView>(); bool data_transform_successful = skcms_Transform( content.Data(), src_format, alpha_format, nullptr, u8_array->Data(), skcms_PixelFormat_RGBA_8888, alpha_format, nullptr, num_pixels); @@ -721,9 +712,10 @@ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( } if (storage_format == kUint16ArrayStorageFormat) { - DOMUint16Array* u16_array = AllocateAndValidateUint16Array(num_pixels * 4); + NotShared<DOMUint16Array> u16_array = + AllocateAndValidateUint16Array(num_pixels * 4); if (!u16_array) - return nullptr; + return NotShared<DOMArrayBufferView>(); bool data_transform_successful = skcms_Transform( content.Data(), src_format, alpha_format, nullptr, u16_array->Data(), skcms_PixelFormat_RGBA_16161616LE, alpha_format, nullptr, num_pixels); @@ -731,9 +723,10 @@ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( return u16_array; } - DOMFloat32Array* f32_array = AllocateAndValidateFloat32Array(num_pixels * 4); + NotShared<DOMFloat32Array> f32_array = + AllocateAndValidateFloat32Array(num_pixels * 4); if (!f32_array) - return nullptr; + return NotShared<DOMArrayBufferView>(); bool data_transform_successful = skcms_Transform( content.Data(), src_format, alpha_format, nullptr, f32_array->Data(), skcms_PixelFormat_RGBA_ffff, alpha_format, nullptr, num_pixels); @@ -756,11 +749,12 @@ CanvasColorParams ImageData::GetCanvasColorParams() { return CanvasColorParams(); CanvasColorSpace color_space = ImageData::GetCanvasColorSpace(color_settings_->colorSpace()); - CanvasPixelFormat pixel_format = CanvasPixelFormat::kRGBA8; - if (color_settings_->storageFormat() != kUint8ClampedArrayStorageFormatName) - pixel_format = CanvasPixelFormat::kF16; - return CanvasColorParams(color_space, pixel_format, kNonOpaque, - CanvasForceRGBA::kNotForced); + return CanvasColorParams( + color_space, + color_settings_->storageFormat() != kUint8ClampedArrayStorageFormatName + ? CanvasPixelFormat::kF16 + : CanvasColorParams::GetNativeCanvasPixelFormat(), + kNonOpaque); } bool ImageData::ImageDataInCanvasColorSettings( @@ -774,8 +768,7 @@ bool ImageData::ImageDataInCanvasColorSettings( return false; CanvasColorParams canvas_color_params = - CanvasColorParams(canvas_color_space, canvas_pixel_format, kNonOpaque, - CanvasForceRGBA::kNotForced); + CanvasColorParams(canvas_color_space, canvas_pixel_format, kNonOpaque); unsigned char* src_data = static_cast<unsigned char*>(BufferBase()->Data()); @@ -788,13 +781,16 @@ bool ImageData::ImageDataInCanvasColorSettings( src_pixel_format = skcms_PixelFormat_RGBA_ffff; skcms_PixelFormat dst_pixel_format = skcms_PixelFormat_RGBA_8888; - if (canvas_pixel_format == CanvasPixelFormat::kRGBA8 && - u8_color_type == kN32ColorType && - kN32_SkColorType == kBGRA_8888_SkColorType) { - dst_pixel_format = skcms_PixelFormat_BGRA_8888; - } else if (canvas_pixel_format == CanvasPixelFormat::kF16) { + if (canvas_pixel_format == CanvasPixelFormat::kF16) { dst_pixel_format = skcms_PixelFormat_RGBA_hhhh; } +#if SK_PMCOLOR_BYTE_ORDER(B, G, R, A) + else if (canvas_pixel_format == + CanvasColorParams::GetNativeCanvasPixelFormat() && + u8_color_type == kN32ColorType) { + dst_pixel_format = skcms_PixelFormat_BGRA_8888; + } +#endif skcms_AlphaFormat src_alpha_format = skcms_AlphaFormat_Unpremul; skcms_AlphaFormat dst_alpha_format = skcms_AlphaFormat_Unpremul; @@ -863,16 +859,16 @@ void ImageData::Trace(Visitor* visitor) { } ImageData::ImageData(const IntSize& size, - DOMArrayBufferView* data, + NotShared<DOMArrayBufferView> data, const ImageDataColorSettings* color_settings) : size_(size), color_settings_(ImageDataColorSettings::Create()) { DCHECK_GE(size.Width(), 0); DCHECK_GE(size.Height(), 0); DCHECK(data); - data_ = nullptr; - data_u16_ = nullptr; - data_f32_ = nullptr; + data_.Clear(); + data_u16_.Clear(); + data_f32_.Clear(); if (color_settings) { color_settings_->setColorSpace(color_settings->colorSpace()); @@ -891,8 +887,7 @@ ImageData::ImageData(const IntSize& size, case kUint8ClampedArrayStorageFormat: DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint8Clamped); - data_ = const_cast<DOMUint8ClampedArray*>( - static_cast<const DOMUint8ClampedArray*>(data)); + data_ = data; DCHECK(data_); data_union_.SetUint8ClampedArray(data_); SECURITY_CHECK( @@ -902,8 +897,7 @@ ImageData::ImageData(const IntSize& size, case kUint16ArrayStorageFormat: DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint16); - data_u16_ = - const_cast<DOMUint16Array*>(static_cast<const DOMUint16Array*>(data)); + data_u16_ = data; DCHECK(data_u16_); data_union_.SetUint16Array(data_u16_); SECURITY_CHECK( @@ -913,8 +907,7 @@ ImageData::ImageData(const IntSize& size, case kFloat32ArrayStorageFormat: DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeFloat32); - data_f32_ = const_cast<DOMFloat32Array*>( - static_cast<const DOMFloat32Array*>(data)); + data_f32_ = data; DCHECK(data_f32_); data_union_.SetFloat32Array(data_f32_); SECURITY_CHECK( diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h index 6bcc61fef27..6690cd30bb7 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h @@ -31,9 +31,9 @@ #include "base/numerics/checked_math.h" #include "third_party/blink/renderer/bindings/core/v8/uint8_clamped_array_or_uint16_array_or_float32_array.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_image_data_color_settings.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" -#include "third_party/blink/renderer/core/html/canvas/image_data_color_settings.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" @@ -104,11 +104,11 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, static ImageData* CreateForTest(const IntSize&); static ImageData* CreateForTest(const IntSize&, - DOMArrayBufferView*, + NotShared<DOMArrayBufferView>, const ImageDataColorSettings* = nullptr); ImageData(const IntSize&, - DOMArrayBufferView*, + NotShared<DOMArrayBufferView>, const ImageDataColorSettings* = nullptr); ImageData* CropRect(const IntRect&, bool flip_y = false); @@ -119,7 +119,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, static ImageDataStorageFormat GetImageDataStorageFormat(const String&); static unsigned StorageFormatDataSize(const String&); static unsigned StorageFormatDataSize(ImageDataStorageFormat); - static DOMArrayBufferView* + static NotShared<DOMArrayBufferView> ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( ArrayBufferContents&, CanvasPixelFormat, @@ -156,7 +156,8 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, ScriptPromise CreateImageBitmap(ScriptState*, EventTarget&, base::Optional<IntRect> crop_rect, - const ImageBitmapOptions*) override; + const ImageBitmapOptions*, + ExceptionState&) override; void Trace(Visitor*) override; @@ -170,7 +171,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, const IntSize* = nullptr, const unsigned& = 0, const unsigned& = 0, - const DOMArrayBufferView* = nullptr, + const NotShared<DOMArrayBufferView> = NotShared<DOMArrayBufferView>(), const ImageDataColorSettings* = nullptr, ExceptionState* = nullptr); @@ -178,24 +179,24 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, IntSize size_; Member<ImageDataColorSettings> color_settings_; ImageDataArray data_union_; - Member<DOMUint8ClampedArray> data_; - Member<DOMUint16Array> data_u16_; - Member<DOMFloat32Array> data_f32_; + NotShared<DOMUint8ClampedArray> data_; + NotShared<DOMUint16Array> data_u16_; + NotShared<DOMFloat32Array> data_f32_; - static DOMArrayBufferView* AllocateAndValidateDataArray( + static NotShared<DOMArrayBufferView> AllocateAndValidateDataArray( const unsigned&, ImageDataStorageFormat, ExceptionState* = nullptr); - static DOMUint8ClampedArray* AllocateAndValidateUint8ClampedArray( + static NotShared<DOMUint8ClampedArray> AllocateAndValidateUint8ClampedArray( const unsigned&, ExceptionState* = nullptr); - static DOMUint16Array* AllocateAndValidateUint16Array( + static NotShared<DOMUint16Array> AllocateAndValidateUint16Array( const unsigned&, ExceptionState* = nullptr); - static DOMFloat32Array* AllocateAndValidateFloat32Array( + static NotShared<DOMFloat32Array> AllocateAndValidateFloat32Array( const unsigned&, ExceptionState* = nullptr); }; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl b/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl index 45eace16cc1..11907ae1ff1 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl @@ -32,12 +32,11 @@ typedef (Uint8ClampedArray or Uint16Array or Float32Array) ImageDataArray; [ - Constructor(unsigned long sw, unsigned long sh), - Constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh), Exposed=(Window,Worker), - RaisesException=Constructor, Serializable ] interface ImageData { + [RaisesException] constructor(unsigned long sw, unsigned long sh); + [RaisesException] constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh); [RuntimeEnabled=CanvasColorManagement] ImageDataColorSettings getColorSettings(); readonly attribute unsigned long width; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc index 22d583835bd..15db4684f74 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc @@ -75,16 +75,16 @@ TEST_F(ImageDataTest, // Testing CanvasPixelFormat::kRGBA8-> // kUint8ClampedArrayStorageFormat - DOMArrayBufferView* data = + NotShared<DOMArrayBufferView> data( ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( contents_rgba32, CanvasPixelFormat::kRGBA8, - kUint8ClampedArrayStorageFormat); + kUint8ClampedArrayStorageFormat)); DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint8Clamped); ColorCorrectionTestUtils::CompareColorCorrectedPixels( data->BaseAddress(), rgba32_pixels, kNumPixels, kPixelFormat_8888, kAlphaUnmultiplied, kNoUnpremulRoundTripTolerance); - // Testing CanvasPixelFormat::kRGBA8prN32-> + // Testing CanvasPixelFormat::kRGBA8-> // kUint16ArrayStorageFormat data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( contents_rgba32_2, CanvasPixelFormat::kRGBA8, kUint16ArrayStorageFormat); @@ -92,8 +92,7 @@ TEST_F(ImageDataTest, ColorCorrectionTestUtils::CompareColorCorrectedPixels( data->BaseAddress(), u16_pixels, kNumPixels, kPixelFormat_16161616, kAlphaUnmultiplied, kUnpremulRoundTripTolerance); - - // Testing CanvasPixelFormat::kRGBA8prN32 -> + // Testing CanvasPixelFormat::kRGBA8 -> // kFloat32ArrayStorageFormat data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( contents_rgba32_2, CanvasPixelFormat::kRGBA8, kFloat32ArrayStorageFormat); @@ -172,28 +171,28 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) { 0, 0, 0, 0, // Transparent 255, 192, 128, 64, // Decreasing values 93, 117, 205, 11}; // Random values - unsigned data_length = 16; + size_t data_length = 16; uint16_t* u16_pixels = new uint16_t[data_length]; - for (unsigned i = 0; i < data_length; i++) + for (size_t i = 0; i < data_length; i++) u16_pixels[i] = u8_pixels[i] * 257; float* f32_pixels = new float[data_length]; - for (unsigned i = 0; i < data_length; i++) + for (size_t i = 0; i < data_length; i++) f32_pixels[i] = u8_pixels[i] / 255.0; - DOMArrayBufferView* data_array = nullptr; - - DOMUint8ClampedArray* data_u8 = - DOMUint8ClampedArray::Create(u8_pixels, data_length); + NotShared<DOMUint8ClampedArray> data_u8( + DOMUint8ClampedArray::Create(u8_pixels, data_length)); DCHECK(data_u8); - EXPECT_EQ(data_length, data_u8->deprecatedLengthAsUnsigned()); - DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length); + EXPECT_EQ(data_length, data_u8->lengthAsSizeT()); + NotShared<DOMUint16Array> data_u16( + DOMUint16Array::Create(u16_pixels, data_length)); DCHECK(data_u16); - EXPECT_EQ(data_length, data_u16->deprecatedLengthAsUnsigned()); - DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length); + EXPECT_EQ(data_length, data_u16->lengthAsSizeT()); + NotShared<DOMFloat32Array> data_f32( + DOMFloat32Array::Create(f32_pixels, data_length)); DCHECK(data_f32); - EXPECT_EQ(data_length, data_f32->deprecatedLengthAsUnsigned()); + EXPECT_EQ(data_length, data_f32->lengthAsSizeT()); ImageData* image_data = nullptr; ImageDataColorSettings* color_settings = ImageDataColorSettings::Create(); @@ -211,17 +210,18 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) { ImageData::CanvasColorSpaceName(image_data_color_spaces[i])); for (unsigned j = 0; j < num_image_data_storage_formats; j++) { + NotShared<DOMArrayBufferView> data_array; switch (image_data_storage_formats[j]) { case kUint8ClampedArrayStorageFormat: - data_array = static_cast<DOMArrayBufferView*>(data_u8); + data_array = data_u8; color_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName); break; case kUint16ArrayStorageFormat: - data_array = static_cast<DOMArrayBufferView*>(data_u16); + data_array = data_u16; color_settings->setStorageFormat(kUint16ArrayStorageFormatName); break; case kFloat32ArrayStorageFormat: - data_array = static_cast<DOMArrayBufferView*>(data_f32); + data_array = data_f32; color_settings->setStorageFormat(kFloat32ArrayStorageFormatName); break; default: @@ -395,7 +395,7 @@ TEST_F(ImageDataTest, TestCropRect) { // Source pixels unsigned width = 20; unsigned height = 20; - unsigned data_length = width * height * 4; + size_t data_length = width * height * 4; uint8_t* u8_pixels = new uint8_t[data_length]; uint16_t* u16_pixels = new uint16_t[data_length]; float* f32_pixels = new float[data_length]; @@ -427,30 +427,32 @@ TEST_F(ImageDataTest, TestCropRect) { } // Create ImageData objects - DOMArrayBufferView* data_array = nullptr; - DOMUint8ClampedArray* data_u8 = - DOMUint8ClampedArray::Create(u8_pixels, data_length); + NotShared<DOMUint8ClampedArray> data_u8( + DOMUint8ClampedArray::Create(u8_pixels, data_length)); DCHECK(data_u8); - EXPECT_EQ(data_length, data_u8->deprecatedLengthAsUnsigned()); - DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length); + EXPECT_EQ(data_length, data_u8->lengthAsSizeT()); + NotShared<DOMUint16Array> data_u16( + DOMUint16Array::Create(u16_pixels, data_length)); DCHECK(data_u16); - EXPECT_EQ(data_length, data_u16->deprecatedLengthAsUnsigned()); - DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length); + EXPECT_EQ(data_length, data_u16->lengthAsSizeT()); + NotShared<DOMFloat32Array> data_f32( + DOMFloat32Array::Create(f32_pixels, data_length)); DCHECK(data_f32); - EXPECT_EQ(data_length, data_f32->deprecatedLengthAsUnsigned()); + EXPECT_EQ(data_length, data_f32->lengthAsSizeT()); ImageData* image_data = nullptr; ImageData* cropped_image_data = nullptr; bool test_passed = true; for (int i = 0; i < num_image_data_storage_formats; i++) { + NotShared<DOMArrayBufferView> data_array; if (image_data_storage_formats[i] == kUint8ClampedArrayStorageFormat) - data_array = static_cast<DOMArrayBufferView*>(data_u8); + data_array = data_u8; else if (image_data_storage_formats[i] == kUint16ArrayStorageFormat) - data_array = static_cast<DOMArrayBufferView*>(data_u16); + data_array = data_u16; else - data_array = static_cast<DOMArrayBufferView*>(data_f32); + data_array = data_f32; ImageDataColorSettings* color_settings = ImageDataColorSettings::Create(); color_settings->setStorageFormat(image_data_storage_format_names[i]); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc index 15abb2f3633..86980200a42 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc @@ -38,11 +38,11 @@ const Element& ImageElementBase::GetElement() const { } bool ImageElementBase::IsSVGSource() const { - return CachedImage() && CachedImage()->GetImage()->IsSVGImage(); + return CachedImage() && IsA<SVGImage>(CachedImage()->GetImage()); } bool ImageElementBase::IsImageElement() const { - return CachedImage() && !CachedImage()->GetImage()->IsSVGImage(); + return CachedImage() && !IsA<SVGImage>(CachedImage()->GetImage()); } scoped_refptr<Image> ImageElementBase::GetSourceImageForCanvas( @@ -61,9 +61,8 @@ scoped_refptr<Image> ImageElementBase::GetSourceImageForCanvas( } scoped_refptr<Image> source_image = image_content->GetImage(); - if (source_image->IsSVGImage()) { + if (auto* svg_image = DynamicTo<SVGImage>(source_image.get())) { UseCounter::Count(GetElement().GetDocument(), WebFeature::kSVGInCanvas2D); - SVGImage* svg_image = ToSVGImage(source_image.get()); FloatSize image_size = svg_image->ConcreteObjectSize(default_object_size); source_image = SVGImageForContainer::Create( svg_image, image_size, 1, @@ -79,33 +78,21 @@ bool ImageElementBase::WouldTaintOrigin() const { } FloatSize ImageElementBase::ElementSize( - const FloatSize& default_object_size) const { + const FloatSize& default_object_size, + const RespectImageOrientationEnum respect_orientation) const { ImageResourceContent* image_content = CachedImage(); - if (!image_content) + if (!image_content || !image_content->HasImage()) return FloatSize(); - Image* image = image_content->GetImage(); - if (image->IsSVGImage()) - return ToSVGImage(image)->ConcreteObjectSize(default_object_size); - - return FloatSize( - image_content->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation( - GetElement().GetLayoutObject()))); + if (auto* svg_image = DynamicTo<SVGImage>(image)) + return svg_image->ConcreteObjectSize(default_object_size); + return FloatSize(image->Size(respect_orientation)); } FloatSize ImageElementBase::DefaultDestinationSize( - const FloatSize& default_object_size) const { - ImageResourceContent* image_content = CachedImage(); - if (!image_content) - return FloatSize(); - - Image* image = image_content->GetImage(); - if (image->IsSVGImage()) - return ToSVGImage(image)->ConcreteObjectSize(default_object_size); - - return FloatSize( - image_content->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation( - GetElement().GetLayoutObject()))); + const FloatSize& default_object_size, + const RespectImageOrientationEnum respect_orientation) const { + return ElementSize(default_object_size, respect_orientation); } bool ImageElementBase::IsAccelerated() const { @@ -128,46 +115,49 @@ IntSize ImageElementBase::BitmapSourceSize() const { ImageResourceContent* image = CachedImage(); if (!image) return IntSize(); - return image->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation( - GetElement().GetLayoutObject())); + // This method is called by ImageBitmap when creating and cropping the image. + // Return un-oriented size because the cropping must happen before + // orienting. + return image->IntrinsicSize(kDoNotRespectImageOrientation); } ScriptPromise ImageElementBase::CreateImageBitmap( ScriptState* script_state, EventTarget& event_target, base::Optional<IntRect> crop_rect, - const ImageBitmapOptions* options) { + const ImageBitmapOptions* options, + ExceptionState& exception_state) { DCHECK(event_target.ToLocalDOMWindow()); ImageResourceContent* image_content = CachedImage(); if (!image_content) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "No image can be retrieved from the provided element.")); + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "No image can be retrieved from the provided element."); + return ScriptPromise(); } Image* image = image_content->GetImage(); - if (image->IsSVGImage()) { - if (!ToSVGImage(image)->HasIntrinsicDimensions() && + if (auto* svg_image = DynamicTo<SVGImage>(image)) { + if (!svg_image->HasIntrinsicDimensions() && (!crop_rect && (!options->hasResizeWidth() || !options->hasResizeHeight()))) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "The image element contains an SVG image without intrinsic " - "dimensions, and no resize options or crop region are " - "specified.")); + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "The image element contains an SVG image without intrinsic " + "dimensions, and no resize options or crop region are " + "specified."); + return ScriptPromise(); } return ImageBitmap::CreateAsync(this, crop_rect, event_target.ToLocalDOMWindow()->document(), script_state, options); } return ImageBitmapSource::FulfillImageBitmap( - script_state, ImageBitmap::Create( - this, crop_rect, - event_target.ToLocalDOMWindow()->document(), options)); + script_state, + MakeGarbageCollected<ImageBitmap>( + this, crop_rect, event_target.ToLocalDOMWindow()->document(), + options), + exception_state); } Image::ImageDecodingMode ImageElementBase::GetDecodingModeForPainting( @@ -188,4 +178,9 @@ Image::ImageDecodingMode ImageElementBase::GetDecodingModeForPainting( return decoding_mode_; } +RespectImageOrientationEnum ImageElementBase::RespectImageOrientation() const { + return LayoutObject::ShouldRespectImageOrientation( + GetElement().GetLayoutObject()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h index 0b8979db73d..25c5d8f8468 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h @@ -30,7 +30,8 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource, ScriptPromise CreateImageBitmap(ScriptState*, EventTarget&, base::Optional<IntRect>, - const ImageBitmapOptions*) override; + const ImageBitmapOptions*, + ExceptionState&) override; scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, AccelerationHint, @@ -38,9 +39,11 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource, bool WouldTaintOrigin() const override; - FloatSize ElementSize(const FloatSize& default_object_size) const override; + FloatSize ElementSize(const FloatSize& default_object_size, + const RespectImageOrientationEnum) const override; FloatSize DefaultDestinationSize( - const FloatSize& default_object_size) const override; + const FloatSize& default_object_size, + const RespectImageOrientationEnum) const override; bool IsAccelerated() const override; @@ -59,6 +62,11 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource, // Used with HTMLImageElement and SVGImageElement types. Image::ImageDecodingMode GetDecodingModeForPainting(PaintImage::Id); + // Return the image orientation setting from the layout object, if available. + // In the absence of a layout object, kRespectImageOrientation will be + // returned. + RespectImageOrientationEnum RespectImageOrientation() const; + protected: Image::ImageDecodingMode decoding_mode_ = Image::ImageDecodingMode::kUnspecifiedDecode; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc index 8ec200154ae..bdbc4c5a9f9 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/html/canvas/text_metrics.h" -#include "third_party/blink/renderer/core/html/canvas/baselines.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_baselines.h" #include "third_party/blink/renderer/platform/fonts/character_range.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h index e73c0e0d299..2a3529a53e7 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h @@ -26,8 +26,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_TEXT_METRICS_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_TEXT_METRICS_H_ +#include "third_party/blink/renderer/bindings/core/v8/v8_baselines.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/html/canvas/baselines.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/fonts/font.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" |