[go: nahoru, domu]

Refactor SaveLayer and SaveLayerAlpha

For cc::PaintCanvas::saveLayer[Alpha] and cc::SaveLayer[Alpha]Op,
- Change const PaintFlags* parameter to const PaintFlags&. Only one
  production callsites passed nullptr.
- Add a variant without the bounds parameter, and change the existing
  variant to accept const SkRect& for the bounds parameter.
- Change GraphicsContext::BeginLayer() to be several variants,
  without the bounds parameter. Previously only one caller passed the
  bounds parameter where the bounds didn't matter.
- Remove the branch checking alpha-only flags in RecordPaintCanvas::
  saveLayer() because all important callers know when to call
  saveLayerAlpha().

This makes the callsites clearner, and allows temporary SkRect for
the bounds parameter.

Change-Id: I3d8c81ef17ed26ba26c72f6cfd2a5cc9bea693a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4121362
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Owners-Override: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1086856}
diff --git a/ash/fast_ink/cursor/cursor_view.cc b/ash/fast_ink/cursor/cursor_view.cc
index 39ff8c0..22efffcf1 100644
--- a/ash/fast_ink/cursor/cursor_view.cc
+++ b/ash/fast_ink/cursor/cursor_view.cc
@@ -250,7 +250,7 @@
       motion_blur_matrix_.mapRect(&blur_rect);
       cc::PaintFlags flags;
       flags.setImageFilter(motion_blur_filter_);
-      sk_canvas->saveLayer(&blur_rect, &flags);
+      sk_canvas->saveLayer(blur_rect, flags);
       sk_canvas->concat(SkM44(motion_blur_matrix_));
       paint.canvas().DrawImageInt(cursor_image_, 0, 0);
       sk_canvas->restore();
diff --git a/ash/wallpaper/wallpaper_view.cc b/ash/wallpaper/wallpaper_view.cc
index 697e876..540a165 100644
--- a/ash/wallpaper/wallpaper_view.cc
+++ b/ash/wallpaper/wallpaper_view.cc
@@ -177,7 +177,7 @@
   gfx::Canvas filtered_canvas(small_image_->size(),
                               /*image_scale=*/1.f,
                               /*is_opaque=*/false);
-  filtered_canvas.sk_canvas()->saveLayer(nullptr, &filter_flags);
+  filtered_canvas.sk_canvas()->saveLayer(filter_flags);
   filtered_canvas.DrawImageInt(
       *small_image_, 0, 0, small_image_->width(), small_image_->height(), 0, 0,
       small_image_->width(), small_image_->height(), true);
diff --git a/cc/paint/discardable_image_map_unittest.cc b/cc/paint/discardable_image_map_unittest.cc
index 107d9bd..696effa 100644
--- a/cc/paint/discardable_image_map_unittest.cc
+++ b/cc/paint/discardable_image_map_unittest.cc
@@ -369,8 +369,7 @@
   scoped_refptr<DisplayItemList> display_list = new DisplayItemList;
   PaintFlags paint;
   display_list->StartPaint();
-  SkRect visible_sk_rect(gfx::RectToSkRect(visible_rect));
-  display_list->push<SaveLayerOp>(&visible_sk_rect, &paint);
+  display_list->push<SaveLayerOp>(gfx::RectToSkRect(visible_rect), paint);
   display_list->push<DrawRecordOp>(std::move(record));
   display_list->push<RestoreOp>();
   display_list->EndPaintOfUnpaired(visible_rect);
@@ -425,7 +424,7 @@
       CreateDiscardablePaintImage(gfx::Size(25, 25));
   display_list->push<TranslateOp>(25.0f, 25.0f);
   display_list->push<DrawImageOp>(discardable_image1, 0.f, 0.f);
-  display_list->push<SaveLayerOp>(nullptr, &paint);
+  display_list->push<SaveLayerOp>(paint);
   display_list->push<TranslateOp>(100.0f, 100.0f);
   display_list->push<DrawImageOp>(discardable_image2, 0.f, 0.f);
   display_list->push<RestoreOp>();
@@ -454,8 +453,8 @@
 
   scoped_refptr<DisplayItemList> display_list = new DisplayItemList;
   display_list->StartPaint();
-  SkRect visible_sk_rect(gfx::RectToSkRect(visible_rect));
-  display_list->push<SaveLayerOp>(&visible_sk_rect, nullptr);
+  display_list->push<SaveLayerOp>(gfx::RectToSkRect(visible_rect),
+                                  PaintFlags());
   display_list->push<DrawRecordOp>(std::move(record));
   display_list->push<RestoreOp>();
   display_list->EndPaintOfUnpaired(visible_rect);
@@ -911,7 +910,7 @@
   gfx::Rect visible_rect(500, 500);
   scoped_refptr<DisplayItemList> display_list = new DisplayItemList();
   display_list->StartPaint();
-  display_list->push<SaveLayerOp>(nullptr, &flags);
+  display_list->push<SaveLayerOp>(flags);
   display_list->push<DrawColorOp>(SkColors::kBlue, SkBlendMode::kSrc);
   display_list->EndPaintOfUnpaired(visible_rect);
   display_list->Finalize();
diff --git a/cc/paint/display_item_list_unittest.cc b/cc/paint/display_item_list_unittest.cc
index 584c857..ab856c8 100644
--- a/cc/paint/display_item_list_unittest.cc
+++ b/cc/paint/display_item_list_unittest.cc
@@ -388,7 +388,7 @@
 
     SkRect layer_bounds = gfx::RectFToSkRect(filter_bounds);
     layer_bounds.offset(-filter_bounds.x(), -filter_bounds.y());
-    list->push<SaveLayerOp>(&layer_bounds, &flags);
+    list->push<SaveLayerOp>(layer_bounds, flags);
     list->push<TranslateOp>(-filter_bounds.x(), -filter_bounds.y());
 
     list->EndPaintOfPairedBegin();
@@ -530,7 +530,7 @@
     PaintFlags red_paint;
     red_paint.setColor(SK_ColorRED);
 
-    list->push<SaveLayerOp>(nullptr, &red_paint);
+    list->push<SaveLayerOp>(red_paint);
     list->push<TranslateOp>(static_cast<float>(offset.x()),
                             static_cast<float>(offset.y()));
     list->push<DrawRectOp>(SkRect::MakeWH(4, 4), red_paint);
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc
index 6427ccd..80f097f 100644
--- a/cc/paint/oop_pixeltest.cc
+++ b/cc/paint/oop_pixeltest.cc
@@ -423,7 +423,7 @@
   auto display_item_list = base::MakeRefCounted<DisplayItemList>();
   display_item_list->StartPaint();
   display_item_list->push<DrawColorOp>(SkColors::kWhite, SkBlendMode::kSrc);
-  display_item_list->push<SaveLayerOp>(nullptr, &record_flags);
+  display_item_list->push<SaveLayerOp>(record_flags);
   display_item_list->push<RestoreOp>();
   display_item_list->EndPaintOfUnpaired(gfx::Rect(output_size));
   display_item_list->Finalize();
@@ -1627,7 +1627,7 @@
       PaintFlags layer_flags;
       layer_flags.setImageFilter(std::move(filter));
       filter = nullptr;
-      display_item_list->push<SaveLayerOp>(nullptr, &layer_flags);
+      display_item_list->push<SaveLayerOp>(layer_flags);
     }
 
     PushDrawOp(display_item_list, std::move(filter));
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h
index 1f8871b..7a76d09 100644
--- a/cc/paint/paint_canvas.h
+++ b/cc/paint/paint_canvas.h
@@ -72,8 +72,10 @@
   virtual void flush() = 0;
 
   virtual int save() = 0;
