Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(372)

Unified Diff: content/browser/compositor/reflector_impl.cc

Issue 1123763003: Draw the offscreen texture to reflector's surface without extra copy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..1c80d5179379ea140ed69f9b3ae09344dafa9a44 100644
--- a/content/browser/compositor/reflector_impl.cc
+++ b/content/browser/compositor/reflector_impl.cc
@@ -25,9 +25,10 @@ ReflectorImpl::ReflectorImpl(ui::Compositor* mirrored_compositor,
: 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 +47,12 @@ 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;
+ if (mirrored_compositor_gl_helper_.get()) {
+ 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,24 +66,35 @@ 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();
+ OnSourceTextureMailboxUpdated();
+ // If the source output surface didn't have its own
+ // mailbox, create one for mirror mode.
+ if (!mailbox_.get()) {
+ // 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);
+
+ // 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());
+
+ for (LayerData* layer_data : mirroring_layers_)
+ layer_data->needs_set_mailbox = true;
+ }
flip_texture_ = !output_surface->capabilities().flipped_output_surface;
@@ -90,7 +104,6 @@ void ReflectorImpl::OnSourceSurfaceReady(
// texture appropriately.
mirrored_compositor_->ScheduleFullRedraw();
- output_surface_ = output_surface;
output_surface_->SetReflector(this);
}
@@ -106,6 +119,8 @@ void ReflectorImpl::AddMirroringLayer(ui::Layer* layer) {
layer_data->needs_set_mailbox = true;
mirroring_layers_.push_back(layer_data);
mirrored_compositor_->ScheduleFullRedraw();
+
+ layer->GetCompositor()->AddObserver(this);
piman 2015/05/07 01:56:45 Is the layer guaranteed to be in the tree at that
oshima 2015/05/07 16:43:24 Yes, it's supposed to be in the tree. I'll add DCH
}
void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) {
@@ -114,44 +129,79 @@ void ReflectorImpl::RemoveMirroringLayer(ui::Layer* layer) {
(*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() {
+ mailbox_ = output_surface_->GetTextureMailbox();
+ for (LayerData* layer_data : mirroring_layers_)
+ layer_data->needs_set_mailbox = true;
+}
+
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();
+ if (mirrored_compositor_gl_helper_.get()) {
+ 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();
+ if (mirrored_compositor_gl_helper_.get()) {
+ 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,11 +212,12 @@ 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,
- unsigned int sync_point,
- bool is_lost) {
+ unsigned int sync_point,
+ bool is_lost) {
mailbox->UpdateSyncPoint(sync_point);
}

Powered by Google App Engine
This is Rietveld 408576698