Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
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
26 changes: 23 additions & 3 deletions display_list/display_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,34 @@ void DisplayList::ComputeRTree() {
void DisplayList::Dispatch(Dispatcher& dispatcher,
uint8_t* ptr,
uint8_t* end) const {
DispatchContext context = {
.dispatcher = dispatcher,

.cur_offset = 0,
.next_render_offset = 0,

.next_restore_offset = std::numeric_limits<dl_offset>::max(),
};

uint8_t* op_base = storage_.get();
while (ptr < end) {
context.cur_offset = ptr - op_base;
// The following line would be used to cull render ops by setting
// it to the next rendering op that matched in the RTree instead
// of setting it to cur_offset. For now it is using the cur_offset
// as the next_render_offset to test the op_needed tests in the
// DLOps, but if there is no RTree culling going on, it would be
// just as valid to leave the next_render_offset as 0 for the
// entire run (in fact, that scenario has also been tested and
// works just fine to avoid any culling).
context.next_render_offset = context.cur_offset;
auto op = reinterpret_cast<const DLOp*>(ptr);
ptr += op->size;
FML_DCHECK(ptr <= end);
switch (op->type) {
#define DL_OP_DISPATCH(name) \
case DisplayListOpType::k##name: \
static_cast<const name##Op*>(op)->dispatch(dispatcher); \
#define DL_OP_DISPATCH(name) \
case DisplayListOpType::k##name: \
static_cast<const name##Op*>(op)->dispatch(context); \
break;

FOR_EACH_DISPLAY_LIST_OP(DL_OP_DISPATCH)
Expand Down
14 changes: 10 additions & 4 deletions display_list/display_list_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,9 @@ void DisplayListBuilder::setAttributesFromPaint(

void DisplayListBuilder::checkForDeferredSave() {
if (current_layer_->has_deferred_save_op_) {
size_t save_offset = used_;
Push<SaveOp>(0, 1);
current_layer_->save_offset = save_offset;
current_layer_->has_deferred_save_op_ = false;
}
}
Expand All @@ -436,7 +438,10 @@ void DisplayListBuilder::save() {

void DisplayListBuilder::restore() {
if (layer_stack_.size() > 1) {
SaveOpBase* op = reinterpret_cast<SaveOpBase*>(storage_.get() +
current_layer_->save_offset);
if (!current_layer_->has_deferred_save_op_) {
op->restore_offset = used_;
Push<RestoreOp>(0, 1);
}
// Grab the current layer info before we push the restore
Expand All @@ -445,6 +450,9 @@ void DisplayListBuilder::restore() {
layer_stack_.pop_back();
current_layer_ = &layer_stack_.back();
if (layer_info.has_layer) {
// Layers are never deferred for now, we need to update the
// following code if we ever do saveLayer culling...
FML_DCHECK(!layer_info.has_deferred_save_op_);
if (layer_info.is_group_opacity_compatible()) {
// We are now going to go back and modify the matching saveLayer
// call to add the option indicating it can distribute an opacity
Expand All @@ -458,8 +466,6 @@ void DisplayListBuilder::restore() {
// in the DisplayList are only allowed *during* the build phase.
// Once built, the DisplayList records must remain read only to
// ensure consistency of rendering and |Equals()| behavior.
SaveLayerOp* op = reinterpret_cast<SaveLayerOp*>(
storage_.get() + layer_info.save_layer_offset);
op->options = op->options.with_can_distribute_opacity();
}
} else {
Expand All @@ -486,11 +492,11 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
size_t save_layer_offset = used_;
if (backdrop) {
bounds //
? Push<SaveLayerBackdropBoundsOp>(0, 1, *bounds, options, backdrop)
? Push<SaveLayerBackdropBoundsOp>(0, 1, options, *bounds, backdrop)
: Push<SaveLayerBackdropOp>(0, 1, options, backdrop);
} else {
bounds //
? Push<SaveLayerBoundsOp>(0, 1, *bounds, options)
? Push<SaveLayerBoundsOp>(0, 1, options, *bounds)
: Push<SaveLayerOp>(0, 1, options);
}
CheckLayerOpacityCompatibility(options.renders_with_attributes());
Expand Down
6 changes: 3 additions & 3 deletions display_list/display_list_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,9 @@ class DisplayListBuilder final : public virtual Dispatcher,
struct LayerInfo {
LayerInfo(const SkM44& matrix,
const SkRect& clip_bounds,
size_t save_layer_offset = 0,
size_t save_offset = 0,
bool has_layer = false)
: save_layer_offset(save_layer_offset),
: save_offset(save_offset),
has_layer(has_layer),
cannot_inherit_opacity(false),
has_compatible_op(false),
Expand All @@ -407,7 +407,7 @@ class DisplayListBuilder final : public virtual Dispatcher,
// the records inside the saveLayer that may impact how the saveLayer
// is handled (e.g., |cannot_inherit_opacity| == false).
// This offset is only valid if |has_layer| is true.
size_t save_layer_offset;
size_t save_offset;

bool has_deferred_save_op_ = false;

Expand Down
Loading