Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions display_list/display_list_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "flutter/display_list/display_list_builder.h"

#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_blend_mode.h"
#include "flutter/display_list/display_list_ops.h"

Expand Down Expand Up @@ -413,19 +414,29 @@ void DisplayListBuilder::setAttributesFromPaint(
}
}

void DisplayListBuilder::checkForDeferredSave() {
if (current_layer_->has_deferred_save_op_) {
Push<SaveOp>(0, 1);
current_layer_->has_deferred_save_op_ = false;
}
}

void DisplayListBuilder::save() {
Push<SaveOp>(0, 1);
layer_stack_.emplace_back(current_layer_);
current_layer_ = &layer_stack_.back();
current_layer_->has_deferred_save_op_ = true;
}

void DisplayListBuilder::restore() {
if (layer_stack_.size() > 1) {
if (!current_layer_->has_deferred_save_op_) {
Push<RestoreOp>(0, 1);
}
// Grab the current layer info before we push the restore
// on the stack.
LayerInfo layer_info = layer_stack_.back();
layer_stack_.pop_back();
current_layer_ = &layer_stack_.back();
Push<RestoreOp>(0, 1);
if (layer_info.has_layer) {
if (layer_info.is_group_opacity_compatible()) {
// We are now going to go back and modify the matching saveLayer
Expand Down Expand Up @@ -504,26 +515,30 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
if (SkScalarIsFinite(tx) && SkScalarIsFinite(ty) &&
(tx != 0.0 || ty != 0.0)) {
checkForDeferredSave();
Push<TranslateOp>(0, 1, tx, ty);
current_layer_->matrix.preTranslate(tx, ty);
}
}
void DisplayListBuilder::scale(SkScalar sx, SkScalar sy) {
if (SkScalarIsFinite(sx) && SkScalarIsFinite(sy) &&
(sx != 1.0 || sy != 1.0)) {
checkForDeferredSave();
Push<ScaleOp>(0, 1, sx, sy);
current_layer_->matrix.preScale(sx, sy);
}
}
void DisplayListBuilder::rotate(SkScalar degrees) {
if (SkScalarMod(degrees, 360.0) != 0.0) {
checkForDeferredSave();
Push<RotateOp>(0, 1, degrees);
current_layer_->matrix.preConcat(SkMatrix::RotateDeg(degrees));
}
}
void DisplayListBuilder::skew(SkScalar sx, SkScalar sy) {
if (SkScalarIsFinite(sx) && SkScalarIsFinite(sy) &&
(sx != 0.0 || sy != 0.0)) {
checkForDeferredSave();
Push<SkewOp>(0, 1, sx, sy);
current_layer_->matrix.preConcat(SkMatrix::Skew(sx, sy));
}
Expand All @@ -540,6 +555,7 @@ void DisplayListBuilder::transform2DAffine(
SkScalarsAreFinite(mxt, myt) &&
!(mxx == 1 && mxy == 0 && mxt == 0 &&
myx == 0 && myy == 1 && myt == 0)) {
checkForDeferredSave();
Push<Transform2DAffineOp>(0, 1,
mxx, mxy, mxt,
myx, myy, myt);
Expand All @@ -565,6 +581,7 @@ void DisplayListBuilder::transformFullPerspective(
SkScalarsAreFinite(myx, myy) && SkScalarsAreFinite(myz, myt) &&
SkScalarsAreFinite(mzx, mzy) && SkScalarsAreFinite(mzz, mzt) &&
SkScalarsAreFinite(mwx, mwy) && SkScalarsAreFinite(mwz, mwt)) {
checkForDeferredSave();
Push<TransformFullPerspectiveOp>(0, 1,
mxx, mxy, mxz, mxt,
myx, myy, myz, myt,
Expand All @@ -578,6 +595,7 @@ void DisplayListBuilder::transformFullPerspective(
}
// clang-format on
void DisplayListBuilder::transformReset() {
checkForDeferredSave();
Push<TransformResetOp>(0, 0);
current_layer_->matrix.setIdentity();
}
Expand All @@ -599,6 +617,10 @@ void DisplayListBuilder::transform(const SkM44* m44) {
void DisplayListBuilder::clipRect(const SkRect& rect,
SkClipOp clip_op,
bool is_aa) {
if (!rect.isFinite()) {
return;
}
checkForDeferredSave();
switch (clip_op) {
case SkClipOp::kIntersect:
Push<ClipIntersectRectOp>(0, 1, rect, is_aa);
Expand All @@ -615,6 +637,7 @@ void DisplayListBuilder::clipRRect(const SkRRect& rrect,
if (rrect.isRect()) {
clipRect(rrect.rect(), clip_op, is_aa);
} else {
checkForDeferredSave();
switch (clip_op) {
case SkClipOp::kIntersect:
Push<ClipIntersectRRectOp>(0, 1, rrect, is_aa);
Expand Down Expand Up @@ -646,6 +669,7 @@ void DisplayListBuilder::clipPath(const SkPath& path,
return;
}
}
checkForDeferredSave();
switch (clip_op) {
case SkClipOp::kIntersect:
Push<ClipIntersectPathOp>(0, 1, path, is_aa);
Expand Down
4 changes: 4 additions & 0 deletions display_list/display_list_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ class DisplayListBuilder final : public virtual Dispatcher,
sk_sp<DisplayList> Build();

private:
void checkForDeferredSave();

SkAutoTMalloc<uint8_t> storage_;
size_t used_ = 0;
size_t allocated_ = 0;
Expand Down Expand Up @@ -397,6 +399,8 @@ class DisplayListBuilder final : public virtual Dispatcher,
// This offset is only valid if |has_layer| is true.
size_t save_layer_offset;

bool has_deferred_save_op_ = false;

bool has_layer;
bool cannot_inherit_opacity;
bool has_compatible_op;
Expand Down
Loading