-  virtual int saveLayer(const SkRect* bounds, const PaintFlags* flags) = 0;
-  virtual int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) = 0;
+  virtual int saveLayer(const PaintFlags& flags) = 0;
+  virtual int saveLayer(const SkRect& bounds, const PaintFlags& flags) = 0;
+  virtual int saveLayerAlpha(uint8_t alpha) = 0;
+  virtual int saveLayerAlpha(const SkRect& bounds, uint8_t alpha) = 0;
 
   virtual void restore() = 0;
   virtual int getSaveCount() const = 0;
diff --git a/cc/paint/paint_flags.cc b/cc/paint/paint_flags.cc
index 0a7c1831..7949d4e 100644
--- a/cc/paint/paint_flags.cc
+++ b/cc/paint/paint_flags.cc
@@ -103,27 +103,6 @@
   return skpathutils::FillPathWithPaint(src, paint, dst, cull_rect, res_scale);
 }
 
-bool PaintFlags::IsSimpleOpacity() const {
-  uint32_t color = getColor();
-  if (SK_ColorTRANSPARENT != SkColorSetA(color, SK_AlphaTRANSPARENT))
-    return false;
-  if (getBlendMode() != SkBlendMode::kSrcOver)
-    return false;
-  if (getLooper())
-    return false;
-  if (getPathEffect())
-    return false;
-  if (HasShader())
-    return false;
-  if (getMaskFilter())
-    return false;
-  if (getColorFilter())
-    return false;
-  if (getImageFilter())
-    return false;
-  return true;
-}
-
 bool PaintFlags::SupportsFoldingAlpha() const {
   if (getBlendMode() != SkBlendMode::kSrcOver)
     return false;
diff --git a/cc/paint/paint_flags.h b/cc/paint/paint_flags.h
index b073de96c..fe7b927 100644
--- a/cc/paint/paint_flags.h
+++ b/cc/paint/paint_flags.h
@@ -165,10 +165,6 @@
     draw_looper_ = std::move(looper);
   }
 
-  // Returns true if this just represents an opacity blend when used as
-  // saveLayer flags, thus the saveLayer can be converted to a saveLayerAlpha.
-  bool IsSimpleOpacity() const;
-
   // Returns true if this (of a drawOp) allows the sequence
   // saveLayerAlpha/drawOp/restore to be folded into a single drawOp by baking
   // the alpha in the saveLayerAlpha into the flags of the drawOp.
