summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
blob: 8b76eb1fdd9e65930c84b723b53f546076840edc (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
// Copyright 2016 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/foreign_layer_display_item.h"

#include <utility>

#include "cc/layers/layer.h"
#include "cc/layers/picture_layer.h"
#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"

namespace blink {

namespace {

// It uses DebugName and OwnerNodeId of the input DisplayItemClient, while
// calculate VisualRect from the layer's offset and bounds.
class ForeignLayerDisplayItemClient final : public DisplayItemClient {
 public:
  ForeignLayerDisplayItemClient(const DisplayItemClient& client,
                                scoped_refptr<cc::Layer> layer,
                                const FloatPoint& offset)
      : client_(client), layer_(std::move(layer)), offset_(offset) {
    DCHECK(layer_);
    Invalidate(PaintInvalidationReason::kUncacheable);
  }

  String DebugName() const final { return client_.DebugName(); }

  DOMNodeId OwnerNodeId() const final { return client_.OwnerNodeId(); }

  IntRect VisualRect() const final {
    const auto& bounds = layer_->bounds();
    return EnclosingIntRect(
        FloatRect(offset_.X(), offset_.Y(), bounds.width(), bounds.height()));
  }

  cc::Layer* GetLayer() const { return layer_.get(); }

 private:
  const DisplayItemClient& client_;
  scoped_refptr<cc::Layer> layer_;
  FloatPoint offset_;
};

}  // anonymous namespace

ForeignLayerDisplayItem::ForeignLayerDisplayItem(
    const DisplayItemClient& client,
    Type type,
    scoped_refptr<cc::Layer> layer,
    const FloatPoint& offset)
    : DisplayItem(
          *new ForeignLayerDisplayItemClient(client, std::move(layer), offset),
          type,
          sizeof(*this)),
      offset_(offset) {
  DCHECK(IsForeignLayerType(type));
  DCHECK(!IsCacheable());
}

ForeignLayerDisplayItem::~ForeignLayerDisplayItem() {
  delete &Client();
}

cc::Layer* ForeignLayerDisplayItem::GetLayer() const {
  return static_cast<const ForeignLayerDisplayItemClient&>(Client()).GetLayer();
}

bool ForeignLayerDisplayItem::Equals(const DisplayItem& other) const {
  return GetType() == other.GetType() &&
         GetLayer() ==
             static_cast<const ForeignLayerDisplayItem&>(other).GetLayer();
}

#if DCHECK_IS_ON()
void ForeignLayerDisplayItem::PropertiesAsJSON(JSONObject& json) const {
  DisplayItem::PropertiesAsJSON(json);
  json.SetInteger("layer", GetLayer()->id());
  json.SetDouble("offset_x", Offset().X());
  json.SetDouble("offset_y", Offset().Y());
}
#endif

void RecordForeignLayer(GraphicsContext& context,
                        const DisplayItemClient& client,
                        DisplayItem::Type type,
                        scoped_refptr<cc::Layer> layer,
                        const FloatPoint& offset,
                        const PropertyTreeState* properties) {
  PaintController& paint_controller = context.GetPaintController();
  // This is like ScopedPaintChunkProperties but uses null id because foreign
  // layer chunk doesn't need an id nor a client.
  base::Optional<PropertyTreeState> previous_properties;
  if (properties) {
    previous_properties.emplace(paint_controller.CurrentPaintChunkProperties());
    paint_controller.UpdateCurrentPaintChunkProperties(nullptr, *properties);
  }
  paint_controller.CreateAndAppend<ForeignLayerDisplayItem>(
      client, type, std::move(layer), offset);
  if (properties) {
    paint_controller.UpdateCurrentPaintChunkProperties(nullptr,
                                                       *previous_properties);
  }
}

}  // namespace blink