summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc
blob: acab9ab196b04c672363a8fb709a5b6cf1d2cd8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"

#include "cc/paint/display_item_list.h"
#include "third_party/blink/public/platform/web_display_item_list.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/skia/include/core/SkRegion.h"

namespace blink {

namespace {

void ComputeChunkBoundsAndOpaqueness(const DisplayItemList& display_items,
                                     Vector<PaintChunk>& paint_chunks) {
  for (PaintChunk& chunk : paint_chunks) {
    FloatRect bounds;
    SkRegion known_to_be_opaque_region;
    for (const DisplayItem& item : display_items.ItemsInPaintChunk(chunk)) {
      bounds.Unite(item.VisualRect());
      if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
          !item.IsDrawing())
        continue;
      const auto& drawing = static_cast<const DrawingDisplayItem&>(item);
      if (drawing.GetPaintRecord() && drawing.KnownToBeOpaque()) {
        known_to_be_opaque_region.op(
            SkIRect(EnclosedIntRect(drawing.VisualRect())),
            SkRegion::kUnion_Op);
      }
    }
    chunk.bounds = bounds;
    if (known_to_be_opaque_region.contains(EnclosingIntRect(bounds)))
      chunk.known_to_be_opaque = true;
  }
}

}  // namespace

PaintArtifact::PaintArtifact() : display_item_list_(0) {}

PaintArtifact::PaintArtifact(DisplayItemList display_items,
                             Vector<PaintChunk> paint_chunks)
    : display_item_list_(std::move(display_items)),
      paint_chunks_(std::move(paint_chunks)) {
  if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
    ComputeChunkBoundsAndOpaqueness(display_item_list_, paint_chunks_);
}

PaintArtifact::PaintArtifact(PaintArtifact&& source)
    : display_item_list_(std::move(source.display_item_list_)),
      paint_chunks_(std::move(source.paint_chunks_)) {}

PaintArtifact::~PaintArtifact() = default;

PaintArtifact& PaintArtifact::operator=(PaintArtifact&& source) {
  display_item_list_ = std::move(source.display_item_list_);
  paint_chunks_ = std::move(source.paint_chunks_);
  return *this;
}

void PaintArtifact::Reset() {
  display_item_list_.Clear();
  paint_chunks_.clear();
}

size_t PaintArtifact::ApproximateUnsharedMemoryUsage() const {
  return sizeof(*this) + display_item_list_.MemoryUsageInBytes() +
         paint_chunks_.capacity() * sizeof(paint_chunks_[0]);
}

void PaintArtifact::Replay(GraphicsContext& graphics_context,
                           const PropertyTreeState& replay_state,
                           const IntPoint& offset) const {
  if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
    DCHECK(offset == IntPoint());
    TRACE_EVENT0("blink,benchmark", "PaintArtifact::replay");
    for (const DisplayItem& display_item : display_item_list_)
      display_item.Replay(graphics_context);
  } else {
    Replay(*graphics_context.Canvas(), replay_state, offset);
  }
}

void PaintArtifact::Replay(PaintCanvas& canvas,
                           const PropertyTreeState& replay_state,
                           const IntPoint& offset) const {
  TRACE_EVENT0("blink,benchmark", "PaintArtifact::replay");
  DCHECK(RuntimeEnabledFeatures::SlimmingPaintV175Enabled());
  scoped_refptr<cc::DisplayItemList> display_item_list =
      PaintChunksToCcLayer::Convert(
          PaintChunks(), replay_state, gfx::Vector2dF(offset.X(), offset.Y()),
          GetDisplayItemList(),
          cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer);
  canvas.drawPicture(display_item_list->ReleaseAsRecord());
}

DISABLE_CFI_PERF
void PaintArtifact::AppendToWebDisplayItemList(
    const FloatSize& visual_rect_offset,
    WebDisplayItemList* list) const {
  TRACE_EVENT0("blink,benchmark", "PaintArtifact::appendToWebDisplayItemList");
  for (const DisplayItem& item : display_item_list_)
    item.AppendToWebDisplayItemList(visual_rect_offset, list);
}

}  // namespace blink