diff --git a/cc/paint/paint_op.h b/cc/paint/paint_op.h
index 26655ef7..899b7d2 100644
--- a/cc/paint/paint_op.h
+++ b/cc/paint/paint_op.h
@@ -909,9 +909,10 @@
 class CC_PAINT_EXPORT SaveLayerOp final : public PaintOpWithFlags {
  public:
   static constexpr PaintOpType kType = PaintOpType::SaveLayer;
-  SaveLayerOp(const SkRect* bounds, const PaintFlags* flags)
-      : PaintOpWithFlags(kType, flags ? *flags : PaintFlags()),
-        bounds(bounds ? *bounds : kUnsetRect) {}
+  explicit SaveLayerOp(const PaintFlags& flags)
+      : PaintOpWithFlags(kType, flags), bounds(kUnsetRect) {}
+  SaveLayerOp(const SkRect& bounds, const PaintFlags& flags)
+      : PaintOpWithFlags(kType, flags), bounds(bounds) {}
   SaveLayerOp(const SaveLayerOp&) = default;
   SaveLayerOp& operator=(const SaveLayerOp&) = default;
   static void RasterWithFlags(const SaveLayerOp* op,
@@ -938,8 +939,11 @@
  public:
   static constexpr PaintOpType kType = PaintOpType::SaveLayerAlpha;
   template <class F, class = std::enable_if_t<std::is_same_v<F, float>>>
-  SaveLayerAlphaOp(const SkRect* bounds, F alpha)
-      : PaintOp(kType), bounds(bounds ? *bounds : kUnsetRect), alpha(alpha) {}
+  explicit SaveLayerAlphaOp(F alpha)
+      : PaintOp(kType), bounds(kUnsetRect), alpha(alpha) {}
+  template <class F, class = std::enable_if_t<std::is_same_v<F, float>>>
+  SaveLayerAlphaOp(const SkRect& bounds, F alpha)
+      : PaintOp(kType), bounds(bounds), alpha(alpha) {}
   SaveLayerAlphaOp(const SaveLayerAlphaOp&) = default;
   SaveLayerAlphaOp& operator=(const SaveLayerAlphaOp&) = default;
   static void Raster(const SaveLayerAlphaOp* op,
diff --git a/cc/paint/paint_op_buffer_serializer.cc b/cc/paint/paint_op_buffer_serializer.cc
index 3e83f61..59ad4aa3 100644
--- a/cc/paint/paint_op_buffer_serializer.cc
+++ b/cc/paint/paint_op_buffer_serializer.cc
@@ -232,9 +232,9 @@
       return false;
 
     // In DrawImageRectOp::RasterWithFlags, the save layer uses the
-    // flags_to_serialize or default(null) flags. At this point in the
+    // flags_to_serialize or default (PaintFlags()) flags. At this point in the
     // serialization, flags_to_serialize is always null as well.
-    SaveLayerOp save_layer_op(&draw_op.src, nullptr);
+    SaveLayerOp save_layer_op(draw_op.src, PaintFlags());
     success = SerializeOpWithFlags(canvas, save_layer_op, params, 255);
     if (!success)
       return false;
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc
index 6d33534..e06e7c08 100644
--- a/cc/paint/paint_op_buffer_unittest.cc
+++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -140,7 +140,7 @@
   }
 
   void PushOps(PaintOpBuffer* buffer) {
-    buffer->push<SaveLayerOp>(&rect_, &flags_);
+    buffer->push<SaveLayerOp>(rect_, flags_);
     buffer->push<SaveOp>();
     buffer->push<DrawColorOp>(draw_color_, blend_);
     buffer->push<RestoreOp>();
@@ -149,7 +149,7 @@
 
   void VerifyOps(PaintOpBuffer* buffer) {
     EXPECT_THAT(*buffer,
-                PaintOpsAreEq(SaveLayerOp(&rect_, &flags_), SaveOp(),
+                PaintOpsAreEq(SaveLayerOp(rect_, flags_), SaveOp(),
                               DrawColorOp(draw_color_, blend_), RestoreOp()));
   }
 
@@ -240,7 +240,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
 
   int paint_flags_alpha = 50;
   PaintFlags draw_flags;
@@ -269,7 +269,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
 
   PaintFlags paint_flags;
   EXPECT_TRUE(paint_flags.SupportsFoldingAlpha());
@@ -291,7 +291,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
 
   PaintFlags draw_flags;
   draw_flags.setColor(SkColors::kMagenta);
@@ -318,7 +318,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 1.0f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
 
   PaintFlags draw_flags;
   draw_flags.setColor(SkColors::kMagenta);
@@ -343,7 +343,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
 
   PaintFlags draw_flags;
   draw_flags.setColor(SkColors::kMagenta);
@@ -370,7 +370,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
 
   buffer.push<NoopOp>();
   buffer.push<RestoreOp>();
@@ -399,7 +399,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
   buffer.push<DrawRecordOp>(sub_buffer.ReleaseAsRecord());
   buffer.push<RestoreOp>();
 
@@ -427,7 +427,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
   buffer.push<DrawRecordOp>(sub_buffer.ReleaseAsRecord());
   buffer.push<RestoreOp>();
 
@@ -443,7 +443,7 @@
   float alpha = 0.4f;
   SkColor original = SkColorSetA(50, SK_ColorRED);
 
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
   buffer.push<DrawColorOp>(SkColor4f::FromColor(original),
                            SkBlendMode::kSrcOver);
   buffer.push<RestoreOp>();
@@ -521,9 +521,7 @@
   EXPECT_EQ(buffer.num_slow_paths_up_to_min_for_MSAA(), 0);
 
   // Op without slow paths
-  PaintFlags noop_flags;
-  SkRect rect = SkRect::MakeXYWH(2, 3, 4, 5);
-  buffer.push<SaveLayerOp>(&rect, &noop_flags);
+  buffer.push<SaveLayerOp>(SkRect::MakeXYWH(2, 3, 4, 5), PaintFlags());
 
   // Line op with a slow path
   PaintFlags line_effect_slow;
@@ -679,8 +677,7 @@
 
     PaintFlags non_aa_flags;
     non_aa_flags.setAntiAlias(true);
-    auto bounds = SkRect::MakeWH(1, 1);
-    buffer.push<SaveLayerOp>(&bounds, &non_aa_flags);
+    buffer.push<SaveLayerOp>(SkRect::MakeWH(1, 1), non_aa_flags);
 
     EXPECT_FALSE(buffer.HasNonAAPaint());
   }
@@ -832,7 +829,7 @@
   push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
   push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
   float alpha = 0.4f;
-  push_op<SaveLayerAlphaOp>(nullptr, alpha);
+  push_op<SaveLayerAlphaOp>(alpha);
   push_op<RestoreOp>();
   push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
   push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
@@ -858,7 +855,7 @@
   push_op<DrawColorOp>(SkColor4f::FromColor(0u), SkBlendMode::kClear);
   push_op<DrawColorOp>(SkColor4f::FromColor(1u), SkBlendMode::kClear);
   float alpha = 0.4f;
-  push_op<SaveLayerAlphaOp>(nullptr, alpha);
+  push_op<SaveLayerAlphaOp>(alpha);
   push_op<DrawColorOp>(SkColor4f::FromColor(2u), SkBlendMode::kClear);
   push_op<DrawColorOp>(SkColor4f::FromColor(3u), SkBlendMode::kClear);
   push_op<RestoreOp>();
@@ -908,7 +905,7 @@
   add_draw_rect(0u);
   add_draw_rect(1u);
   float alpha = 0.4f;
-  push_op<SaveLayerAlphaOp>(nullptr, alpha);
+  push_op<SaveLayerAlphaOp>(alpha);
   add_draw_rect(2u);
   push_op<RestoreOp>();
   add_draw_rect(3u);
@@ -941,7 +938,7 @@
   add_draw_rect(0u);
   add_draw_rect(1u);
   float alpha = 0.4f;
-  push_op<SaveLayerAlphaOp>(nullptr, alpha);
+  push_op<SaveLayerAlphaOp>(alpha);
   add_draw_rect(2u);
   add_draw_rect(3u);
   add_draw_rect(4u);
@@ -1000,7 +997,7 @@
 
   add_draw_rect(&buffer, 0u);
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
   add_draw_rect(&buffer, 1u);
   buffer.push<RestoreOp>();
   add_draw_rect(&buffer, 2u);
@@ -1029,9 +1026,9 @@
   // Push 2 saves.
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
   add_draw_rect(&buffer, 0u);
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
   add_draw_rect(&buffer, 1u);
   add_draw_rect(&buffer, 2u);
   // But only 1 restore.
@@ -1729,22 +1726,22 @@
 void PushSaveLayerOps(PaintOpBuffer* buffer) {
   size_t len = std::min(test_flags.size(), test_rects.size());
   for (size_t i = 0; i < len; ++i)
-    buffer->push<SaveLayerOp>(&test_rects[i], &test_flags[i]);
+    buffer->push<SaveLayerOp>(test_rects[i], test_flags[i]);
 
   // Test combinations of optional args.
-  buffer->push<SaveLayerOp>(nullptr, &test_flags[0]);
-  buffer->push<SaveLayerOp>(&test_rects[0], nullptr);
-  buffer->push<SaveLayerOp>(nullptr, nullptr);
+  buffer->push<SaveLayerOp>(test_flags[0]);
+  buffer->push<SaveLayerOp>(test_rects[0], PaintFlags());
+  buffer->push<SaveLayerOp>(PaintFlags());
   EXPECT_THAT(*buffer, Each(PaintOpIs<SaveLayerOp>()));
 }
 
 void PushSaveLayerAlphaOps(PaintOpBuffer* buffer) {
   size_t len = std::min(test_floats.size(), test_rects.size());
   for (size_t i = 0; i < len; ++i)
-    buffer->push<SaveLayerAlphaOp>(&test_rects[i], test_floats[i]);
+    buffer->push<SaveLayerAlphaOp>(test_rects[i], test_floats[i]);
 
   // Test optional args.
-  buffer->push<SaveLayerAlphaOp>(nullptr, test_floats[0]);
+  buffer->push<SaveLayerAlphaOp>(test_floats[0]);
   EXPECT_THAT(*buffer, Each(PaintOpIs<SaveLayerAlphaOp>()));
 }
 
@@ -2293,7 +2290,7 @@
   PaintOpBuffer buffer;
 
   float alpha = 0.4f;
-  buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
+  buffer.push<SaveLayerAlphaOp>(alpha);
 
   PaintFlags draw_flags;
   draw_flags.setColor(SkColors::kMagenta);
@@ -2549,9 +2546,9 @@
                                SkCanvas::kStrict_SrcRectConstraint);
   buffer.push<DrawOvalOp>(bad_rect, test_flags[0]);
   buffer.push<DrawRectOp>(bad_rect, test_flags[0]);
-  buffer.push<SaveLayerOp>(&bad_rect, nullptr);
-  buffer.push<SaveLayerOp>(&bad_rect, &test_flags[0]);
-  buffer.push<SaveLayerAlphaOp>(&bad_rect, test_floats[0]);
+  buffer.push<SaveLayerOp>(bad_rect, PaintFlags());
+  buffer.push<SaveLayerOp>(bad_rect, test_flags[0]);
+  buffer.push<SaveLayerAlphaOp>(bad_rect, test_floats[0]);
 
   TestOptionsProvider options_provider;
 
@@ -2850,10 +2847,9 @@
 
 TEST(PaintOpBufferTest, RasterPaintWorkletImageRectBasicCase) {
   PaintOpBuffer paint_worklet_buffer;
-  PaintFlags noop_flags;
-  SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 100, 100);
   paint_worklet_buffer.push<TranslateOp>(8.0f, 8.0f);
-  paint_worklet_buffer.push<SaveLayerOp>(&savelayer_rect, &noop_flags);
+  paint_worklet_buffer.push<SaveLayerOp>(SkRect::MakeXYWH(0, 0, 100, 100),
+                                         PaintFlags());
   PaintFlags draw_flags;
   draw_flags.setColor(0u);
   SkRect rect = SkRect::MakeXYWH(0, 0, 100, 100);
@@ -2890,9 +2886,8 @@
 
 TEST(PaintOpBufferTest, RasterPaintWorkletImageRectTranslated) {
   PaintOpBuffer paint_worklet_buffer;
-  PaintFlags noop_flags;
-  SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 10, 10);
-  paint_worklet_buffer.push<SaveLayerOp>(&savelayer_rect, &noop_flags);
+  paint_worklet_buffer.push<SaveLayerOp>(SkRect::MakeXYWH(0, 0, 10, 10),
+                                         PaintFlags());
   PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10));
   paint_worklet_buffer.push<DrawImageOp>(
       paint_image, 0.0f, 0.0f, SkSamplingOptions(SkFilterMode::kLinear),
@@ -2937,9 +2932,8 @@
 
 TEST(PaintOpBufferTest, RasterPaintWorkletImageRectScaled) {
   PaintOpBuffer paint_worklet_buffer;
-  PaintFlags noop_flags;
-  SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 10, 10);
-  paint_worklet_buffer.push<SaveLayerOp>(&savelayer_rect, &noop_flags);
+  paint_worklet_buffer.push<SaveLayerOp>(SkRect::MakeXYWH(0, 0, 10, 10),
+                                         PaintFlags());
   PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10));
   paint_worklet_buffer.push<DrawImageOp>(
       paint_image, 0.0f, 0.0f, SkSamplingOptions(SkFilterMode::kLinear),
@@ -2984,9 +2978,8 @@
 
 TEST(PaintOpBufferTest, RasterPaintWorkletImageRectClipped) {
   PaintOpBuffer paint_worklet_buffer;
-  PaintFlags noop_flags;
-  SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 60, 60);
-  paint_worklet_buffer.push<SaveLayerOp>(&savelayer_rect, &noop_flags);
+  paint_worklet_buffer.push<SaveLayerOp>(SkRect::MakeXYWH(0, 0, 60, 60),
+                                         PaintFlags());
   SkSamplingOptions linear(SkFilterMode::kLinear);
   PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10));
   // One rect inside the src-rect, one outside.
