Chromium Code Reviews| 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 "content/browser/compositor/browser_compositor_output_surface.h" | 9 #include "content/browser/compositor/browser_compositor_output_surface.h" |
| 10 #include "content/browser/compositor/owned_mailbox.h" | 10 #include "content/browser/compositor/owned_mailbox.h" |
| 11 #include "content/common/gpu/client/gl_helper.h" | 11 //#include "content/common/gpu/client/gl_helper.h" |
| 12 #include "ui/compositor/layer.h" | 12 #include "ui/compositor/layer.h" |
| 13 | 13 |
| 14 namespace content { | 14 namespace content { |
| 15 | 15 |
| 16 struct ReflectorImpl::LayerData { | 16 struct ReflectorImpl::LayerData { |
| 17 LayerData(ui::Layer* layer) : layer(layer) {} | 17 LayerData(ui::Layer* layer) : layer(layer) {} |
| 18 | 18 |
| 19 ui::Layer* layer; | 19 ui::Layer* layer; |
| 20 bool needs_set_mailbox = false; | 20 bool needs_set_mailbox = false; |
| 21 }; | 21 }; |
| 22 | 22 |
| 23 ReflectorImpl::ReflectorImpl(ui::Compositor* mirrored_compositor, | 23 ReflectorImpl::ReflectorImpl(ui::Compositor* mirrored_compositor, |
| 24 ui::Layer* mirroring_layer) | 24 ui::Layer* mirroring_layer) |
| 25 : mirrored_compositor_(mirrored_compositor), | 25 : mirrored_compositor_(mirrored_compositor), |
| 26 mirrored_compositor_gl_helper_texture_id_(0), | 26 // mirrored_compositor_gl_helper_texture_id_(0), |
|
piman
2015/05/13 19:46:23
nit: remove
oshima
2015/05/14 14:44:58
Done.
| |
| 27 flip_texture_(false), | 27 flip_texture_(false), |
| 28 composition_count_(0), | |
| 28 output_surface_(nullptr) { | 29 output_surface_(nullptr) { |
| 29 if (mirroring_layer) | 30 if (mirroring_layer) |
| 30 mirroring_layers_.push_back(new LayerData(mirroring_layer)); | 31 AddMirroringLayer(mirroring_layer); |
| 31 } | 32 } |
| 32 | 33 |
| 33 ReflectorImpl::~ReflectorImpl() { | 34 ReflectorImpl::~ReflectorImpl() { |
| 34 } | 35 } |
| 35 | 36 |
| 36 void ReflectorImpl::Shutdown() { | 37 void ReflectorImpl::Shutdown() { |
| 37 if (output_surface_) | 38 if (output_surface_) |
| 38 DetachFromOutputSurface(); | 39 DetachFromOutputSurface(); |
| 39 // Prevent the ReflectorImpl from picking up a new output surface. | 40 // Prevent the ReflectorImpl from picking up a new output surface. |
| 40 mirroring_layers_.clear(); | 41 mirroring_layers_.clear(); |
| 41 } | 42 } |
| 42 | 43 |
| 43 void ReflectorImpl::DetachFromOutputSurface() { | 44 void ReflectorImpl::DetachFromOutputSurface() { |
| 44 DCHECK(output_surface_); | 45 DCHECK(output_surface_); |
| 45 output_surface_->SetReflector(nullptr); | 46 output_surface_->SetReflector(nullptr); |
| 46 DCHECK(mailbox_.get()); | 47 DCHECK(mailbox_.get()); |
| 47 mailbox_ = nullptr; | 48 mailbox_ = nullptr; |
| 48 output_surface_ = nullptr; | 49 output_surface_ = nullptr; |
| 49 mirrored_compositor_gl_helper_->DeleteTexture( | |
| 50 mirrored_compositor_gl_helper_texture_id_); | |
| 51 mirrored_compositor_gl_helper_texture_id_ = 0; | |
| 52 mirrored_compositor_gl_helper_ = nullptr; | |
| 53 for (LayerData* layer_data : mirroring_layers_) | 50 for (LayerData* layer_data : mirroring_layers_) |
| 54 layer_data->layer->SetShowSolidColorContent(); | 51 layer_data->layer->SetShowSolidColorContent(); |
| 55 } | 52 } |
| 56 | 53 |
| 57 void ReflectorImpl::OnSourceSurfaceReady( | 54 void ReflectorImpl::OnSourceSurfaceReady( |
| 58 BrowserCompositorOutputSurface* output_surface) { | 55 BrowserCompositorOutputSurface* output_surface) { |
| 59 if (mirroring_layers_.empty()) | 56 if (mirroring_layers_.empty()) |
| 60 return; // Was already Shutdown(). | 57 return; // Was already Shutdown(). |
| 61 if (output_surface == output_surface_) | 58 if (output_surface == output_surface_) |
| 62 return; // Is already attached. | 59 return; // Is already attached. |
| 63 if (output_surface_) | 60 if (output_surface_) |
| 64 DetachFromOutputSurface(); | 61 DetachFromOutputSurface(); |
| 65 | 62 |
| 66 // Use the GLHelper from the ImageTransportFactory for our OwnedMailbox so we | 63 output_surface_ = output_surface; |
| 67 // don't have to manage the lifetime of the GLHelper relative to the lifetime | |
| 68 // of the mailbox. | |
| 69 GLHelper* shared_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); | |
| 70 mailbox_ = new OwnedMailbox(shared_helper); | |
| 71 for (LayerData* layer_data : mirroring_layers_) | |
| 72 layer_data->needs_set_mailbox = true; | |
| 73 | 64 |
| 74 // Create a GLHelper attached to the mirrored compositor's output surface for | 65 composition_started_callback_ = |
| 75 // copying the output of the mirrored compositor. | 66 output_surface_->CreateCompositionStartedCallback(); |
| 76 mirrored_compositor_gl_helper_.reset( | |
| 77 new GLHelper(output_surface->context_provider()->ContextGL(), | |
| 78 output_surface->context_provider()->ContextSupport())); | |
| 79 // Create a texture id in the name space of the new GLHelper to update the | |
| 80 // mailbox being held by the |mirroring_layer_|. | |
| 81 mirrored_compositor_gl_helper_texture_id_ = | |
| 82 mirrored_compositor_gl_helper_->ConsumeMailboxToTexture( | |
| 83 mailbox_->mailbox(), mailbox_->sync_point()); | |
| 84 | 67 |
| 85 flip_texture_ = !output_surface->capabilities().flipped_output_surface; | 68 flip_texture_ = !output_surface->capabilities().flipped_output_surface; |
| 86 | 69 |
| 87 // The texture doesn't have the data. Request full redraw on mirrored | |
| 88 // compositor so that the full content will be copied to mirroring compositor. | |
| 89 // This full redraw should land us in OnSourceSwapBuffers() to resize the | |
| 90 // texture appropriately. | |
| 91 mirrored_compositor_->ScheduleFullRedraw(); | |
| 92 | |
| 93 output_surface_ = output_surface; | |
| 94 output_surface_->SetReflector(this); | 70 output_surface_->SetReflector(this); |
| 95 } | 71 } |
| 96 | 72 |
| 97 void ReflectorImpl::OnMirroringCompositorResized() { | 73 void ReflectorImpl::OnMirroringCompositorResized() { |
| 98 for (LayerData* layer_data : mirroring_layers_) | 74 for (LayerData* layer_data : mirroring_layers_) |
| 99 layer_data->layer->SchedulePaint(layer_data->layer->bounds()); | 75 layer_data->layer->SchedulePaint(layer_data->layer->bounds()); |
| 100 } | 76 } |
| 101 | 77 |
| 102 void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) { | 78 void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) { |
| 79 DCHECK(layer->GetCompositor()); | |
| 103 DCHECK(mirroring_layers_.end() == FindLayerData(layer)); | 80 DCHECK(mirroring_layers_.end() == FindLayerData(layer)); |
| 81 | |
| 104 LayerData* layer_data = new LayerData(layer); | 82 LayerData* layer_data = new LayerData(layer); |
| 105 if (mailbox_) | 83 if (mailbox_) |
| 106 layer_data->needs_set_mailbox = true; | 84 layer_data->needs_set_mailbox = true; |
| 107 mirroring_layers_.push_back(layer_data); | 85 mirroring_layers_.push_back(layer_data); |
| 108 mirrored_compositor_->ScheduleFullRedraw(); | 86 mirrored_compositor_->ScheduleFullRedraw(); |
| 87 | |
| 88 layer->GetCompositor()->AddObserver(this); | |
| 109 } | 89 } |
| 110 | 90 |
| 111 void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) { | 91 void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) { |
| 92 DCHECK(layer->GetCompositor()); | |
| 93 | |
| 112 ScopedVector<LayerData>::iterator iter = FindLayerData(layer); | 94 ScopedVector<LayerData>::iterator iter = FindLayerData(layer); |
| 113 DCHECK(iter != mirroring_layers_.end()); | 95 DCHECK(iter != mirroring_layers_.end()); |
| 114 (*iter)->layer->SetShowSolidColorContent(); | 96 (*iter)->layer->SetShowSolidColorContent(); |
| 115 mirroring_layers_.erase(iter); | 97 mirroring_layers_.erase(iter); |
| 116 | 98 |
| 99 layer->GetCompositor()->RemoveObserver(this); | |
| 100 composition_count_--; | |
| 101 if (composition_count_ == 0 && !composition_started_callback_.is_null()) | |
| 102 composition_started_callback_.Run(); | |
| 103 | |
| 117 if (mirroring_layers_.empty() && output_surface_) | 104 if (mirroring_layers_.empty() && output_surface_) |
| 118 DetachFromOutputSurface(); | 105 DetachFromOutputSurface(); |
| 119 } | 106 } |
| 120 | 107 |
| 108 void ReflectorImpl::OnCompositingStarted(ui::Compositor* compositor, | |
| 109 base::TimeTicks start_time) { | |
| 110 if (composition_count_ > 0 && --composition_count_ == 0 && | |
| 111 !composition_started_callback_.is_null()) { | |
| 112 composition_started_callback_.Run(); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 void ReflectorImpl::OnSourceTextureMailboxUpdated( | |
| 117 scoped_refptr<OwnedMailbox> mailbox) { | |
| 118 mailbox_ = mailbox; | |
| 119 if (mailbox_.get()) { | |
| 120 for (LayerData* layer_data : mirroring_layers_) | |
| 121 layer_data->needs_set_mailbox = true; | |
| 122 | |
| 123 // The texture doesn't have the data. Request full redraw on mirrored | |
| 124 // compositor so that the full content will be copied to mirroring | |
| 125 // compositor. This full redraw should land us in OnSourceSwapBuffers() to | |
| 126 // resize the texture appropriately. | |
| 127 mirrored_compositor_->ScheduleFullRedraw(); | |
| 128 } | |
| 129 } | |
| 130 | |
| 121 void ReflectorImpl::OnSourceSwapBuffers() { | 131 void ReflectorImpl::OnSourceSwapBuffers() { |
| 122 if (mirroring_layers_.empty()) | 132 if (mirroring_layers_.empty()) { |
| 133 if (!composition_started_callback_.is_null()) | |
| 134 composition_started_callback_.Run(); | |
| 123 return; | 135 return; |
| 136 } | |
| 137 | |
| 124 // Should be attached to the source output surface already. | 138 // Should be attached to the source output surface already. |
| 125 DCHECK(mailbox_.get()); | 139 DCHECK(mailbox_.get()); |
| 126 | 140 |
| 127 gfx::Size size = output_surface_->SurfaceSize(); | 141 gfx::Size size = output_surface_->SurfaceSize(); |
| 128 mirrored_compositor_gl_helper_->CopyTextureFullImage( | |
| 129 mirrored_compositor_gl_helper_texture_id_, size); | |
| 130 // Insert a barrier to make the copy show up in the mirroring compositor's | |
| 131 // mailbox. Since the the compositor contexts and the ImageTransportFactory's | |
| 132 // GLHelper are all on the same GPU channel, this is sufficient instead of | |
| 133 // plumbing through a sync point. | |
| 134 mirrored_compositor_gl_helper_->InsertOrderingBarrier(); | |
| 135 | 142 |
| 136 // Request full redraw on mirroring compositor. | 143 // Request full redraw on mirroring compositor. |
| 137 for (LayerData* layer_data : mirroring_layers_) | 144 for (LayerData* layer_data : mirroring_layers_) |
| 138 UpdateTexture(layer_data, size, layer_data->layer->bounds()); | 145 UpdateTexture(layer_data, size, layer_data->layer->bounds()); |
| 146 composition_count_ = mirroring_layers_.size(); | |
| 139 } | 147 } |
| 140 | 148 |
| 141 void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& rect) { | 149 void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& rect) { |
| 142 if (mirroring_layers_.empty()) | 150 if (mirroring_layers_.empty()) { |
| 151 if (!composition_started_callback_.is_null()) | |
| 152 composition_started_callback_.Run(); | |
| 143 return; | 153 return; |
| 154 } | |
| 155 | |
| 144 // Should be attached to the source output surface already. | 156 // Should be attached to the source output surface already. |
| 145 DCHECK(mailbox_.get()); | 157 DCHECK(mailbox_.get()); |
| 146 | 158 |
| 147 gfx::Size size = output_surface_->SurfaceSize(); | 159 gfx::Size size = output_surface_->SurfaceSize(); |
| 148 mirrored_compositor_gl_helper_->CopyTextureSubImage( | |
| 149 mirrored_compositor_gl_helper_texture_id_, rect); | |
| 150 // Insert a barrier to make the copy show up in the mirroring compositor's | |
| 151 // mailbox. Since the the compositor contexts and the ImageTransportFactory's | |
| 152 // GLHelper are all on the same GPU channel, this is sufficient instead of | |
| 153 // plumbing through a sync point. | |
| 154 mirrored_compositor_gl_helper_->InsertOrderingBarrier(); | |
| 155 | 160 |
| 156 int y = rect.y(); | 161 int y = rect.y(); |
| 157 // Flip the coordinates to compositor's one. | 162 // Flip the coordinates to compositor's one. |
| 158 if (flip_texture_) | 163 if (flip_texture_) |
| 159 y = size.height() - rect.y() - rect.height(); | 164 y = size.height() - rect.y() - rect.height(); |
| 160 gfx::Rect mirroring_rect(rect.x(), y, rect.width(), rect.height()); | 165 gfx::Rect mirroring_rect(rect.x(), y, rect.width(), rect.height()); |
| 161 | 166 |
| 162 // Request redraw of the dirty portion in mirroring compositor. | 167 // Request redraw of the dirty portion in mirroring compositor. |
| 163 for (LayerData* layer_data : mirroring_layers_) | 168 for (LayerData* layer_data : mirroring_layers_) |
| 164 UpdateTexture(layer_data, size, mirroring_rect); | 169 UpdateTexture(layer_data, size, mirroring_rect); |
| 170 composition_count_ = mirroring_layers_.size(); | |
| 165 } | 171 } |
| 166 | 172 |
| 167 static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox, | 173 static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox, |
| 168 unsigned int sync_point, | 174 unsigned int sync_point, |
| 169 bool is_lost) { | 175 bool is_lost) { |
| 170 mailbox->UpdateSyncPoint(sync_point); | 176 mailbox->UpdateSyncPoint(sync_point); |
| 171 } | 177 } |
| 172 | 178 |
| 173 ScopedVector<ReflectorImpl::LayerData>::iterator ReflectorImpl::FindLayerData( | 179 ScopedVector<ReflectorImpl::LayerData>::iterator ReflectorImpl::FindLayerData( |
| 174 ui::Layer* layer) { | 180 ui::Layer* layer) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 189 layer_data->needs_set_mailbox = false; | 195 layer_data->needs_set_mailbox = false; |
| 190 } else { | 196 } else { |
| 191 layer_data->layer->SetTextureSize(source_size); | 197 layer_data->layer->SetTextureSize(source_size); |
| 192 } | 198 } |
| 193 layer_data->layer->SetBounds(gfx::Rect(source_size)); | 199 layer_data->layer->SetBounds(gfx::Rect(source_size)); |
| 194 layer_data->layer->SetTextureFlipped(flip_texture_); | 200 layer_data->layer->SetTextureFlipped(flip_texture_); |
| 195 layer_data->layer->SchedulePaint(redraw_rect); | 201 layer_data->layer->SchedulePaint(redraw_rect); |
| 196 } | 202 } |
| 197 | 203 |
| 198 } // namespace content | 204 } // namespace content |
| OLD | NEW |