Index: cc/paint/paint_op_buffer.cc |
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc |
index c0da76581e2eb61049bebf9d5822253a547f4270..722fae32bbeae69a22fb86ac082d676e392c6d95 100644 |
--- a/cc/paint/paint_op_buffer.cc |
+++ b/cc/paint/paint_op_buffer.cc |
@@ -55,9 +55,10 @@ using RasterWithFlagsFunction = void (*)(const PaintOpWithFlags* op, |
NOINLINE static void RasterWithAlphaInternal(RasterFunction raster_fn, |
const PaintOp* op, |
SkCanvas* canvas, |
+ const SkRect& bounds, |
uint8_t alpha) { |
- // TODO(enne): is it ok to just drop the bounds here? |
- canvas->saveLayerAlpha(nullptr, alpha); |
+ bool unset = bounds.x() == PaintOp::kUnsetRect.x(); |
+ canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); |
SkMatrix unused_matrix; |
raster_fn(op, canvas, unused_matrix); |
canvas->restore(); |
@@ -67,12 +68,15 @@ NOINLINE static void RasterWithAlphaInternal(RasterFunction raster_fn, |
// have or don't have PaintFlags. |
template <typename T, bool HasFlags> |
struct Rasterizer { |
- static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { |
+ static void RasterWithAlpha(const T* op, |
+ SkCanvas* canvas, |
+ const SkRect& bounds, |
+ uint8_t alpha) { |
static_assert( |
!T::kHasPaintFlags, |
"This function should not be used for a PaintOp that has PaintFlags"); |
DCHECK(T::kIsDrawOp); |
- RasterWithAlphaInternal(&T::Raster, op, canvas, alpha); |
+ RasterWithAlphaInternal(&T::Raster, op, canvas, bounds, alpha); |
} |
}; |
@@ -80,6 +84,7 @@ NOINLINE static void RasterWithAlphaInternalForFlags( |
RasterWithFlagsFunction raster_fn, |
const PaintOpWithFlags* op, |
SkCanvas* canvas, |
+ const SkRect& bounds, |
uint8_t alpha) { |
SkMatrix unused_matrix; |
if (alpha == 255) { |
@@ -89,7 +94,8 @@ NOINLINE static void RasterWithAlphaInternalForFlags( |
flags.setAlpha(SkMulDiv255Round(flags.getAlpha(), alpha)); |
raster_fn(op, &flags, canvas, unused_matrix); |
} else { |
- canvas->saveLayerAlpha(nullptr, alpha); |
+ bool unset = bounds.x() == PaintOp::kUnsetRect.x(); |
+ canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); |
raster_fn(op, &op->flags, canvas, unused_matrix); |
canvas->restore(); |
} |
@@ -97,11 +103,15 @@ NOINLINE static void RasterWithAlphaInternalForFlags( |
template <typename T> |
struct Rasterizer<T, true> { |
- static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { |
+ static void RasterWithAlpha(const T* op, |
+ SkCanvas* canvas, |
+ const SkRect& bounds, |
+ uint8_t alpha) { |
static_assert(T::kHasPaintFlags, |
"This function expects the PaintOp to have PaintFlags"); |
DCHECK(T::kIsDrawOp); |
- RasterWithAlphaInternalForFlags(&T::RasterWithFlags, op, canvas, alpha); |
+ RasterWithAlphaInternalForFlags(&T::RasterWithFlags, op, canvas, bounds, |
+ alpha); |
} |
}; |
@@ -109,6 +119,7 @@ template <> |
struct Rasterizer<DrawRecordOp, false> { |
static void RasterWithAlpha(const DrawRecordOp* op, |
SkCanvas* canvas, |
+ const SkRect& bounds, |
uint8_t alpha) { |
// This "looking into records" optimization is done here instead of |
// in the PaintOpBuffer::Raster function as DisplayItemList calls |
@@ -117,12 +128,13 @@ struct Rasterizer<DrawRecordOp, false> { |
PaintOp* single_op = op->record->GetFirstOp(); |
// RasterWithAlpha only supported for draw ops. |
if (single_op->IsDrawOp()) { |
- single_op->RasterWithAlpha(canvas, alpha); |
+ single_op->RasterWithAlpha(canvas, bounds, alpha); |
return; |
} |
} |
- canvas->saveLayerAlpha(nullptr, alpha); |
+ bool unset = bounds.x() == PaintOp::kUnsetRect.x(); |
+ canvas->saveLayerAlpha(unset ? nullptr : &bounds, alpha); |
SkMatrix unused_matrix; |
DrawRecordOp::Raster(op, canvas, unused_matrix); |
canvas->restore(); |
@@ -148,12 +160,13 @@ static const RasterFunction g_raster_functions[kNumOpTypes] = {TYPES(M)}; |
using RasterAlphaFunction = void (*)(const PaintOp* op, |
SkCanvas* canvas, |
+ const SkRect& bounds, |
uint8_t alpha); |
#define M(T) \ |
- T::kIsDrawOp ? \ |
- [](const PaintOp* op, SkCanvas* canvas, uint8_t alpha) { \ |
+ T::kIsDrawOp ? [](const PaintOp* op, SkCanvas* canvas, const SkRect& bounds, \ |
+ uint8_t alpha) { \ |
Rasterizer<T, T::kHasPaintFlags>::RasterWithAlpha( \ |
- static_cast<const T*>(op), canvas, alpha); \ |
+ static_cast<const T*>(op), canvas, bounds, alpha); \ |
} : static_cast<RasterAlphaFunction>(nullptr), |
static const RasterAlphaFunction g_raster_alpha_functions[kNumOpTypes] = { |
TYPES(M)}; |
@@ -446,8 +459,10 @@ void PaintOp::Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const { |
g_raster_functions[type](this, canvas, original_ctm); |
} |
-void PaintOp::RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const { |
- g_raster_alpha_functions[type](this, canvas, alpha); |
+void PaintOp::RasterWithAlpha(SkCanvas* canvas, |
+ const SkRect& bounds, |
+ uint8_t alpha) const { |
+ g_raster_alpha_functions[type](this, canvas, bounds, alpha); |
} |
int ClipPathOp::CountSlowPaths() const { |
@@ -715,7 +730,7 @@ void PaintOpBuffer::PlaybackRanges(const std::vector<size_t>& range_starts, |
if (third && third->GetType() == PaintOpType::Restore) { |
const SaveLayerAlphaOp* save_op = |
static_cast<const SaveLayerAlphaOp*>(op); |
- second->RasterWithAlpha(canvas, save_op->alpha); |
+ second->RasterWithAlpha(canvas, save_op->bounds, save_op->alpha); |
continue; |
} |
} |