@@ -3901,7 +3894,7 @@
   EXPECT_FALSE(buffer2.has_effects_preventing_lcd_text_for_save_layer_alpha());
   buffer2.push<DrawRecordOp>(buffer1.ReleaseAsRecord());
   EXPECT_FALSE(buffer2.has_effects_preventing_lcd_text_for_save_layer_alpha());
-  buffer2.push<SaveLayerOp>(nullptr, nullptr);
+  buffer2.push<SaveLayerOp>(PaintFlags());
   EXPECT_TRUE(buffer2.has_effects_preventing_lcd_text_for_save_layer_alpha());
   buffer2.push<DrawRectOp>(SkRect::MakeWH(4, 5), PaintFlags());
   EXPECT_TRUE(buffer2.has_effects_preventing_lcd_text_for_save_layer_alpha());
@@ -3914,7 +3907,7 @@
 
 TEST(PaintOpBufferTest, NeedsAdditionalInvalidationForLCDText) {
   PaintOpBuffer buffer1;
-  buffer1.push<SaveLayerAlphaOp>(nullptr, 0.4f);
+  buffer1.push<SaveLayerAlphaOp>(0.4f);
   EXPECT_FALSE(buffer1.has_draw_text_ops());
   EXPECT_TRUE(buffer1.has_save_layer_alpha_ops());
   EXPECT_FALSE(buffer1.has_effects_preventing_lcd_text_for_save_layer_alpha());
@@ -3922,7 +3915,7 @@
   PaintOpBuffer buffer2;
   buffer2.push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()),
                                0.0f, 0.0f, PaintFlags());
-  buffer2.push<SaveLayerOp>(nullptr, nullptr);
+  buffer2.push<SaveLayerOp>(PaintFlags());
   EXPECT_TRUE(buffer2.has_draw_ops());
   EXPECT_FALSE(buffer2.has_save_layer_alpha_ops());
   EXPECT_TRUE(buffer2.has_effects_preventing_lcd_text_for_save_layer_alpha());
diff --git a/cc/paint/paint_op_helper_unittest.cc b/cc/paint/paint_op_helper_unittest.cc
index be17da9..da02eaeb 100644
--- a/cc/paint/paint_op_helper_unittest.cc
+++ b/cc/paint/paint_op_helper_unittest.cc
@@ -78,8 +78,7 @@
       "strokeJoin=kMiter_Join, colorFilter=(nil), "
       "maskFilter=(nil), shader=(nil), hasShader=false, shaderIsOpaque=false, "
       "pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
-      "isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
-      "hasDiscardableImages=false])");
+      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, DrawImageToString) {
@@ -93,8 +92,8 @@
       "strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
       "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
       "hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
-      "imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
-      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
+      "imageFilter=(nil), drawLooper=(nil), supportsFoldingAlpha=true, "
+      "isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, DrawImageRectToString) {
@@ -111,8 +110,8 @@
       "strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
       "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
       "hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
-      "imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
-      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
+      "imageFilter=(nil), drawLooper=(nil), supportsFoldingAlpha=true, "
+      "isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, DrawIRectToString) {
@@ -126,7 +125,7 @@
             "colorFilter=(nil), maskFilter=(nil), "
             "shader=(nil), hasShader=false, shaderIsOpaque=false, "
             "pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
-            "isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
+            "supportsFoldingAlpha=true, isValid=true, "
             "hasDiscardableImages=false])");
 }
 
@@ -141,8 +140,8 @@
       "strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
       "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
       "hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
-      "imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
-      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
+      "imageFilter=(nil), drawLooper=(nil), supportsFoldingAlpha=true, "
+      "isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, DrawOvalToString) {
@@ -156,8 +155,8 @@
       "strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
       "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
       "hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
-      "imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
-      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
+      "imageFilter=(nil), drawLooper=(nil), supportsFoldingAlpha=true, "
+      "isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, DrawPathToString) {
@@ -172,7 +171,7 @@
             "colorFilter=(nil), maskFilter=(nil), "
             "shader=(nil), hasShader=false, shaderIsOpaque=false, "
             "pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
-            "isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
+            "supportsFoldingAlpha=true, isValid=true, "
             "hasDiscardableImages=false], use_cache=false)");
 }
 
@@ -194,8 +193,7 @@
       "strokeJoin=kMiter_Join, colorFilter=(nil), "
       "maskFilter=(nil), shader=(nil), hasShader=false, shaderIsOpaque=false, "
       "pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
-      "isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
-      "hasDiscardableImages=false])");
+      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, DrawRRectToString) {
@@ -210,8 +208,8 @@
       "strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
       "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
       "hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
-      "imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
-      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
+      "imageFilter=(nil), drawLooper=(nil), supportsFoldingAlpha=true, "
+      "isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, DrawTextBlobToString) {
@@ -225,8 +223,8 @@
       "strokeMiter=4.000, strokeCap=kButt_Cap, strokeJoin=kMiter_Join, "
       "colorFilter=(nil), maskFilter=(nil), shader=(nil), "
       "hasShader=false, shaderIsOpaque=false, pathEffect=(nil), "
-      "imageFilter=(nil), drawLooper=(nil), isSimpleOpacity=true, "
-      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
+      "imageFilter=(nil), drawLooper=(nil), supportsFoldingAlpha=true, "
+      "isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, NoopToString) {
@@ -254,8 +252,7 @@
 }
 
 TEST(PaintOpHelper, SaveLayerToString) {
-  SkRect bounds = SkRect::MakeXYWH(1, 2, 3, 4);
-  SaveLayerOp op(&bounds, nullptr);
+  SaveLayerOp op(SkRect::MakeXYWH(1, 2, 3, 4), PaintFlags());
   std::string str = PaintOpHelper::ToString(&op);
   EXPECT_EQ(
       str,
@@ -266,13 +263,11 @@
       "strokeJoin=kMiter_Join, colorFilter=(nil), "
       "maskFilter=(nil), shader=(nil), hasShader=false, shaderIsOpaque=false, "
       "pathEffect=(nil), imageFilter=(nil), drawLooper=(nil), "
-      "isSimpleOpacity=true, supportsFoldingAlpha=true, isValid=true, "
-      "hasDiscardableImages=false])");
+      "supportsFoldingAlpha=true, isValid=true, hasDiscardableImages=false])");
 }
 
 TEST(PaintOpHelper, SaveLayerAlphaToString) {
-  SkRect bounds = SkRect::MakeXYWH(1, 2, 3, 4);
-  SaveLayerAlphaOp op(&bounds, 1.0f);
+  SaveLayerAlphaOp op(SkRect::MakeXYWH(1, 2, 3, 4), 1.0f);
   std::string str = PaintOpHelper::ToString(&op);
   EXPECT_EQ(str,
             "SaveLayerAlphaOp(bounds=[1.000,2.000 3.000x4.000], alpha=255)");
diff --git a/cc/paint/record_paint_canvas.cc b/cc/paint/record_paint_canvas.cc
index d56d128..66d5782 100644
--- a/cc/paint/record_paint_canvas.cc
+++ b/cc/paint/record_paint_canvas.cc
@@ -72,24 +72,23 @@
   return save_count_++;
 }
 
