Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: components/exo/surface.cc

Issue 1419373013: exo: Add support for subcompositor interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@exosphere-xdg-shell
Patch Set: rebase Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/exo/surface.h" 5 #include "components/exo/surface.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "base/trace_event/trace_event_argument.h" 10 #include "base/trace_event/trace_event_argument.h"
11 #include "cc/resources/single_release_callback.h" 11 #include "cc/resources/single_release_callback.h"
12 #include "components/exo/buffer.h" 12 #include "components/exo/buffer.h"
13 #include "components/exo/surface_delegate.h" 13 #include "components/exo/surface_delegate.h"
14 #include "components/exo/surface_observer.h"
14 #include "ui/compositor/layer.h" 15 #include "ui/compositor/layer.h"
15 #include "ui/gfx/buffer_format_util.h" 16 #include "ui/gfx/buffer_format_util.h"
16 #include "ui/gfx/gpu_memory_buffer.h" 17 #include "ui/gfx/gpu_memory_buffer.h"
17 18
18 namespace exo { 19 namespace exo {
19 20
20 //////////////////////////////////////////////////////////////////////////////// 21 ////////////////////////////////////////////////////////////////////////////////
21 // Surface, public: 22 // Surface, public:
22 23
23 Surface::Surface() : compositor_(nullptr), delegate_(nullptr) { 24 Surface::Surface()
25 : needs_commit_surface_hierarchy_(false),
26 has_contents_(false),
27 compositor_(nullptr),
28 delegate_(nullptr) {
24 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR)); 29 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR));
25 set_owned_by_client(); 30 set_owned_by_client();
31 SetVisible(false);
32 SetEnabled(false);
26 } 33 }
27 34
28 Surface::~Surface() { 35 Surface::~Surface() {
29 if (delegate_) 36 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this));
30 delegate_->OnSurfaceDestroying();
31 37
32 layer()->SetShowSolidColorContent(); 38 layer()->SetShowSolidColorContent();
33 39
34 if (compositor_) 40 if (compositor_)
35 compositor_->RemoveObserver(this); 41 compositor_->RemoveObserver(this);
36 42
37 // Call pending frame callbacks with a null frame time to indicate that they 43 // Call pending frame callbacks with a null frame time to indicate that they
38 // have been cancelled. 44 // have been cancelled.
39 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); 45 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
40 active_frame_callbacks_.splice(active_frame_callbacks_.end(), 46 active_frame_callbacks_.splice(active_frame_callbacks_.end(),
(...skipping 21 matching lines...) Expand all
62 pending_frame_callbacks_.push_back(callback); 68 pending_frame_callbacks_.push_back(callback);
63 } 69 }
64 70
65 void Surface::SetOpaqueRegion(const SkRegion& region) { 71 void Surface::SetOpaqueRegion(const SkRegion& region) {
66 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region", 72 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region",
67 gfx::SkIRectToRect(region.getBounds()).ToString()); 73 gfx::SkIRectToRect(region.getBounds()).ToString());
68 74
69 pending_opaque_region_ = region; 75 pending_opaque_region_ = region;
70 } 76 }
71 77
78 void Surface::AddSubSurface(Surface* sub_surface) {
79 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface",
80 sub_surface->AsTracedValue());
81
82 DCHECK(!sub_surface->parent());
83 DCHECK(!sub_surface->visible());
84 DCHECK(!sub_surface->enabled());
85 DCHECK(sub_surface->bounds().origin() == gfx::Point());
86 AddChildView(sub_surface);
87
88 pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point()));
piman 2015/11/19 21:59:10 nit: DCHECK that the sub_surface is not already in
reveman 2015/11/20 05:19:48 Done.
89 }
90
91 void Surface::RemoveSubSurface(Surface* sub_surface) {
92 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface",
93 sub_surface->AsTracedValue());
94
95 RemoveChildView(sub_surface);
96
97 SubSurfaceEntryList::iterator it =
98 std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
99 [sub_surface](const SubSurfaceEntry& entry) {
100 return entry.first == sub_surface;
101 });
piman 2015/11/19 21:59:10 nit: worth a helper function SubSurfaceEntryList::
reveman 2015/11/20 05:19:49 Done.
102 DCHECK(it != pending_sub_surfaces_.end());
103 pending_sub_surfaces_.erase(it);
104 }
105
106 void Surface::SetSubSurfacePosition(Surface* sub_surface,
107 const gfx::Point& position) {
108 TRACE_EVENT2("exo", "Surface::SetSubSurfacePosition", "sub_surface",
109 sub_surface->AsTracedValue(), "position", position.ToString());
110
111 SubSurfaceEntryList::iterator it =
112 std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
113 [sub_surface](const SubSurfaceEntry& entry) {
114 return entry.first == sub_surface;
115 });
116 DCHECK(it != pending_sub_surfaces_.end());
117 it->second = position;
118 }
119
120 void Surface::PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference) {
121 TRACE_EVENT2("exo", "Surface::PlaceSubSurfaceAbove", "sub_surface",
122 sub_surface->AsTracedValue(), "reference",
123 reference->AsTracedValue());
piman 2015/11/19 21:59:10 nit: can you add a DCHECK_NE(sub_surface, referenc
reveman 2015/11/20 05:19:48 I added proper checking here in latest patch inste
124
125 SubSurfaceEntryList::iterator position_it;
126 if (reference == this) {
127 position_it = pending_sub_surfaces_.begin();
128 } else {
129 position_it =
130 std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
131 [reference](const SubSurfaceEntry& entry) {
132 return entry.first == reference;
133 });
134 if (position_it == pending_sub_surfaces_.end()) {
135 DLOG(WARNING) << "Client tried to place sub-surface above a reference "
136 "surface that is neither a parent nor s sibling";
piman 2015/11/19 21:59:10 nit: typo 's sibling'->'a sibling'
reveman 2015/11/20 05:19:49 Done.
137 return;
138 }
139
140 // Advance iterator to have |position_it| point to the sibling surface
141 // above |reference|.
142 std::advance(position_it, 1);
piman 2015/11/19 21:59:10 nit: ++position_it ?
reveman 2015/11/20 05:19:48 Done.
143 }
144
145 SubSurfaceEntryList::iterator it =
146 std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
147 [sub_surface](const SubSurfaceEntry& entry) {
148 return entry.first == sub_surface;
149 });
150 DCHECK(it != pending_sub_surfaces_.end());
151 pending_sub_surfaces_.splice(position_it, pending_sub_surfaces_, it);
152 }
153
154 void Surface::PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling) {
155 TRACE_EVENT2("exo", "Surface::PlaceSubSurfaceBelow", "sub_surface",
156 sub_surface->AsTracedValue(), "sibling",
157 sibling->AsTracedValue());
158
159 SubSurfaceEntryList::iterator sibling_it =
160 std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
161 [sibling](const SubSurfaceEntry& entry) {
162 return entry.first == sibling;
163 });
164 if (sibling_it == pending_sub_surfaces_.end()) {
165 DLOG(WARNING) << "Client tried to place sub-surface below a surface that "
166 "is not a sibling";
167 return;
168 }
169
170 SubSurfaceEntryList::iterator it =
171 std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
172 [sub_surface](const SubSurfaceEntry& entry) {
173 return entry.first == sub_surface;
174 });
175 DCHECK(it != pending_sub_surfaces_.end());
176 pending_sub_surfaces_.splice(sibling_it, pending_sub_surfaces_, it);
177 }
178
72 void Surface::Commit() { 179 void Surface::Commit() {
73 TRACE_EVENT0("exo", "Surface::Commit"); 180 TRACE_EVENT0("exo", "Surface::Commit");
74 181
182 needs_commit_surface_hierarchy_ = true;
183
75 if (delegate_) 184 if (delegate_)
76 delegate_->OnSurfaceCommit(); 185 delegate_->OnSurfaceCommit();
186 else
187 CommitSurfaceHierarchy();
188 }
189
190 void Surface::CommitSurfaceHierarchy() {
191 DCHECK(needs_commit_surface_hierarchy_);
192 needs_commit_surface_hierarchy_ = false;
77 193
78 cc::TextureMailbox texture_mailbox; 194 cc::TextureMailbox texture_mailbox;
79 scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback; 195 scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
80 if (pending_buffer_) { 196 if (pending_buffer_) {
81 texture_mailbox_release_callback = 197 texture_mailbox_release_callback =
82 pending_buffer_->AcquireTextureMailbox(&texture_mailbox); 198 pending_buffer_->AcquireTextureMailbox(&texture_mailbox);
83 pending_buffer_.reset(); 199 pending_buffer_.reset();
200 has_contents_ = true;
84 } else { 201 } else {
85 // Show solid color content if there is no pending buffer. 202 // Show solid color content if there is no pending buffer.
86 layer()->SetShowSolidColorContent(); 203 layer()->SetShowSolidColorContent();
204 has_contents_ = false;
87 } 205 }
88 206
89 if (texture_mailbox_release_callback) { 207 if (texture_mailbox_release_callback) {
90 // Update layer with the new contents. 208 // Update layer with the new contents.
91 layer()->SetTextureMailbox(texture_mailbox, 209 layer()->SetTextureMailbox(texture_mailbox,
92 texture_mailbox_release_callback.Pass(), 210 texture_mailbox_release_callback.Pass(),
93 texture_mailbox.size_in_pixels()); 211 texture_mailbox.size_in_pixels());
94 layer()->SetTextureFlipped(false); 212 layer()->SetTextureFlipped(false);
95 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(), 213 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(),
96 texture_mailbox.size_in_pixels())); 214 texture_mailbox.size_in_pixels()));
97 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains( 215 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains(
98 gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels())))); 216 gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels()))));
99 } 217 }
100 218
101 // Schedule redraw of the damage region. 219 // Schedule redraw of the damage region.
102 layer()->SchedulePaint(pending_damage_); 220 layer()->SchedulePaint(pending_damage_);
103 pending_damage_ = gfx::Rect(); 221 pending_damage_ = gfx::Rect();
104 222
105 ui::Compositor* compositor = layer()->GetCompositor(); 223 ui::Compositor* compositor = layer()->GetCompositor();
106 if (compositor && !pending_frame_callbacks_.empty()) { 224 if (compositor && !pending_frame_callbacks_.empty()) {
107 // Start observing the compositor for frame callbacks. 225 // Start observing the compositor for frame callbacks.
108 if (!compositor_) { 226 if (!compositor_) {
109 compositor->AddObserver(this); 227 compositor->AddObserver(this);
110 compositor_ = compositor; 228 compositor_ = compositor;
111 } 229 }
112 230
113 // Move pending frame callbacks to the end of |frame_callbacks_|. 231 // Move pending frame callbacks to the end of |frame_callbacks_|.
114 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); 232 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
115 } 233 }
234
235 // Synchronize view hierarchy. This will position and update the stacking
236 // order of all sub-surfaces after committing all pending state of sub-surface
237 // descendants.
238 int index = 0;
239 for (auto& sub_surface_entry : pending_sub_surfaces_) {
240 Surface* sub_surface = sub_surface_entry.first;
241
242 // Synchronsouly commit all pending state of the sub-surface and its
243 // decendents.
244 if (sub_surface->needs_commit_surface_hierarchy())
245 sub_surface->CommitSurfaceHierarchy();
246
247 // Enable/disable sub-surface based on if it has contents.
248 sub_surface->SetVisible(sub_surface->has_contents());
249 sub_surface->SetEnabled(sub_surface->has_contents());
250
251 // Move sub-surface to its new position in the stack.
252 DCHECK_LT(index, child_count());
253 ReorderChildView(sub_surface, index);
254
255 // Update sub-surface position relative to surface origin.
256 sub_surface->SetPosition(sub_surface_entry.second);
257
258 ++index;
259 }
260 }
261
262 bool Surface::IsSynchronized() const {
263 return delegate_ ? delegate_->IsSurfaceSynchronized() : false;
116 } 264 }
117 265
118 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { 266 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) {
119 DCHECK(!delegate_ || !delegate); 267 DCHECK(!delegate_ || !delegate);
120 delegate_ = delegate; 268 delegate_ = delegate;
121 } 269 }
122 270
271 bool Surface::HasSurfaceDelegate() const {
272 return !!delegate_;
273 }
274
275 void Surface::AddSurfaceObserver(SurfaceObserver* observer) {
276 observers_.AddObserver(observer);
277 }
278
279 void Surface::RemoveSurfaceObserver(SurfaceObserver* observer) {
280 observers_.RemoveObserver(observer);
281 }
282
283 bool Surface::HasSurfaceObserver(const SurfaceObserver* observer) const {
284 return observers_.HasObserver(observer);
285 }
286
123 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { 287 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const {
124 scoped_refptr<base::trace_event::TracedValue> value = 288 scoped_refptr<base::trace_event::TracedValue> value =
125 new base::trace_event::TracedValue; 289 new base::trace_event::TracedValue;
126 value->SetString("name", layer()->name()); 290 value->SetString("name", layer()->name());
127 return value; 291 return value;
128 } 292 }
129 293
130 //////////////////////////////////////////////////////////////////////////////// 294 ////////////////////////////////////////////////////////////////////////////////
131 // views::Views overrides: 295 // views::Views overrides:
132 296
(...skipping 18 matching lines...) Expand all
151 active_frame_callbacks_.pop_front(); 315 active_frame_callbacks_.pop_front();
152 } 316 }
153 } 317 }
154 318
155 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { 319 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) {
156 compositor->RemoveObserver(this); 320 compositor->RemoveObserver(this);
157 compositor_ = nullptr; 321 compositor_ = nullptr;
158 } 322 }
159 323
160 } // namespace exo 324 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698