diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/blink/renderer/modules/canvas | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-c30a6232df03e1efbd9f3b226777b07e087a1122.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/canvas')
24 files changed, 393 insertions, 221 deletions
diff --git a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn index 3a4fad46751..1ef75bd432b 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn @@ -9,6 +9,8 @@ blink_modules_sources("canvas") { sources = [ "canvas2d/base_rendering_context_2d.cc", "canvas2d/base_rendering_context_2d.h", + "canvas2d/blink_identifiability_digest_helpers.cc", + "canvas2d/blink_identifiability_digest_helpers.h", "canvas2d/canvas_gradient.cc", "canvas2d/canvas_gradient.h", "canvas2d/canvas_path.cc", @@ -25,6 +27,7 @@ blink_modules_sources("canvas") { "canvas2d/clip_list.h", "canvas2d/hit_region.cc", "canvas2d/hit_region.h", + "canvas2d/identifiability_study_helper.h", "canvas2d/path_2d.h", "htmlcanvas/canvas_context_creation_attributes_helpers.cc", "htmlcanvas/canvas_context_creation_attributes_helpers.h", diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS index 11fa35c31af..a7389356a86 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+services/metrics/public/cpp/ukm_recorder.h", "+third_party/skia/include", ] @@ -7,4 +8,4 @@ specific_include_rules = { ".*_test(_.*)?\.(cc|h)" : [ "+components/viz", ] -}
\ No newline at end of file +} 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 b36da920302..b9837cb73ae 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 @@ -8,6 +8,7 @@ #include <cmath> #include <memory> +#include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/numerics/checked_math.h" #include "third_party/blink/public/common/features.h" @@ -642,7 +643,10 @@ void BaseRenderingContext2D::DrawPathInternal( { c->drawPath(sk_path, *flags); }, [](const SkIRect& rect) // overdraw test lambda { return false; }, - bounds, paint_type); + bounds, paint_type, + GetState().HasPattern(paint_type) + ? CanvasRenderingContext2DState::kNonOpaqueImage + : CanvasRenderingContext2DState::kNoImage); } static SkPathFillType ParseWinding(const String& winding_rule_string) { @@ -699,15 +703,20 @@ void BaseRenderingContext2D::fillRect(double x, // pattern was unaccelerated is because it was not possible to hold that image // in an accelerated texture - that is, into the GPU). That's why we disable // the acceleration to be sure that it will work. - if (IsAccelerated() && GetState().HasPattern() && - !GetState().PatternIsAccelerated()) + if (IsAccelerated() && + GetState().HasPattern(CanvasRenderingContext2DState::kFillPaintType) && + !GetState().PatternIsAccelerated( + CanvasRenderingContext2DState::kFillPaintType)) DisableAcceleration(); SkRect rect = SkRect::MakeXYWH(fx, fy, fwidth, fheight); Draw([&rect](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda { c->drawRect(rect, *flags); }, [&rect, this](const SkIRect& clip_bounds) // overdraw test lambda { return RectContainsTransformedRect(rect, clip_bounds); }, - rect, CanvasRenderingContext2DState::kFillPaintType); + rect, CanvasRenderingContext2DState::kFillPaintType, + GetState().HasPattern(CanvasRenderingContext2DState::kFillPaintType) + ? CanvasRenderingContext2DState::kNonOpaqueImage + : CanvasRenderingContext2DState::kNoImage); } static void StrokeRectOnCanvas(const FloatRect& rect, @@ -755,7 +764,10 @@ void BaseRenderingContext2D::strokeRect(double x, { StrokeRectOnCanvas(rect, c, flags); }, [](const SkIRect& clip_bounds) // overdraw test lambda { return false; }, - bounds, CanvasRenderingContext2DState::kStrokePaintType); + bounds, CanvasRenderingContext2DState::kStrokePaintType, + GetState().HasPattern(CanvasRenderingContext2DState::kStrokePaintType) + ? CanvasRenderingContext2DState::kNonOpaqueImage + : CanvasRenderingContext2DState::kNoImage); } void BaseRenderingContext2D::ClipInternal(const Path& path, @@ -1179,9 +1191,7 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state, FloatSize default_object_size(Width(), Height()); SourceImageStatus source_image_status = kInvalidSourceImageStatus; if (!image_source->IsVideoElement()) { - AccelerationHint hint = - IsAccelerated() ? kPreferAcceleration : kPreferNoAcceleration; - image = image_source->GetSourceImageForCanvas(&source_image_status, hint, + image = image_source->GetSourceImageForCanvas(&source_image_status, default_object_size); if (source_image_status == kUndecodableSourceImageStatus) { exception_state.ThrowDOMException( @@ -1405,8 +1415,7 @@ CanvasPattern* BaseRenderingContext2D::createPattern( FloatSize default_object_size(Width(), Height()); scoped_refptr<Image> image_for_rendering = - image_source->GetSourceImageForCanvas(&status, kPreferNoAcceleration, - default_object_size); + image_source->GetSourceImageForCanvas(&status, default_object_size); switch (status) { case kNormalSourceImageStatus: @@ -1613,7 +1622,7 @@ ImageData* BaseRenderingContext2D::getImageData( // Deferred offscreen canvases might have recorded commands, make sure // that those get drawn here FinalizeFrame(); - scoped_refptr<StaticBitmapImage> snapshot = GetImage(kPreferNoAcceleration); + scoped_refptr<StaticBitmapImage> snapshot = GetImage(); // GetImagedata is faster in Unaccelerated canvases if (IsAccelerated()) @@ -1836,7 +1845,13 @@ void BaseRenderingContext2D::PutByteArray(const unsigned char* source, DCHECK_GE(origin_y, 0); DCHECK_LT(origin_y, source_rect.MaxY()); - const size_t src_bytes_per_row = bytes_per_pixel * source_size.Width(); + const base::CheckedNumeric<size_t> src_bytes_per_row_checked = + base::CheckMul(bytes_per_pixel, source_size.Width()); + if (!src_bytes_per_row_checked.IsValid()) { + VLOG(1) << "Invalid sizes"; + return; + } + const size_t src_bytes_per_row = src_bytes_per_row_checked.ValueOrDie(); const void* src_addr = source + origin_y * src_bytes_per_row + origin_x * bytes_per_pixel; @@ -1997,7 +2012,7 @@ void BaseRenderingContext2D::setTextBaseline(const String& s) { ModifiableState().SetTextBaseline(baseline); } -void BaseRenderingContext2D::Trace(Visitor* visitor) { +void BaseRenderingContext2D::Trace(Visitor* visitor) const { 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 9fd5cb6cb48..de9369d92b0 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,6 +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/bindings/exception_state.h" #include "third_party/blink/renderer/platform/graphics/image_orientation.h" namespace blink { @@ -195,7 +196,11 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, // For deferred canvases this will have the side effect of drawing recorded // commands in order to finalize the frame - ImageData* getImageData(int sx, int sy, int sw, int sh, ExceptionState&); + virtual ImageData* getImageData(int sx, + int sy, + int sw, + int sh, + ExceptionState&); void putImageData(ImageData*, int dx, int dy, ExceptionState&); void putImageData(ImageData*, int dx, @@ -264,7 +269,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, String textBaseline() const; void setTextBaseline(const String&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; enum DrawCallType { kStrokePath = 0, @@ -332,8 +337,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, const ContainsFunc&, const SkRect& bounds, CanvasRenderingContext2DState::PaintType, - CanvasRenderingContext2DState::ImageType = - CanvasRenderingContext2DState::kNoImage); + CanvasRenderingContext2DState::ImageType); void InflateStrokeRect(FloatRect&) const; @@ -348,7 +352,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, NOTREACHED(); return false; } - virtual scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) { + virtual scoped_refptr<StaticBitmapImage> GetImage() { NOTREACHED(); return nullptr; } @@ -387,6 +391,19 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, bool ShouldDrawImageAntialiased(const FloatRect& dest_rect) const; + // When the canvas is stroked or filled with a pattern, which is assumed to + // have a transparent background, the shadow needs to be applied with + // DropShadowPaintFilter for kNonOpaqueImageType + // Used in Draw and CompositedDraw to avoid the shadow offset being modified + // by the transformation matrix + bool ShouldUseDropShadowPaintFilter( + CanvasRenderingContext2DState::PaintType paint_type, + CanvasRenderingContext2DState::ImageType image_type) const { + return (paint_type == CanvasRenderingContext2DState::kFillPaintType || + paint_type == CanvasRenderingContext2DState::kStrokePaintType) && + image_type == CanvasRenderingContext2DState::kNonOpaqueImage; + } + void DrawPathInternal(const Path&, CanvasRenderingContext2DState::PaintType, SkPathFillType = SkPathFillType::kWinding); @@ -461,7 +478,9 @@ void BaseRenderingContext2D::Draw( return; if (IsFullCanvasCompositeMode(GetState().GlobalComposite()) || - StateHasFilter()) { + StateHasFilter() || + (GetState().ShouldDrawShadows() && + ShouldUseDropShadowPaintFilter(paint_type, image_type))) { CompositedDraw(draw_func, GetPaintCanvas(), paint_type, image_type); DidDraw(clip_bounds); } else if (GetState().GlobalComposite() == SkBlendMode::kSrc) { @@ -490,8 +509,11 @@ void BaseRenderingContext2D::CompositedDraw( cc::PaintCanvas* c, CanvasRenderingContext2DState::PaintType paint_type, CanvasRenderingContext2DState::ImageType image_type) { - sk_sp<PaintFilter> filter = StateGetFilter(); - DCHECK(IsFullCanvasCompositeMode(GetState().GlobalComposite()) || filter); + sk_sp<PaintFilter> canvas_filter = StateGetFilter(); + DCHECK(IsFullCanvasCompositeMode(GetState().GlobalComposite()) || + canvas_filter || + (GetState().ShouldDrawShadows() && + ShouldUseDropShadowPaintFilter(paint_type, image_type))); SkMatrix ctm = c->getTotalMatrix(); c->setMatrix(SkMatrix::I()); PaintFlags composite_flags; @@ -502,13 +524,14 @@ void BaseRenderingContext2D::CompositedDraw( *GetState().GetFlags(paint_type, kDrawShadowOnly, image_type); int save_count = c->getSaveCount(); c->save(); - if (filter) { + if (canvas_filter || + ShouldUseDropShadowPaintFilter(paint_type, image_type)) { PaintFlags foreground_flags = *GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type); shadow_flags.setImageFilter(sk_make_sp<ComposePaintFilter>( sk_make_sp<ComposePaintFilter>(foreground_flags.getImageFilter(), shadow_flags.getImageFilter()), - filter)); + canvas_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); @@ -524,7 +547,7 @@ void BaseRenderingContext2D::CompositedDraw( c->restoreToCount(save_count); } - composite_flags.setImageFilter(std::move(filter)); + composite_flags.setImageFilter(std::move(canvas_filter)); c->saveLayer(nullptr, &composite_flags); PaintFlags foreground_flags = *GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc new file mode 100644 index 00000000000..89d1e8051dc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc @@ -0,0 +1,34 @@ +// 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/blink_identifiability_digest_helpers.h" + +#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" +#include "third_party/blink/renderer/platform/wtf/shared_buffer.h" +#include "third_party/blink/renderer/platform/wtf/text/string_hash.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +// Arbitrary value chosen to represent null strings. +constexpr uint64_t kNullStringDigest = 6554271438612835841L; + +uint64_t IdentifiabilityDigestHelper(const String& in) { + if (in.IsNull()) + return kNullStringDigest; + // Return the precomputed hash for the string. This makes this method O(1) + // instead of O(n), at the cost of only using the lower 32 bits of the hash. + return StringHash::GetHash(in); +} + +uint16_t IdentifiabilitySensitiveString(const String& in) { + if (in.IsNull()) + return static_cast<uint16_t>(kNullStringDigest); + // Take the precomputed 32-bit hash, and xor the top and bottom halves to + // produce a 16-bit hash. + const uint32_t original_hash = StringHash::GetHash(in); + return ((original_hash & 0xFFFF0000) >> 16) ^ (original_hash & 0xFFFF); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h new file mode 100644 index 00000000000..56c6ef4845e --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h @@ -0,0 +1,30 @@ +// 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_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_ + +#include "third_party/blink/renderer/platform/wtf/forward.h" + +// Provide additional overloads of IdentifiabilityDigestHelper() for +// blink-internal types. +// +// *NOTE*: This header extends the functionality of +// third_party/blink/public/common/privacy_budget/identifiability_metrics.h +// -- it must be included before that header. + +// TODO(crbug.com/973801): Consider moving to another directory. + +namespace blink { + +uint64_t IdentifiabilityDigestHelper(const String&); + +// For sensitive strings, this function narrows the hash width to 16 bits. This +// 16-bit value can be combined with other values using the parameter-pack +// IdentifiabilityDigestHelper() overload. +uint16_t IdentifiabilitySensitiveString(const String&); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_ 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 e916fc83dab..d4e0d5d0657 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 @@ -36,6 +36,8 @@ #include "base/metrics/histogram_functions.h" #include "base/rand_util.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h" @@ -48,6 +50,7 @@ #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/events/mouse_event.h" #include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h" #include "third_party/blink/renderer/core/html/canvas/text_metrics.h" #include "third_party/blink/renderer/core/layout/hit_test_canvas_result.h" @@ -133,7 +136,9 @@ CanvasRenderingContext2D::CanvasRenderingContext2D( &CanvasRenderingContext2D::TryRestoreContextEvent), should_prune_local_font_cache_(false), random_generator_((uint32_t)base::RandUint64()), - bernoulli_distribution_(kRasterMetricProbability) { + bernoulli_distribution_(kRasterMetricProbability), + ukm_recorder_(canvas->GetDocument().UkmRecorder()), + ukm_source_id_(canvas->GetDocument().UkmSourceID()) { if (canvas->GetDocument().GetSettings() && canvas->GetDocument().GetSettings()->GetAntialiasedClips2dCanvasEnabled()) clip_antialiasing_ = kAntiAliased; @@ -223,7 +228,7 @@ void CanvasRenderingContext2D::DidSetSurfaceSize() { } } -void CanvasRenderingContext2D::Trace(Visitor* visitor) { +void CanvasRenderingContext2D::Trace(Visitor* visitor) const { visitor->Trace(hit_region_manager_); visitor->Trace(filter_operations_); CanvasRenderingContext::Trace(visitor); @@ -497,6 +502,8 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { // documents. if (!canvas()->GetDocument().GetFrame()) return; + identifiability_study_helper_.MaybeUpdateDigest(CanvasOps::kSetFont, + new_font); base::TimeTicks start_time = base::TimeTicks::Now(); canvas()->GetDocument().UpdateStyleAndLayoutTreeForNode(canvas()); @@ -570,9 +577,8 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { } // The parse succeeded. - String new_font_safe_copy( - new_font); // Create a string copy since newFont can be - // deleted inside realizeSaves. + String new_font_safe_copy(new_font); // Create a string copy since newFont + // can be deleted inside realizeSaves. ModifiableState().SetUnparsedFont(new_font_safe_copy); if (bernoulli_distribution_(random_generator_)) { base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; @@ -662,11 +668,25 @@ bool CanvasRenderingContext2D::CanCreateCanvas2dResourceProvider() const { return canvas()->GetOrCreateCanvas2DLayerBridge(); } -scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage( - AccelerationHint hint) { +scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage() { if (!IsPaintable()) return nullptr; - return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot(hint); + return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot(); +} + +ImageData* CanvasRenderingContext2D::getImageData( + int sx, + int sy, + int sw, + int sh, + ExceptionState& exception_state) { + blink::IdentifiabilityMetricBuilder(ukm_source_id_) + .Set(blink::IdentifiableSurface::FromTypeAndInput( + blink::IdentifiableSurface::Type::kCanvasReadback, + GetContextType()), + 0) + .Record(ukm_recorder_); + return BaseRenderingContext2D::getImageData(sx, sy, sw, sh, exception_state); } void CanvasRenderingContext2D::FinalizeFrame() { @@ -845,6 +865,12 @@ void CanvasRenderingContext2D::DrawTextInternal( if (max_width && (!std::isfinite(*max_width) || *max_width <= 0)) return; + identifiability_study_helper_.MaybeUpdateDigest( + paint_type == CanvasRenderingContext2DState::kFillPaintType + ? CanvasOps::kFillText + : CanvasOps::kStrokeText, + IdentifiabilitySensitiveString(text), x, y, max_width ? *max_width : -1); + const Font& font = AccessFont(); const SimpleFontData* font_data = font.PrimaryFont(); DCHECK(font_data); @@ -919,7 +945,7 @@ void CanvasRenderingContext2D::DrawTextInternal( }, [](const SkIRect& rect) // overdraw test lambda { return false; }, - bounds, paint_type); + bounds, paint_type, CanvasRenderingContext2DState::kNoImage); } const Font& CanvasRenderingContext2D::AccessFont() { @@ -963,6 +989,8 @@ CanvasRenderingContext2D::getContextAttributes() const { settings->setPixelFormat(PixelFormatAsString()); } settings->setDesynchronized(Host()->LowLatencyEnabled()); + if (RuntimeEnabledFeatures::NewCanvas2DAPIEnabled()) + settings->setWillReadFrequently(CreationAttributes().will_read_frequently); return settings; } 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 bda1b439ed3..5bc40f38019 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,15 +30,19 @@ #include <random> #include "base/macros.h" +#include "services/metrics/public/cpp/ukm_recorder.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/html/canvas/image_data.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_state.h" +#include "third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -184,7 +188,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final cc::PaintCanvas* GetPaintCanvas() const final; void DidDraw(const SkIRect& dirty_rect) final; - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; + scoped_refptr<StaticBitmapImage> GetImage() final; bool StateHasFilter() final; sk_sp<PaintFilter> StateGetFilter() final; @@ -200,10 +204,20 @@ class MODULES_EXPORT CanvasRenderingContext2D final void WillDrawImage(CanvasImageSource*) const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; + + ImageData* getImageData(int sx, + int sy, + int sw, + int sh, + ExceptionState&) override; CanvasColorParams ColorParamsForTest() const { return ColorParams(); } + uint64_t IdentifiabilityTextDigest() override { + return identifiability_study_helper_.digest(); + } + protected: CanvasColorParams ColorParams() const override; bool WritePixels(const SkImageInfo& orig_info, @@ -244,7 +258,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final String ColorSpaceAsString() const override; CanvasPixelFormat PixelFormat() const override; - bool Is2d() const override { return true; } + bool IsRenderingContext2D() const override { return true; } bool IsComposited() const override; bool IsAccelerated() const override; bool IsOriginTopLeft() const override; @@ -276,6 +290,11 @@ class MODULES_EXPORT CanvasRenderingContext2D final static constexpr float kRasterMetricProbability = 0.01; std::mt19937 random_generator_; std::bernoulli_distribution bernoulli_distribution_; + + IdentifiabilityStudyHelper identifiability_study_helper_; + + ukm::UkmRecorder* ukm_recorder_; + ukm::SourceId ukm_source_id_; }; } // namespace blink 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 79a5ddca35d..50575304842 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 @@ -46,7 +46,7 @@ CanvasRenderingContext2D* CanvasRenderingContext2DAPITest::Context2D() const { // If the following check fails, perhaps you forgot to call createContext // in your test? EXPECT_NE(nullptr, CanvasElement().RenderingContext()); - EXPECT_TRUE(CanvasElement().RenderingContext()->Is2d()); + EXPECT_TRUE(CanvasElement().RenderingContext()->IsRenderingContext2D()); return static_cast<CanvasRenderingContext2D*>( CanvasElement().RenderingContext()); } @@ -318,7 +318,7 @@ void ResetCanvasForAccessibilityRectTest(Document& document) { canvas->GetCanvasRenderingContext(canvas_type, attributes); EXPECT_NE(nullptr, canvas->RenderingContext()); - EXPECT_TRUE(canvas->RenderingContext()->Is2d()); + EXPECT_TRUE(canvas->RenderingContext()->IsRenderingContext2D()); } TEST_F(CanvasRenderingContext2DAPITest, AccessibilityRectTestForAddHitRegion) { diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl index be91d92a97b..d8bd1c01547 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl @@ -10,5 +10,6 @@ dictionary CanvasRenderingContext2DSettings { [RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb"; [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8"; [RuntimeEnabled=SurfaceEmbeddingFeatures] boolean desynchronized = false; + [RuntimeEnabled=NewCanvas2DAPI] boolean willReadFrequently = false; }; 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 3b2e419bde0..316014a4c06 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 @@ -136,7 +136,7 @@ void CanvasRenderingContext2DState::FontsNeedUpdate(FontSelector* font_selector, resolved_filter_.reset(); } -void CanvasRenderingContext2DState::Trace(Visitor* visitor) { +void CanvasRenderingContext2DState::Trace(Visitor* visitor) const { visitor->Trace(stroke_style_); visitor->Trace(fill_style_); visitor->Trace(filter_value_); @@ -638,15 +638,16 @@ const PaintFlags* CanvasRenderingContext2DState::GetFlags( return flags; } -bool CanvasRenderingContext2DState::HasPattern() const { - return FillStyle() && FillStyle()->GetCanvasPattern() && - FillStyle()->GetCanvasPattern()->GetPattern(); +bool CanvasRenderingContext2DState::HasPattern(PaintType paint_type) const { + return Style(paint_type) && Style(paint_type)->GetCanvasPattern() && + Style(paint_type)->GetCanvasPattern()->GetPattern(); } // Only to be used if the CanvasRenderingContext2DState has Pattern -bool CanvasRenderingContext2DState::PatternIsAccelerated() const { - DCHECK(HasPattern()); - return FillStyle()->GetCanvasPattern()->GetPattern()->IsTextureBacked(); +bool CanvasRenderingContext2DState::PatternIsAccelerated( + PaintType paint_type) const { + DCHECK(HasPattern(paint_type)); + return Style(paint_type)->GetCanvasPattern()->GetPattern()->IsTextureBacked(); } } // namespace blink 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 abfb18fed68..efaafed0a9c 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(Visitor*) override; + void Trace(Visitor*) const override; enum PaintType { kFillPaintType, @@ -110,12 +110,16 @@ class CanvasRenderingContext2DState final void SetFillStyle(CanvasStyle*); CanvasStyle* FillStyle() const { return fill_style_.Get(); } + // Prefer to use Style() over StrokeStyle() and FillStyle() + // if properties of CanvasStyle are concerned CanvasStyle* Style(PaintType) const; - bool HasPattern() const; + // Check the pattern in StrokeStyle or FillStyle depending on the PaintType + bool HasPattern(PaintType) const; // Only to be used if the CanvasRenderingContext2DState has Pattern - bool PatternIsAccelerated() const; + // Pattern is in either StrokeStyle or FillStyle depending on the PaintType + bool PatternIsAccelerated(PaintType) const; enum Direction { kDirectionInherit, kDirectionRTL, kDirectionLTR }; 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 3d1c70fbfff..5d9f02205e9 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 @@ -65,7 +65,6 @@ class FakeImageSource : public CanvasImageSource { FakeImageSource(IntSize, BitmapOpacity); scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, - AccelerationHint, const FloatSize&) override; bool WouldTaintOrigin() const override { return false; } @@ -95,7 +94,6 @@ FakeImageSource::FakeImageSource(IntSize size, BitmapOpacity opacity) scoped_refptr<Image> FakeImageSource::GetSourceImageForCanvas( SourceImageStatus* status, - AccelerationHint, const FloatSize&) { if (status) *status = kNormalSourceImageStatus; @@ -104,8 +102,6 @@ scoped_refptr<Image> FakeImageSource::GetSourceImageForCanvas( //============================================================================ -enum LinearPixelMathState { kLinearPixelMathDisabled, kLinearPixelMathEnabled }; - class CanvasRenderingContext2DTest : public ::testing::Test { protected: CanvasRenderingContext2DTest(); @@ -130,21 +126,24 @@ class CanvasRenderingContext2DTest : public ::testing::Test { Context2D()->FinalizeFrame(); CanvasElement().PostFinalizeFrame(); // Grabbing an image forces a flush - CanvasElement().Snapshot(kBackBuffer, kPreferAcceleration); + CanvasElement().Snapshot(kBackBuffer); } enum LatencyMode { kNormalLatency, kLowLatency }; - void CreateContext(OpacityMode, LatencyMode = kNormalLatency); + enum class ReadFrequencyMode { kWillReadFrequency, kWillNotReadFrequency }; + + void CreateContext( + OpacityMode, + LatencyMode = kNormalLatency, + ReadFrequencyMode = ReadFrequencyMode::kWillNotReadFrequency); ScriptState* GetScriptState() { return ToScriptStateForMainWorld(canvas_element_->GetFrame()); } void TearDown() override; void UnrefCanvas(); - std::unique_ptr<Canvas2DLayerBridge> MakeBridge( - const IntSize&, - Canvas2DLayerBridge::AccelerationMode); + std::unique_ptr<Canvas2DLayerBridge> MakeBridge(const IntSize&, RasterMode); Document& GetDocument() const { return *web_view_helper_->GetWebView() @@ -168,7 +167,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test { class WrapGradients final : public GarbageCollected<WrapGradients> { public: - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(opaque_gradient_); visitor->Trace(alpha_gradient_); } @@ -202,12 +201,16 @@ CanvasRenderingContext2DTest::CanvasRenderingContext2DTest() opaque_bitmap_(IntSize(10, 10), kOpaqueBitmap), alpha_bitmap_(IntSize(10, 10), kTransparentBitmap) {} -void CanvasRenderingContext2DTest::CreateContext(OpacityMode opacity_mode, - LatencyMode latency_mode) { +void CanvasRenderingContext2DTest::CreateContext( + OpacityMode opacity_mode, + LatencyMode latency_mode, + ReadFrequencyMode read_frequency_mode) { String canvas_type("2d"); CanvasContextCreationAttributesCore attributes; attributes.alpha = opacity_mode == kNonOpaque; attributes.desynchronized = latency_mode == kLowLatency; + attributes.will_read_frequently = + read_frequency_mode == ReadFrequencyMode::kWillReadFrequency; canvas_element_->GetCanvasRenderingContext(canvas_type, attributes); } @@ -273,9 +276,9 @@ void CanvasRenderingContext2DTest::TearDown() { std::unique_ptr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::MakeBridge( const IntSize& size, - Canvas2DLayerBridge::AccelerationMode acceleration_mode) { + RasterMode raster_mode) { std::unique_ptr<Canvas2DLayerBridge> bridge = - std::make_unique<Canvas2DLayerBridge>(size, acceleration_mode, + std::make_unique<Canvas2DLayerBridge>(size, raster_mode, CanvasColorParams()); bridge->SetCanvasResourceHost(canvas_element_); return bridge; @@ -287,9 +290,9 @@ class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge { public: FakeCanvas2DLayerBridge(const IntSize& size, CanvasColorParams color_params, - AccelerationHint hint) - : Canvas2DLayerBridge(size, kDisableAcceleration, color_params), - is_accelerated_(hint != kPreferNoAcceleration) {} + RasterModeHint hint) + : Canvas2DLayerBridge(size, RasterMode::kCPU, color_params), + is_accelerated_(hint != RasterModeHint::kPreferCPU) {} ~FakeCanvas2DLayerBridge() override = default; bool IsAccelerated() const override { return is_accelerated_; } void SetIsAccelerated(bool is_accelerated) { @@ -309,16 +312,15 @@ class FakeCanvasResourceProvider : public CanvasResourceProvider { public: FakeCanvasResourceProvider(const IntSize& size, CanvasColorParams color_params, - AccelerationHint hint) + RasterModeHint hint) : CanvasResourceProvider(CanvasResourceProvider::kBitmap, size, - /*msaa_sample_count=*/0, kLow_SkFilterQuality, color_params, /*is_origin_top_left=*/false, nullptr, nullptr), - is_accelerated_(hint != kPreferNoAcceleration) {} + is_accelerated_(hint != RasterModeHint::kPreferCPU) {} ~FakeCanvasResourceProvider() override = default; bool IsAccelerated() const override { return is_accelerated_; } scoped_refptr<CanvasResource> ProduceCanvasResource() override { @@ -344,9 +346,7 @@ class MockImageBufferSurfaceForOverwriteTesting : public Canvas2DLayerBridge { public: MockImageBufferSurfaceForOverwriteTesting(const IntSize& size, CanvasColorParams color_params) - : Canvas2DLayerBridge(size, - Canvas2DLayerBridge::kDisableAcceleration, - color_params) {} + : Canvas2DLayerBridge(size, RasterMode::kCPU, color_params) {} ~MockImageBufferSurfaceForOverwriteTesting() override = default; MOCK_METHOD0(WillOverwriteCanvas, void()); }; @@ -610,10 +610,10 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) { IntSize size(10, 10); std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider = std::make_unique<FakeCanvasResourceProvider>(size, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge = std::make_unique<FakeCanvas2DLayerBridge>(size, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); FakeCanvas2DLayerBridge* fake_2d_layer_bridge_ptr = fake_2d_layer_bridge.get(); CanvasElement().SetResourceProviderForTesting( @@ -638,10 +638,10 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) { IntSize size2(10, 5); std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge2 = std::make_unique<FakeCanvas2DLayerBridge>(size2, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider2 = std::make_unique<FakeCanvasResourceProvider>(size2, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); anotherCanvas->SetResourceProviderForTesting( std::move(fake_resource_provider2), std::move(fake_2d_layer_bridge2), size2); @@ -686,7 +686,7 @@ TEST_F(CanvasRenderingContext2DTest, CreateContext(kNonOpaque); IntSize size(10, 10); auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferGPU); CanvasElement().SetResourceProviderForTesting( nullptr, std::move(fake_accelerate_surface), size); @@ -700,7 +700,7 @@ TEST_F(CanvasRenderingContext2DTest, IntSize size(10, 10); auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferGPU); CanvasElement().SetResourceProviderForTesting( nullptr, std::move(fake_accelerate_surface), size); CanvasRenderingContext2D* context = Context2D(); @@ -727,13 +727,13 @@ TEST_F(CanvasRenderingContext2DTest, CreateContext(kNonOpaque); IntSize size(10, 10); auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferGPU); CanvasElement().SetResourceProviderForTesting( nullptr, std::move(fake_accelerate_surface), size); FakeCanvasResourceHost host(size); auto fake_deaccelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferNoAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferCPU); fake_deaccelerate_surface->SetCanvasResourceHost(&host); FakeCanvas2DLayerBridge* surface_ptr = fake_deaccelerate_surface.get(); @@ -844,12 +844,6 @@ static void TestDrawHighBitDepthPNGsOnWideGamutCanvas( } } -TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnLinearRGBCanvas) { - TestDrawHighBitDepthPNGsOnWideGamutCanvas( - "linear-rgb", GetDocument(), - Persistent<HTMLCanvasElement>(CanvasElement()), GetScriptState()); -} - TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnP3Canvas) { TestDrawHighBitDepthPNGsOnWideGamutCanvas( "p3", GetDocument(), Persistent<HTMLCanvasElement>(CanvasElement()), @@ -862,92 +856,14 @@ TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnRec2020Canvas) { GetScriptState()); } -TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { - Persistent<HTMLCanvasElement> canvas = - Persistent<HTMLCanvasElement>(CanvasElement()); - CanvasContextCreationAttributesCore attributes; - attributes.alpha = true; - attributes.color_space = "srgb"; - CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>( - canvas->GetCanvasRenderingContext("2d", attributes)); - StringOrCanvasGradientOrCanvasPattern fill_style; - fill_style.SetString("#FFC08040"); // 255,192,128,64 - context->setFillStyle(fill_style); - context->fillRect(0, 0, 1, 1); - scoped_refptr<StaticBitmapImage> snapshot = - canvas->Snapshot(kFrontBuffer, kPreferNoAcceleration); - ASSERT_TRUE(snapshot); - sk_sp<SkImage> source_image = - snapshot->PaintImageForCurrentFrame().GetSkImage(); - SkPixmap source_pixmap; - source_image->peekPixels(&source_pixmap); - - // Create and test the ImageBitmap objects. - base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1); - for (int conversion_iterator = kColorSpaceConversion_Default; - conversion_iterator <= kColorSpaceConversion_Last; - conversion_iterator++) { - // TODO(crbug.com/898631): Do not test "preserve" which - // is not a valid value of ColorSpaceConversion. - if (conversion_iterator == kColorSpaceConversion_Preserve) - continue; - - // Color convert using ImageBitmap - ImageBitmapOptions* options = ImageBitmapOptions::Create(); - options->setColorSpaceConversion( - ColorCorrectionTestUtils::ColorSpaceConversionToString( - static_cast<ColorSpaceConversion>(conversion_iterator))); - ImageBitmap* image_bitmap = - MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, options); - ASSERT_TRUE(image_bitmap); - sk_sp<SkImage> converted_image = - image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage(); - ASSERT_TRUE(converted_image); - SkPixmap converted_pixmap; - converted_image->peekPixels(&converted_pixmap); - ASSERT_TRUE(converted_pixmap.addr()); - - // Manual color convert for testing - sk_sp<SkColorSpace> color_space = - ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace( - static_cast<ColorSpaceConversion>(conversion_iterator)); - if (conversion_iterator == kColorSpaceConversion_Preserve) - color_space = SkColorSpace::MakeSRGB(); - - // TODO: crbug.com/768855: Remove if statement when CanvasResourceProvider - // does not use SkColorSpaceXformCanvas (which rips off sRGB from - // ImageBitmap). - if (!color_space->isSRGB()) { - EXPECT_TRUE(SkColorSpace::Equals(color_space.get(), - converted_image->colorSpace())); - } - - SkColorType color_type = SkColorType::kN32_SkColorType; - if (color_space && color_space->gammaIsLinear()) - color_type = kRGBA_F16_SkColorType; - SkImageInfo image_info = SkImageInfo::Make( - 1, 1, color_type, SkAlphaType::kPremul_SkAlphaType, color_space); - SkBitmap manual_converted_bitmap; - EXPECT_TRUE(manual_converted_bitmap.tryAllocPixels(image_info)); - source_pixmap.readPixels(manual_converted_bitmap.pixmap(), 0, 0); - - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - converted_pixmap.addr(), manual_converted_bitmap.pixmap().addr(), 1, - (color_type == kN32_SkColorType) ? kPixelFormat_8888 - : kPixelFormat_hhhh, - kAlphaMultiplied, kNoUnpremulRoundTripTolerance); - } -} - // The color settings of the surface of the canvas always remaines loyal to the // first created context 2D. Therefore, we have to test different canvas color // space settings for CanvasRenderingContext2D::putImageData() in different // tests. enum class CanvasColorSpaceSettings : uint8_t { CANVAS_SRGB = 0, - CANVAS_LINEARSRGB = 1, - CANVAS_REC2020 = 2, - CANVAS_P3 = 3, + CANVAS_REC2020 = 1, + CANVAS_P3 = 2, LAST = CANVAS_P3 }; @@ -957,10 +873,9 @@ enum class CanvasColorSpaceSettings : uint8_t { void TestPutImageDataOnCanvasWithColorSpaceSettings( HTMLCanvasElement& canvas_element, CanvasColorSpaceSettings canvas_colorspace_setting) { - unsigned num_image_data_color_spaces = 4; + unsigned num_image_data_color_spaces = 3; CanvasColorSpace image_data_color_spaces[] = { CanvasColorSpace::kSRGB, - CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020, CanvasColorSpace::kP3, }; @@ -972,19 +887,20 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings( }; CanvasColorSpace canvas_color_spaces[] = { - CanvasColorSpace::kSRGB, CanvasColorSpace::kSRGB, - CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020, + CanvasColorSpace::kSRGB, + CanvasColorSpace::kSRGB, + CanvasColorSpace::kRec2020, CanvasColorSpace::kP3, }; String canvas_color_space_names[] = { kSRGBCanvasColorSpaceName, kSRGBCanvasColorSpaceName, - kLinearRGBCanvasColorSpaceName, kRec2020CanvasColorSpaceName, - kP3CanvasColorSpaceName}; + kRec2020CanvasColorSpaceName, kP3CanvasColorSpaceName}; CanvasPixelFormat canvas_pixel_formats[] = { - CanvasPixelFormat::kRGBA8, CanvasPixelFormat::kF16, - CanvasPixelFormat::kF16, CanvasPixelFormat::kF16, + CanvasPixelFormat::kRGBA8, + CanvasPixelFormat::kF16, + CanvasPixelFormat::kF16, CanvasPixelFormat::kF16, }; @@ -1103,12 +1019,6 @@ TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnSRGBCanvas) { CanvasElement(), CanvasColorSpaceSettings::CANVAS_SRGB); } -TEST_F(CanvasRenderingContext2DTest, - ColorManagedPutImageDataOnLinearSRGBCanvas) { - TestPutImageDataOnCanvasWithColorSpaceSettings( - CanvasElement(), CanvasColorSpaceSettings::CANVAS_LINEARSRGB); -} - TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnRec2020Canvas) { TestPutImageDataOnCanvasWithColorSpaceSettings( CanvasElement(), CanvasColorSpaceSettings::CANVAS_REC2020); @@ -1126,9 +1036,29 @@ TEST_F(CanvasRenderingContext2DTest, DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); - EXPECT_FALSE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferNoAcceleration) - ->SupportsSingleBuffering()); + EXPECT_FALSE( + CanvasElement() + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferCPU) + ->SupportsSingleBuffering()); + EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); +} + +TEST_F(CanvasRenderingContext2DTest, + UnacceleratedIfNormalLatencyWillReadFrequently) { + CreateContext(kNonOpaque, kNormalLatency, + ReadFrequencyMode::kWillReadFrequency); + DrawSomething(); + EXPECT_TRUE(Context2D()->getContextAttributes()->willReadFrequently()); + EXPECT_FALSE( + CanvasElement().GetOrCreateCanvas2DLayerBridge()->IsAccelerated()); +} + +TEST_F(CanvasRenderingContext2DTest, + UnacceleratedIfLowLatencyWillReadFrequently) { + CreateContext(kNonOpaque, kLowLatency, ReadFrequencyMode::kWillReadFrequency); + // No need to set-up the layer bridge when testing low latency mode. + DrawSomething(); + EXPECT_TRUE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); } @@ -1146,8 +1076,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, CreateContext(kNonOpaque); IntSize size(300, 300); std::unique_ptr<Canvas2DLayerBridge> bridge = - std::make_unique<Canvas2DLayerBridge>( - size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); + std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU, + CanvasColorParams()); // Force hibernatation to occur in an immediate task. bridge->DontUseIdleSchedulingForTesting(); CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge), @@ -1157,8 +1087,7 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); // Take a snapshot to trigger lazy resource provider creation - CanvasElement().GetCanvas2DLayerBridge()->NewImageSnapshot( - kPreferAcceleration); + CanvasElement().GetCanvas2DLayerBridge()->NewImageSnapshot(); EXPECT_TRUE(!!CanvasElement().ResourceProvider()); EXPECT_TRUE(CanvasElement().ResourceProvider()->IsAccelerated()); EXPECT_TRUE(CanvasElement().GetLayoutBoxModelObject()); @@ -1196,8 +1125,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, CreateContext(kNonOpaque); IntSize size(300, 300); std::unique_ptr<Canvas2DLayerBridge> bridge = - std::make_unique<Canvas2DLayerBridge>( - size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); + std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU, + CanvasColorParams()); // Force hibernatation to occur in an immediate task. bridge->DontUseIdleSchedulingForTesting(); CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge), @@ -1230,10 +1159,12 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, LowLatencyIsNotSingleBuffered) { // No need to set-up the layer bridge when testing low latency mode. DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); + EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); - EXPECT_FALSE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) - ->SupportsSingleBuffering()); + EXPECT_FALSE( + CanvasElement() + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) + ->SupportsSingleBuffering()); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); } @@ -1268,20 +1199,21 @@ TEST_F(CanvasRenderingContext2DTestImageChromium, LowLatencyIsSingleBuffered) { // No need to set-up the layer bridge when testing low latency mode. DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); + EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); EXPECT_TRUE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->SupportsSingleBuffering()); auto frame1_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame1_resource); DrawSomething(); auto frame2_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame2_resource); EXPECT_EQ(frame1_resource.get(), frame2_resource.get()); @@ -1312,20 +1244,21 @@ TEST_F(CanvasRenderingContext2DTestSwapChain, LowLatencyIsSingleBuffered) { // No need to set-up the layer bridge when testing low latency mode. DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); + EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); EXPECT_TRUE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->SupportsSingleBuffering()); auto frame1_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame1_resource); DrawSomething(); auto frame2_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame2_resource); EXPECT_EQ(frame1_resource.get(), frame2_resource.get()); 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 db362e3bd6f..9c728290626 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 @@ -133,7 +133,7 @@ RGBA32 CanvasStyle::PaintColor() const { return Color::kBlack; } -void CanvasStyle::Trace(Visitor* visitor) { +void CanvasStyle::Trace(Visitor* visitor) const { 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 fca9d07f187..9d500ad1bf4 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 @@ -59,7 +59,7 @@ class CanvasStyle final : public GarbageCollected<CanvasStyle> { return type_ == kColorRGBA && rgba_ == rgba; } - void Trace(Visitor*); + void Trace(Visitor*) const; 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 ab288595cb0..a9b0a45c73e 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(Visitor* visitor) { +void HitRegion::Trace(Visitor* visitor) const { visitor->Trace(control_); } @@ -118,7 +118,7 @@ unsigned HitRegionManager::GetHitRegionsCount() const { return hit_region_list_.size(); } -void HitRegionManager::Trace(Visitor* visitor) { +void HitRegionManager::Trace(Visitor* visitor) const { 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 968009a8535..dc5b137b311 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 @@ -28,7 +28,7 @@ class HitRegion final : public GarbageCollected<HitRegion> { const Path& GetPath() const { return path_; } Element* Control() const { return control_.Get(); } - void Trace(Visitor*); + void Trace(Visitor*) const; private: String id_; @@ -56,7 +56,7 @@ class HitRegionManager final : public GarbageCollected<HitRegionManager> { unsigned GetHitRegionsCount() const; - void Trace(Visitor*); + void Trace(Visitor*) const; private: typedef HeapLinkedHashSet<Member<HitRegion>> HitRegionList; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h new file mode 100644 index 00000000000..e39074ee39d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h @@ -0,0 +1,61 @@ +// 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_IDENTIFIABILITY_STUDY_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_ + +#include <stdint.h> + +// Must be included before identifiable_surface.h. +#include "third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h" + +#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h" + +namespace blink { + +// Text operations supported on different canvas types; the intent is to use +// these values (and any input supplied to these operations) to build a running +// hash that reprensents the sequence of text operations performed on the +// canvas. A hash of all other canvas operations is maintained by hashing the +// serialized PaintOps produced by the canvas in CanvasResourceProvider. +// +// If a canvas method to exfiltrate the canvas buffer is called by a script +// (getData(), etc.), this hash will be uploaded to UKM along with a hash of the +// canvas buffer data. +// +// **Don't renumber after the privacy budget study has started to ensure +// consistency.** +enum class CanvasOps { + // CanvasRenderingContext2D / OffscreenCanvasRenderingContext2D methods. + kSetFont, + kFillText, + kStrokeText, +}; + +// A helper class to simplify maintaining the current text digest for the canvas +// context. An operation count is also maintained to limit the performance +// impact of the study. +class IdentifiabilityStudyHelper { + public: + template <typename... Ts> + void MaybeUpdateDigest(Ts... args) { + constexpr int kMaxOperations = 1 << 20; + if (!IsUserInIdentifiabilityStudy() || operation_count_ > kMaxOperations) { + return; + } + digest_ ^= IdentifiabilityDigestHelper(args...); + operation_count_++; + } + + uint64_t digest() { return digest_; } + + private: + uint64_t digest_ = 0; + int operation_count_ = 0; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_ 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 29e9fbb4961..aecd6cfc5fb 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 @@ -29,6 +29,7 @@ CanvasContextCreationAttributesCore ToCanvasContextCreationAttributes( result.preserve_drawing_buffer = attrs->preserveDrawingBuffer(); result.power_preference = attrs->powerPreference(); result.stencil = attrs->stencil(); + result.will_read_frequently = attrs->willReadFrequently(); result.xr_compatible = attrs->xrCompatible(); return result; } diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl index 21324b678ac..56955c7b395 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl @@ -46,6 +46,7 @@ dictionary CanvasContextCreationAttributesModule { boolean alpha = true; // Also used for WebGL. [RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb"; [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8"; + [RuntimeEnabled=NewCanvas2DAPI] boolean willReadFrequently = false; // WebGL attributes boolean depth = true; 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 2f2752c5f07..4b94289ec16 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 @@ -51,8 +51,7 @@ void ImageBitmapRenderingContextBase::SetImage(ImageBitmap* image_bitmap) { image_bitmap->close(); } -scoped_refptr<StaticBitmapImage> ImageBitmapRenderingContextBase::GetImage( - AccelerationHint) { +scoped_refptr<StaticBitmapImage> ImageBitmapRenderingContextBase::GetImage() { return image_layer_bridge_->GetImage(); } @@ -84,7 +83,7 @@ bool ImageBitmapRenderingContextBase::IsPaintable() const { return !!image_layer_bridge_->GetImage(); } -void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) { +void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) const { 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 d5d8150fbe6..1c52a9285c5 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(Visitor*) override; + void Trace(Visitor*) const override; // TODO(juanmihd): Remove this method crbug.com/941579 HTMLCanvasElement* canvas() const { @@ -44,9 +44,7 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase void SetIsBeingDisplayed(bool) override {} bool isContextLost() const override { return false; } void SetImage(ImageBitmap*); - // The acceleration hint here is ignored as GetImage(AccelerationHint) only - // calls to image_layer_bridge->GetImage(), without giving it a hint - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; + scoped_refptr<StaticBitmapImage> GetImage() final; // This function resets the internal image resource to a image of the same // size than the original, with the same properties, but completely black. // This is used to follow the standard regarding transferToBitmap 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 266926c5f67..24460a75f43 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 @@ -105,7 +105,7 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D( canvas->SetDisableReadingFromCanvasTrue(); } -void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) { +void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) const { CanvasRenderingContext::Trace(visitor); BaseRenderingContext2D::Trace(visitor); } @@ -216,7 +216,7 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap( if (!GetOrCreateCanvasResourceProvider()) return nullptr; - scoped_refptr<StaticBitmapImage> image = GetImage(kPreferAcceleration); + scoped_refptr<StaticBitmapImage> image = GetImage(); if (!image) return nullptr; image->SetOriginClean(this->OriginClean()); @@ -236,8 +236,7 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap( return MakeGarbageCollected<ImageBitmap>(std::move(image)); } -scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage( - AccelerationHint hint) { +scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage() { FinalizeFrame(); if (!IsPaintable()) return nullptr; @@ -391,6 +390,8 @@ String OffscreenCanvasRenderingContext2D::font() const { void OffscreenCanvasRenderingContext2D::setFont(const String& new_font) { if (GetState().HasRealizedFont() && new_font == GetState().UnparsedFont()) return; + identifiability_study_helper_.MaybeUpdateDigest(CanvasOps::kSetFont, + new_font); base::TimeTicks start_time = base::TimeTicks::Now(); OffscreenFontCache& font_cache = GetOffscreenFontCache(); @@ -509,6 +510,12 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal( if (max_width && (!std::isfinite(*max_width) || *max_width <= 0)) return; + identifiability_study_helper_.MaybeUpdateDigest( + paint_type == CanvasRenderingContext2DState::kFillPaintType + ? CanvasOps::kFillText + : CanvasOps::kStrokeText, + IdentifiabilitySensitiveString(text), x, y, max_width ? *max_width : -1); + const Font& font = AccessFont(); const SimpleFontData* font_data = font.PrimaryFont(); DCHECK(font_data); @@ -575,9 +582,15 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal( }, [](const SkIRect& rect) // overdraw test lambda { return false; }, - bounds, paint_type); - paint_canvas->restoreToCount(save_count); - ValidateStateStack(); + bounds, paint_type, CanvasRenderingContext2DState::kNoImage); + + // |paint_canvas| maybe rese during Draw. If that happens, + // GetOrCreatePaintCanvas will create a new |paint_canvas| and return a new + // address. In this case, there is no need to call |restoreToCount|. + if (paint_canvas == GetOrCreatePaintCanvas()) { + paint_canvas->restoreToCount(save_count); + ValidateStateStack(); + } } TextMetrics* OffscreenCanvasRenderingContext2D::measureText( 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 bd98a0a7acf..faa12203c40 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,6 +12,7 @@ #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/modules/canvas/canvas2d/identifiability_study_helper.h" namespace blink { @@ -58,7 +59,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final // CanvasRenderingContext implementation ~OffscreenCanvasRenderingContext2D() override; ContextType GetContextType() const override { return kContext2D; } - bool Is2d() const override { return true; } + bool IsRenderingContext2D() const override { return true; } bool IsComposited() const override { return false; } bool IsAccelerated() const override; void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; @@ -69,7 +70,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final void ClearRect(double x, double y, double width, double height) override { BaseRenderingContext2D::clearRect(x, y, width, height); } - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; + scoped_refptr<StaticBitmapImage> GetImage() final; void Reset() override; void RestoreCanvasMatrixClipStack(cc::PaintCanvas* c) const override { RestoreMatrixClipStack(c); @@ -123,10 +124,14 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final ImageBitmap* TransferToImageBitmap(ScriptState*) final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool PushFrame() override; + uint64_t IdentifiabilityTextDigest() override { + return identifiability_study_helper_.digest(); + } + protected: CanvasColorParams ColorParams() const override; bool WritePixels(const SkImageInfo& orig_info, @@ -160,6 +165,8 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final std::mt19937 random_generator_; std::bernoulli_distribution bernoulli_distribution_; + + IdentifiabilityStudyHelper identifiability_study_helper_; }; } // namespace blink |