-int RecordPaintCanvas::saveLayer(const SkRect* bounds,
-                                 const PaintFlags* flags) {
-  if (flags && flags->IsSimpleOpacity()) {
-    // TODO(enne): maybe more callers should know this and call
-    // saveLayerAlpha instead of needing to check here.
-    uint8_t alpha = SkColorGetA(flags->getColor());
-    return saveLayerAlpha(bounds, alpha);
-  }
-  return saveLayerInternal(bounds, flags);
+int RecordPaintCanvas::saveLayer(const PaintFlags& flags) {
+  push<SaveLayerOp>(flags);
+  return save_count_++;
 }
 
-int RecordPaintCanvas::saveLayerInternal(const SkRect* bounds,
-                                         const PaintFlags* flags) {
+int RecordPaintCanvas::saveLayer(const SkRect& bounds,
+                                 const PaintFlags& flags) {
   push<SaveLayerOp>(bounds, flags);
   return save_count_++;
 }
 
-int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
+int RecordPaintCanvas::saveLayerAlpha(uint8_t alpha) {
+  push<SaveLayerAlphaOp>(static_cast<float>(alpha / 255.0f));
+  return save_count_++;
+}
+
+int RecordPaintCanvas::saveLayerAlpha(const SkRect& bounds, uint8_t alpha) {
   push<SaveLayerAlphaOp>(bounds, static_cast<float>(alpha / 255.0f));
   return save_count_++;
 }
@@ -358,26 +357,27 @@
   return CheckSaveCount(RecordPaintCanvas::save(), canvas_.save());
 }
 
-int InspectableRecordPaintCanvas::saveLayerInternal(const SkRect* bounds,
-                                                    const PaintFlags* flags) {
-  int canvas_prev_save_count;
-  // TODO(enne): it appears that image filters affect matrices and color
-  // matrices affect transparent flags on SkCanvas layers, but it's not clear
-  // whether those are actually needed and we could just skip ToSkPaint here.
-  if (flags) {
-    SkPaint paint = flags->ToSkPaint();
-    canvas_prev_save_count = canvas_.saveLayer(bounds, &paint);
-  } else {
-    canvas_prev_save_count = canvas_.saveLayer(bounds, nullptr);
-  }
-  return CheckSaveCount(RecordPaintCanvas::saveLayerInternal(bounds, flags),
-                        canvas_prev_save_count);
+int InspectableRecordPaintCanvas::saveLayer(const PaintFlags& flags) {
+  SkPaint paint = flags.ToSkPaint();
+  return CheckSaveCount(RecordPaintCanvas::saveLayer(flags),
+                        canvas_.saveLayer(nullptr, &paint));
 }
 
-int InspectableRecordPaintCanvas::saveLayerAlpha(const SkRect* bounds,
+int InspectableRecordPaintCanvas::saveLayer(const SkRect& bounds,
+                                            const PaintFlags& flags) {
+  SkPaint paint = flags.ToSkPaint();
+  return CheckSaveCount(RecordPaintCanvas::saveLayer(bounds, flags),
+                        canvas_.saveLayer(&bounds, &paint));
+}
+int InspectableRecordPaintCanvas::saveLayerAlpha(uint8_t alpha) {
+  return CheckSaveCount(RecordPaintCanvas::saveLayerAlpha(alpha),
+                        canvas_.saveLayerAlpha(nullptr, alpha));
+}
+
+int InspectableRecordPaintCanvas::saveLayerAlpha(const SkRect& bounds,
                                                  uint8_t alpha) {
   return CheckSaveCount(RecordPaintCanvas::saveLayerAlpha(bounds, alpha),
-                        canvas_.saveLayerAlpha(bounds, alpha));
+                        canvas_.saveLayerAlpha(&bounds, alpha));
 }
 
 void InspectableRecordPaintCanvas::restore() {
diff --git a/cc/paint/record_paint_canvas.h b/cc/paint/record_paint_canvas.h
index 31aac65..0cfa0b3f 100644
--- a/cc/paint/record_paint_canvas.h
+++ b/cc/paint/record_paint_canvas.h
@@ -44,8 +44,10 @@
   bool NeedsFlush() const override;
 
   int save() override;
-  int saveLayer(const SkRect* bounds, const PaintFlags* flags) final;
-  int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override;
+  int saveLayer(const PaintFlags& flags) override;
+  int saveLayer(const SkRect& bounds, const PaintFlags& flags) override;
+  int saveLayerAlpha(uint8_t alpha) override;
+  int saveLayerAlpha(const SkRect& bounds, uint8_t alpha) override;
   void restore() override;
   int getSaveCount() const final;
   void restoreToCount(int save_count) override;
@@ -175,7 +177,6 @@
   };
 
  protected:
-  virtual int saveLayerInternal(const SkRect* bounds, const PaintFlags* flags);
   virtual void clipRRectInternal(const SkRRect& rrect,
                                  SkClipOp op,
                                  bool antialias);
@@ -205,7 +206,10 @@
   ~InspectableRecordPaintCanvas() override;
 
   int save() override;
-  int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override;
+  int saveLayer(const PaintFlags& flags) override;
+  int saveLayer(const SkRect& bounds, const PaintFlags& flags) override;
+  int saveLayerAlpha(uint8_t alpha) override;
+  int saveLayerAlpha(const SkRect& bounds, uint8_t alpha) override;
   void restore() override;
 
   void translate(SkScalar dx, SkScalar dy) override;
@@ -228,7 +232,6 @@
   using RecordPaintCanvas::clipRect;
 
  private:
-  int saveLayerInternal(const SkRect* bounds, const PaintFlags* flags) override;
   void clipRRectInternal(const SkRRect& rrect,
                          SkClipOp op,
                          bool antialias) override;
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc
index 9c94373..b9cad71 100644
--- a/cc/paint/skia_paint_canvas.cc
+++ b/cc/paint/skia_paint_canvas.cc
@@ -73,16 +73,22 @@
   return canvas_->save();
 }
 
-int SkiaPaintCanvas::saveLayer(const SkRect* bounds, const PaintFlags* flags) {
-  if (!flags)
-    return canvas_->saveLayer(bounds, nullptr);
-
-  SkPaint paint = flags->ToSkPaint();
-  return canvas_->saveLayer(bounds, &paint);
+int SkiaPaintCanvas::saveLayer(const PaintFlags& flags) {
+  SkPaint paint = flags.ToSkPaint();
+  return canvas_->saveLayer(nullptr, &paint);
 }
 
-int SkiaPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
-  return canvas_->saveLayerAlpha(bounds, alpha);
+int SkiaPaintCanvas::saveLayer(const SkRect& bounds, const PaintFlags& flags) {
+  SkPaint paint = flags.ToSkPaint();
+  return canvas_->saveLayer(&bounds, &paint);
+}
+
+int SkiaPaintCanvas::saveLayerAlpha(uint8_t alpha) {
+  return canvas_->saveLayerAlpha(nullptr, alpha);
+}
+
+int SkiaPaintCanvas::saveLayerAlpha(const SkRect& bounds, uint8_t alpha) {
+  return canvas_->saveLayerAlpha(&bounds, alpha);
 }
 
 void SkiaPaintCanvas::restore() {
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h
index 8aca4401e0..fe578e1 100644
--- a/cc/paint/skia_paint_canvas.h
+++ b/cc/paint/skia_paint_canvas.h
@@ -71,8 +71,10 @@
   void flush() override;
 
   int save() override;
-  int saveLayer(const SkRect* bounds, const PaintFlags* flags) override;
-  int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) override;
+  int saveLayer(const PaintFlags& flags) override;
+  int saveLayer(const SkRect& bounds, const PaintFlags& flags) override;
+  int saveLayerAlpha(uint8_t alpha) override;
+  int saveLayerAlpha(const SkRect& bounds, uint8_t alpha) override;
 
   void restore() override;
   int getSaveCount() const override;
diff --git a/cc/paint/solid_color_analyzer_unittest.cc b/cc/paint/solid_color_analyzer_unittest.cc
index 9c4cecc6..07bae36 100644
--- a/cc/paint/solid_color_analyzer_unittest.cc
+++ b/cc/paint/solid_color_analyzer_unittest.cc
@@ -301,9 +301,7 @@
   PaintFlags flags;
   SkColor4f color = SkColor4f::FromColor(SkColorSetARGB(255, 11, 22, 33));
   flags.setColor(color);
-
-  SkRect rect = SkRect::MakeWH(200, 200);
-  canvas_.saveLayer(&rect, &flags);
+  canvas_.saveLayer(SkRect::MakeWH(200, 200), flags);
   EXPECT_FALSE(IsSolidColor());
 }
 
diff --git a/cc/test/paint_op_helper.h b/cc/test/paint_op_helper.h
index ce674193..e4cbd2d 100644
--- a/cc/test/paint_op_helper.h
+++ b/cc/test/paint_op_helper.h
@@ -618,7 +618,6 @@
         << PaintOpHelper::PaintFilterToString(flags.getImageFilter());
     str << ", drawLooper="
         << PaintOpHelper::SkiaTypeToString(flags.getLooper());
-    str << ", isSimpleOpacity=" << flags.IsSimpleOpacity();
     str << ", supportsFoldingAlpha=" << flags.SupportsFoldingAlpha();
     str << ", isValid=" << flags.IsValid();
     str << ", hasDiscardableImages=" << flags.HasDiscardableImages();
diff --git a/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc b/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc
index fe98946..e610651 100644
--- a/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc
+++ b/components/paint_preview/renderer/paint_preview_recorder_utils_unittest.cc
@@ -124,8 +124,8 @@
   outer_canvas->drawPicture(AddLink(link_4, rect_4));
   outer_canvas->restore();
 
-  outer_canvas->saveLayer(&rect_1, nullptr);
-  outer_canvas->saveLayerAlpha(&rect_1, 8);
+  outer_canvas->saveLayer(rect_1, cc::PaintFlags());
+  outer_canvas->saveLayerAlpha(8);
   outer_canvas->restoreToCount(1);
   auto record = outer_recorder.finishRecordingAsPicture();
 
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc
index 38c1bb6..2c22b67 100644
--- a/third_party/blink/renderer/core/paint/box_painter_base.cc
+++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -1190,7 +1190,7 @@
   GraphicsContextStateSaver background_clip_state_saver(context, false);
   background_clip_state_saver.Save();
   context.Clip(mask_rect);
-  context.BeginLayer(1, composite_op);
+  context.BeginLayer(composite_op);
 
   PaintFillLayerBackground(document_, context, info, node_, style_, image,
                            SkBlendMode::kSrcOver, geometry,
@@ -1199,7 +1199,7 @@
   // Create the text mask layer and draw the text into the mask. We do this by
   // painting using a special paint phase that signals to InlineTextBoxes that
   // they should just add their contents to the clip.
-  context.BeginLayer(1, SkBlendMode::kDstIn);
+  context.BeginLayer(SkBlendMode::kDstIn);
 
   PaintTextClipMask(paint_info, mask_rect, scrolled_paint_rect.offset,
                     object_has_multiple_boxes);
diff --git a/third_party/blink/renderer/core/paint/clip_path_clipper.cc b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
index aa9ca3a..c8f6115 100644
--- a/third_party/blink/renderer/core/paint/clip_path_clipper.cc
+++ b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
@@ -335,10 +335,11 @@
       if (!resource_clipper)
         break;
 
-      if (is_first)
+      if (is_first) {
         context.Save();
-      else
-        context.BeginLayer(1.f, SkBlendMode::kDstIn);
+      } else {
+        context.BeginLayer(SkBlendMode::kDstIn);
+      }
 
       if (resource_clipper->StyleRef().HasClipPath()) {
         // Try to apply nested clip-path as path-based clip.
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc
index afecde7..008d800 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_text_painter_base.cc
@@ -89,11 +89,9 @@
     DCHECK_GE(blur, 0);
     const auto sigma = BlurRadiusToStdDev(blur);
 
-    context.BeginLayer(
-        1.0f, SkBlendMode::kSrcOver, nullptr, kColorFilterNone,
-        sk_make_sp<DropShadowPaintFilter>(
-            offset.x(), offset.y(), sigma, sigma, color.toSkColor4f(),
-            DropShadowPaintFilter::ShadowMode::kDrawShadowOnly, nullptr));
+    context.BeginLayer(sk_make_sp<DropShadowPaintFilter>(
+        offset.x(), offset.y(), sigma, sigma, color.toSkColor4f(),
+        DropShadowPaintFilter::ShadowMode::kDrawShadowOnly, nullptr));
 
     PaintUnderOrOverLineDecorations(fragment_paint_info, decoration_offset,
                                     decoration_info, lines_to_paint, flags,
diff --git a/third_party/blink/renderer/core/paint/svg_mask_painter.cc b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
index 7cf360a..3c2a5924 100644
--- a/third_party/blink/renderer/core/paint/svg_mask_painter.cc
+++ b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
@@ -73,8 +73,7 @@
   bool needs_luminance_layer =
       masker->StyleRef().MaskType() == EMaskType::kLuminance;
   if (needs_luminance_layer) {
-    context.BeginLayer(1.0f, SkBlendMode::kSrcOver, nullptr,
-                       kColorFilterLuminanceToAlpha);
+    context.BeginLayer(kColorFilterLuminanceToAlpha);
   }
   context.DrawRecord(std::move(record));
   if (needs_luminance_layer)
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc
index afd1e80..23564a3 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc
@@ -264,7 +264,6 @@
 
   GraphicsContextStateSaver state_saver(context);
   context.Translate(rect.x(), rect.y());
-  gfx::Rect local_rect(rect.size());
 
   if (!scrollbar.Enabled())
     return;
@@ -297,8 +296,7 @@
   }
 
   if (opacity != 1.0f) {
-    gfx::RectF float_local_rect(local_rect);
-    context.BeginLayer(opacity, SkBlendMode::kSrcOver, &float_local_rect);
+    context.BeginLayer(opacity);
   }
 
   WebThemeEngine::Part thumb_part =
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index 5f3d974..591b0aa 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -611,7 +611,7 @@
     PaintCanvasAutoRestore ar(canvas, false);
     if (DrawNeedsLayer(flags)) {
       SkRect layer_rect = gfx::RectFToSkRect(dst_rect);
-      canvas->saveLayer(&layer_rect, &flags);
+      canvas->saveLayer(layer_rect, flags);
     }
     // We can only draw the entire frame, clipped to the rect we want. So
     // compute where the top left of the image would be if we were drawing
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index e2fee9d..219077b8 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -204,7 +204,7 @@
     flags.setImageFilter(GetState().ShouldDrawShadows()
                              ? GetState().ShadowAndForegroundImageFilter()
                              : StateGetFilter());
-    canvas->saveLayer(nullptr, &flags);
+    canvas->saveLayer(flags);
 
     // Push to state stack to keep stack size up to date.
     state_stack_.push_back(MakeGarbageCollected<CanvasRenderingContext2DState>(
@@ -219,7 +219,7 @@
     extra_flags.setAlpha(globalAlpha() * 255);
     if (GetState().ShouldDrawShadows())
       extra_flags.setImageFilter(StateGetFilter());
-    canvas->saveLayer(nullptr, &extra_flags);
+    canvas->saveLayer(extra_flags);
   } else {
     cc::PaintFlags flags;
     GetState().FillStyle()->ApplyToFlags(flags);
@@ -230,7 +230,7 @@
     flags.setImageFilter(sk_make_sp<ComposePaintFilter>(
         GetState().ShadowAndForegroundImageFilter(), StateGetFilter()));
     flags.setAlpha(globalAlpha() * 255);
-    canvas->saveLayer(nullptr, &flags);
+    canvas->saveLayer(flags);
   }
 
   ValidateStateStack();
@@ -1515,7 +1515,7 @@
     layer_flags.setBlendMode(flags->getBlendMode());
     layer_flags.setImageFilter(flags->getImageFilter());
 
-    c->saveLayer(&bounds, &layer_flags);
+    c->saveLayer(bounds, layer_flags);
     c->concat(ctm);
     image_flags.setBlendMode(SkBlendMode::kSrcOver);
     image_flags.setImageFilter(nullptr);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
index 14f2903..7463140 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -821,14 +821,14 @@
       // Saving the shadow layer before setting the matrix, so the shadow offset
       // does not get modified by the transformation matrix
       shadow_flags.setBlendMode(state.GlobalComposite());
-      c->saveLayer(nullptr, &shadow_flags);
+      c->saveLayer(shadow_flags);
       foreground_flags.setBlendMode(SkBlendMode::kSrcOver);
       c->setMatrix(ctm);
       draw_func(c, &foreground_flags);
     } else {
       DCHECK(IsFullCanvasCompositeMode(state.GlobalComposite()) ||
              BlendModeRequiresCompositedDraw(state.GlobalComposite()));
-      c->saveLayer(nullptr, &composite_flags);
+      c->saveLayer(composite_flags);
       shadow_flags.setBlendMode(SkBlendMode::kSrcOver);
       c->setMatrix(ctm);
       draw_func(c, &shadow_flags);
@@ -837,7 +837,7 @@
   }
 
   composite_flags.setImageFilter(std::move(canvas_filter));
-  c->saveLayer(nullptr, &composite_flags);
+  c->saveLayer(composite_flags);
   cc::PaintFlags foreground_flags =
       *state.GetFlags(paint_type, kDrawForegroundOnly, image_type);
   foreground_flags.setBlendMode(SkBlendMode::kSrcOver);
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
index 62fa38d..a43ee1af 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -599,10 +599,10 @@
       cc::PaintFlags flags;
       flags.setBlendMode(effect.BlendMode());
       flags.setAlpha(alpha);
-      save_layer_id = push<cc::SaveLayerOp>(nullptr, &flags);
+      save_layer_id = push<cc::SaveLayerOp>(flags);
     } else {
-      save_layer_id = push<cc::SaveLayerAlphaOp>(
-          nullptr, static_cast<float>(alpha / 255.0f));
+      save_layer_id =
+          push<cc::SaveLayerAlphaOp>(static_cast<float>(alpha / 255.0f));
     }
   } else {
     // Handle filter effect.
@@ -612,7 +612,7 @@
     cc::PaintFlags filter_flags;
     filter_flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter(
         effect.Filter().AsCcFilterOperations(), empty));
-    save_layer_id = push<cc::SaveLayerOp>(nullptr, &filter_flags);
+    save_layer_id = push<cc::SaveLayerOp>(filter_flags);
   }
   result_.EndPaintOfPairedBegin();
 
