Index: content/browser/compositor/reflector_impl.cc |
diff --git a/content/browser/compositor/reflector_impl.cc b/content/browser/compositor/reflector_impl.cc |
index c58ee567640d107ab725888d5902e0f322e6c0ee..dcc0dc2bbe675af19151a929184a1353e7e00cb9 100644 |
--- a/content/browser/compositor/reflector_impl.cc |
+++ b/content/browser/compositor/reflector_impl.cc |
@@ -8,7 +8,7 @@ |
#include "base/location.h" |
#include "content/browser/compositor/browser_compositor_output_surface.h" |
#include "content/browser/compositor/owned_mailbox.h" |
-#include "content/common/gpu/client/gl_helper.h" |
+//#include "content/common/gpu/client/gl_helper.h" |
#include "ui/compositor/layer.h" |
namespace content { |
@@ -23,11 +23,11 @@ struct ReflectorImpl::LayerData { |
ReflectorImpl::ReflectorImpl(ui::Compositor* mirrored_compositor, |
ui::Layer* mirroring_layer) |
: mirrored_compositor_(mirrored_compositor), |
- mirrored_compositor_gl_helper_texture_id_(0), |
flip_texture_(false), |
+ composition_count_(0), |
output_surface_(nullptr) { |
if (mirroring_layer) |
- mirroring_layers_.push_back(new LayerData(mirroring_layer)); |
+ AddMirroringLayer(mirroring_layer); |
} |
ReflectorImpl::~ReflectorImpl() { |
@@ -46,10 +46,6 @@ void ReflectorImpl::DetachFromOutputSurface() { |
DCHECK(mailbox_.get()); |
mailbox_ = nullptr; |
output_surface_ = nullptr; |
- mirrored_compositor_gl_helper_->DeleteTexture( |
- mirrored_compositor_gl_helper_texture_id_); |
- mirrored_compositor_gl_helper_texture_id_ = 0; |
- mirrored_compositor_gl_helper_ = nullptr; |
for (LayerData* layer_data : mirroring_layers_) |
layer_data->layer->SetShowSolidColorContent(); |
} |
@@ -63,34 +59,13 @@ void ReflectorImpl::OnSourceSurfaceReady( |
if (output_surface_) |
DetachFromOutputSurface(); |
- // Use the GLHelper from the ImageTransportFactory for our OwnedMailbox so we |
- // don't have to manage the lifetime of the GLHelper relative to the lifetime |
- // of the mailbox. |
- GLHelper* shared_helper = ImageTransportFactory::GetInstance()->GetGLHelper(); |
- mailbox_ = new OwnedMailbox(shared_helper); |
- for (LayerData* layer_data : mirroring_layers_) |
- layer_data->needs_set_mailbox = true; |
+ output_surface_ = output_surface; |
- // Create a GLHelper attached to the mirrored compositor's output surface for |
- // copying the output of the mirrored compositor. |
- mirrored_compositor_gl_helper_.reset( |
- new GLHelper(output_surface->context_provider()->ContextGL(), |
- output_surface->context_provider()->ContextSupport())); |
- // Create a texture id in the name space of the new GLHelper to update the |
- // mailbox being held by the |mirroring_layer_|. |
- mirrored_compositor_gl_helper_texture_id_ = |
- mirrored_compositor_gl_helper_->ConsumeMailboxToTexture( |
- mailbox_->mailbox(), mailbox_->sync_point()); |
+ composition_started_callback_ = |
+ output_surface_->CreateCompositionStartedCallback(); |
flip_texture_ = !output_surface->capabilities().flipped_output_surface; |
- // The texture doesn't have the data. Request full redraw on mirrored |
- // compositor so that the full content will be copied to mirroring compositor. |
- // This full redraw should land us in OnSourceSwapBuffers() to resize the |
- // texture appropriately. |
- mirrored_compositor_->ScheduleFullRedraw(); |
- |
- output_surface_ = output_surface; |
output_surface_->SetReflector(this); |
} |
@@ -100,58 +75,87 @@ void ReflectorImpl::OnMirroringCompositorResized() { |
} |
void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) { |
+ DCHECK(layer->GetCompositor()); |
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(); |
+ |
+ layer->GetCompositor()->AddObserver(this); |
} |
void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) { |
+ DCHECK(layer->GetCompositor()); |
+ |
ScopedVector<LayerData>::iterator iter = FindLayerData(layer); |
DCHECK(iter != mirroring_layers_.end()); |
(*iter)->layer->SetShowSolidColorContent(); |
mirroring_layers_.erase(iter); |
+ layer->GetCompositor()->RemoveObserver(this); |
+ composition_count_--; |
+ if (composition_count_ == 0 && !composition_started_callback_.is_null()) |
+ composition_started_callback_.Run(); |
+ |
if (mirroring_layers_.empty() && output_surface_) |
DetachFromOutputSurface(); |
} |
+void ReflectorImpl::OnCompositingStarted(ui::Compositor* compositor, |
+ base::TimeTicks start_time) { |
+ if (composition_count_ > 0 && --composition_count_ == 0 && |
+ !composition_started_callback_.is_null()) { |
+ composition_started_callback_.Run(); |
+ } |
+} |
+ |
+void ReflectorImpl::OnSourceTextureMailboxUpdated( |
+ scoped_refptr<OwnedMailbox> mailbox) { |
+ mailbox_ = mailbox; |
+ if (mailbox_.get()) { |
+ for (LayerData* layer_data : mirroring_layers_) |
+ layer_data->needs_set_mailbox = true; |
+ |
+ // The texture doesn't have the data. Request full redraw on mirrored |
+ // compositor so that the full content will be copied to mirroring |
+ // compositor. This full redraw should land us in OnSourceSwapBuffers() to |
+ // resize the texture appropriately. |
+ mirrored_compositor_->ScheduleFullRedraw(); |
+ } |
+} |
+ |
void ReflectorImpl::OnSourceSwapBuffers() { |
- if (mirroring_layers_.empty()) |
+ if (mirroring_layers_.empty()) { |
+ if (!composition_started_callback_.is_null()) |
+ composition_started_callback_.Run(); |
return; |
+ } |
+ |
// Should be attached to the source output surface already. |
DCHECK(mailbox_.get()); |
gfx::Size size = output_surface_->SurfaceSize(); |
- mirrored_compositor_gl_helper_->CopyTextureFullImage( |
- mirrored_compositor_gl_helper_texture_id_, size); |
- // Insert a barrier to make the copy show up in the mirroring compositor's |
- // mailbox. Since the the compositor contexts and the ImageTransportFactory's |
- // GLHelper are all on the same GPU channel, this is sufficient instead of |
- // plumbing through a sync point. |
- mirrored_compositor_gl_helper_->InsertOrderingBarrier(); |
// Request full redraw on mirroring compositor. |
for (LayerData* layer_data : mirroring_layers_) |
UpdateTexture(layer_data, size, layer_data->layer->bounds()); |
+ composition_count_ = mirroring_layers_.size(); |
} |
void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& rect) { |
- if (mirroring_layers_.empty()) |
+ if (mirroring_layers_.empty()) { |
+ if (!composition_started_callback_.is_null()) |
+ composition_started_callback_.Run(); |
return; |
+ } |
+ |
// Should be attached to the source output surface already. |
DCHECK(mailbox_.get()); |
gfx::Size size = output_surface_->SurfaceSize(); |
- mirrored_compositor_gl_helper_->CopyTextureSubImage( |
- mirrored_compositor_gl_helper_texture_id_, rect); |
- // Insert a barrier to make the copy show up in the mirroring compositor's |
- // mailbox. Since the the compositor contexts and the ImageTransportFactory's |
- // GLHelper are all on the same GPU channel, this is sufficient instead of |
- // plumbing through a sync point. |
- mirrored_compositor_gl_helper_->InsertOrderingBarrier(); |
int y = rect.y(); |
// Flip the coordinates to compositor's one. |
@@ -162,6 +166,7 @@ void ReflectorImpl::OnSourcePostSubBuffer(const gfx::Rect& rect) { |
// Request redraw of the dirty portion in mirroring compositor. |
for (LayerData* layer_data : mirroring_layers_) |
UpdateTexture(layer_data, size, mirroring_rect); |
+ composition_count_ = mirroring_layers_.size(); |
} |
static void ReleaseMailbox(scoped_refptr<OwnedMailbox> mailbox, |