OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "content/browser/compositor/reflector_impl.h" | 5 #include "content/browser/compositor/reflector_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/memory/ptr_util.h" |
9 #include "content/browser/compositor/browser_compositor_output_surface.h" | 10 #include "content/browser/compositor/browser_compositor_output_surface.h" |
10 #include "content/browser/compositor/owned_mailbox.h" | 11 #include "content/browser/compositor/owned_mailbox.h" |
11 #include "ui/compositor/layer.h" | 12 #include "ui/compositor/layer.h" |
12 | 13 |
13 namespace content { | 14 namespace content { |
14 | 15 |
15 struct ReflectorImpl::LayerData { | 16 struct ReflectorImpl::LayerData { |
16 LayerData(ui::Layer* layer) : layer(layer) {} | 17 LayerData(ui::Layer* layer) : layer(layer) {} |
17 | 18 |
18 ui::Layer* layer; | 19 ui::Layer* layer; |
(...skipping 18 matching lines...) Expand all Loading... |
37 // Prevent the ReflectorImpl from picking up a new output surface. | 38 // Prevent the ReflectorImpl from picking up a new output surface. |
38 mirroring_layers_.clear(); | 39 mirroring_layers_.clear(); |
39 } | 40 } |
40 | 41 |
41 void ReflectorImpl::DetachFromOutputSurface() { | 42 void ReflectorImpl::DetachFromOutputSurface() { |
42 DCHECK(output_surface_); | 43 DCHECK(output_surface_); |
43 output_surface_->SetReflector(nullptr); | 44 output_surface_->SetReflector(nullptr); |
44 DCHECK(mailbox_.get()); | 45 DCHECK(mailbox_.get()); |
45 mailbox_ = nullptr; | 46 mailbox_ = nullptr; |
46 output_surface_ = nullptr; | 47 output_surface_ = nullptr; |
47 for (LayerData* layer_data : mirroring_layers_) | 48 for (const auto& layer_data : mirroring_layers_) |
48 layer_data->layer->SetShowSolidColorContent(); | 49 layer_data->layer->SetShowSolidColorContent(); |
49 } | 50 } |
50 | 51 |
51 void ReflectorImpl::OnSourceSurfaceReady( | 52 void ReflectorImpl::OnSourceSurfaceReady( |
52 BrowserCompositorOutputSurface* output_surface) { | 53 BrowserCompositorOutputSurface* output_surface) { |
53 if (mirroring_layers_.empty()) | 54 if (mirroring_layers_.empty()) |
54 return; // Was already Shutdown(). | 55 return; // Was already Shutdown(). |
55 if (output_surface == output_surface_) | 56 if (output_surface == output_surface_) |
56 return; // Is already attached. | 57 return; // Is already attached. |
57 if (output_surface_) | 58 if (output_surface_) |
58 DetachFromOutputSurface(); | 59 DetachFromOutputSurface(); |
59 | 60 |
60 output_surface_ = output_surface; | 61 output_surface_ = output_surface; |
61 | 62 |
62 flip_texture_ = !output_surface->capabilities().flipped_output_surface; | 63 flip_texture_ = !output_surface->capabilities().flipped_output_surface; |
63 | 64 |
64 output_surface_->SetReflector(this); | 65 output_surface_->SetReflector(this); |
65 } | 66 } |
66 | 67 |
67 void ReflectorImpl::OnMirroringCompositorResized() { | 68 void ReflectorImpl::OnMirroringCompositorResized() { |
68 for (LayerData* layer_data : mirroring_layers_) | 69 for (const auto& layer_data : mirroring_layers_) |
69 layer_data->layer->SchedulePaint(layer_data->layer->bounds()); | 70 layer_data->layer->SchedulePaint(layer_data->layer->bounds()); |
70 } | 71 } |
71 | 72 |
72 void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) { | 73 void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) { |
73 DCHECK(layer->GetCompositor()); | 74 DCHECK(layer->GetCompositor()); |
74 DCHECK(mirroring_layers_.end() == FindLayerData(layer)); | 75 DCHECK(mirroring_layers_.end() == FindLayerData(layer)); |
75 | 76 |
76 LayerData* layer_data = new LayerData(layer); | 77 mirroring_layers_.push_back(base::MakeUnique<LayerData>(layer)); |
77 if (mailbox_) | 78 if (mailbox_) |
78 layer_data->needs_set_mailbox = true; | 79 mirroring_layers_.back()->needs_set_mailbox = true; |
79 mirroring_layers_.push_back(layer_data); | |
80 mirrored_compositor_->ScheduleFullRedraw(); | 80 mirrored_compositor_->ScheduleFullRedraw(); |
81 } | 81 } |
82 | 82 |
83 void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) { | 83 void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) { |
84 DCHECK(layer->GetCompositor()); | 84 DCHECK(layer->GetCompositor()); |
85 | 85 |
86 ScopedVector<LayerData>::iterator iter = FindLayerData(layer); | 86 auto iter = FindLayerData(layer); |
87 DCHECK(iter != mirroring_layers_.end()); | 87 DCHECK(iter != mirroring_layers_.end()); |
88 (*iter)->layer->SetShowSolidColorContent(); | 88 (*iter)->layer->SetShowSolidColorContent(); |
89 mirroring_layers_.erase(iter); | 89 mirroring_layers_.erase(iter); |
90 | 90 |
91 if (mirroring_layers_.empty() && output_surface_) | 91 if (mirroring_layers_.empty() && output_surface_) |
92 DetachFromOutputSurface(); | 92 DetachFromOutputSurface(); |
93 } | 93 } |
94 | 94 |
95 void ReflectorImpl::OnSourceTextureMailboxUpdated( | 95 void ReflectorImpl::OnSourceTextureMailboxUpdated( |
96 scoped_refptr<OwnedMailbox> mailbox) { | 96 scoped_refptr<OwnedMailbox> mailbox) { |
97 mailbox_ = mailbox; | 97 mailbox_ = mailbox; |
98 if (mailbox_.get()) { | 98 if (mailbox_.get()) { |
99 for (LayerData* layer_data : mirroring_layers_) | 99 for (const auto& layer_data : mirroring_layers_) |
100 layer_data->needs_set_mailbox = true; | 100 layer_data->needs_set_mailbox = true; |
101 | 101 |
102 // The texture doesn't have the data. Request full redraw on mirrored | 102 // The texture doesn't have the data. Request full redraw on mirrored |
103 // compositor so that the full content will be copied to mirroring | 103 // compositor so that the full content will be copied to mirroring |
104 // compositor. This full redraw should land us in OnSourceSwapBuffers() to | 104 // compositor. This full redraw should land us in OnSourceSwapBuffers() to |
105 // resize the texture appropriately. | 105 // resize the texture appropriately. |
106 mirrored_compositor_->ScheduleFullRedraw(); | 106 mirrored_compositor_->ScheduleFullRedraw(); |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 void ReflectorImpl::OnSourceSwapBuffers(const gfx::Size& surface_size) { | 110 void ReflectorImpl::OnSourceSwapBuffers(const gfx::Size& surface_size) { |
111 if (mirroring_layers_.empty()) | 111 if (mirroring_layers_.empty()) |
112 return; | 112 return; |
113 | 113 |
114 // Should be attached to the source output surface already. | 114 // Should be attached to the source output surface already. |
115 DCHECK(mailbox_.get()); | 115 DCHECK(mailbox_.get()); |
116 | 116 |
117 // Request full redraw on mirroring compositor. | 117 // Request full redraw on mirroring compositor. |
118 for (LayerData* layer_data : mirroring_layers_) | 118 for (const auto& layer_data : mirroring_layers_) |
119 UpdateTexture(layer_data, surface_size, layer_data->layer->bounds()); | 119 UpdateTexture(layer_data.get(), surface_size, layer_data->layer->bounds()); |
120 } | 120 } |
121 | 121 |
122 void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& swap_rect, | 122 void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& swap_rect, |
123 const gfx::Size& surface_size) { | 123 const gfx::Size& surface_size) { |
124 if (mirroring_layers_.empty()) | 124 if (mirroring_layers_.empty()) |
125 return; | 125 return; |
126 | 126 |
127 // Should be attached to the source output surface already. | 127 // Should be attached to the source output surface already. |
128 DCHECK(mailbox_.get()); | 128 DCHECK(mailbox_.get()); |
129 | 129 |
130 gfx::Rect mirroring_rect = swap_rect; | 130 gfx::Rect mirroring_rect = swap_rect; |
131 if (flip_texture_) { | 131 if (flip_texture_) { |
132 // Flip the coordinates to compositor's one. | 132 // Flip the coordinates to compositor's one. |
133 mirroring_rect.set_y(surface_size.height() - swap_rect.y() - | 133 mirroring_rect.set_y(surface_size.height() - swap_rect.y() - |
134 swap_rect.height()); | 134 swap_rect.height()); |
135 } | 135 } |
136 | 136 |
137 // Request redraw of the dirty portion in mirroring compositor. | 137 // Request redraw of the dirty portion in mirroring compositor. |
138 for (LayerData* layer_data : mirroring_layers_) | 138 for (const auto& layer_data : mirroring_layers_) |
139 UpdateTexture(layer_data, surface_size, mirroring_rect); | 139 UpdateTexture(layer_data.get(), surface_size, mirroring_rect); |
140 } | 140 } |
141 | 141 |
142 static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox, | 142 static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox, |
143 const gpu::SyncToken& sync_token, | 143 const gpu::SyncToken& sync_token, |
144 bool is_lost) { | 144 bool is_lost) { |
145 mailbox->UpdateSyncToken(sync_token); | 145 mailbox->UpdateSyncToken(sync_token); |
146 } | 146 } |
147 | 147 |
148 ScopedVector<ReflectorImpl::LayerData>::iterator ReflectorImpl::FindLayerData( | 148 std::vector<std::unique_ptr<ReflectorImpl::LayerData>>::iterator |
149 ui::Layer* layer) { | 149 ReflectorImpl::FindLayerData(ui::Layer* layer) { |
150 return std::find_if(mirroring_layers_.begin(), mirroring_layers_.end(), | 150 return std::find_if(mirroring_layers_.begin(), mirroring_layers_.end(), |
151 [layer](const LayerData* layer_data) { | 151 [layer](const std::unique_ptr<LayerData>& layer_data) { |
152 return layer_data->layer == layer; | 152 return layer_data->layer == layer; |
153 }); | 153 }); |
154 } | 154 } |
155 | 155 |
156 void ReflectorImpl::UpdateTexture(ReflectorImpl::LayerData* layer_data, | 156 void ReflectorImpl::UpdateTexture(ReflectorImpl::LayerData* layer_data, |
157 const gfx::Size& source_size, | 157 const gfx::Size& source_size, |
158 const gfx::Rect& redraw_rect) { | 158 const gfx::Rect& redraw_rect) { |
159 if (layer_data->needs_set_mailbox) { | 159 if (layer_data->needs_set_mailbox) { |
160 layer_data->layer->SetTextureMailbox( | 160 layer_data->layer->SetTextureMailbox( |
161 cc::TextureMailbox(mailbox_->holder()), | 161 cc::TextureMailbox(mailbox_->holder()), |
162 cc::SingleReleaseCallback::Create(base::Bind(ReleaseMailbox, mailbox_)), | 162 cc::SingleReleaseCallback::Create(base::Bind(ReleaseMailbox, mailbox_)), |
163 source_size); | 163 source_size); |
164 layer_data->needs_set_mailbox = false; | 164 layer_data->needs_set_mailbox = false; |
165 } else { | 165 } else { |
166 layer_data->layer->SetTextureSize(source_size); | 166 layer_data->layer->SetTextureSize(source_size); |
167 } | 167 } |
168 layer_data->layer->SetBounds(gfx::Rect(source_size)); | 168 layer_data->layer->SetBounds(gfx::Rect(source_size)); |
169 layer_data->layer->SetTextureFlipped(flip_texture_); | 169 layer_data->layer->SetTextureFlipped(flip_texture_); |
170 layer_data->layer->SchedulePaint(redraw_rect); | 170 layer_data->layer->SchedulePaint(redraw_rect); |
171 } | 171 } |
172 | 172 |
173 } // namespace content | 173 } // namespace content |
OLD | NEW |