diff --git a/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc b/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc
index 7b197bf5..a1a0e2f 100644
--- a/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc
+++ b/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc
@@ -56,7 +56,7 @@
   cc::PaintFlags layer_flags;
   layer_flags.setBlendMode(flags.getBlendMode());
   PaintCanvasAutoRestore ar(canvas, false);
-  canvas->saveLayer(nullptr, &layer_flags);
+  canvas->saveLayer(layer_flags);
 
   cc::PaintFlags image_flags(flags);
   image_flags.setBlendMode(SkBlendMode::kSrcOver);
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc
index 0537805..2518b71 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -223,17 +223,6 @@
 }
 #endif
 
-void GraphicsContext::SaveLayer(const SkRect* bounds,
-                                const cc::PaintFlags* flags) {
-  DCHECK(canvas_);
-  canvas_->saveLayer(bounds, flags);
-}
-
-void GraphicsContext::RestoreLayer() {
-  DCHECK(canvas_);
-  canvas_->restore();
-}
-
 void GraphicsContext::SetInDrawingRecorder(bool val) {
   // Nested drawing recorers are not allowed.
   DCHECK(!val || !in_drawing_recorder_);
@@ -277,23 +266,36 @@
   canvas_->concat(matrix);
 }
 
-void GraphicsContext::BeginLayer(float opacity,
-                                 SkBlendMode xfermode,
-                                 const gfx::RectF* bounds,
-                                 ColorFilter color_filter,
-                                 sk_sp<PaintFilter> image_filter) {
-  cc::PaintFlags layer_flags;
-  layer_flags.setAlpha(static_cast<unsigned char>(opacity * 255));
-  layer_flags.setBlendMode(xfermode);
-  layer_flags.setColorFilter(WebCoreColorFilterToSkiaColorFilter(color_filter));
-  layer_flags.setImageFilter(std::move(image_filter));
+void GraphicsContext::BeginLayer(float opacity) {
+  DCHECK(canvas_);
+  canvas_->saveLayerAlpha(static_cast<uint8_t>(opacity * 255));
 
-  if (bounds) {
-    SkRect sk_bounds = gfx::RectFToSkRect(*bounds);
-    SaveLayer(&sk_bounds, &layer_flags);
-  } else {
-    SaveLayer(nullptr, &layer_flags);
-  }
+#if DCHECK_IS_ON()
+  ++layer_count_;
+#endif
+}
+
+void GraphicsContext::BeginLayer(SkBlendMode xfermode) {
+  cc::PaintFlags flags;
+  flags.setBlendMode(xfermode);
+  BeginLayer(flags);
+}
+
+void GraphicsContext::BeginLayer(ColorFilter color_filter) {
+  cc::PaintFlags flags;
+  flags.setColorFilter(WebCoreColorFilterToSkiaColorFilter(color_filter));
+  BeginLayer(flags);
+}
+
+void GraphicsContext::BeginLayer(sk_sp<PaintFilter> image_filter) {
+  cc::PaintFlags flags;
+  flags.setImageFilter(std::move(image_filter));
+  BeginLayer(flags);
+}
+
+void GraphicsContext::BeginLayer(const cc::PaintFlags& flags) {
+  DCHECK(canvas_);
+  canvas_->saveLayer(flags);
 
 #if DCHECK_IS_ON()
   ++layer_count_;
@@ -301,7 +303,8 @@
 }
 
 void GraphicsContext::EndLayer() {
-  RestoreLayer();
+  DCHECK(canvas_);
+  canvas_->restore();
 
 #if DCHECK_IS_ON()
   DCHECK_GT(layer_count_--, 0);
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h
index 3d4a766..ca6ada2 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.h
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -459,14 +459,13 @@
                        const AutoDarkMode& auto_dark_mode,
                        const cc::PaintFlags* flags = nullptr);
 
-  // beginLayer()/endLayer() behave like save()/restore() for CTM and clip
-  // states. Apply SkBlendMode when the layer is composited on the backdrop
-  // (i.e. endLayer()).
-  void BeginLayer(float opacity = 1.0f,
-                  SkBlendMode = SkBlendMode::kSrcOver,
-                  const gfx::RectF* = nullptr,
-                  ColorFilter = kColorFilterNone,
-                  sk_sp<PaintFilter> = nullptr);
+  // BeginLayer()/EndLayer() behave like Save()/Restore() for CTM and clip
+  // states. Apply opacity, blend mode, filter when the layer is composited on
+  // the backdrop (i.e. EndLayer()).
+  void BeginLayer(float opacity = 1.0f);
+  void BeginLayer(SkBlendMode);
+  void BeginLayer(ColorFilter);
+  void BeginLayer(sk_sp<PaintFilter>);
   void EndLayer();
 
   // Instead of being dispatched to the active canvas, draw commands following
@@ -582,8 +581,7 @@
   template <typename DrawTextFunc>
   void DrawTextPasses(const AutoDarkMode& auto_dark_mode, const DrawTextFunc&);
 
-  void SaveLayer(const SkRect* bounds, const cc::PaintFlags*);
-  void RestoreLayer();
+  void BeginLayer(const cc::PaintFlags&);
 
   // SkCanvas wrappers.
   void ClipRRect(const SkRRect&,
@@ -618,7 +616,7 @@
   PaintController& paint_controller_;
 
   // Paint states stack. The state controls the appearance of drawn content, so
-  // this stack enables local drawing state changes with save()/restore() calls.
+  // this stack enables local drawing state changes with Save()/Restore() calls.
   // We do not delete from this stack to avoid memory churn.
   Vector<std::unique_ptr<GraphicsContextState>> paint_state_stack_;
 
diff --git a/third_party/blink/renderer/platform/graphics/paint_generated_image.cc b/third_party/blink/renderer/platform/graphics/paint_generated_image.cc
index 6f4f6ec..cb746c0 100644
--- a/third_party/blink/renderer/platform/graphics/paint_generated_image.cc
+++ b/third_party/blink/renderer/platform/graphics/paint_generated_image.cc
@@ -21,7 +21,7 @@
   SkRect sk_src_rect = gfx::RectFToSkRect(src_rect);
   canvas->clipRect(sk_dest_rect);
   canvas->concat(SkM44::RectToRect(sk_src_rect, sk_dest_rect));
-  canvas->saveLayer(&sk_src_rect, &flags);
+  canvas->saveLayer(sk_src_rect, flags);
   canvas->drawPicture(record_);
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h b/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h
index 9c2d15a..8f17ab0 100644
--- a/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h
+++ b/third_party/blink/renderer/platform/graphics/test/mock_paint_canvas.h
@@ -26,9 +26,11 @@
   MOCK_METHOD1(setNodeId, void(int));
   MOCK_METHOD0(flush, void());
   MOCK_METHOD0(save, int());
+  MOCK_METHOD1(saveLayer, int(const cc::PaintFlags& flags));
   MOCK_METHOD2(saveLayer,
-               int(const SkRect* bounds, const cc::PaintFlags* flags));
-  MOCK_METHOD2(saveLayerAlpha, int(const SkRect* bounds, uint8_t alpha));
+               int(const SkRect& bounds, const cc::PaintFlags& flags));
+  MOCK_METHOD1(saveLayerAlpha, int(uint8_t alpha));
+  MOCK_METHOD2(saveLayerAlpha, int(const SkRect& bounds, uint8_t alpha));
   MOCK_METHOD0(restore, void());
   MOCK_CONST_METHOD0(getSaveCount, int());
   MOCK_METHOD1(restoreToCount, void(int save_count));
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc
index 7d924f2f..57c53ca 100644
--- a/ui/gfx/canvas.cc
+++ b/ui/gfx/canvas.cc
@@ -111,16 +111,15 @@
 }
 
 void Canvas::SaveLayerAlpha(uint8_t alpha) {
-  canvas_->saveLayerAlpha(NULL, alpha);
+  canvas_->saveLayerAlpha(alpha);
 }
 
 void Canvas::SaveLayerAlpha(uint8_t alpha, const Rect& layer_bounds) {
-  SkRect bounds(RectToSkRect(layer_bounds));
-  canvas_->saveLayerAlpha(&bounds, alpha);
+  canvas_->saveLayerAlpha(RectToSkRect(layer_bounds), alpha);
 }
 
 void Canvas::SaveLayerWithFlags(const cc::PaintFlags& flags) {
-  canvas_->saveLayer(nullptr /* bounds */, &flags);
+  canvas_->saveLayer(flags);
 }
 
 void Canvas::Restore() {
@@ -319,7 +318,7 @@
                  SkFloatToScalar(1.0f / bitmap_scale));
   canvas_->translate(SkFloatToScalar(std::round(x * bitmap_scale)),
                      SkFloatToScalar(std::round(y * bitmap_scale)));
