Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Unified Diff: cc/paint/display_item_list.cc

Issue 2768143002: Back PaintRecord with PaintOpBuffer instead of SkPicture (Closed)
Patch Set: More unit tests Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/paint/display_item_list.cc
diff --git a/cc/paint/display_item_list.cc b/cc/paint/display_item_list.cc
index 830b3fbb15ffed9066378c28404c6e5b35aaf8d4..e056d87433a5e2a3c9ecca37487523bb4adf81d0 100644
--- a/cc/paint/display_item_list.cc
+++ b/cc/paint/display_item_list.cc
@@ -100,9 +100,13 @@ NOINLINE DISABLE_CFI_PERF void RasterItem(const DisplayItem& base_item,
if (canvas->quickReject(item.picture->cullRect()))
break;
- // SkPicture always does a wrapping save/restore on the canvas, so it is
- // not necessary here.
+ // TODO(enne): Maybe the PaintRecord itself could know whether this
+ // was needed? It's not clear whether these save/restore semantics
mtklein_C 2017/04/05 15:26:43 If you don't save and restore, you may want to at
enne (OOO) 2017/04/06 00:25:22 That's fair. The recorder does restoreToCount for
+ // that SkPicture handles during playback are things that should be
+ // kept around.
+ canvas->save();
item.picture->playback(canvas, callback);
+ canvas->restore();
break;
}
case DisplayItem::FLOAT_CLIP: {
@@ -176,6 +180,33 @@ void DisplayItemList::Raster(SkCanvas* canvas,
canvas->restore();
}
+// Atttempts to merge a CompositingDisplayItem and DrawingDisplayItem
+// into a single "draw with alpha". This function returns true if
+// it was successful. If false, then the caller is responsible for
+// drawing these items. This is a DisplayItemList version of the
+// SkRecord optimization SkRecordNoopSaveLayerDrawRestores.
+static bool MergeAndDrawIfPossible(const CompositingDisplayItem& save_item,
+ const DrawingDisplayItem& draw_item,
+ SkCanvas* canvas) {
+ if (save_item.color_filter)
+ return false;
+ if (save_item.xfermode != SkBlendMode::kSrcOver)
+ return false;
+ // TODO(enne): I believe that lcd_text_requires_opaque_layer is not
+ // relevant here and that lcd text is preserved post merge, but I haven't
+ // tested that.
+ const PaintRecord* record = draw_item.picture.get();
+ if (record->approximateOpCount() != 1)
+ return false;
+
+ const PaintOp* op = record->GetFirstOp();
+ if (!op->IsDrawOp())
+ return false;
+
+ op->RasterWithAlpha(canvas, save_item.alpha);
+ return true;
+}
+
void DisplayItemList::Raster(SkCanvas* canvas,
SkPicture::AbortCallback* callback) const {
gfx::Rect canvas_playback_rect;
@@ -184,8 +215,32 @@ void DisplayItemList::Raster(SkCanvas* canvas,
std::vector<size_t> indices;
rtree_.Search(canvas_playback_rect, &indices);
- for (size_t index : indices) {
- RasterItem(items_[index], canvas, callback);
+ for (size_t i = 0; i < indices.size(); ++i) {
+ const DisplayItem& item = items_[indices[i]];
+ // Optimize empty begin/end compositing and merge begin/draw/end compositing
+ // where possible.
+ // TODO(enne): remove empty clips here too?
+ // TODO(enne): does this happen recursively? Or is this good enough?
+ if (i < indices.size() - 2 && item.type == DisplayItem::COMPOSITING) {
+ const DisplayItem& second = items_[indices[i + 1]];
+ if (second.type == DisplayItem::END_COMPOSITING) {
+ i++;
+ // TODO(enne): does this ever happen? Is this worth catching?
+ continue;
+ }
+ const DisplayItem& third = items_[indices[i + 2]];
+ if (second.type == DisplayItem::DRAWING &&
+ third.type == DisplayItem::END_COMPOSITING) {
+ if (MergeAndDrawIfPossible(
+ static_cast<const CompositingDisplayItem&>(item),
+ static_cast<const DrawingDisplayItem&>(second), canvas)) {
+ i += 2;
+ continue;
+ }
+ }
+ }
+
+ RasterItem(item, canvas, callback);
// We use a callback during solid color analysis on the compositor thread to
// break out early. Since we're handling a sequence of pictures via rtree

Powered by Google App Engine
This is Rietveld 408576698