| 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 |