-  canvas_->saveLayer(nullptr, &flags);
+  canvas_->saveLayer(flags);
   canvas_->drawPicture(image_rep.GetPaintRecord());
   canvas_->restore();
 }
diff --git a/ui/views/controls/button/label_button_border.cc b/ui/views/controls/button/label_button_border.cc
index 2eda120..367001d9079 100644
--- a/ui/views/controls/button/label_button_border.cc
+++ b/ui/views/controls/button/label_button_border.cc
@@ -101,12 +101,12 @@
 
     const SkRect sk_rect = gfx::RectToSkRect(rect);
     cc::PaintCanvasAutoRestore auto_restore(canvas->sk_canvas(), false);
-    canvas->sk_canvas()->saveLayer(&sk_rect, nullptr);
+    canvas->sk_canvas()->saveLayer(sk_rect, cc::PaintFlags());
 
     {
       // First, modulate the background by 1 - alpha.
       cc::PaintCanvasAutoRestore auto_restore_alpha(canvas->sk_canvas(), false);
-      canvas->sk_canvas()->saveLayerAlpha(&sk_rect, 255 - fg_alpha);
+      canvas->sk_canvas()->saveLayerAlpha(sk_rect, 255 - fg_alpha);
       state = native_theme_delegate->GetBackgroundThemeState(&extra);
       PaintHelper(this, canvas, state, rect, extra);
     }
@@ -115,7 +115,7 @@
     cc::PaintFlags flags;
     flags.setAlpha(fg_alpha);
     flags.setBlendMode(SkBlendMode::kPlus);
-    canvas->sk_canvas()->saveLayer(&sk_rect, &flags);
+    canvas->sk_canvas()->saveLayer(sk_rect, flags);
     state = native_theme_delegate->GetForegroundThemeState(&extra);
     PaintHelper(this, canvas, state, rect, extra);
   } else {