summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
blob: 1e7e0c1f11389e7e657f6496a021133bd795a025 (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// 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/compositing/content_layer_client_impl.h"

#include <memory>
#include "base/bind.h"
#include "base/optional.h"
#include "base/trace_event/traced_value.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_op_buffer.h"
#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
#include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h"
#include "third_party/blink/renderer/platform/graphics/logging_canvas.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_list.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h"
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h"
#include "third_party/blink/renderer/platform/json/json_values.h"

namespace blink {

ContentLayerClientImpl::ContentLayerClientImpl()
    : cc_picture_layer_(cc::PictureLayer::Create(this)),
      raster_invalidation_function_(
          base::BindRepeating(&ContentLayerClientImpl::InvalidateRect,
                              base::Unretained(this))),
      layer_state_(PropertyTreeState::Uninitialized()) {}

ContentLayerClientImpl::~ContentLayerClientImpl() {
  cc_picture_layer_->ClearClient();
}

void ContentLayerClientImpl::AppendAdditionalInfoAsJSON(
    LayerTreeFlags flags,
    const cc::Layer& layer,
    JSONObject& json) const {
#if DCHECK_IS_ON()
  if (flags & kLayerTreeIncludesDebugInfo)
    json.SetValue("paintChunkContents", paint_chunk_debug_data_->Clone());
#endif

  if ((flags & (kLayerTreeIncludesInvalidations |
                kLayerTreeIncludesDetailedInvalidations)) &&
      raster_invalidator_.GetTracking()) {
    raster_invalidator_.GetTracking()->AsJSON(
        &json, flags & kLayerTreeIncludesDetailedInvalidations);
  }

#if DCHECK_IS_ON()
  if (flags & kLayerTreeIncludesPaintRecords) {
    LoggingCanvas canvas;
    cc_display_item_list_->Raster(&canvas);
    json.SetValue("paintRecord", canvas.Log());
  }
#endif
}

scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
    scoped_refptr<const PaintArtifact> paint_artifact,
    const PaintChunkSubset& paint_chunks,
    const gfx::Rect& layer_bounds,
    const PropertyTreeState& layer_state) {
  if (paint_chunks[0].is_cacheable)
    id_.emplace(paint_chunks[0].id);
  else
    id_ = base::nullopt;

  const auto& display_item_list = paint_artifact->GetDisplayItemList();

#if DCHECK_IS_ON()
  paint_chunk_debug_data_ = std::make_unique<JSONArray>();
  for (const auto& chunk : paint_chunks) {
    auto json = std::make_unique<JSONObject>();
    json->SetString("data", chunk.ToString());
    json->SetArray("displayItems",
                   paint_artifact->GetDisplayItemList().DisplayItemsAsJSON(
                       chunk.begin_index, chunk.end_index,
                       DisplayItemList::kShowOnlyDisplayItemTypes));
    paint_chunk_debug_data_->PushObject(std::move(json));
  }
#endif

  // The raster invalidator will only handle invalidations within a cc::Layer so
  // we need this invalidation if the layer's properties have changed.
  if (layer_state != layer_state_)
    cc_picture_layer_->SetSubtreePropertyChanged();

  raster_invalidator_.Generate(raster_invalidation_function_, paint_artifact,
                               paint_chunks, layer_bounds, layer_state);
  layer_state_ = layer_state;

  // Note: cc::Layer API assumes the layer bounds start at (0, 0), but the
  // bounding box of a paint chunk does not necessarily start at (0, 0) (and
  // could even be negative). Internally the generated layer translates the
  // paint chunk to align the bounding box to (0, 0) and we set the layer's
  // offset_to_transform_parent with the origin of the paint chunk here.
  cc_picture_layer_->SetOffsetToTransformParent(
      layer_bounds.OffsetFromOrigin());
  cc_picture_layer_->SetBounds(layer_bounds.size());
  cc_picture_layer_->SetHitTestable(true);

  base::Optional<RasterUnderInvalidationCheckingParams> params;
  if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
    params.emplace(*raster_invalidator_.GetTracking(),
                   IntRect(0, 0, layer_bounds.width(), layer_bounds.height()),
                   paint_chunks[0].id.client.DebugName());
  }
  cc_display_item_list_ = PaintChunksToCcLayer::Convert(
      paint_chunks, layer_state, layer_bounds.OffsetFromOrigin(),
      display_item_list, cc::DisplayItemList::kTopLevelDisplayItemList,
      base::OptionalOrNullptr(params));

  cc_picture_layer_->SetIsDrawable(
      (!layer_bounds.IsEmpty() && cc_display_item_list_->TotalOpCount()) ||
      // Backdrop filters require the layer to be drawable even if the layer
      // draws nothing.
      !layer_state.Effect().BackdropFilter().IsEmpty());

  auto safe_opaque_background_color =
      paint_artifact->SafeOpaqueBackgroundColor(paint_chunks);
  cc_picture_layer_->SetSafeOpaqueBackgroundColor(safe_opaque_background_color);
  // TODO(masonfreed): We don't need to set the background color here; only the
  // safe opaque background color matters. But making that change would require
  // rebaselining 787 tests to remove the "background_color" property from the
  // layer dumps.
  cc_picture_layer_->SetBackgroundColor(safe_opaque_background_color);
  return cc_picture_layer_;
}

}  // namespace blink