Remove obsolete entries from .gitignore.
[chromium-blink-merge.git] / components / mus / server_view.cc
blobd31903321922a002dc3dcb568eb6952cc36f1110
1 // Copyright 2014 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.
5 #include "components/mus/server_view.h"
7 #include <inttypes.h>
9 #include "base/strings/stringprintf.h"
10 #include "components/mus/server_view_delegate.h"
11 #include "components/mus/server_view_observer.h"
12 #include "components/mus/surfaces/surfaces_state.h"
13 #include "mojo/converters/geometry/geometry_type_converters.h"
14 #include "mojo/converters/surfaces/surfaces_type_converters.h"
16 namespace mus {
18 namespace {
20 void CallCallback(const mojo::Closure& callback, cc::SurfaceDrawStatus status) {
21 callback.Run();
24 } // namespace
26 ServerView::ServerView(ServerViewDelegate* delegate, const ViewId& id)
27 : delegate_(delegate),
28 id_(id),
29 parent_(nullptr),
30 visible_(false),
31 opacity_(1),
32 // Don't notify newly added observers during notification. This causes
33 // problems for code that adds an observer as part of an observer
34 // notification (such as ServerViewDrawTracker).
35 observers_(base::ObserverList<ServerViewObserver>::NOTIFY_EXISTING_ONLY),
36 binding_(this) {
37 DCHECK(delegate); // Must provide a delegate.
40 ServerView::~ServerView() {
41 FOR_EACH_OBSERVER(ServerViewObserver, observers_, OnWillDestroyView(this));
43 while (!children_.empty())
44 children_.front()->parent()->Remove(children_.front());
46 if (parent_)
47 parent_->Remove(this);
49 FOR_EACH_OBSERVER(ServerViewObserver, observers_, OnViewDestroyed(this));
51 // SurfaceFactory's destructor will attempt to return resources which will
52 // call back into here and access |client_| so we should destroy
53 // |surface_factory_| early on.
54 surface_factory_.reset();
57 void ServerView::AddObserver(ServerViewObserver* observer) {
58 observers_.AddObserver(observer);
61 void ServerView::RemoveObserver(ServerViewObserver* observer) {
62 observers_.RemoveObserver(observer);
65 void ServerView::Bind(mojo::InterfaceRequest<Surface> request,
66 mojo::SurfaceClientPtr client) {
67 if (binding_.is_bound()) {
68 if (surface_factory_) {
69 // Destroy frame surfaces submitted by the old client before replacing
70 // client_, so those surfaces will be returned to the old client.
71 surface_factory_->DestroyAll();
72 SetSurfaceId(cc::SurfaceId());
74 binding_.Close();
75 client_ = nullptr;
77 binding_.Bind(request.Pass());
78 client_ = client.Pass();
81 void ServerView::Add(ServerView* child) {
82 // We assume validation checks happened already.
83 DCHECK(child);
84 DCHECK(child != this);
85 DCHECK(!child->Contains(this));
86 if (child->parent() == this) {
87 if (children_.size() == 1)
88 return; // Already in the right position.
89 Reorder(child, children_.back(), mojo::ORDER_DIRECTION_ABOVE);
90 return;
93 ServerView* old_parent = child->parent();
94 FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
95 OnWillChangeViewHierarchy(child, this, old_parent));
97 if (child->parent())
98 child->parent()->RemoveImpl(child);
100 child->parent_ = this;
101 children_.push_back(child);
102 FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
103 OnViewHierarchyChanged(child, this, old_parent));
106 void ServerView::Remove(ServerView* child) {
107 // We assume validation checks happened else where.
108 DCHECK(child);
109 DCHECK(child != this);
110 DCHECK(child->parent() == this);
112 FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
113 OnWillChangeViewHierarchy(child, nullptr, this));
114 RemoveImpl(child);
115 FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
116 OnViewHierarchyChanged(child, nullptr, this));
119 void ServerView::Reorder(ServerView* child,
120 ServerView* relative,
121 mojo::OrderDirection direction) {
122 // We assume validation checks happened else where.
123 DCHECK(child);
124 DCHECK(child->parent() == this);
125 DCHECK_GT(children_.size(), 1u);
126 children_.erase(std::find(children_.begin(), children_.end(), child));
127 Views::iterator i = std::find(children_.begin(), children_.end(), relative);
128 if (direction == mojo::ORDER_DIRECTION_ABOVE) {
129 DCHECK(i != children_.end());
130 children_.insert(++i, child);
131 } else if (direction == mojo::ORDER_DIRECTION_BELOW) {
132 DCHECK(i != children_.end());
133 children_.insert(i, child);
135 FOR_EACH_OBSERVER(ServerViewObserver, observers_,
136 OnViewReordered(this, relative, direction));
139 void ServerView::SetBounds(const gfx::Rect& bounds) {
140 if (bounds_ == bounds)
141 return;
143 const gfx::Rect old_bounds = bounds_;
144 bounds_ = bounds;
145 FOR_EACH_OBSERVER(ServerViewObserver, observers_,
146 OnViewBoundsChanged(this, old_bounds, bounds));
149 const ServerView* ServerView::GetRoot() const {
150 return delegate_->GetRootView(this);
153 std::vector<const ServerView*> ServerView::GetChildren() const {
154 std::vector<const ServerView*> children;
155 children.reserve(children_.size());
156 for (size_t i = 0; i < children_.size(); ++i)
157 children.push_back(children_[i]);
158 return children;
161 std::vector<ServerView*> ServerView::GetChildren() {
162 // TODO(sky): rename to children() and fix return type.
163 return children_;
166 bool ServerView::Contains(const ServerView* view) const {
167 for (const ServerView* parent = view; parent; parent = parent->parent_) {
168 if (parent == this)
169 return true;
171 return false;
174 void ServerView::SetVisible(bool value) {
175 if (visible_ == value)
176 return;
178 FOR_EACH_OBSERVER(ServerViewObserver, observers_,
179 OnWillChangeViewVisibility(this));
180 visible_ = value;
181 FOR_EACH_OBSERVER(ServerViewObserver, observers_,
182 OnViewVisibilityChanged(this));
185 void ServerView::SetOpacity(float value) {
186 if (value == opacity_)
187 return;
188 opacity_ = value;
189 delegate_->OnScheduleViewPaint(this);
192 void ServerView::SetTransform(const gfx::Transform& transform) {
193 if (transform_ == transform)
194 return;
196 transform_ = transform;
197 delegate_->OnScheduleViewPaint(this);
200 void ServerView::SetProperty(const std::string& name,
201 const std::vector<uint8_t>* value) {
202 auto it = properties_.find(name);
203 if (it != properties_.end()) {
204 if (value && it->second == *value)
205 return;
206 } else if (!value) {
207 // This property isn't set in |properties_| and |value| is NULL, so there's
208 // no change.
209 return;
212 if (value) {
213 properties_[name] = *value;
214 } else if (it != properties_.end()) {
215 properties_.erase(it);
218 FOR_EACH_OBSERVER(ServerViewObserver, observers_,
219 OnViewSharedPropertyChanged(this, name, value));
222 void ServerView::SetTextInputState(const ui::TextInputState& state) {
223 const bool changed = !(text_input_state_ == state);
224 if (changed) {
225 text_input_state_ = state;
226 // keyboard even if the state is not changed. So we have to notify
227 // |observers_|.
228 FOR_EACH_OBSERVER(ServerViewObserver, observers_,
229 OnViewTextInputStateChanged(this, state));
233 bool ServerView::IsDrawn() const {
234 const ServerView* root = delegate_->GetRootView(this);
235 if (!root || !root->visible())
236 return false;
237 const ServerView* view = this;
238 while (view && view != root && view->visible())
239 view = view->parent();
240 return root == view;
243 void ServerView::SetSurfaceId(cc::SurfaceId surface_id) {
244 surface_id_ = surface_id;
245 delegate_->OnScheduleViewPaint(this);
248 void ServerView::SubmitCompositorFrame(
249 mojo::CompositorFramePtr frame,
250 const SubmitCompositorFrameCallback& callback) {
251 gfx::Size frame_size = frame->passes[0]->output_rect.To<gfx::Rect>().size();
252 // Create Surfaces state on demand.
253 if (!surface_factory_) {
254 surface_factory_.reset(
255 new cc::SurfaceFactory(delegate_->GetSurfacesState()->manager(), this));
257 if (!surface_id_allocator_) {
258 surface_id_allocator_.reset(
259 new cc::SurfaceIdAllocator(ViewIdToTransportId(id())));
261 if (surface_id().is_null()) {
262 // Create a Surface ID for the first time for this view.
263 cc::SurfaceId surface_id(surface_id_allocator_->GenerateId());
264 surface_factory_->Create(surface_id);
265 SetSurfaceId(surface_id);
266 } else {
267 // If the size of the CompostiorFrame has changed then destroy the existing
268 // Surface and create a new one of the appropriate size.
269 if (frame_size != last_submitted_frame_size()) {
270 surface_factory_->Destroy(surface_id());
271 cc::SurfaceId surface_id(surface_id_allocator_->GenerateId());
272 surface_factory_->Create(surface_id);
273 SetSurfaceId(surface_id);
276 surface_factory_->SubmitCompositorFrame(
277 surface_id(), delegate_->UpdateViewTreeFromCompositorFrame(frame),
278 base::Bind(&CallCallback, callback));
279 delegate_->GetSurfacesState()->scheduler()->SetNeedsDraw();
280 last_submitted_frame_size_ = frame_size;
283 #if !defined(NDEBUG)
284 std::string ServerView::GetDebugWindowHierarchy() const {
285 std::string result;
286 BuildDebugInfo(std::string(), &result);
287 return result;
290 void ServerView::BuildDebugInfo(const std::string& depth,
291 std::string* result) const {
292 *result += base::StringPrintf(
293 "%sid=%d,%d visible=%s bounds=%d,%d %dx%d surface_id=%" PRIu64 "\n",
294 depth.c_str(), static_cast<int>(id_.connection_id),
295 static_cast<int>(id_.view_id), visible_ ? "true" : "false", bounds_.x(),
296 bounds_.y(), bounds_.width(), bounds_.height(), surface_id_.id);
297 for (const ServerView* child : children_)
298 child->BuildDebugInfo(depth + " ", result);
300 #endif
302 void ServerView::ReturnResources(const cc::ReturnedResourceArray& resources) {
303 if (!client_)
304 return;
305 client_->ReturnResources(
306 mojo::Array<mojo::ReturnedResourcePtr>::From(resources));
309 void ServerView::RemoveImpl(ServerView* view) {
310 view->parent_ = NULL;
311 children_.erase(std::find(children_.begin(), children_.end(), view));
314 } // namespace mus