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
|