forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathca_layer_tree_coordinator.mm
134 lines (114 loc) · 4.6 KB
/
ca_layer_tree_coordinator.mm
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
134
// 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 "ui/accelerated_widget_mac/ca_layer_tree_coordinator.h"
#include <AVFoundation/AVFoundation.h>
#include "base/mac/mac_util.h"
#include "base/trace_event/trace_event.h"
#include "ui/base/cocoa/animation_utils.h"
namespace ui {
namespace {
const uint64_t kFramesBeforeFlushingLowPowerLayer = 15;
}
CALayerTreeCoordinator::CALayerTreeCoordinator(
bool allow_remote_layers,
bool allow_av_sample_buffer_display_layer)
: allow_remote_layers_(allow_remote_layers),
allow_av_sample_buffer_display_layer_(
allow_av_sample_buffer_display_layer) {
if (allow_remote_layers_) {
root_ca_layer_.reset([[CALayer alloc] init]);
[root_ca_layer_ setGeometryFlipped:YES];
[root_ca_layer_ setOpaque:YES];
if (allow_av_sample_buffer_display_layer_) {
fullscreen_low_power_layer_.reset(
[[AVSampleBufferDisplayLayer alloc] init]);
}
}
}
CALayerTreeCoordinator::~CALayerTreeCoordinator() {}
void CALayerTreeCoordinator::Resize(const gfx::Size& pixel_size,
float scale_factor) {
pixel_size_ = pixel_size;
scale_factor_ = scale_factor;
}
bool CALayerTreeCoordinator::SetPendingGLRendererBackbuffer(
base::ScopedCFTypeRef<IOSurfaceRef> backbuffer) {
if (pending_ca_renderer_layer_tree_) {
DLOG(ERROR) << "Either CALayer overlays or a backbuffer should be "
"specified, but not both.";
return false;
}
if (pending_gl_renderer_layer_tree_) {
DLOG(ERROR) << "Only one backbuffer per swap is allowed.";
return false;
}
pending_gl_renderer_layer_tree_.reset(new GLRendererLayerTree(
allow_remote_layers_, backbuffer, gfx::Rect(pixel_size_)));
return true;
}
CARendererLayerTree* CALayerTreeCoordinator::GetPendingCARendererLayerTree() {
DCHECK(allow_remote_layers_);
if (pending_gl_renderer_layer_tree_) {
DLOG(ERROR) << "Either CALayer overlays or a backbuffer should be "
"specified, but not both.";
}
if (!pending_ca_renderer_layer_tree_)
pending_ca_renderer_layer_tree_.reset(new CARendererLayerTree(
allow_av_sample_buffer_display_layer_, false));
return pending_ca_renderer_layer_tree_.get();
}
void CALayerTreeCoordinator::CommitPendingTreesToCA(
const gfx::Rect& pixel_damage_rect,
bool* fullscreen_low_power_layer_valid) {
*fullscreen_low_power_layer_valid = false;
// Update the CALayer hierarchy.
ScopedCAActionDisabler disabler;
if (pending_ca_renderer_layer_tree_) {
pending_ca_renderer_layer_tree_->CommitScheduledCALayers(
root_ca_layer_.get(), std::move(current_ca_renderer_layer_tree_),
scale_factor_);
*fullscreen_low_power_layer_valid =
pending_ca_renderer_layer_tree_->CommitFullscreenLowPowerLayer(
fullscreen_low_power_layer_);
current_ca_renderer_layer_tree_.swap(pending_ca_renderer_layer_tree_);
current_gl_renderer_layer_tree_.reset();
} else if (pending_gl_renderer_layer_tree_) {
pending_gl_renderer_layer_tree_->CommitCALayers(
root_ca_layer_.get(), std::move(current_gl_renderer_layer_tree_),
scale_factor_, pixel_damage_rect);
current_gl_renderer_layer_tree_.swap(pending_gl_renderer_layer_tree_);
current_ca_renderer_layer_tree_.reset();
} else {
TRACE_EVENT0("gpu", "Blank frame: No overlays or CALayers");
[root_ca_layer_ setSublayers:nil];
current_gl_renderer_layer_tree_.reset();
current_ca_renderer_layer_tree_.reset();
}
// It is necessary to leave the last image up for a few extra frames to allow
// a smooth switch between the normal and low-power NSWindows.
if (*fullscreen_low_power_layer_valid)
frames_since_low_power_layer_was_valid_ = 0;
else
frames_since_low_power_layer_was_valid_ += 1;
if (frames_since_low_power_layer_was_valid_ ==
kFramesBeforeFlushingLowPowerLayer)
[fullscreen_low_power_layer_ flushAndRemoveImage];
// Reset all state for the next frame.
pending_ca_renderer_layer_tree_.reset();
pending_gl_renderer_layer_tree_.reset();
}
CALayer* CALayerTreeCoordinator::GetCALayerForDisplay() const {
DCHECK(allow_remote_layers_);
return root_ca_layer_.get();
}
CALayer* CALayerTreeCoordinator::GetFullscreenLowPowerLayerForDisplay() const {
return fullscreen_low_power_layer_.get();
}
IOSurfaceRef CALayerTreeCoordinator::GetIOSurfaceForDisplay() {
DCHECK(!allow_remote_layers_);
if (!current_gl_renderer_layer_tree_)
return nullptr;
return current_gl_renderer_layer_tree_->RootLayerIOSurface();
}
} // namespace ui