diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/canvas')
39 files changed, 459 insertions, 395 deletions
diff --git a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn index 7fcd19b31ae..3a4fad46751 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn @@ -42,9 +42,7 @@ blink_modules_sources("canvas") { } fuzzer_test("canvas_fuzzer") { - sources = [ - "canvas_fuzzer.cc", - ] + sources = [ "canvas_fuzzer.cc" ] seed_corpuses = [ "//third_party/blink/web_tests/fast/canvas" ] deps = [ "../../platform:blink_fuzzer_test_support", diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index 78833214386..5afdc0bb021 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc @@ -21,8 +21,10 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h" #include "third_party/blink/renderer/platform/geometry/float_quad.h" +#include "third_party/blink/renderer/platform/graphics/bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/graphics/stroke_data.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -48,6 +50,11 @@ void BaseRenderingContext2D::RealizeSaves() { ValidateStateStack(); if (GetState().HasUnrealizedSaves()) { DCHECK_GE(state_stack_.size(), 1u); + // GetOrCreatePaintCanvas() can call RestoreMatrixClipStack which syncs + // canvas to state_stack_. Get the canvas before adjusting state_stack_ to + // ensure canvas is synced prior to adjusting state_stack_. + cc::PaintCanvas* canvas = GetOrCreatePaintCanvas(); + // Reduce the current state's unrealized count by one now, // to reflect the fact we are saving one state. state_stack_.back()->Restore(); @@ -60,7 +67,6 @@ void BaseRenderingContext2D::RealizeSaves() { // state (in turn necessary to support correct resizing and unwinding of the // stack). state_stack_.back()->ResetUnrealizedSaveCount(); - cc::PaintCanvas* canvas = DrawingCanvas(); if (canvas) canvas->save(); ValidateStateStack(); @@ -68,11 +74,15 @@ void BaseRenderingContext2D::RealizeSaves() { } void BaseRenderingContext2D::save() { + if (isContextLost()) + return; state_stack_.back()->Save(); ValidateStateStack(); } void BaseRenderingContext2D::restore() { + if (isContextLost()) + return; ValidateStateStack(); if (GetState().HasUnrealizedSaves()) { // We never realized the save, so just record that it was unnecessary. @@ -92,7 +102,7 @@ void BaseRenderingContext2D::restore() { if (GetState().IsTransformInvertible()) path_.Transform(GetState().Transform().Inverse()); - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (c) c->restore(); @@ -115,12 +125,12 @@ void BaseRenderingContext2D::RestoreMatrixClipStack(cc::PaintCanvas* c) const { c->save(); } c->restore(); - ValidateStateStack(); + ValidateStateStackWithCanvas(c); } void BaseRenderingContext2D::UnwindStateStack() { if (size_t stack_size = state_stack_.size()) { - if (cc::PaintCanvas* sk_canvas = ExistingDrawingCanvas()) { + if (cc::PaintCanvas* sk_canvas = GetPaintCanvas()) { while (--stack_size) sk_canvas->restore(); } @@ -133,7 +143,7 @@ void BaseRenderingContext2D::Reset() { state_stack_.resize(1); state_stack_.front() = MakeGarbageCollected<CanvasRenderingContext2DState>(); path_.Clear(); - if (cc::PaintCanvas* c = ExistingDrawingCanvas()) { + if (cc::PaintCanvas* c = GetPaintCanvas()) { // The canvas should always have an initial/unbalanced save frame, which // we use to reset the top level matrix and clip here. DCHECK_EQ(c->getSaveCount(), 2); @@ -186,16 +196,17 @@ void BaseRenderingContext2D::setStrokeStyle( ModifiableState().SetUnparsedStrokeColor(color_string); return; } - canvas_style = CanvasStyle::CreateFromRGBA(parsed_color.Rgb()); + canvas_style = MakeGarbageCollected<CanvasStyle>(parsed_color.Rgb()); } else if (style.IsCanvasGradient()) { - canvas_style = CanvasStyle::CreateFromGradient(style.GetAsCanvasGradient()); + canvas_style = + MakeGarbageCollected<CanvasStyle>(style.GetAsCanvasGradient()); } else if (style.IsCanvasPattern()) { CanvasPattern* canvas_pattern = style.GetAsCanvasPattern(); if (!origin_tainted_by_content_ && !canvas_pattern->OriginClean()) SetOriginTaintedByContent(); - canvas_style = CanvasStyle::CreateFromPattern(canvas_pattern); + canvas_style = MakeGarbageCollected<CanvasStyle>(canvas_pattern); } DCHECK(canvas_style); @@ -227,16 +238,17 @@ void BaseRenderingContext2D::setFillStyle( ModifiableState().SetUnparsedFillColor(color_string); return; } - canvas_style = CanvasStyle::CreateFromRGBA(parsed_color.Rgb()); + canvas_style = MakeGarbageCollected<CanvasStyle>(parsed_color.Rgb()); } else if (style.IsCanvasGradient()) { - canvas_style = CanvasStyle::CreateFromGradient(style.GetAsCanvasGradient()); + canvas_style = + MakeGarbageCollected<CanvasStyle>(style.GetAsCanvasGradient()); } else if (style.IsCanvasPattern()) { CanvasPattern* canvas_pattern = style.GetAsCanvasPattern(); if (!origin_tainted_by_content_ && !canvas_pattern->OriginClean()) { SetOriginTaintedByContent(); } - canvas_style = CanvasStyle::CreateFromPattern(canvas_pattern); + canvas_style = MakeGarbageCollected<CanvasStyle>(canvas_pattern); } DCHECK(canvas_style); @@ -423,7 +435,7 @@ void BaseRenderingContext2D::setFilter( } void BaseRenderingContext2D::scale(double sx, double sy) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; @@ -446,7 +458,7 @@ void BaseRenderingContext2D::scale(double sx, double sy) { } void BaseRenderingContext2D::rotate(double angle_in_radians) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; @@ -466,7 +478,7 @@ void BaseRenderingContext2D::rotate(double angle_in_radians) { } void BaseRenderingContext2D::translate(double tx, double ty) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; if (!GetState().IsTransformInvertible()) @@ -496,7 +508,7 @@ void BaseRenderingContext2D::transform(double m11, double m22, double dx, double dy) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; @@ -526,7 +538,7 @@ void BaseRenderingContext2D::transform(double m11, } void BaseRenderingContext2D::resetTransform() { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; @@ -623,7 +635,7 @@ void BaseRenderingContext2D::DrawPathInternal( if (paint_type == CanvasRenderingContext2DState::kStrokePaintType) InflateStrokeRect(bounds); - if (!DrawingCanvas()) + if (!GetOrCreatePaintCanvas()) return; Draw([&sk_path](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda @@ -671,7 +683,7 @@ void BaseRenderingContext2D::fillRect(double x, if (!ValidateRectForCanvas(x, y, width, height)) return; - if (!DrawingCanvas()) + if (!GetOrCreatePaintCanvas()) return; // clamp to float to avoid float cast overflow when used as SkScalar @@ -721,7 +733,7 @@ void BaseRenderingContext2D::strokeRect(double x, if (!ValidateRectForCanvas(x, y, width, height)) return; - if (!DrawingCanvas()) + if (!GetOrCreatePaintCanvas()) return; // clamp to float to avoid float cast overflow when used as SkScalar @@ -748,7 +760,7 @@ void BaseRenderingContext2D::strokeRect(double x, void BaseRenderingContext2D::ClipInternal(const Path& path, const String& winding_rule_string) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) { return; } @@ -790,7 +802,7 @@ bool BaseRenderingContext2D::IsPointInPathInternal( const double x, const double y, const String& winding_rule_string) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return false; if (!GetState().IsTransformInvertible()) @@ -819,7 +831,7 @@ bool BaseRenderingContext2D::isPointInStroke(Path2D* dom_path, bool BaseRenderingContext2D::IsPointInStrokeInternal(const Path& path, const double x, const double y) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return false; if (!GetState().IsTransformInvertible()) @@ -847,12 +859,10 @@ void BaseRenderingContext2D::clearRect(double x, double y, double width, double height) { - usage_counters_.num_clear_rect_calls++; - if (!ValidateRectForCanvas(x, y, width, height)) return; - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; if (!GetState().IsTransformInvertible()) @@ -877,8 +887,8 @@ void BaseRenderingContext2D::clearRect(double x, if (RectContainsTransformedRect(rect, clip_bounds)) { CheckOverdraw(rect, &clear_flags, CanvasRenderingContext2DState::kNoImage, kClipFill); - if (DrawingCanvas()) - DrawingCanvas()->drawRect(rect, clear_flags); + c = GetPaintCanvas(); // Check overdraw may have swapped the PaintCanvas + c->drawRect(rect, clear_flags); DidDraw(clip_bounds); } else { SkIRect dirty_rect; @@ -987,11 +997,12 @@ void BaseRenderingContext2D::drawImage( ToImageSourceInternal(image_source, exception_state); if (!image_source_internal) return; + RespectImageOrientationEnum respect_orientation = RespectImageOrientation(); FloatSize default_object_size(Width(), Height()); - FloatSize source_rect_size = - image_source_internal->ElementSize(default_object_size); - FloatSize dest_rect_size = - image_source_internal->DefaultDestinationSize(default_object_size); + FloatSize source_rect_size = image_source_internal->ElementSize( + default_object_size, respect_orientation); + FloatSize dest_rect_size = image_source_internal->DefaultDestinationSize( + default_object_size, respect_orientation); drawImage(script_state, image_source_internal, 0, 0, source_rect_size.Width(), source_rect_size.Height(), x, y, dest_rect_size.Width(), dest_rect_size.Height(), exception_state); @@ -1010,8 +1021,8 @@ void BaseRenderingContext2D::drawImage( if (!image_source_internal) return; FloatSize default_object_size(this->Width(), this->Height()); - FloatSize source_rect_size = - image_source_internal->ElementSize(default_object_size); + FloatSize source_rect_size = image_source_internal->ElementSize( + default_object_size, RespectImageOrientation()); drawImage(script_state, image_source_internal, 0, 0, source_rect_size.Width(), source_rect_size.Height(), x, y, width, height, exception_state); } @@ -1040,7 +1051,7 @@ bool BaseRenderingContext2D::ShouldDrawImageAntialiased( const FloatRect& dest_rect) const { if (!GetState().ShouldAntialias()) return false; - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetPaintCanvas(); DCHECK(c); const SkMatrix& ctm = c->getTotalMatrix(); @@ -1086,10 +1097,19 @@ void BaseRenderingContext2D::DrawImageInternal(cc::PaintCanvas* c, // crbug.com/504687 return; } - c->save(); - c->concat(inv_ctm); SkRect bounds = dst_rect; ctm.mapRect(&bounds); + if (!bounds.isFinite()) { + // There is an earlier check for the correctness of the bounds, but it is + // possible that after applying the matrix transformation we get a faulty + // set of bounds, so we want to catch this asap and avoid sending a draw + // command. crbug.com/1039125 + // We want to do this before the save command is sent. + return; + } + c->save(); + c->concat(inv_ctm); + PaintFlags layer_flags; layer_flags.setBlendMode(flags->getBlendMode()); layer_flags.setImageFilter(flags->getImageFilter()); @@ -1101,10 +1121,20 @@ void BaseRenderingContext2D::DrawImageInternal(cc::PaintCanvas* c, } if (!image_source->IsVideoElement()) { + // We always use the image-orientation property on the canvas element + // because the alternative would result in complex rules depending on + // the source of the image. + RespectImageOrientationEnum respect_orientation = RespectImageOrientation(); + FloatRect corrected_src_rect = src_rect; + if (respect_orientation == kRespectImageOrientation && + !image->HasDefaultOrientation()) { + corrected_src_rect = image->CorrectSrcRectForImageOrientation( + image->SizeAsFloat(kRespectImageOrientation), src_rect); + } image_flags.setAntiAlias(ShouldDrawImageAntialiased(dst_rect)); - image->Draw(c, image_flags, dst_rect, src_rect, - kDoNotRespectImageOrientation, - Image::kDoNotClampImageToSourceRect, Image::kSyncDecode); + image->Draw(c, image_flags, dst_rect, corrected_src_rect, + respect_orientation, Image::kDoNotClampImageToSourceRect, + Image::kSyncDecode); } else { c->save(); c->clipRect(dst_rect); @@ -1140,7 +1170,7 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state, double dw, double dh, ExceptionState& exception_state) { - if (!DrawingCanvas()) + if (!GetOrCreatePaintCanvas()) return; base::TimeTicks start_time = base::TimeTicks::Now(); @@ -1182,13 +1212,12 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state, FloatRect src_rect = NormalizeRect(FloatRect(fsx, fsy, fsw, fsh)); FloatRect dst_rect = NormalizeRect(FloatRect(fdx, fdy, fdw, fdh)); - FloatSize image_size = image_source->ElementSize(default_object_size); + FloatSize image_size = + image_source->ElementSize(default_object_size, RespectImageOrientation()); ClipRectsToImageRect(FloatRect(FloatPoint(), image_size), &src_rect, &dst_rect); - image_source->AdjustDrawRects(&src_rect, &dst_rect); - if (src_rect.IsEmpty()) return; @@ -1276,7 +1305,7 @@ void BaseRenderingContext2D::ClearCanvas() { FloatRect canvas_rect(0, 0, Width(), Height()); CheckOverdraw(canvas_rect, nullptr, CanvasRenderingContext2DState::kNoImage, kClipFill); - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (c) c->clear(HasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK); } @@ -1386,7 +1415,10 @@ CanvasPattern* BaseRenderingContext2D::createPattern( exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, String::Format("The canvas %s is 0.", - image_source->ElementSize(default_object_size).Width() + image_source + ->ElementSize(default_object_size, + RespectImageOrientation()) + .Width() ? "height" : "width")); return nullptr; @@ -1396,7 +1428,7 @@ CanvasPattern* BaseRenderingContext2D::createPattern( "Source image is in the 'broken' state."); return nullptr; case kInvalidSourceImageStatus: - image_for_rendering = Image::NullImage(); + image_for_rendering = BitmapImage::Create(); break; case kIncompleteSourceImageStatus: return nullptr; @@ -1415,7 +1447,8 @@ CanvasPattern* BaseRenderingContext2D::createPattern( bool BaseRenderingContext2D::ComputeDirtyRect(const FloatRect& local_rect, SkIRect* dirty_rect) { SkIRect clip_bounds; - if (!DrawingCanvas()->getDeviceClipBounds(&clip_bounds)) + if (!GetOrCreatePaintCanvas() || + !GetPaintCanvas()->getDeviceClipBounds(&clip_bounds)) return false; return ComputeDirtyRect(local_rect, clip_bounds, dirty_rect); } @@ -1529,8 +1562,6 @@ ImageData* BaseRenderingContext2D::getImageData( base::TimeTicks start_time = base::TimeTicks::Now(); - usage_counters_.num_get_image_data_calls++; - usage_counters_.area_get_image_data_calls += sw * sh; if (!OriginClean()) { exception_state.ThrowSecurityError( "The canvas has been tainted by cross-origin data."); @@ -1620,22 +1651,26 @@ ImageData* BaseRenderingContext2D::getImageData( } // Convert pixels to proper storage format if needed - if (PixelFormat() != CanvasPixelFormat::kRGBA8) { + if (PixelFormat() != CanvasColorParams::GetNativeCanvasPixelFormat()) { ImageDataStorageFormat storage_format = ImageData::GetImageDataStorageFormat(color_settings->storageFormat()); - DOMArrayBufferView* array_buffer_view = + NotShared<DOMArrayBufferView> array_buffer_view = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( contents, PixelFormat(), storage_format); - return ImageData::Create(image_data_rect.Size(), - NotShared<DOMArrayBufferView>(array_buffer_view), + return ImageData::Create(image_data_rect.Size(), array_buffer_view, color_settings); } - DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents); + if (size_in_bytes > std::numeric_limits<unsigned int>::max()) { + exception_state.ThrowRangeError( + "Buffer size exceeds maximum heap object size."); + return nullptr; + } + DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(std::move(contents)); ImageData* imageData = ImageData::Create( image_data_rect.Size(), NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create( - array_buffer, 0, array_buffer->DeprecatedByteLengthAsUnsigned())), + array_buffer, 0, static_cast<unsigned int>(size_in_bytes))), color_settings); if (!IsPaint2D()) { @@ -1687,8 +1722,6 @@ void BaseRenderingContext2D::putImageData(ImageData* data, return; } base::TimeTicks start_time = base::TimeTicks::Now(); - usage_counters_.num_put_image_data_calls++; - usage_counters_.area_put_image_data_calls += dirty_width * dirty_height; if (data->BufferBase()->IsDetached()) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, @@ -1741,8 +1774,7 @@ void BaseRenderingContext2D::putImageData(ImageData* data, // additional swizzling is needed. CanvasColorParams data_color_params = data->GetCanvasColorParams(); CanvasColorParams context_color_params = - CanvasColorParams(ColorParams().ColorSpace(), PixelFormat(), kNonOpaque, - CanvasForceRGBA::kNotForced); + CanvasColorParams(ColorParams().ColorSpace(), PixelFormat(), kNonOpaque); if (data_color_params.NeedsColorConversion(context_color_params) || PixelFormat() == CanvasPixelFormat::kF16) { size_t data_length; @@ -1874,7 +1906,7 @@ void BaseRenderingContext2D::CheckOverdraw( const PaintFlags* flags, CanvasRenderingContext2DState::ImageType image_type, DrawType draw_type) { - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; @@ -1964,12 +1996,7 @@ void BaseRenderingContext2D::setTextBaseline(const String& s) { ModifiableState().SetTextBaseline(baseline); } -const BaseRenderingContext2D::UsageCounters& -BaseRenderingContext2D::GetUsage() { - return usage_counters_; -} - -void BaseRenderingContext2D::Trace(blink::Visitor* visitor) { +void BaseRenderingContext2D::Trace(Visitor* visitor) { visitor->Trace(state_stack_); } diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h index 53c5a939a93..9fd5cb6cb48 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h @@ -14,7 +14,7 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h" -#include "third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h" +#include "third_party/blink/renderer/platform/graphics/image_orientation.h" namespace blink { class CanvasImageSource; @@ -89,15 +89,15 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, double m22, double dx, double dy); - virtual void setTransform(double m11, - double m12, - double m21, - double m22, - double dx, - double dy); - virtual void setTransform(DOMMatrix2DInit*, ExceptionState&); - DOMMatrix* getTransform(); - void resetTransform(); + void setTransform(double m11, + double m12, + double m21, + double m22, + double dx, + double dy); + void setTransform(DOMMatrix2DInit*, ExceptionState&); + virtual DOMMatrix* getTransform(); + virtual void resetTransform(); void beginPath(); @@ -224,11 +224,13 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, } virtual bool CanCreateCanvas2dResourceProvider() const = 0; + virtual RespectImageOrientationEnum RespectImageOrientation() const = 0; + virtual bool ParseColorOrCurrentColor(Color&, const String& color_string) const = 0; - virtual cc::PaintCanvas* DrawingCanvas() const = 0; - virtual cc::PaintCanvas* ExistingDrawingCanvas() const = 0; + virtual cc::PaintCanvas* GetOrCreatePaintCanvas() = 0; + virtual cc::PaintCanvas* GetPaintCanvas() const = 0; virtual void DidDraw(const SkIRect& dirty_rect) = 0; @@ -236,7 +238,10 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, virtual sk_sp<PaintFilter> StateGetFilter() = 0; virtual void SnapshotStateForFilter() = 0; - virtual void ValidateStateStack() const = 0; + void ValidateStateStack() const { + ValidateStateStackWithCanvas(GetPaintCanvas()); + } + virtual void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const = 0; virtual bool HasAlpha() const = 0; @@ -248,7 +253,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, return kSRGBCanvasColorSpaceName; } virtual CanvasPixelFormat PixelFormat() const { - return CanvasPixelFormat::kRGBA8; + return CanvasColorParams::GetNativeCanvasPixelFormat(); } void RestoreMatrixClipStack(cc::PaintCanvas*) const; @@ -259,7 +264,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, String textBaseline() const; void setTextBaseline(const String&); - void Trace(blink::Visitor*) override; + void Trace(Visitor*) override; enum DrawCallType { kStrokePath = 0, @@ -361,8 +366,6 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, HeapVector<Member<CanvasRenderingContext2DState>> state_stack_; AntiAliasingMode clip_antialiasing_; - mutable UsageCounters usage_counters_; - virtual void FinalizeFrame() {} float GetFontBaseline(const SimpleFontData&) const; @@ -377,7 +380,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, virtual void DisableAcceleration() {} virtual bool IsPaint2D() const { return false; } - virtual void WillOverwriteCanvas() {} + virtual void WillOverwriteCanvas() = 0; private: void RealizeSaves(); @@ -453,18 +456,19 @@ void BaseRenderingContext2D::Draw( return; SkIRect clip_bounds; - if (!DrawingCanvas() || !DrawingCanvas()->getDeviceClipBounds(&clip_bounds)) + cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas(); + if (!paint_canvas || !paint_canvas->getDeviceClipBounds(&clip_bounds)) return; if (IsFullCanvasCompositeMode(GetState().GlobalComposite()) || StateHasFilter()) { - CompositedDraw(draw_func, DrawingCanvas(), paint_type, image_type); + CompositedDraw(draw_func, GetPaintCanvas(), paint_type, image_type); DidDraw(clip_bounds); } else if (GetState().GlobalComposite() == SkBlendMode::kSrc) { ClearCanvas(); // takes care of checkOverdraw() const PaintFlags* flags = GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type); - draw_func(DrawingCanvas(), flags); + draw_func(GetPaintCanvas(), flags); DidDraw(clip_bounds); } else { SkIRect dirty_rect; @@ -474,7 +478,7 @@ void BaseRenderingContext2D::Draw( if (paint_type != CanvasRenderingContext2DState::kStrokePaintType && draw_covers_clip_bounds(clip_bounds)) CheckOverdraw(bounds, flags, image_type, kClipFill); - draw_func(DrawingCanvas(), flags); + draw_func(GetPaintCanvas(), flags); DidDraw(dirty_rect); } } @@ -491,7 +495,7 @@ void BaseRenderingContext2D::CompositedDraw( SkMatrix ctm = c->getTotalMatrix(); c->setMatrix(SkMatrix::I()); PaintFlags composite_flags; - composite_flags.setBlendMode((SkBlendMode)GetState().GlobalComposite()); + composite_flags.setBlendMode(GetState().GlobalComposite()); if (GetState().ShouldDrawShadows()) { // unroll into two independently composited passes if drawing shadows PaintFlags shadow_flags = @@ -501,10 +505,13 @@ void BaseRenderingContext2D::CompositedDraw( if (filter) { PaintFlags foreground_flags = *GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type); - foreground_flags.setImageFilter(sk_make_sp<ComposePaintFilter>( + shadow_flags.setImageFilter(sk_make_sp<ComposePaintFilter>( sk_make_sp<ComposePaintFilter>(foreground_flags.getImageFilter(), shadow_flags.getImageFilter()), filter)); + // Saving the shadow layer before setting the matrix, so the shadow offset + // does not get modified by the transformation matrix + c->saveLayer(nullptr, &shadow_flags); c->setMatrix(ctm); draw_func(c, &foreground_flags); } else { diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h index be45b1d2fff..789c99a2a80 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h @@ -26,7 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_PATTERN_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_PATTERN_H_ -#include "third_party/blink/renderer/core/geometry/dom_matrix_2d_init.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/graphics/pattern.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl index afb67a419b1..fdab94ab301 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl @@ -22,10 +22,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +// https://html.spec.whatwg.org/C/#canvaspattern + [ Exposed=(Window,Worker) ] interface CanvasPattern { - [RaisesException] void setTransform(optional DOMMatrix2DInit transform); + [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {}); }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 41dc3431667..f5947119128 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc @@ -38,7 +38,6 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/public/platform/web_scroll_into_view_params.h" #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/css/css_font_selector.h" @@ -64,8 +63,6 @@ #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/text_run_paint_info.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/draw_looper_builder.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" @@ -97,21 +94,21 @@ class CanvasRenderingContext2DAutoRestoreSkCanvas { CanvasRenderingContext2D* context) : context_(context), save_count_(0) { DCHECK(context_); - cc::PaintCanvas* c = context_->DrawingCanvas(); + cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas(); if (c) { save_count_ = c->getSaveCount(); } } ~CanvasRenderingContext2DAutoRestoreSkCanvas() { - cc::PaintCanvas* c = context_->DrawingCanvas(); + cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas(); if (c) c->restoreToCount(save_count_); context_->ValidateStateStack(); } private: - Member<CanvasRenderingContext2D> context_; + CanvasRenderingContext2D* context_; int save_count_; }; @@ -151,15 +148,16 @@ void CanvasRenderingContext2D::SetCanvasGetContextResult( CanvasRenderingContext2D::~CanvasRenderingContext2D() = default; -void CanvasRenderingContext2D::ValidateStateStack() const { +void CanvasRenderingContext2D::ValidateStateStackWithCanvas( + const cc::PaintCanvas* canvas) const { #if DCHECK_IS_ON() - if (cc::PaintCanvas* sk_canvas = ExistingDrawingCanvas()) { + if (canvas) { // The canvas should always have an initial save frame, to support // resetting the top level matrix and clip. - DCHECK_GT(sk_canvas->getSaveCount(), 1); + DCHECK_GT(canvas->getSaveCount(), 1); if (context_lost_mode_ == kNotLostContext) { - DCHECK_EQ(static_cast<size_t>(sk_canvas->getSaveCount()), + DCHECK_EQ(static_cast<size_t>(canvas->getSaveCount()), state_stack_.size() + 1); } } @@ -225,7 +223,7 @@ void CanvasRenderingContext2D::DidSetSurfaceSize() { } } -void CanvasRenderingContext2D::Trace(blink::Visitor* visitor) { +void CanvasRenderingContext2D::Trace(Visitor* visitor) { visitor->Trace(hit_region_manager_); visitor->Trace(filter_operations_); CanvasRenderingContext::Trace(visitor); @@ -346,7 +344,8 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) { if (!GetState().IsTransformInvertible() || path.IsEmpty()) return; - canvas()->GetDocument().UpdateStyleAndLayout(); + canvas()->GetDocument().UpdateStyleAndLayout( + DocumentUpdateReason::kJavaScript); LayoutObject* renderer = canvas()->GetLayoutObject(); LayoutBox* layout_box = canvas()->GetLayoutBox(); @@ -378,9 +377,10 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) { path_rect.Intersect(canvas_rect); // Horizontal text is aligned at the top of the screen - ScrollAlignment horizontal_scroll_mode = - ScrollAlignment::kAlignToEdgeIfNeeded; - ScrollAlignment vertical_scroll_mode = ScrollAlignment::kAlignTopAlways; + mojom::blink::ScrollAlignment horizontal_scroll_mode = + ScrollAlignment::ToEdgeIfNeeded(); + mojom::blink::ScrollAlignment vertical_scroll_mode = + ScrollAlignment::TopAlways(); // Vertical text needs be aligned horizontally on the screen bool is_horizontal_writing_mode = @@ -388,15 +388,15 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) { if (!is_horizontal_writing_mode) { bool is_right_to_left = canvas()->EnsureComputedStyle()->IsFlippedBlocksWritingMode(); - horizontal_scroll_mode = - (is_right_to_left ? ScrollAlignment::kAlignRightAlways - : ScrollAlignment::kAlignLeftAlways); - vertical_scroll_mode = ScrollAlignment::kAlignToEdgeIfNeeded; + horizontal_scroll_mode = (is_right_to_left ? ScrollAlignment::RightAlways() + : ScrollAlignment::LeftAlways()); + vertical_scroll_mode = ScrollAlignment::ToEdgeIfNeeded(); } renderer->ScrollRectToVisible( - path_rect, - WebScrollIntoViewParams(horizontal_scroll_mode, vertical_scroll_mode, - kProgrammaticScroll, false, kScrollBehaviorAuto)); + path_rect, ScrollAlignment::CreateScrollIntoViewParams( + horizontal_scroll_mode, vertical_scroll_mode, + mojom::blink::ScrollType::kProgrammatic, false, + mojom::blink::ScrollBehavior::kAuto)); } void CanvasRenderingContext2D::clearRect(double x, @@ -437,19 +437,19 @@ void CanvasRenderingContext2D::SnapshotStateForFilter() { ModifiableState().SetFontForFilter(AccessFont()); } -cc::PaintCanvas* CanvasRenderingContext2D::DrawingCanvas() const { +cc::PaintCanvas* CanvasRenderingContext2D::GetOrCreatePaintCanvas() { if (isContextLost()) return nullptr; if (canvas()->GetOrCreateCanvas2DLayerBridge()) - return canvas()->GetCanvas2DLayerBridge()->DrawingCanvas(); + return canvas()->GetCanvas2DLayerBridge()->GetPaintCanvas(); return nullptr; } -cc::PaintCanvas* CanvasRenderingContext2D::ExistingDrawingCanvas() const { - if (isContextLost()) +cc::PaintCanvas* CanvasRenderingContext2D::GetPaintCanvas() const { + if (isContextLost() || !canvas()->GetCanvas2DLayerBridge()) return nullptr; - if (IsPaintable()) - return canvas()->GetCanvas2DLayerBridge()->DrawingCanvas(); + if (canvas() && canvas()->GetCanvas2DLayerBridge()->ResourceProvider()) + return canvas()->GetCanvas2DLayerBridge()->GetPaintCanvas(); return nullptr; } @@ -459,8 +459,7 @@ String CanvasRenderingContext2D::font() const { canvas()->GetDocument().GetCanvasFontCache()->WillUseCurrentFont(); StringBuilder serialized_font; - const FontDescription& font_description = - GetState().GetFont().GetFontDescription(); + const FontDescription& font_description = GetState().GetFontDescription(); if (font_description.Style() == ItalicSlopeValue()) serialized_font.Append("italic "); @@ -518,8 +517,7 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { scoped_refptr<ComputedStyle> font_style; const ComputedStyle* computed_style = canvas()->EnsureComputedStyle(); if (computed_style) { - HashMap<String, Font>::iterator i = - fonts_resolved_using_current_style_.find(new_font); + auto i = fonts_resolved_using_current_style_.find(new_font); if (i != fonts_resolved_using_current_style_.end()) { auto add_result = font_lru_list_.PrependOrMoveToFirst(new_font); DCHECK(!add_result.is_new_entry); @@ -540,7 +538,6 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { element_font_description.SpecifiedSize()); font_style->SetFontDescription(element_font_description); - font_style->GetFont().Update(font_style->GetFont().GetFontSelector()); canvas()->GetDocument().EnsureStyleResolver().ComputeFont( *canvas(), font_style.get(), *parsed_style); @@ -550,14 +547,13 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { font_style->GetFont().GetFontDescription()); final_description.SetComputedSize(final_description.SpecifiedSize()); final_description.SetAdjustedSize(final_description.SpecifiedSize()); - Font final_font(final_description); - fonts_resolved_using_current_style_.insert(new_font, final_font); + fonts_resolved_using_current_style_.insert(new_font, final_description); auto add_result = font_lru_list_.PrependOrMoveToFirst(new_font); DCHECK(add_result.is_new_entry); PruneLocalFontCache(canvas_font_cache->HardMaxFonts()); // hard limit should_prune_local_font_cache_ = true; // apply soft limit - ModifiableState().SetFont(final_font, Host()->GetFontSelector()); + ModifiableState().SetFont(final_description, Host()->GetFontSelector()); } } else { Font resolved_font; @@ -570,8 +566,7 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { FontDescription final_description(resolved_font.GetFontDescription()); final_description.SetComputedSize(final_description.SpecifiedSize()); final_description.SetAdjustedSize(final_description.SpecifiedSize()); - Font final_font(final_description); - ModifiableState().SetFont(final_font, Host()->GetFontSelector()); + ModifiableState().SetFont(final_description, Host()->GetFontSelector()); } // The parse succeeded. @@ -678,7 +673,6 @@ void CanvasRenderingContext2D::FinalizeFrame() { TRACE_EVENT0("blink", "CanvasRenderingContext2D::FinalizeFrame"); if (IsPaintable()) canvas()->GetCanvas2DLayerBridge()->FinalizeFrame(); - usage_counters_.num_frames_since_reset++; } bool CanvasRenderingContext2D::ParseColorOrCurrentColor( @@ -839,10 +833,10 @@ void CanvasRenderingContext2D::DrawTextInternal( // accessFont needs the style to be up to date, but updating style can cause // script to run, (e.g. due to autofocus) which can free the canvas (set size - // to 0, for example), so update style before grabbing the drawingCanvas. + // to 0, for example), so update style before grabbing the PaintCanvas. canvas()->GetDocument().UpdateStyleAndLayoutTreeForNode(canvas()); - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (!c) return; @@ -907,13 +901,13 @@ void CanvasRenderingContext2D::DrawTextInternal( CanvasRenderingContext2DAutoRestoreSkCanvas state_restorer(this); if (use_max_width) { - DrawingCanvas()->save(); - DrawingCanvas()->translate(location.X(), location.Y()); + c->save(); // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) - // still work. - DrawingCanvas()->scale( - (font_width > 0 ? clampTo<float>(width / font_width) : 0), 1); - location = FloatPoint(); + // still work. As the width of canvas is scaled, so text can be scaled to + // match the given maxwidth, update text location so it appears on desired + // place. + c->scale(clampTo<float>(width / font_width), 1); + location.SetX(location.X() / clampTo<float>(width / font_width)); } Draw( @@ -933,7 +927,7 @@ const Font& CanvasRenderingContext2D::AccessFont() { if (!GetState().HasRealizedFont()) setFont(GetState().UnparsedFont()); canvas()->GetDocument().GetCanvasFontCache()->WillUseCurrentFont(); - return GetState().GetFont(); + return ModifiableState().GetFont(); } void CanvasRenderingContext2D::SetIsInHiddenPage(bool hidden) { @@ -1013,15 +1007,13 @@ bool CanvasRenderingContext2D::FocusRingCallIsValid(const Path& path, } void CanvasRenderingContext2D::DrawFocusRing(const Path& path) { - usage_counters_.num_draw_focus_calls++; - if (!DrawingCanvas()) + if (!GetOrCreatePaintCanvas()) return; SkColor color = LayoutTheme::GetTheme().FocusRingColor().Rgb(); const int kFocusRingWidth = 5; - - DrawPlatformFocusRing(path.GetSkPath(), DrawingCanvas(), color, - kFocusRingWidth); + DrawPlatformFocusRing(path.GetSkPath(), GetPaintCanvas(), color, + /*width=*/kFocusRingWidth, /*radius=*/kFocusRingWidth); // We need to add focusRingWidth to dirtyRect. StrokeData stroke_data; @@ -1036,7 +1028,8 @@ void CanvasRenderingContext2D::DrawFocusRing(const Path& path) { void CanvasRenderingContext2D::UpdateElementAccessibility(const Path& path, Element* element) { - element->GetDocument().UpdateStyleAndLayout(); + element->GetDocument().UpdateStyleAndLayout( + DocumentUpdateReason::kAccessibility); AXObjectCache* ax_object_cache = element->GetDocument().ExistingAXObjectCache(); LayoutBoxModelObject* lbmo = canvas()->GetLayoutBoxModelObject(); @@ -1077,7 +1070,7 @@ void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions* options, Path hit_region_path = options->path() ? options->path()->GetPath() : path_; - cc::PaintCanvas* c = DrawingCanvas(); + cc::PaintCanvas* c = GetOrCreatePaintCanvas(); if (hit_region_path.IsEmpty() || !c || !GetState().IsTransformInvertible() || c->isClipEmpty()) { @@ -1147,4 +1140,12 @@ bool CanvasRenderingContext2D::IsCanvas2DBufferValid() const { return false; } +RespectImageOrientationEnum CanvasRenderingContext2D::RespectImageOrientation() + const { + if (canvas()->RespectImageOrientation() != kRespectImageOrientation) { + return kDoNotRespectImageOrientation; + } + return kRespectImageOrientation; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h index 7efef4f19b4..bda1b439ed3 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h @@ -30,13 +30,13 @@ #include <random> #include "base/macros.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d_settings.h" #include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.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/style/filter_operations.h" #include "third_party/blink/renderer/core/svg/svg_resource_client.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h" -#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -176,10 +176,12 @@ class MODULES_EXPORT CanvasRenderingContext2D final bool CanCreateCanvas2dResourceProvider() const final; + RespectImageOrientationEnum RespectImageOrientation() const final; + bool ParseColorOrCurrentColor(Color&, const String& color_string) const final; - cc::PaintCanvas* DrawingCanvas() const final; - cc::PaintCanvas* ExistingDrawingCanvas() const final; + cc::PaintCanvas* GetOrCreatePaintCanvas() final; + cc::PaintCanvas* GetPaintCanvas() const final; void DidDraw(const SkIRect& dirty_rect) final; scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; @@ -188,7 +190,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final sk_sp<PaintFilter> StateGetFilter() final; void SnapshotStateForFilter() final; - void ValidateStateStack() const final; + void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const final; void FinalizeFrame() override; @@ -198,7 +200,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final void WillDrawImage(CanvasImageSource*) const final; - void Trace(blink::Visitor*) override; + void Trace(Visitor*) override; CanvasColorParams ColorParamsForTest() const { return ColorParams(); } @@ -267,7 +269,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final TaskRunnerTimer<CanvasRenderingContext2D> try_restore_context_event_timer_; FilterOperations filter_operations_; - HashMap<String, Font> fonts_resolved_using_current_style_; + HashMap<String, FontDescription> fonts_resolved_using_current_style_; bool should_prune_local_font_cache_; LinkedHashSet<String> font_lru_list_; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl index d2b906ebb71..b4b6ae1e108 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl @@ -59,7 +59,7 @@ interface CanvasRenderingContext2D { void translate(unrestricted double x, unrestricted double y); void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); - [RaisesException] void setTransform(optional DOMMatrix2DInit transform); + [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {}); DOMMatrix getTransform(); void resetTransform(); @@ -119,7 +119,7 @@ interface CanvasRenderingContext2D { [CallWith=ScriptState, RaisesException] void drawImage(CanvasImageSource image, unrestricted double sx, unrestricted double sy, unrestricted double sw, unrestricted double sh, unrestricted double dx, unrestricted double dy, unrestricted double dw, unrestricted double dh); // hit regions - [RuntimeEnabled=CanvasHitRegion, RaisesException] void addHitRegion(optional HitRegionOptions options); + [RuntimeEnabled=CanvasHitRegion, RaisesException] void addHitRegion(optional HitRegionOptions options = {}); [RuntimeEnabled=CanvasHitRegion] void removeHitRegion(DOMString id); [RuntimeEnabled=CanvasHitRegion] void clearHitRegions(); @@ -132,7 +132,7 @@ interface CanvasRenderingContext2D { // https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings); - [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, optional ImageDataColorSettings imageDataColorSettings); + [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, optional ImageDataColorSettings imageDataColorSettings = {}); // Context state // Should be merged with WebGL counterpart in CanvasRenderingContext, once no-longer experimental diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc index 466ff0c1167..79a5ddca35d 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc @@ -7,6 +7,7 @@ #include <memory> #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_hit_region_options.h" #include "third_party/blink/renderer/core/accessibility/ax_context.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -19,7 +20,6 @@ #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h" -#include "third_party/blink/renderer/modules/canvas/canvas2d/hit_region_options.h" #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h" using testing::Mock; @@ -61,7 +61,7 @@ void CanvasRenderingContext2DAPITest::CreateContext(OpacityMode opacity_mode) { void CanvasRenderingContext2DAPITest::SetUp() { PageTestBase::SetUp(); - GetDocument().documentElement()->SetInnerHTMLFromString( + GetDocument().documentElement()->setInnerHTML( "<body><canvas id='c'></canvas></body>"); UpdateAllLifecyclePhasesForTest(); canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c")); @@ -305,7 +305,7 @@ TEST_F(CanvasRenderingContext2DAPITest, } void ResetCanvasForAccessibilityRectTest(Document& document) { - document.documentElement()->SetInnerHTMLFromString(R"HTML( + document.documentElement()->setInnerHTML(R"HTML( <canvas id='canvas' style='position:absolute; top:0px; left:0px; padding:10px; margin:5px;'> <button id='button'></button></canvas> @@ -338,8 +338,8 @@ TEST_F(CanvasRenderingContext2DAPITest, AccessibilityRectTestForAddHitRegion) { context->rect(10, 10, 40, 40); context->addHitRegion(options, exception_state); - AXObjectCacheImpl* ax_object_cache = - ToAXObjectCacheImpl(GetDocument().ExistingAXObjectCache()); + auto* ax_object_cache = + To<AXObjectCacheImpl>(GetDocument().ExistingAXObjectCache()); AXObject* ax_object = ax_object_cache->GetOrCreate(button_element); LayoutRect ax_bounds = ax_object->GetBoundsInFrameCoordinates(); @@ -365,8 +365,8 @@ TEST_F(CanvasRenderingContext2DAPITest, context->rect(10, 10, 40, 40); context->drawFocusIfNeeded(button_element); - AXObjectCacheImpl* ax_object_cache = - ToAXObjectCacheImpl(GetDocument().ExistingAXObjectCache()); + auto* ax_object_cache = + To<AXObjectCacheImpl>(GetDocument().ExistingAXObjectCache()); AXObject* ax_object = ax_object_cache->GetOrCreate(button_element); LayoutRect ax_bounds = ax_object->GetBoundsInFrameCoordinates(); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc index b670fe73bca..de05aa36b3b 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/skia/include/effects/SkDashPathEffect.h" #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" @@ -35,8 +36,8 @@ namespace blink { CanvasRenderingContext2DState::CanvasRenderingContext2DState() : unrealized_save_count_(0), - stroke_style_(CanvasStyle::CreateFromRGBA(SK_ColorBLACK)), - fill_style_(CanvasStyle::CreateFromRGBA(SK_ColorBLACK)), + stroke_style_(MakeGarbageCollected<CanvasStyle>(SK_ColorBLACK)), + fill_style_(MakeGarbageCollected<CanvasStyle>(SK_ColorBLACK)), shadow_blur_(0), shadow_color_(Color::kTransparent), global_alpha_(1), @@ -124,13 +125,13 @@ void CanvasRenderingContext2DState::FontsNeedUpdate( DCHECK_EQ(font_selector, font_.GetFontSelector()); DCHECK(realized_font_); - font_.Update(font_selector); + font_ = Font(font_.GetFontDescription(), font_selector); // FIXME: We only really need to invalidate the resolved filter if the font // update above changed anything and the filter uses font-dependent units. resolved_filter_.reset(); } -void CanvasRenderingContext2DState::Trace(blink::Visitor* visitor) { +void CanvasRenderingContext2DState::Trace(Visitor* visitor) { visitor->Trace(stroke_style_); visitor->Trace(fill_style_); visitor->Trace(filter_value_); @@ -252,20 +253,28 @@ void CanvasRenderingContext2DState::ClipPath( has_complex_clip_ = true; } -void CanvasRenderingContext2DState::SetFont(const Font& font, - FontSelector* selector) { - font_ = font; - font_.Update(selector); +void CanvasRenderingContext2DState::SetFont( + const FontDescription& font_description, + FontSelector* selector) { + font_ = Font(font_description, selector); realized_font_ = true; if (selector) selector->RegisterForInvalidationCallbacks(this); } -const Font& CanvasRenderingContext2DState::GetFont() const { +const Font& CanvasRenderingContext2DState::GetFont() { DCHECK(realized_font_); + if (!font_.IsFallbackValid()) + FontsNeedUpdate(font_.GetFontSelector()); return font_; } +const FontDescription& CanvasRenderingContext2DState::GetFontDescription() + const { + DCHECK(realized_font_); + return font_.GetFontDescription(); +} + void CanvasRenderingContext2DState::SetTransform( const AffineTransform& transform) { is_transform_invertible_ = transform.IsInvertible(); @@ -329,7 +338,8 @@ sk_sp<PaintFilter> CanvasRenderingContext2DState::GetFilter( if (!resolved_filter_) { // Update the filter value to the proper base URL if needed. if (filter_value_->MayContainUrl()) { - style_resolution_host->GetDocument().UpdateStyleAndLayout(); + style_resolution_host->GetDocument().UpdateStyleAndLayout( + DocumentUpdateReason::kCanvas); filter_value_->ReResolveUrl(style_resolution_host->GetDocument()); } diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h index eaf5b21390c..b224ec4c62c 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h @@ -37,7 +37,7 @@ class CanvasRenderingContext2DState final ClipListCopyMode); ~CanvasRenderingContext2DState() override; - void Trace(blink::Visitor*) override; + void Trace(Visitor*) override; enum PaintType { kFillPaintType, @@ -45,12 +45,6 @@ class CanvasRenderingContext2DState final kImagePaintType, }; - static CanvasRenderingContext2DState* Create( - const CanvasRenderingContext2DState& other, - ClipListCopyMode mode) { - return MakeGarbageCollected<CanvasRenderingContext2DState>(other, mode); - } - // FontSelectorClient implementation void FontsNeedUpdate(FontSelector*) override; @@ -84,8 +78,9 @@ class CanvasRenderingContext2DState final return clip_list_.GetCurrentClipPath(); } - void SetFont(const Font&, FontSelector*); - const Font& GetFont() const; + void SetFont(const FontDescription&, FontSelector*); + const Font& GetFont(); + const FontDescription& GetFontDescription() const; bool HasRealizedFont() const { return realized_font_; } void SetUnparsedFont(const String& font) { unparsed_font_ = font; } const String& UnparsedFont() const { return unparsed_font_; } diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc index 4663521456d..4d1e27c05a5 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc @@ -16,6 +16,7 @@ #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -26,7 +27,6 @@ #include "third_party/blink/renderer/core/html/canvas/image_data.h" #include "third_party/blink/renderer/core/html/html_image_element.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/layout/layout_box_model_object.h" #include "third_party/blink/renderer/core/loader/resource/image_resource_content.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -34,7 +34,6 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h" #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.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/color_correction_test_utils.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" @@ -70,7 +69,8 @@ class FakeImageSource : public CanvasImageSource { const FloatSize&) override; bool WouldTaintOrigin() const override { return false; } - FloatSize ElementSize(const FloatSize&) const override { + FloatSize ElementSize(const FloatSize&, + const RespectImageOrientationEnum) const override { return FloatSize(size_); } bool IsOpaque() const override { return is_opaque_; } @@ -155,8 +155,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test { } void UpdateAllLifecyclePhasesForTest() { - GetDocument().View()->UpdateAllLifecyclePhases( - DocumentLifecycle::LifecycleUpdateReason::kTest); + GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest); GetDocument().View()->RunPostLifecycleSteps(); } @@ -169,7 +168,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test { class WrapGradients final : public GarbageCollected<WrapGradients> { public: - void Trace(blink::Visitor* visitor) { + void Trace(Visitor* visitor) { visitor->Trace(opaque_gradient_); visitor->Trace(alpha_gradient_); } @@ -220,7 +219,7 @@ void CanvasRenderingContext2DTest::SetUp() { web_view_helper_ = std::make_unique<frame_test_helpers::WebViewHelper>(); web_view_helper_->Initialize(); - GetDocument().documentElement()->SetInnerHTMLFromString(String::FromUTF8( + GetDocument().documentElement()->setInnerHTML(String::FromUTF8( "<body><canvas id='c'></canvas><canvas id='d'></canvas></body>")); UpdateAllLifecyclePhasesForTest(); @@ -330,8 +329,9 @@ class FakeCanvasResourceProvider : public CanvasResourceProvider { sk_sp<SkSurface> CreateSkSurface() const override { return sk_sp<SkSurface>(); } - scoped_refptr<StaticBitmapImage> Snapshot() override { - return SnapshotInternal(); + scoped_refptr<StaticBitmapImage> Snapshot( + const ImageOrientation& orientation) override { + return SnapshotInternal(orientation); } private: @@ -586,13 +586,13 @@ TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) { const ImageBitmapOptions* default_options = ImageBitmapOptions::Create(); base::Optional<IntRect> crop_rect = IntRect(0, 0, canvas->width(), canvas->height()); - ImageBitmap* image_bitmap_from_canvas = - ImageBitmap::Create(canvas, crop_rect, default_options); + auto* image_bitmap_from_canvas = + MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, default_options); ASSERT_TRUE(image_bitmap_from_canvas); crop_rect = IntRect(0, 0, 20, 20); - image_bitmap_derived = ImageBitmap::Create(image_bitmap_from_canvas, - crop_rect, default_options); + image_bitmap_derived = MakeGarbageCollected<ImageBitmap>( + image_bitmap_from_canvas, crop_rect, default_options); ASSERT_TRUE(image_bitmap_derived); } CanvasContextCreationAttributesCore attributes; @@ -736,13 +736,10 @@ TEST_F(CanvasRenderingContext2DTest, size, CanvasColorParams(), kPreferNoAcceleration); fake_deaccelerate_surface->SetCanvasResourceHost(&host); - cc::PaintCanvas* paint_canvas_ptr = - fake_deaccelerate_surface->DrawingCanvas(); FakeCanvas2DLayerBridge* surface_ptr = fake_deaccelerate_surface.get(); EXPECT_CALL(*fake_deaccelerate_surface, DrawFullImage(_)).Times(1); - EXPECT_CALL(*fake_deaccelerate_surface, - DidRestoreCanvasMatrixClipStack(paint_canvas_ptr)) + EXPECT_CALL(*fake_deaccelerate_surface, DidRestoreCanvasMatrixClipStack(_)) .Times(1); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); @@ -895,7 +892,8 @@ TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { options->setColorSpaceConversion( ColorCorrectionTestUtils::ColorSpaceConversionToString( static_cast<ColorSpaceConversion>(conversion_iterator))); - ImageBitmap* image_bitmap = ImageBitmap::Create(canvas, crop_rect, options); + ImageBitmap* image_bitmap = + MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, options); ASSERT_TRUE(image_bitmap); sk_sp<SkImage> converted_image = image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage(); @@ -995,28 +993,28 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings( 0, 0, 0, 0, // Transparent 255, 192, 128, 64, // Decreasing values 93, 117, 205, 41}; // 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(); @@ -1033,17 +1031,18 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings( 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: @@ -1142,11 +1141,14 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, CreateContext(kNonOpaque); IntSize size(300, 300); std::unique_ptr<Canvas2DLayerBridge> bridge = - MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration); + std::make_unique<Canvas2DLayerBridge>( + size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); // Force hibernatation to occur in an immediate task. bridge->DontUseIdleSchedulingForTesting(); CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge), size); + CanvasElement().GetCanvas2DLayerBridge()->SetCanvasResourceHost( + canvas_element_); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); // Take a snapshot to trigger lazy resource provider creation @@ -1171,7 +1173,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, // The page is hidden so it doesn't make sense to paint, and doing so will // DCHECK. Update all other lifecycle phases. - GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(); + GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint( + DocumentUpdateReason::kTest); EXPECT_FALSE(layer->NeedsCompositingInputsUpdate()); // Wake up again, which should request a compositing update synchronously. @@ -1186,12 +1189,14 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, CreateContext(kNonOpaque); IntSize size(300, 300); std::unique_ptr<Canvas2DLayerBridge> bridge = - MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration); + std::make_unique<Canvas2DLayerBridge>( + size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); // Force hibernatation to occur in an immediate task. bridge->DontUseIdleSchedulingForTesting(); CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge), size); - + CanvasElement().GetCanvas2DLayerBridge()->SetCanvasResourceHost( + canvas_element_); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); EXPECT_TRUE(CanvasElement().GetLayoutBoxModelObject()); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc index 96540a18a01..db362e3bd6f 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc @@ -53,7 +53,7 @@ enum ColorParseResult { static ColorParseResult ParseColor(Color& parsed_color, const String& color_string, WebColorScheme color_scheme) { - if (DeprecatedEqualIgnoringCase(color_string, "currentcolor")) + if (EqualIgnoringASCIICase(color_string, "currentcolor")) return kParsedCurrentColor; const bool kUseStrictParsing = true; if (CSSParser::ParseColor(parsed_color, color_string, kUseStrictParsing)) @@ -109,16 +109,6 @@ CanvasStyle::CanvasStyle(CanvasGradient* gradient) CanvasStyle::CanvasStyle(CanvasPattern* pattern) : type_(kImagePattern), pattern_(pattern) {} -CanvasStyle* CanvasStyle::CreateFromGradient(CanvasGradient* gradient) { - DCHECK(gradient); - return MakeGarbageCollected<CanvasStyle>(gradient); -} - -CanvasStyle* CanvasStyle::CreateFromPattern(CanvasPattern* pattern) { - DCHECK(pattern); - return MakeGarbageCollected<CanvasStyle>(pattern); -} - void CanvasStyle::ApplyToFlags(PaintFlags& flags) const { switch (type_) { case kColorRGBA: @@ -143,7 +133,7 @@ RGBA32 CanvasStyle::PaintColor() const { return Color::kBlack; } -void CanvasStyle::Trace(blink::Visitor* visitor) { +void CanvasStyle::Trace(Visitor* visitor) { visitor->Trace(gradient_); visitor->Trace(pattern_); } diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h index c5c55670009..fca9d07f187 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h @@ -41,15 +41,9 @@ class HTMLCanvasElement; class CanvasStyle final : public GarbageCollected<CanvasStyle> { public: - static CanvasStyle* CreateFromRGBA(RGBA32 rgba) { - return MakeGarbageCollected<CanvasStyle>(rgba); - } - static CanvasStyle* CreateFromGradient(CanvasGradient*); - static CanvasStyle* CreateFromPattern(CanvasPattern*); - - CanvasStyle(RGBA32); - CanvasStyle(CanvasGradient*); - CanvasStyle(CanvasPattern*); + explicit CanvasStyle(RGBA32); + explicit CanvasStyle(CanvasGradient*); + explicit CanvasStyle(CanvasPattern*); String GetColor() const { DCHECK_EQ(type_, kColorRGBA); @@ -65,7 +59,7 @@ class CanvasStyle final : public GarbageCollected<CanvasStyle> { return type_ == kColorRGBA && rgba_ == rgba; } - void Trace(blink::Visitor*); + void Trace(Visitor*); private: enum Type { kColorRGBA, kGradient, kImagePattern }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc index fc1ba5beebd..ab288595cb0 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc @@ -26,7 +26,7 @@ void HitRegion::RemovePixels(const Path& clear_area) { path_.SubtractPath(clear_area); } -void HitRegion::Trace(blink::Visitor* visitor) { +void HitRegion::Trace(Visitor* visitor) { visitor->Trace(control_); } @@ -118,7 +118,7 @@ unsigned HitRegionManager::GetHitRegionsCount() const { return hit_region_list_.size(); } -void HitRegionManager::Trace(blink::Visitor* visitor) { +void HitRegionManager::Trace(Visitor* visitor) { visitor->Trace(hit_region_list_); visitor->Trace(hit_region_id_map_); visitor->Trace(hit_region_control_map_); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h index 909768d929b..968009a8535 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h @@ -7,8 +7,8 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_hit_region_options.h" #include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/modules/canvas/canvas2d/hit_region_options.h" #include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" @@ -28,7 +28,7 @@ class HitRegion final : public GarbageCollected<HitRegion> { const Path& GetPath() const { return path_; } Element* Control() const { return control_.Get(); } - void Trace(blink::Visitor*); + void Trace(Visitor*); private: String id_; @@ -56,7 +56,7 @@ class HitRegionManager final : public GarbageCollected<HitRegionManager> { unsigned GetHitRegionsCount() const; - void Trace(blink::Visitor*); + void Trace(Visitor*); private: typedef HeapLinkedHashSet<Member<HitRegion>> HitRegionList; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h index d03101cb9b4..e5905ff6049 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h @@ -29,9 +29,9 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_PATH_2D_H_ #include "base/macros.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h" #include "third_party/blink/renderer/bindings/modules/v8/path_2d_or_string.h" #include "third_party/blink/renderer/core/geometry/dom_matrix.h" -#include "third_party/blink/renderer/core/geometry/dom_matrix_2d_init.h" #include "third_party/blink/renderer/core/svg/svg_path_utilities.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl index ab9862676cb..c9049fc14f0 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl @@ -29,10 +29,10 @@ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path2d [ - Constructor(optional (Path2D or DOMString) path), Exposed=(PaintWorklet,Window,Worker) ] interface Path2D { - [RaisesException] void addPath(Path2D path, optional DOMMatrix2DInit transform); + constructor(optional (Path2D or DOMString) path); + [RaisesException] void addPath(Path2D path, optional DOMMatrix2DInit transform = {}); }; Path2D includes CanvasPath; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc new file mode 100644 index 00000000000..7e2e0c295e4 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc @@ -0,0 +1,18 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h" + +#include "third_party/blink/renderer/core/testing/internals.h" +#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h" + +namespace blink { + +uint32_t InternalsCanvasRenderingContext2D::countHitRegions( + Internals&, + CanvasRenderingContext2D* context) { + return context->HitRegionsCount(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h new file mode 100644 index 00000000000..180c2ffcdde --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h @@ -0,0 +1,24 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_TESTING_INTERNALS_CANVAS_RENDERING_CONTEXT_2D_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_TESTING_INTERNALS_CANVAS_RENDERING_CONTEXT_2D_H_ + +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" + +namespace blink { + +class CanvasRenderingContext2D; +class Internals; + +class InternalsCanvasRenderingContext2D { + STATIC_ONLY(InternalsCanvasRenderingContext2D); + + public: + static uint32_t countHitRegions(Internals&, CanvasRenderingContext2D*); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_INTERNALS_CANVAS_RENDERING_CONTEXT_2D_H_ diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.idl new file mode 100644 index 00000000000..cbe0cac6524 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.idl @@ -0,0 +1,9 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + ImplementedAs=InternalsCanvasRenderingContext2D +] partial interface Internals { + unsigned long countHitRegions(CanvasRenderingContext2D context); +}; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc index fd870c40e1b..0ac852367fd 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc @@ -44,14 +44,13 @@ class PageHelper { void SetBodyContentFromFuzzer(const uint8_t* data, size_t size) { FuzzedDataProvider provider(data, size); std::string body_content = provider.ConsumeBytesAsString(size); - GetDocument().documentElement()->SetInnerHTMLFromString( + GetDocument().documentElement()->setInnerHTML( String::FromUTF8(body_content)); UpdateAllLifecyclePhasesForTest(); } void UpdateAllLifecyclePhasesForTest() { - GetDocument().View()->UpdateAllLifecyclePhases( - DocumentLifecycle::LifecycleUpdateReason::kTest); + GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest); GetDocument().View()->RunPostLifecycleSteps(); } diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc index a8756b35373..29e9fbb4961 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc @@ -4,8 +4,8 @@ #include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h" #include "build/build_config.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_context_creation_attributes_module.h" #include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h" -#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc index 3593258deb0..a696431a6d0 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc @@ -4,13 +4,12 @@ #include "third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h" +#include "base/metrics/histogram_functions.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_context_creation_attributes_module.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" #include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h" -#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.h" -#include "third_party/blink/renderer/platform/instrumentation/histogram.h" namespace blink { @@ -18,8 +17,8 @@ void HTMLCanvasElementModule::getContext( HTMLCanvasElement& canvas, const String& type, const CanvasContextCreationAttributesModule* attributes, - ExceptionState& exception_state, - RenderingContext& result) { + RenderingContext& result, + ExceptionState& exception_state) { if (canvas.SurfaceLayerBridge() && !canvas.LowLatencyEnabled()) { // The existence of canvas surfaceLayerBridge indicates that // HTMLCanvasElement.transferControlToOffscreen() has been called. @@ -51,8 +50,8 @@ OffscreenCanvas* HTMLCanvasElementModule::transferControlToOffscreen( execution_context, canvas, exception_state); } - UMA_HISTOGRAM_BOOLEAN("Blink.OffscreenCanvas.TransferControlToOffscreen", - bool(offscreen_canvas)); + base::UmaHistogramBoolean("Blink.OffscreenCanvas.TransferControlToOffscreen", + !!offscreen_canvas); return offscreen_canvas; } @@ -70,12 +69,6 @@ OffscreenCanvas* HTMLCanvasElementModule::TransferControlToOffscreenInternal( execution_context, canvas.width(), canvas.height()); offscreen_canvas->SetFilterQuality(canvas.FilterQuality()); - // If this canvas is cross-origin, then the associated offscreen canvas - // should prefer using the low-power GPU. - LocalFrame* frame = canvas.GetDocument().GetFrame(); - if (!(frame && frame->IsCrossOriginSubframe())) - offscreen_canvas->AllowHighPerformancePowerPreference(); - DOMNodeId canvas_id = DOMNodeIds::IdForNode(&canvas); canvas.RegisterPlaceholderCanvas(static_cast<int>(canvas_id)); offscreen_canvas->SetPlaceholderCanvasId(canvas_id); diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h index 85dff7093da..e8c0e6d202a 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h @@ -24,8 +24,8 @@ class MODULES_EXPORT HTMLCanvasElementModule { static void getContext(HTMLCanvasElement&, const String&, const CanvasContextCreationAttributesModule*, - ExceptionState&, - RenderingContext&); + RenderingContext&, + ExceptionState&); static OffscreenCanvas* transferControlToOffscreen(ExecutionContext*, HTMLCanvasElement&, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl index 3ca7190541e..8df9faac92a 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl @@ -23,6 +23,6 @@ typedef (CanvasRenderingContext2D or // requires throwing TypeError if the incoming argument is not an object type // (and is not undefined or null). The binding must ignore this. // Related spec issue: https://github.com/whatwg/html/issues/595 - [RaisesException] RenderingContext? getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributesModule attributes); + [RaisesException] RenderingContext? getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributesModule attributes = {}); [CallWith=ExecutionContext, RaisesException, MeasureAs=OffscreenCanvas, RuntimeEnabled=SurfaceEmbeddingFeatures] OffscreenCanvas transferControlToOffscreen(); }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc index 348cd5009df..d20b64e71bf 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc @@ -60,7 +60,7 @@ class HTMLCanvasElementModuleTest : public ::testing::Test, protected: void SetUp() override { web_view_helper_.Initialize(); - GetDocument().documentElement()->SetInnerHTMLFromString( + GetDocument().documentElement()->setInnerHTML( String::FromUTF8("<body><canvas id='c'></canvas></body>")); canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c")); } @@ -76,7 +76,7 @@ class HTMLCanvasElementModuleTest : public ::testing::Test, HTMLCanvasElement& canvas_element() const { return *canvas_element_; } OffscreenCanvas* TransferControlToOffscreen(ExceptionState& exception_state) { return HTMLCanvasElementModule::TransferControlToOffscreenInternal( - &GetDocument(), canvas_element(), exception_state); + GetDocument().ToExecutionContext(), canvas_element(), exception_state); } frame_test_helpers::WebViewHelper web_view_helper_; @@ -96,11 +96,8 @@ TEST_F(HTMLCanvasElementModuleTest, TransferControlToOffscreen) { // Verifies that a desynchronized canvas has the appropriate opacity/blending // information sent to the CompositorFrameSink. TEST_P(HTMLCanvasElementModuleTest, LowLatencyCanvasCompositorFrameOpacity) { -#if defined(OS_MACOSX) // TODO(crbug.com/922218): enable desynchronized on Mac. - return; -#endif - +#if !defined(OS_MACOSX) // This test relies on GpuMemoryBuffers being supported and enabled for low // latency canvas. The latter is true only on ChromeOS in production. ScopedTestingPlatformSupport<LowLatencyTestPlatform> platform; @@ -165,6 +162,7 @@ TEST_P(HTMLCanvasElementModuleTest, LowLatencyCanvasCompositorFrameOpacity) { platform->RunUntilIdle(); SharedGpuContext::ResetForTesting(); +#endif } INSTANTIATE_TEST_SUITE_P(All, HTMLCanvasElementModuleTest, Values(true, false)); diff --git a/chromium/third_party/blink/renderer/modules/canvas/idls.gni b/chromium/third_party/blink/renderer/modules/canvas/idls.gni new file mode 100644 index 00000000000..bb4d2f14fdf --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/idls.gni @@ -0,0 +1,37 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/blink/renderer/config.gni") + +modules_idl_files = [ + "canvas2d/canvas_gradient.idl", + "canvas2d/canvas_pattern.idl", + "canvas2d/canvas_rendering_context_2d.idl", + "canvas2d/path_2d.idl", + "imagebitmap/image_bitmap_rendering_context.idl", + "offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl", +] + +modules_dictionary_idl_files = [ + "canvas2d/canvas_rendering_context_2d_settings.idl", + "canvas2d/hit_region_options.idl", + "htmlcanvas/canvas_context_creation_attributes_module.idl", +] + +modules_dependency_idl_files = [ "canvas2d/canvas_path.idl" ] + +if (support_webgl2_compute_context) { + modules_dependency_idl_files += [ + "htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl", + "offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl", + ] +} else { + modules_dependency_idl_files += [ + "htmlcanvas/html_canvas_element_module.idl", + "offscreencanvas/offscreen_canvas_module.idl", + ] +} + +modules_testing_dependency_idl_files = + [ "canvas2d/testing/internals_canvas_rendering_context_2d.idl" ] diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc index 90bcad5e210..d6cd4077d11 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc @@ -52,7 +52,7 @@ ImageBitmap* ImageBitmapRenderingContext::TransferToImageBitmap(ScriptState*) { return nullptr; image->Transfer(); - return ImageBitmap::Create(std::move(image)); + return MakeGarbageCollected<ImageBitmap>(std::move(image)); } CanvasRenderingContext* ImageBitmapRenderingContext::Factory::Create( diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h index 016be9b4c0c..5e0f291de67 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h +++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h @@ -55,14 +55,6 @@ class MODULES_EXPORT ImageBitmapRenderingContext final ~ImageBitmapRenderingContext() override; }; -DEFINE_TYPE_CASTS(ImageBitmapRenderingContext, - CanvasRenderingContext, - context, - context->GetContextType() == - CanvasRenderingContext::kContextImageBitmap, - context.GetContextType() == - CanvasRenderingContext::kContextImageBitmap); - } // namespace blink #endif diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc index e149b1aee29..2f2752c5f07 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc @@ -84,7 +84,7 @@ bool ImageBitmapRenderingContextBase::IsPaintable() const { return !!image_layer_bridge_->GetImage(); } -void ImageBitmapRenderingContextBase::Trace(blink::Visitor* visitor) { +void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) { visitor->Trace(image_layer_bridge_); CanvasRenderingContext::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h index b8524aef4b0..d5d8150fbe6 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h +++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h @@ -28,7 +28,7 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase const CanvasContextCreationAttributesCore&); ~ImageBitmapRenderingContextBase() override; - void Trace(blink::Visitor*) override; + void Trace(Visitor*) override; // TODO(juanmihd): Remove this method crbug.com/941579 HTMLCanvasElement* canvas() const { diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc index b9646e38983..e365ea77f13 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc @@ -4,10 +4,10 @@ #include "third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_context_creation_attributes_module.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" #include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h" -#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.h" #include "third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h" namespace blink { @@ -17,8 +17,8 @@ void OffscreenCanvasModule::getContext( OffscreenCanvas& offscreen_canvas, const String& id, const CanvasContextCreationAttributesModule* attributes, - ExceptionState& exception_state, - OffscreenRenderingContext& result) { + OffscreenRenderingContext& result, + ExceptionState& exception_state) { if (offscreen_canvas.IsNeutered()) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "OffscreenCanvas object is detached"); diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h index 145092b47af..ba2d44f6f48 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h @@ -24,8 +24,8 @@ class MODULES_EXPORT OffscreenCanvasModule { OffscreenCanvas&, const String&, const CanvasContextCreationAttributesModule*, - ExceptionState&, - OffscreenRenderingContext&); + OffscreenRenderingContext&, + ExceptionState&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl index b98939eb85f..a3728a2af1c 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl @@ -14,5 +14,5 @@ enum OffscreenRenderingContextType { "2d", "webgl", "webgl2", "webgl2-compute", [ ImplementedAs=OffscreenCanvasModule ] partial interface OffscreenCanvas { - [CallWith=ExecutionContext, RaisesException] OffscreenRenderingContext? getContext(OffscreenRenderingContextType contextType, optional CanvasContextCreationAttributesModule attributes); + [CallWith=ExecutionContext, RaisesException] OffscreenRenderingContext? getContext(OffscreenRenderingContextType contextType, optional CanvasContextCreationAttributesModule attributes = {}); }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc index 2b813ccd28d..3c98743511b 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc @@ -84,7 +84,7 @@ void OffscreenCanvasTest::SetUp() { web_view_helper_.Initialize(); - GetDocument().documentElement()->SetInnerHTMLFromString( + GetDocument().documentElement()->setInnerHTML( String::FromUTF8("<body><canvas id='c'></canvas></body>")); auto* canvas_element = @@ -92,7 +92,7 @@ void OffscreenCanvasTest::SetUp() { DummyExceptionStateForTesting exception_state; offscreen_canvas_ = HTMLCanvasElementModule::transferControlToOffscreen( - &GetDocument(), *canvas_element, exception_state); + GetDocument().ToExecutionContext(), *canvas_element, exception_state); // |offscreen_canvas_| should inherit the FrameSinkId from |canvas_element|s // SurfaceLayerBridge, but in tests this id is zero; fill it up by hand. offscreen_canvas_->SetFrameSinkId(kClientId, kSinkId); @@ -103,8 +103,8 @@ void OffscreenCanvasTest::SetUp() { attrs.desynchronized = GetParam().desynchronized; } context_ = static_cast<OffscreenCanvasRenderingContext2D*>( - offscreen_canvas_->GetCanvasRenderingContext(&GetDocument(), String("2d"), - attrs)); + offscreen_canvas_->GetCanvasRenderingContext( + GetDocument().ToExecutionContext(), String("2d"), attrs)); } void OffscreenCanvasTest::TearDown() { diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc index 057eab1e0ac..bc2b60c9771 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc @@ -42,15 +42,15 @@ class OffscreenFontCache { } } - void AddFont(String name, blink::Font font) { + void AddFont(String name, blink::FontDescription font) { fonts_resolved_.insert(name, font); auto add_result = font_lru_list_.PrependOrMoveToFirst(name); DCHECK(add_result.is_new_entry); PruneLocalFontCache(kHardMaxCachedFonts); } - blink::Font* GetFont(String name) { - HashMap<String, blink::Font>::iterator i = fonts_resolved_.find(name); + blink::FontDescription* GetFont(String name) { + auto i = fonts_resolved_.find(name); if (i != fonts_resolved_.end()) { auto add_result = font_lru_list_.PrependOrMoveToFirst(name); DCHECK(!add_result.is_new_entry); @@ -60,7 +60,7 @@ class OffscreenFontCache { } private: - HashMap<String, blink::Font> fonts_resolved_; + HashMap<String, blink::FontDescription> fonts_resolved_; LinkedHashSet<String> font_lru_list_; }; @@ -85,20 +85,14 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D( bernoulli_distribution_(kUMASampleProbability) { is_valid_size_ = IsValidImageSize(Host()->Size()); - StartRecording(); - - // Clear the background transparent or opaque. Similar code at - // CanvasResourceProvider::Clear(). + // Clear the background transparent or opaque. if (IsCanvas2DBufferValid()) { - DCHECK(recorder_); - recorder_->getRecordingCanvas()->clear( - ColorParams().GetOpacityMode() == kOpaque ? SK_ColorBLACK - : SK_ColorTRANSPARENT); + GetCanvasResourceProvider()->Clear(); DidDraw(); } ExecutionContext* execution_context = canvas->GetTopExecutionContext(); - if (auto* document = DynamicTo<Document>(execution_context)) { + if (auto* document = Document::DynamicFrom(execution_context)) { Settings* settings = document->GetSettings(); if (settings && settings->GetDisableReadingFromCanvas()) canvas->SetDisableReadingFromCanvasTrue(); @@ -111,7 +105,7 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D( canvas->SetDisableReadingFromCanvasTrue(); } -void OffscreenCanvasRenderingContext2D::Trace(blink::Visitor* visitor) { +void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) { CanvasRenderingContext::Trace(visitor); BaseRenderingContext2D::Trace(visitor); } @@ -125,31 +119,13 @@ void OffscreenCanvasRenderingContext2D::commit() { GetOffscreenFontCache().PruneLocalFontCache(kMaxCachedFonts); } -void OffscreenCanvasRenderingContext2D::StartRecording() { - recorder_ = std::make_unique<PaintRecorder>(); - - cc::PaintCanvas* canvas = recorder_->beginRecording(Width(), Height()); - // Always save an initial frame, to support resetting the top level matrix - // and clip. - canvas->save(); - - RestoreMatrixClipStack(canvas); -} - void OffscreenCanvasRenderingContext2D::FlushRecording() { - if (!have_recorded_draw_commands_) + if (!GetCanvasResourceProvider() || + !GetCanvasResourceProvider()->HasRecordedDrawOps()) return; - { // Make a new scope so that PaintRecord gets deleted and that gets timed - CanvasResourceProvider* resource_provider = GetCanvasResourceProvider(); - cc::PaintCanvas* canvas = resource_provider->Canvas(); - canvas->drawPicture(recorder_->finishRecordingAsPicture()); - resource_provider->FlushSkia(); - } + GetCanvasResourceProvider()->FlushCanvas(); GetCanvasResourceProvider()->ReleaseLockedImages(); - - StartRecording(); - have_recorded_draw_commands_ = false; } void OffscreenCanvasRenderingContext2D::FinalizeFrame() { @@ -204,7 +180,6 @@ OffscreenCanvasRenderingContext2D::GetCanvasResourceProvider() const { void OffscreenCanvasRenderingContext2D::Reset() { Host()->DiscardResourceProvider(); BaseRenderingContext2D::Reset(); - StartRecording(); // Because the host may have changed to a zero size is_valid_size_ = IsValidImageSize(Host()->Size()); } @@ -256,13 +231,9 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap( return nullptr; } } - - // "Transfer" means no retained buffer. Matrix transformations need to be - // preserved though. Host()->DiscardResourceProvider(); - RestoreMatrixClipStack(recorder_->getRecordingCanvas()); - return ImageBitmap::Create(std::move(image)); + return MakeGarbageCollected<ImageBitmap>(std::move(image)); } scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage( @@ -287,29 +258,30 @@ bool OffscreenCanvasRenderingContext2D::ParseColorOrCurrentColor( return ::blink::ParseColorOrCurrentColor(color, color_string, nullptr); } -cc::PaintCanvas* OffscreenCanvasRenderingContext2D::DrawingCanvas() const { - if (!is_valid_size_) +cc::PaintCanvas* OffscreenCanvasRenderingContext2D::GetOrCreatePaintCanvas() { + if (!is_valid_size_ || !GetOrCreateCanvasResourceProvider()) return nullptr; - return recorder_->getRecordingCanvas(); + return GetPaintCanvas(); } -cc::PaintCanvas* OffscreenCanvasRenderingContext2D::ExistingDrawingCanvas() - const { - if (!is_valid_size_) +cc::PaintCanvas* OffscreenCanvasRenderingContext2D::GetPaintCanvas() const { + if (!is_valid_size_ || !GetCanvasResourceProvider()) return nullptr; - return recorder_->getRecordingCanvas(); + return GetCanvasResourceProvider()->Canvas(); } void OffscreenCanvasRenderingContext2D::DidDraw() { - have_recorded_draw_commands_ = true; - Host()->DidDraw(); dirty_rect_for_commit_.setWH(Width(), Height()); + Host()->DidDraw(); + if (GetCanvasResourceProvider() && GetCanvasResourceProvider()->needs_flush()) + FinalizeFrame(); } void OffscreenCanvasRenderingContext2D::DidDraw(const SkIRect& dirty_rect) { - have_recorded_draw_commands_ = true; dirty_rect_for_commit_.join(dirty_rect); Host()->DidDraw(SkRect::Make(dirty_rect_for_commit_)); + if (GetCanvasResourceProvider() && GetCanvasResourceProvider()->needs_flush()) + FinalizeFrame(); } bool OffscreenCanvasRenderingContext2D::StateHasFilter() { @@ -324,10 +296,11 @@ void OffscreenCanvasRenderingContext2D::SnapshotStateForFilter() { ModifiableState().SetFontForFilter(AccessFont()); } -void OffscreenCanvasRenderingContext2D::ValidateStateStack() const { +void OffscreenCanvasRenderingContext2D::ValidateStateStackWithCanvas( + const cc::PaintCanvas* canvas) const { #if DCHECK_IS_ON() - if (cc::PaintCanvas* sk_canvas = ExistingDrawingCanvas()) { - DCHECK_EQ(static_cast<size_t>(sk_canvas->getSaveCount()), + if (canvas) { + DCHECK_EQ(static_cast<size_t>(canvas->getSaveCount()), state_stack_.size() + 1); } #endif @@ -364,14 +337,6 @@ bool OffscreenCanvasRenderingContext2D::WritePixels( DCHECK(IsPaintable()); FinalizeFrame(); - have_recorded_draw_commands_ = false; - // Add a save to initialize the transform/clip stack and then restore it after - // the draw. This is needed because each recording initializes and the resets - // this state after every flush. - cc::PaintCanvas* canvas = GetCanvasResourceProvider()->Canvas(); - PaintCanvasAutoRestore auto_restore(canvas, true); - if (GetOrCreateCanvasResourceProvider()) - RestoreMatrixClipStack(canvas); return offscreenCanvasForBinding()->ResourceProvider()->WritePixels( orig_info, pixels, row_bytes, x, y); @@ -381,13 +346,16 @@ bool OffscreenCanvasRenderingContext2D::IsAccelerated() const { return IsPaintable() && GetCanvasResourceProvider()->IsAccelerated(); } +void OffscreenCanvasRenderingContext2D::WillOverwriteCanvas() { + GetCanvasResourceProvider()->SkipQueuedDrawCommands(); +} + String OffscreenCanvasRenderingContext2D::font() const { if (!GetState().HasRealizedFont()) return kDefaultFont; StringBuilder serialized_font; - const FontDescription& font_description = - GetState().GetFont().GetFontDescription(); + const FontDescription& font_description = GetState().GetFontDescription(); if (font_description.Style() == ItalicSlopeValue()) serialized_font.Append("italic "); @@ -427,7 +395,7 @@ void OffscreenCanvasRenderingContext2D::setFont(const String& new_font) { base::TimeTicks start_time = base::TimeTicks::Now(); OffscreenFontCache& font_cache = GetOffscreenFontCache(); - Font* cached_font = font_cache.GetFont(new_font); + FontDescription* cached_font = font_cache.GetFont(new_font); if (cached_font) { ModifiableState().SetFont(*cached_font, Host()->GetFontSelector()); } else { @@ -451,10 +419,8 @@ void OffscreenCanvasRenderingContext2D::setFont(const String& new_font) { FontDescription desc = FontStyleResolver::ComputeFont(*style, Host()->GetFontSelector()); - Font font = Font(desc); - - font_cache.AddFont(new_font, font); - ModifiableState().SetFont(font, Host()->GetFontSelector()); + font_cache.AddFont(new_font, desc); + ModifiableState().SetFont(desc, Host()->GetFontSelector()); } ModifiableState().SetUnparsedFont(new_font); if (bernoulli_distribution_(random_generator_)) { @@ -534,8 +500,8 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal( double y, CanvasRenderingContext2DState::PaintType paint_type, double* max_width) { - cc::PaintCanvas* c = DrawingCanvas(); - if (!c) + cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas(); + if (!paint_canvas) return; if (!std::isfinite(x) || !std::isfinite(y)) @@ -591,27 +557,28 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal( if (paint_type == CanvasRenderingContext2DState::kStrokePaintType) InflateStrokeRect(bounds); - int save_count = c->getSaveCount(); + int save_count = paint_canvas->getSaveCount(); if (use_max_width) { - DrawingCanvas()->save(); - DrawingCanvas()->translate(location.X(), location.Y()); + paint_canvas->save(); + paint_canvas->translate(location.X(), location.Y()); // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) // still work. - DrawingCanvas()->scale((font_width > 0 ? (width / font_width) : 0), 1); + paint_canvas->scale((font_width > 0 ? (width / font_width) : 0), 1); location = FloatPoint(); } Draw( [&font, &text_run_paint_info, &location]( - cc::PaintCanvas* c, const PaintFlags* flags) /* draw lambda */ { - font.DrawBidiText(c, text_run_paint_info, location, + cc::PaintCanvas* paint_canvas, + const PaintFlags* flags) /* draw lambda */ { + font.DrawBidiText(paint_canvas, text_run_paint_info, location, Font::kUseFallbackIfFontNotReady, kCDeviceScaleFactor, *flags); }, [](const SkIRect& rect) // overdraw test lambda { return false; }, bounds, paint_type); - c->restoreToCount(save_count); + paint_canvas->restoreToCount(save_count); ValidateStateStack(); } @@ -634,7 +601,7 @@ TextMetrics* OffscreenCanvasRenderingContext2D::measureText( const Font& OffscreenCanvasRenderingContext2D::AccessFont() { if (!GetState().HasRealizedFont()) setFont(GetState().UnparsedFont()); - return GetState().GetFont(); + return ModifiableState().GetFont(); } bool OffscreenCanvasRenderingContext2D::IsCanvas2DBufferValid() const { @@ -642,4 +609,5 @@ bool OffscreenCanvasRenderingContext2D::IsCanvas2DBufferValid() const { return GetCanvasResourceProvider()->IsValid(); return false; } + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h index 5aeed7f7c18..bd98a0a7acf 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h @@ -12,7 +12,6 @@ #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/modules/canvas/canvas2d/base_rendering_context_2d.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h" namespace blink { @@ -100,10 +99,15 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final CanvasResourceProvider* GetOrCreateCanvasResourceProvider() const; CanvasResourceProvider* GetCanvasResourceProvider() const; + // Offscreen canvas doesn't have any notion of image orientation. + RespectImageOrientationEnum RespectImageOrientation() const final { + return kRespectImageOrientation; + } + bool ParseColorOrCurrentColor(Color&, const String& color_string) const final; - cc::PaintCanvas* DrawingCanvas() const final; - cc::PaintCanvas* ExistingDrawingCanvas() const final; + cc::PaintCanvas* GetOrCreatePaintCanvas() final; + cc::PaintCanvas* GetPaintCanvas() const final; void DidDraw() final; void DidDraw(const SkIRect& dirty_rect) final; @@ -112,19 +116,17 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final sk_sp<PaintFilter> StateGetFilter() final; void SnapshotStateForFilter() final; - void ValidateStateStack() const final; + void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const final; bool HasAlpha() const final { return CreationAttributes().alpha; } bool isContextLost() const override; ImageBitmap* TransferToImageBitmap(ScriptState*) final; - void Trace(blink::Visitor*) override; + void Trace(Visitor*) override; bool PushFrame() override; - bool HasRecordedDrawCommands() { return have_recorded_draw_commands_; } - protected: CanvasColorParams ColorParams() const override; bool WritePixels(const SkImageInfo& orig_info, @@ -132,11 +134,9 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final size_t row_bytes, int x, int y) override; + void WillOverwriteCanvas() override; private: - void StartRecording(); - std::unique_ptr<PaintRecorder> recorder_; - bool have_recorded_draw_commands_; void FinalizeFrame() final; void FlushRecording(); @@ -162,12 +162,6 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final std::bernoulli_distribution bernoulli_distribution_; }; -DEFINE_TYPE_CASTS(OffscreenCanvasRenderingContext2D, - CanvasRenderingContext, - context, - context->Is2d() && context->Host(), - context.Is2d() && context.Host()); - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_OFFSCREENCANVAS2D_OFFSCREEN_CANVAS_RENDERING_CONTEXT_2D_H_ diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl index 6555d4c604c..4371777bcd6 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl @@ -23,7 +23,7 @@ void translate(unrestricted double x, unrestricted double y); void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); - [RaisesException] void setTransform(optional DOMMatrix2DInit transform); + [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {}); DOMMatrix getTransform(); void resetTransform(); |