Index: content/browser/compositor/reflector_impl.cc |
diff --git a/content/browser/compositor/reflector_impl.cc b/content/browser/compositor/reflector_impl.cc |
index a3d8f71aaa191112b610efdb404028de33aaacae..c58ee567640d107ab725888d5902e0f322e6c0ee 100644 |
--- a/content/browser/compositor/reflector_impl.cc |
+++ b/content/browser/compositor/reflector_impl.cc |
@@ -13,14 +13,21 @@ |
namespace content { |
+struct ReflectorImpl::LayerData { |
+ LayerData(ui::Layer* layer) : layer(layer) {} |
+ |
+ ui::Layer* layer; |
+ bool needs_set_mailbox = false; |
+}; |
+ |
ReflectorImpl::ReflectorImpl(ui::Compositor* mirrored_compositor, |
ui::Layer* mirroring_layer) |
: mirrored_compositor_(mirrored_compositor), |
- mirroring_layer_(mirroring_layer), |
mirrored_compositor_gl_helper_texture_id_(0), |
- needs_set_mailbox_(false), |
flip_texture_(false), |
output_surface_(nullptr) { |
+ if (mirroring_layer) |
+ mirroring_layers_.push_back(new LayerData(mirroring_layer)); |
} |
ReflectorImpl::~ReflectorImpl() { |
@@ -30,7 +37,7 @@ void ReflectorImpl::Shutdown() { |
if (output_surface_) |
DetachFromOutputSurface(); |
// Prevent the ReflectorImpl from picking up a new output surface. |
- mirroring_layer_ = nullptr; |
+ mirroring_layers_.clear(); |
} |
void ReflectorImpl::DetachFromOutputSurface() { |
@@ -43,12 +50,13 @@ void ReflectorImpl::DetachFromOutputSurface() { |
mirrored_compositor_gl_helper_texture_id_); |
mirrored_compositor_gl_helper_texture_id_ = 0; |
mirrored_compositor_gl_helper_ = nullptr; |
- mirroring_layer_->SetShowSolidColorContent(); |
+ for (LayerData* layer_data : mirroring_layers_) |
+ layer_data->layer->SetShowSolidColorContent(); |
} |
void ReflectorImpl::OnSourceSurfaceReady( |
BrowserCompositorOutputSurface* output_surface) { |
- if (!mirroring_layer_) |
+ if (mirroring_layers_.empty()) |
return; // Was already Shutdown(). |
if (output_surface == output_surface_) |
return; // Is already attached. |
@@ -60,7 +68,8 @@ void ReflectorImpl::OnSourceSurfaceReady( |
// of the mailbox. |
GLHelper* shared_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
mailbox_ = new OwnedMailbox(shared_helper); |
- needs_set_mailbox_ = true; |
+ for (LayerData* layer_data : mirroring_layers_) |
+ layer_data->needs_set_mailbox = true; |
// Create a GLHelper attached to the mirrored compositor's output surface for |
// copying the output of the mirrored compositor. |
@@ -86,11 +95,31 @@ void ReflectorImpl::OnSourceSurfaceReady( |
} |
void ReflectorImpl::OnMirroringCompositorResized() { |
- mirroring_layer_->SchedulePaint(mirroring_layer_->bounds()); |
+ for (LayerData* layer_data : mirroring_layers_) |
+ layer_data->layer->SchedulePaint(layer_data->layer->bounds()); |
+} |
+ |
+void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) { |
+ DCHECK(mirroring_layers_.end() == FindLayerData(layer)); |
+ LayerData* layer_data = new LayerData(layer); |
+ if (mailbox_) |
+ layer_data->needs_set_mailbox = true; |
+ mirroring_layers_.push_back(layer_data); |
+ mirrored_compositor_->ScheduleFullRedraw(); |
+} |
+ |
+void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) { |
+ ScopedVector<LayerData>::iterator iter = FindLayerData(layer); |
+ DCHECK(iter != mirroring_layers_.end()); |
+ (*iter)->layer->SetShowSolidColorContent(); |
+ mirroring_layers_.erase(iter); |
+ |
+ if (mirroring_layers_.empty() && output_surface_) |
+ DetachFromOutputSurface(); |
} |
void ReflectorImpl::OnSourceSwapBuffers() { |
- if (!mirroring_layer_) |
+ if (mirroring_layers_.empty()) |
return; |
// Should be attached to the source output surface already. |
DCHECK(mailbox_.get()); |
@@ -105,11 +134,12 @@ void ReflectorImpl::OnSourceSwapBuffers() { |
mirrored_compositor_gl_helper_->InsertOrderingBarrier(); |
// Request full redraw on mirroring compositor. |
- UpdateTexture(size, mirroring_layer_->bounds()); |
+ for (LayerData* layer_data : mirroring_layers_) |
+ UpdateTexture(layer_data, size, layer_data->layer->bounds()); |
} |
void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& rect) { |
- if (!mirroring_layer_) |
+ if (mirroring_layers_.empty()) |
return; |
// Should be attached to the source output surface already. |
DCHECK(mailbox_.get()); |
@@ -130,7 +160,8 @@ void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& rect) { |
gfx::Rect mirroring_rect(rect.x(), y, rect.width(), rect.height()); |
// Request redraw of the dirty portion in mirroring compositor. |
- UpdateTexture(size, mirroring_rect); |
+ for (LayerData* layer_data : mirroring_layers_) |
+ UpdateTexture(layer_data, size, mirroring_rect); |
} |
static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox, |
@@ -139,20 +170,29 @@ static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox, |
mailbox->UpdateSyncPoint(sync_point); |
} |
-void ReflectorImpl::UpdateTexture(const gfx::Size& source_size, |
+ScopedVector<ReflectorImpl::LayerData>::iterator ReflectorImpl::FindLayerData( |
+ ui::Layer* layer) { |
+ return std::find_if(mirroring_layers_.begin(), mirroring_layers_.end(), |
+ [layer](const LayerData* layer_data) { |
+ return layer_data->layer == layer; |
+ }); |
+} |
+ |
+void ReflectorImpl::UpdateTexture(ReflectorImpl::LayerData* layer_data, |
+ const gfx::Size& source_size, |
const gfx::Rect& redraw_rect) { |
- if (needs_set_mailbox_) { |
- mirroring_layer_->SetTextureMailbox( |
+ if (layer_data->needs_set_mailbox) { |
+ layer_data->layer->SetTextureMailbox( |
cc::TextureMailbox(mailbox_->holder()), |
cc::SingleReleaseCallback::Create(base::Bind(ReleaseMailbox, mailbox_)), |
source_size); |
- needs_set_mailbox_ = false; |
+ layer_data->needs_set_mailbox = false; |
} else { |
- mirroring_layer_->SetTextureSize(source_size); |
+ layer_data->layer->SetTextureSize(source_size); |
} |
- mirroring_layer_->SetBounds(gfx::Rect(source_size)); |
- mirroring_layer_->SetTextureFlipped(flip_texture_); |
- mirroring_layer_->SchedulePaint(redraw_rect); |
+ layer_data->layer->SetBounds(gfx::Rect(source_size)); |
oshima
2015/04/28 16:05:39
This is inefficient as each reflector has a textur
piman
2015/04/28 18:38:13
Agreed, avoiding the copy altogether is a better p
|
+ layer_data->layer->SetTextureFlipped(flip_texture_); |
+ layer_data->layer->SchedulePaint(redraw_rect); |
} |
} // namespace content |