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() : 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 we are observing the compositor for frame callbacks, stop now. | |
38 if (!frame_callbacks_.empty() || !active_frame_callbacks_.empty()) | |
39 layer()->GetCompositor()->RemoveObserver(this); | |
40 } | |
41 | |
42 void Surface::Attach(Buffer* buffer, const gfx::Point& point) { | |
43 TRACE_EVENT2("exo", "Surface::Attach", "buffer", buffer->AsTracedValue(), | |
44 "point", point.ToString()); | |
45 | |
46 // If Attach() is called twice without calling Commit(), run the release | |
47 // callback for the previous buffer now. | |
48 if (pending_mailbox_release_callback_) { | |
49 pending_mailbox_release_callback_->Run(gpu::SyncToken(), false); | |
50 pending_mailbox_release_callback_ = nullptr; | |
51 } | |
52 | |
53 // If |buffer| is null, the following Commit() call will remove the surface | |
54 // content. | |
55 if (buffer) { | |
56 pending_mailbox_release_callback_ = | |
57 buffer->GetTextureMailbox(&pending_mailbox_); | |
58 } | |
59 } | |
60 | |
61 void Surface::Damage(const gfx::Rect& damage) { | |
62 TRACE_EVENT1("exo", "Surface::Damage", "damage", damage.ToString()); | |
63 | |
64 pending_damage_.Union(damage); | |
65 } | |
66 | |
67 void Surface::RequestFrameCallback(const FrameCallback& callback) { | |
68 TRACE_EVENT0("exo", "Surface::RequestFrameCallback"); | |
69 | |
70 pending_frame_callbacks_.push_back(callback); | |
71 } | |
72 | |
73 void Surface::SetOpaqueRegion(const cc::Region& region) { | |
74 TRACE_EVENT1("exo", "Surface::SetOpaqueRegion", "region", region.ToString()); | |
75 | |
76 pending_opaque_region_ = region; | |
77 } | |
78 | |
79 void Surface::Commit() { | |
80 TRACE_EVENT0("exo", "Surface::Commit"); | |
81 | |
82 if (delegate_) | |
83 delegate_->OnSurfaceCommit(); | |
84 | |
85 if (pending_mailbox_release_callback_) { | |
86 // Update layer with the new contents. | |
87 layer()->SetTextureMailbox(pending_mailbox_, | |
88 pending_mailbox_release_callback_.Pass(), | |
89 pending_mailbox_.size_in_pixels()); | |
90 layer()->SetTextureFlipped(false); | |
91 layer()->SetBounds(gfx::Rect(layer()->bounds().origin(), | |
92 pending_mailbox_.size_in_pixels())); | |
93 layer()->SetFillsBoundsOpaquely(pending_opaque_region_.Contains( | |
94 gfx::Rect(pending_mailbox_.size_in_pixels()))); | |
95 } else { | |
96 // Show solid color content if there is no pending buffer. | |
97 layer()->SetShowSolidColorContent(); | |
98 } | |
99 | |
100 // Schedule redraw of the damage region. | |
101 layer()->SchedulePaint(pending_damage_); | |
102 pending_damage_ = gfx::Rect(); | |
103 | |
104 ui::Compositor* compositor = layer()->GetCompositor(); | |
105 if (compositor) { | |
106 // Start observing the compositor for frame callbacks. | |
107 if (frame_callbacks_.empty() && active_frame_callbacks_.empty()) | |
lpique
2015/11/05 21:25:00
Shouldn't you also check "&& !frame_callbacks_.emp
| |
108 compositor->AddObserver(this); | |
109 | |
110 // Move pending frame callbacks to the end of |frame_callbacks_|. | |
111 frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_); | |
lpique
2015/11/05 21:25:00
Under the calling sequence:
Surface::RequestFra
| |
112 } | |
113 } | |
114 | |
115 void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { | |
116 DCHECK(!delegate_ || !delegate); | |
117 delegate_ = delegate; | |
118 } | |
119 | |
120 scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const { | |
121 scoped_refptr<base::trace_event::TracedValue> value = | |
122 new base::trace_event::TracedValue; | |
123 value->SetString("name", layer()->name()); | |
124 return value; | |
125 } | |
126 | |
127 //////////////////////////////////////////////////////////////////////////////// | |
128 // views::Views overrides: | |
129 | |
130 gfx::Size Surface::GetPreferredSize() const { | |
131 return pending_mailbox_release_callback_ ? pending_mailbox_.size_in_pixels() | |
132 : layer()->size(); | |
133 } | |
134 | |
135 //////////////////////////////////////////////////////////////////////////////// | |
136 // ui::CompositorObserver overrides: | |
137 | |
138 void Surface::OnCompositingDidCommit(ui::Compositor* compositor) { | |
139 // Move frame callbacks to the end of |active_frame_callbacks_|. | |
140 active_frame_callbacks_.splice(active_frame_callbacks_.end(), | |
141 frame_callbacks_); | |
142 } | |
143 | |
144 void Surface::OnCompositingStarted(ui::Compositor* compositor, | |
145 base::TimeTicks start_time) { | |
146 // Run all frame callbacks associated with the compositor's active tree. | |
147 while (!active_frame_callbacks_.empty()) { | |
148 active_frame_callbacks_.front().Run(start_time); | |
149 active_frame_callbacks_.pop_front(); | |
150 } | |
151 | |
152 // Stop observing the compositor if we have processed all frame callbacks. | |
153 if (frame_callbacks_.empty()) | |
154 compositor->RemoveObserver(this); | |
155 } | |
156 | |
157 void Surface::OnCompositingShuttingDown(ui::Compositor* compositor) { | |
158 compositor->RemoveObserver(this); | |
159 active_frame_callbacks_.clear(); | |
160 frame_callbacks_.clear(); | |
161 } | |
162 | |
163 } // namespace exo | |
OLD | NEW |