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

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: address review feedback 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
« no previous file with comments | « components/exo/surface.h ('k') | components/exo/surface_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 {
20 namespace {
21
22 // Helper function that returns an iterator to the first entry in |list|
23 // with |key|.
24 template <typename T, typename U>
25 typename T::iterator FindListEntry(T& list, U key) {
26 return std::find_if(list.begin(), list.end(),
27 [key](const typename T::value_type& entry) {
28 return entry.first == key;
29 });
30 }
31
32 // Helper function that returns true if |list| contains an entry with |key|.
33 template <typename T, typename U>
34 bool ListContainsEntry(T& list, U key) {
35 return FindListEntry(list, key) != list.end();
36 }
37
38 } // namespace
19 39
20 //////////////////////////////////////////////////////////////////////////////// 40 ////////////////////////////////////////////////////////////////////////////////
21 // Surface, public: 41 // Surface, public:
22 42
23 Surface::Surface() : compositor_(nullptr), delegate_(nullptr) { 43 Surface::Surface()
44 : needs_commit_surface_hierarchy_(false),
45 has_contents_(false),
46 compositor_(nullptr),
47 delegate_(nullptr) {
24 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR)); 48 SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR));
25 set_owned_by_client(); 49 set_owned_by_client();
50 SetVisible(false);
51 SetEnabled(false);
26 } 52 }
27 53
28 Surface::~Surface() { 54 Surface::~Surface() {
29 if (delegate_) 55 FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this));
30 delegate_->OnSurfaceDestroying();
31 56
32 layer()->SetShowSolidColorContent(); 57 layer()->SetShowSolidColorContent();
33 58
34 if (compositor_) 59 if (compositor_)
35 compositor_->RemoveObserver(this); 60 compositor_->RemoveObserver(this);
36 61
37 // Call pending frame callbacks with a null frame time to indicate that they 62 // Call pending frame callbacks with a null frame time to indicate that they
38 // have been cancelled. 63 // have been cancelled.
39 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); 64 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
40 active_frame_callbacks_.splice(active_frame_callbacks_.end(), 65 active_frame_callbacks_.splice(active_frame_callbacks_.end(),
(...skipping 21 matching lines...) Expand all
62 pending_frame_callbacks_.push_back(callback); 87 pending_frame_callbacks_.push_back(callback);
63 } 88 }
64 89
65 void Surface::SetOpaqueRegion(const SkRegion& region) { 90 void Surface::SetOpaqueRegion(const SkRegion& region) {
66 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region", 91 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region",
67 gfx::SkIRectToRect(region.getBounds()).ToString()); 92 gfx::SkIRectToRect(region.getBounds()).ToString());
68 93
69 pending_opaque_region_ = region; 94 pending_opaque_region_ = region;
70 } 95 }
71 96
97 void Surface::AddSubSurface(Surface* sub_surface) {
98 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface",
99 sub_surface->AsTracedValue());
100
101 DCHECK(!sub_surface->parent());
102 DCHECK(!sub_surface->visible());
103 DCHECK(!sub_surface->enabled());
104 DCHECK(sub_surface->bounds().origin() == gfx::Point());
105 AddChildView(sub_surface);
106
107 DCHECK(!ListContainsEntry(pending_sub_surfaces_, sub_surface));
108 pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point()));
109 }
110
111 void Surface::RemoveSubSurface(Surface* sub_surface) {
112 TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface",
113 sub_surface->AsTracedValue());
114
115 RemoveChildView(sub_surface);
116
117 DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
118 pending_sub_surfaces_.erase(
119 FindListEntry(pending_sub_surfaces_, sub_surface));
120 }
121
122 void Surface::SetSubSurfacePosition(Surface* sub_surface,
123 const gfx::Point& position) {
124 TRACE_EVENT2("exo", "Surface::SetSubSurfacePosition", "sub_surface",
125 sub_surface->AsTracedValue(), "position", position.ToString());
126
127 auto it = FindListEntry(pending_sub_surfaces_, sub_surface);
128 DCHECK(it != pending_sub_surfaces_.end());
129 it->second = position;
130 }
131
132 void Surface::PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference) {
133 TRACE_EVENT2("exo", "Surface::PlaceSubSurfaceAbove", "sub_surface",
134 sub_surface->AsTracedValue(), "reference",
135 reference->AsTracedValue());
136
137 if (sub_surface == reference) {
138 DLOG(WARNING) << "Client tried to place sub-surface above itself";
139 return;
140 }
141
142 auto position_it = pending_sub_surfaces_.begin();
143 if (reference != this) {
144 position_it = FindListEntry(pending_sub_surfaces_, reference);
145 if (position_it == pending_sub_surfaces_.end()) {
146 DLOG(WARNING) << "Client tried to place sub-surface above a reference "
147 "surface that is neither a parent nor a sibling";
148 return;
149 }
150
151 // Advance iterator to have |position_it| point to the sibling surface
152 // above |reference|.
153 ++position_it;
154 }
155
156 DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
157 pending_sub_surfaces_.splice(
158 position_it, pending_sub_surfaces_,
159 FindListEntry(pending_sub_surfaces_, sub_surface));
160 }
161
162 void Surface::PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling) {
163 TRACE_EVENT2("exo", "Surface::PlaceSubSurfaceBelow", "sub_surface",
164 sub_surface->AsTracedValue(), "sibling",
165 sibling->AsTracedValue());
166
167 if (sub_surface == sibling) {
168 DLOG(WARNING) << "Client tried to place sub-surface below itself";
169 return;
170 }
171
172 auto sibling_it = FindListEntry(pending_sub_surfaces_, sibling);
173 if (sibling_it == pending_sub_surfaces_.end()) {
174 DLOG(WARNING) << "Client tried to place sub-surface below a surface that "
175 "is not a sibling";
176 return;
177 }
178
179 DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
180 pending_sub_surfaces_.splice(
181 sibling_it, pending_sub_surfaces_,
182 FindListEntry(pending_sub_surfaces_, sub_surface));
183 }
184
72 void Surface::Commit() { 185 void Surface::Commit() {
73 TRACE_EVENT0("exo", "Surface::Commit"); 186 TRACE_EVENT0("exo", "Surface::Commit");
74 187
188 needs_commit_surface_hierarchy_ = true;
189
75 if (delegate_) 190 if (delegate_)
76 delegate_->OnSurfaceCommit(); 191 delegate_->OnSurfaceCommit();
192 else
193 CommitSurfaceHierarchy();
194 }
195
196 void Surface::CommitSurfaceHierarchy() {
197 DCHECK(needs_commit_surface_hierarchy_);
198 needs_commit_surface_hierarchy_ = false;
77 199
78 cc::TextureMailbox texture_mailbox; 200 cc::TextureMailbox texture_mailbox;
79 scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback; 201 scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
80 if (pending_buffer_) { 202 if (pending_buffer_) {
81 texture_mailbox_release_callback = 203 texture_mailbox_release_callback =
82 pending_buffer_->AcquireTextureMailbox(&texture_mailbox); 204 pending_buffer_->AcquireTextureMailbox(&texture_mailbox);
83 pending_buffer_.reset(); 205 pending_buffer_.reset();
206 has_contents_ = true;
84 } else { 207 } else {
85 // Show solid color content if there is no pending buffer. 208 // Show solid color content if there is no pending buffer.
86 layer()->SetShowSolidColorContent(); 209 layer()->SetShowSolidColorContent();
210 has_contents_ = false;
87 } 211 }
88 212
89 if (texture_mailbox_release_callback) { 213 if (texture_mailbox_release_callback) {
90 // Update layer with the new contents. 214 // Update layer with the new contents.
91 layer()->SetTextureMailbox(texture_mailbox, 215 layer()->SetTextureMailbox(texture_mailbox,
92 texture_mailbox_release_callback.Pass(), 216 texture_mailbox_release_callback.Pass(),
93 texture_mailbox.size_in_pixels()); 217 texture_mailbox.size_in_pixels());
94 layer()->SetTextureFlipped(false); 218 layer()->SetTextureFlipped(false);
95 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(), 219 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(),
96 texture_mailbox.size_in_pixels())); 220 texture_mailbox.size_in_pixels()));
97 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains( 221 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.contains(
98 gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels())))); 222 gfx::RectToSkIRect(gfx::Rect(texture_mailbox.size_in_pixels()))));
99 } 223 }
100 224
101 // Schedule redraw of the damage region. 225 // Schedule redraw of the damage region.
102 layer()->SchedulePaint(pending_damage_); 226 layer()->SchedulePaint(pending_damage_);
103 pending_damage_ = gfx::Rect(); 227 pending_damage_ = gfx::Rect();
104 228
105 ui::Compositor* compositor = layer()->GetCompositor(); 229 ui::Compositor* compositor = layer()->GetCompositor();
106 if (compositor && !pending_frame_callbacks_.empty()) { 230 if (compositor && !pending_frame_callbacks_.empty()) {
107 // Start observing the compositor for frame callbacks. 231 // Start observing the compositor for frame callbacks.
108 if (!compositor_) { 232 if (!compositor_) {
109 compositor->AddObserver(this); 233 compositor->AddObserver(this);
110 compositor_ = compositor; 234 compositor_ = compositor;
111 } 235 }
112 236
113 // Move pending frame callbacks to the end of |frame_callbacks_|. 237 // Move pending frame callbacks to the end of |frame_callbacks_|.
114 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); 238 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
115 } 239 }
240
241 // Synchronize view hierarchy. This will position and update the stacking
242 // order of all sub-surfaces after committing all pending state of sub-surface
243 // descendants.
244 int index = 0;
245 for (auto& sub_surface_entry : pending_sub_surfaces_) {
246 Surface* sub_surface = sub_surface_entry.first;
247
248 // Synchronsouly commit all pending state of the sub-surface and its
249 // decendents.
250 if (sub_surface->needs_commit_surface_hierarchy())
251 sub_surface->CommitSurfaceHierarchy();
252
253 // Enable/disable sub-surface based on if it has contents.
254 sub_surface->SetVisible(sub_surface->has_contents());
255 sub_surface->SetEnabled(sub_surface->has_contents());
256
257 // Move sub-surface to its new position in the stack.
258 DCHECK_LT(index, child_count());
259 ReorderChildView(sub_surface, index);
260
261 // Update sub-surface position relative to surface origin.
262 sub_surface->SetPosition(sub_surface_entry.second);
263
264 ++index;
265 }
266 }
267
268 bool Surface::IsSynchronized() const {
269 return delegate_ ? delegate_->IsSurfaceSynchronized() : false;
116 } 270 }
117 271
118 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { 272 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) {
119 DCHECK(!delegate_ || !delegate); 273 DCHECK(!delegate_ || !delegate);
120 delegate_ = delegate; 274 delegate_ = delegate;
121 } 275 }
122 276
277 bool Surface::HasSurfaceDelegate() const {
278 return !!delegate_;
279 }
280
281 void Surface::AddSurfaceObserver(SurfaceObserver* observer) {
282 observers_.AddObserver(observer);
283 }
284
285 void Surface::RemoveSurfaceObserver(SurfaceObserver* observer) {
286 observers_.RemoveObserver(observer);
287 }
288
289 bool Surface::HasSurfaceObserver(const SurfaceObserver* observer) const {
290 return observers_.HasObserver(observer);
291 }
292
123 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { 293 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const {
124 scoped_refptr<base::trace_event::TracedValue> value = 294 scoped_refptr<base::trace_event::TracedValue> value =
125 new base::trace_event::TracedValue; 295 new base::trace_event::TracedValue;
126 value->SetString("name", layer()->name()); 296 value->SetString("name", layer()->name());
127 return value; 297 return value;
128 } 298 }
129 299
130 //////////////////////////////////////////////////////////////////////////////// 300 ////////////////////////////////////////////////////////////////////////////////
131 // views::Views overrides: 301 // views::Views overrides:
132 302
(...skipping 18 matching lines...) Expand all
151 active_frame_callbacks_.pop_front(); 321 active_frame_callbacks_.pop_front();
152 } 322 }
153 } 323 }
154 324
155 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { 325 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) {
156 compositor->RemoveObserver(this); 326 compositor->RemoveObserver(this);
157 compositor_ = nullptr; 327 compositor_ = nullptr;
158 } 328 }
159 329
160 } // namespace exo 330 } // namespace exo
OLDNEW
« no previous file with comments | « components/exo/surface.h ('k') | components/exo/surface_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698