OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/exo/surface.h" | |
6 | |
7 #include "base/callback_helpers.h" | |
8 #include "base/logging.h" | |
9 #include "base/trace_event/trace_event.h" | |
10 #include "base/trace_event/trace_event_argument.h" | |
11 #include "cc/resources/single_release_callback.h" | |
12 #include "components/exo/buffer.h" | |
13 #include "components/exo/surface_delegate.h" | |
14 #include "ui/compositor/layer.h" | |
15 #include "ui/gfx/buffer_format_util.h" | |
16 #include "ui/gfx/gpu_memory_buffer.h" | |
17 | |
18 namespace exo { | |
19 | |
20 //////////////////////////////////////////////////////////////////////////////// | |
21 // Surface, public: | |
22 | |
23 Surface::Surface() : compositor_(nullptr), delegate_(nullptr) { | |
24 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR)); | |
25 set_owned_by_client(); | |
26 } | |
27 | |
28 Surface::~Surface() { | |
29 if (delegate_) | |
30 delegate_->OnSurfaceDestroying(); | |
31 | |
32 if (pending_mailbox_release_callback_) | |
33 pending_mailbox_release_callback_->Run(gpu::SyncToken(), false); | |
34 | |
35 layer()->SetShowSolidColorContent(); | |
36 | |
37 if (compositor_) | |
38 compositor_->RemoveObserver(this); | |
39 | |
40 // Call pending frame callbacks with a null frame time to indicate that they | |
41 // have been cancelled. | |
42 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); | |
43 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | |
44 frame_callbacks_); | |
45 std::for_each(active_frame_callbacks_.begin(), active_frame_callbacks_.end(), | |
46 [](const FrameCallback& frame_callback) { | |
47 frame_callback.Run(base::TimeTicks()); | |
48 }); | |
piman
2015/11/17 02:43:53
nit:
for (const auto& frame_callback : active_fram
reveman
2015/11/17 18:04:04
Done.
| |
49 } | |
50 | |
51 void Surface::Attach(Buffer* buffer, const gfx::Point& point) { | |
piman
2015/11/17 02:43:53
What is |point| used for?
reveman
2015/11/17 18:04:04
This was supposed to be an offset and not a point.
| |
52 TRACE_EVENT2("exo", "Surface::Attach", "buffer", buffer->AsTracedValue(), | |
53 "point", point.ToString()); | |
54 | |
55 // If Attach() is called twice without calling Commit(), run the release | |
56 // callback for the previous buffer now. | |
57 if (pending_mailbox_release_callback_) { | |
58 pending_mailbox_release_callback_->Run(gpu::SyncToken(), false); | |
59 pending_mailbox_release_callback_ = nullptr; | |
60 } | |
61 | |
62 // If |buffer| is null, the following Commit() call will remove the surface | |
63 // content. | |
64 if (buffer) { | |
65 pending_mailbox_release_callback_ = | |
66 buffer->GetTextureMailbox(&pending_mailbox_); | |
67 } | |
68 } | |
69 | |
70 void Surface::Damage(const gfx::Rect& damage) { | |
71 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); | |
72 | |
73 pending_damage_.Union(damage); | |
74 } | |
75 | |
76 void Surface::RequestFrameCallback(const FrameCallback& callback) { | |
77 TRACE_EVENT0("exo", "Surface::RequestFrameCallback"); | |
78 | |
79 pending_frame_callbacks_.push_back(callback); | |
80 } | |
81 | |
82 void Surface::SetOpaqueRegion(const cc::Region& region) { | |
83 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region", region.ToString()); | |
84 | |
85 pending_opaque_region_ = region; | |
86 } | |
87 | |
88 void Surface::Commit() { | |
89 TRACE_EVENT0("exo", "Surface::Commit"); | |
90 | |
91 if (delegate_) | |
92 delegate_->OnSurfaceCommit(); | |
93 | |
94 if (pending_mailbox_release_callback_) { | |
95 // Update layer with the new contents. | |
96 layer()->SetTextureMailbox(pending_mailbox_, | |
97 pending_mailbox_release_callback_.Pass(), | |
98 pending_mailbox_.size_in_pixels()); | |
99 layer()->SetTextureFlipped(false); | |
100 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(), | |
101 pending_mailbox_.size_in_pixels())); | |
102 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.Contains( | |
103 gfx::Rect(pending_mailbox_.size_in_pixels()))); | |
104 } else { | |
105 // Show solid color content if there is no pending buffer. | |
106 layer()->SetShowSolidColorContent(); | |
107 } | |
108 | |
109 // Schedule redraw of the damage region. | |
110 layer()->SchedulePaint(pending_damage_); | |
111 pending_damage_ = gfx::Rect(); | |
112 | |
113 ui::Compositor* compositor = layer()->GetCompositor(); | |
114 if (compositor && !pending_frame_callbacks_.empty()) { | |
115 // Start observing the compositor for frame callbacks. | |
116 if (!compositor_) { | |
117 compositor->AddObserver(this); | |
118 compositor_ = compositor; | |
119 } | |
120 | |
121 // Move pending frame callbacks to the end of |frame_callbacks_|. | |
122 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); | |
123 } | |
124 } | |
125 | |
126 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { | |
127 DCHECK(!delegate_ || !delegate); | |
128 delegate_ = delegate; | |
129 } | |
130 | |
131 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { | |
132 scoped_refptr<base::trace_event::TracedValue> value = | |
133 new base::trace_event::TracedValue; | |
134 value->SetString("name", layer()->name()); | |
135 return value; | |
136 } | |
137 | |
138 //////////////////////////////////////////////////////////////////////////////// | |
139 // views::Views overrides: | |
140 | |
141 gfx::Size Surface::GetPreferredSize() const { | |
142 return pending_mailbox_release_callback_ ? pending_mailbox_.size_in_pixels() | |
143 : layer()->size(); | |
144 } | |
145 | |
146 //////////////////////////////////////////////////////////////////////////////// | |
147 // ui::CompositorObserver overrides: | |
148 | |
149 void Surface::OnCompositingDidCommit(ui::Compositor* compositor) { | |
150 // Move frame callbacks to the end of |active_frame_callbacks_|. | |
151 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | |
152 frame_callbacks_); | |
153 } | |
154 | |
155 void Surface::OnCompositingStarted(ui::Compositor* compositor, | |
156 base::TimeTicks start_time) { | |
157 // Run all frame callbacks associated with the compositor's active tree. | |
158 while (!active_frame_callbacks_.empty()) { | |
159 active_frame_callbacks_.front().Run(start_time); | |
160 active_frame_callbacks_.pop_front(); | |
161 } | |
162 } | |
163 | |
164 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { | |
165 compositor->RemoveObserver(this); | |
166 compositor_ = nullptr; | |
167 } | |
168 | |
169 } // namespace exo | |
OLD | NEW |