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

Unified Diff: components/exo/surface.cc

Issue 1419373013: exo: Add support for subcompositor interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@exosphere-xdg-shell
Patch Set: rebase Created 5 years, 1 month 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: components/exo/surface.cc
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 6e21edc3b10fe86422022d86413811c2a64b2d0f..1fc1ca64d842c3ad18a560913e1783de9baeecab 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -11,6 +11,7 @@
#include "cc/resources/single_release_callback.h"
#include "components/exo/buffer.h"
#include "components/exo/surface_delegate.h"
+#include "components/exo/surface_observer.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/gpu_memory_buffer.h"
@@ -20,14 +21,19 @@ namespace exo {
////////////////////////////////////////////////////////////////////////////////
// Surface, public:
-Surface::Surface() : compositor_(nullptr), delegate_(nullptr) {
+Surface::Surface()
+ : needs_commit_surface_hierarchy_(false),
+ has_contents_(false),
+ compositor_(nullptr),
+ delegate_(nullptr) {
SetLayer(new ui::Layer(ui::LAYER_SOLID_COLOR));
set_owned_by_client();
+ SetVisible(false);
+ SetEnabled(false);
}
Surface::~Surface() {
- if (delegate_)
- delegate_->OnSurfaceDestroying();
+ FOR_EACH_OBSERVER(SurfaceObserver, observers_, OnSurfaceDestroying(this));
layer()->SetShowSolidColorContent();
@@ -69,11 +75,121 @@ void Surface::SetOpaqueRegion(const SkRegion& region) {
pending_opaque_region_ = region;
}
+void Surface::AddSubSurface(Surface* sub_surface) {
+ TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface",
+ sub_surface->AsTracedValue());
+
+ DCHECK(!sub_surface->parent());
+ DCHECK(!sub_surface->visible());
+ DCHECK(!sub_surface->enabled());
+ DCHECK(sub_surface->bounds().origin() == gfx::Point());
+ AddChildView(sub_surface);
+
+ pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point()));
piman 2015/11/19 21:59:10 nit: DCHECK that the sub_surface is not already in
reveman 2015/11/20 05:19:48 Done.
+}
+
+void Surface::RemoveSubSurface(Surface* sub_surface) {
+ TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface",
+ sub_surface->AsTracedValue());
+
+ RemoveChildView(sub_surface);
+
+ SubSurfaceEntryList::iterator it =
+ std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
+ [sub_surface](const SubSurfaceEntry& entry) {
+ return entry.first == sub_surface;
+ });
piman 2015/11/19 21:59:10 nit: worth a helper function SubSurfaceEntryList::
reveman 2015/11/20 05:19:49 Done.
+ DCHECK(it != pending_sub_surfaces_.end());
+ pending_sub_surfaces_.erase(it);
+}
+
+void Surface::SetSubSurfacePosition(Surface* sub_surface,
+ const gfx::Point& position) {
+ TRACE_EVENT2("exo", "Surface::SetSubSurfacePosition", "sub_surface",
+ sub_surface->AsTracedValue(), "position", position.ToString());
+
+ SubSurfaceEntryList::iterator it =
+ std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
+ [sub_surface](const SubSurfaceEntry& entry) {
+ return entry.first == sub_surface;
+ });
+ DCHECK(it != pending_sub_surfaces_.end());
+ it->second = position;
+}
+
+void Surface::PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference) {
+ TRACE_EVENT2("exo", "Surface::PlaceSubSurfaceAbove", "sub_surface",
+ sub_surface->AsTracedValue(), "reference",
+ reference->AsTracedValue());
piman 2015/11/19 21:59:10 nit: can you add a DCHECK_NE(sub_surface, referenc
reveman 2015/11/20 05:19:48 I added proper checking here in latest patch inste
+
+ SubSurfaceEntryList::iterator position_it;
+ if (reference == this) {
+ position_it = pending_sub_surfaces_.begin();
+ } else {
+ position_it =
+ std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
+ [reference](const SubSurfaceEntry& entry) {
+ return entry.first == reference;
+ });
+ if (position_it == pending_sub_surfaces_.end()) {
+ DLOG(WARNING) << "Client tried to place sub-surface above a reference "
+ "surface that is neither a parent nor s sibling";
piman 2015/11/19 21:59:10 nit: typo 's sibling'->'a sibling'
reveman 2015/11/20 05:19:49 Done.
+ return;
+ }
+
+ // Advance iterator to have |position_it| point to the sibling surface
+ // above |reference|.
+ std::advance(position_it, 1);
piman 2015/11/19 21:59:10 nit: ++position_it ?
reveman 2015/11/20 05:19:48 Done.
+ }
+
+ SubSurfaceEntryList::iterator it =
+ std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
+ [sub_surface](const SubSurfaceEntry& entry) {
+ return entry.first == sub_surface;
+ });
+ DCHECK(it != pending_sub_surfaces_.end());
+ pending_sub_surfaces_.splice(position_it, pending_sub_surfaces_, it);
+}
+
+void Surface::PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling) {
+ TRACE_EVENT2("exo", "Surface::PlaceSubSurfaceBelow", "sub_surface",
+ sub_surface->AsTracedValue(), "sibling",
+ sibling->AsTracedValue());
+
+ SubSurfaceEntryList::iterator sibling_it =
+ std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
+ [sibling](const SubSurfaceEntry& entry) {
+ return entry.first == sibling;
+ });
+ if (sibling_it == pending_sub_surfaces_.end()) {
+ DLOG(WARNING) << "Client tried to place sub-surface below a surface that "
+ "is not a sibling";
+ return;
+ }
+
+ SubSurfaceEntryList::iterator it =
+ std::find_if(pending_sub_surfaces_.begin(), pending_sub_surfaces_.end(),
+ [sub_surface](const SubSurfaceEntry& entry) {
+ return entry.first == sub_surface;
+ });
+ DCHECK(it != pending_sub_surfaces_.end());
+ pending_sub_surfaces_.splice(sibling_it, pending_sub_surfaces_, it);
+}
+
void Surface::Commit() {
TRACE_EVENT0("exo", "Surface::Commit");
+ needs_commit_surface_hierarchy_ = true;
+
if (delegate_)
delegate_->OnSurfaceCommit();
+ else
+ CommitSurfaceHierarchy();
+}
+
+void Surface::CommitSurfaceHierarchy() {
+ DCHECK(needs_commit_surface_hierarchy_);
+ needs_commit_surface_hierarchy_ = false;
cc::TextureMailbox texture_mailbox;
scoped_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
@@ -81,9 +197,11 @@ void Surface::Commit() {
texture_mailbox_release_callback =
pending_buffer_->AcquireTextureMailbox(&texture_mailbox);
pending_buffer_.reset();
+ has_contents_ = true;
} else {
// Show solid color content if there is no pending buffer.
layer()->SetShowSolidColorContent();
+ has_contents_ = false;
}
if (texture_mailbox_release_callback) {
@@ -113,6 +231,36 @@ void Surface::Commit() {
// Move pending frame callbacks to the end of |frame_callbacks_|.
frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
}
+
+ // Synchronize view hierarchy. This will position and update the stacking
+ // order of all sub-surfaces after committing all pending state of sub-surface
+ // descendants.
+ int index = 0;
+ for (auto& sub_surface_entry : pending_sub_surfaces_) {
+ Surface* sub_surface = sub_surface_entry.first;
+
+ // Synchronsouly commit all pending state of the sub-surface and its
+ // decendents.
+ if (sub_surface->needs_commit_surface_hierarchy())
+ sub_surface->CommitSurfaceHierarchy();
+
+ // Enable/disable sub-surface based on if it has contents.
+ sub_surface->SetVisible(sub_surface->has_contents());
+ sub_surface->SetEnabled(sub_surface->has_contents());
+
+ // Move sub-surface to its new position in the stack.
+ DCHECK_LT(index, child_count());
+ ReorderChildView(sub_surface, index);
+
+ // Update sub-surface position relative to surface origin.
+ sub_surface->SetPosition(sub_surface_entry.second);
+
+ ++index;
+ }
+}
+
+bool Surface::IsSynchronized() const {
+ return delegate_ ? delegate_->IsSurfaceSynchronized() : false;
}
void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) {
@@ -120,6 +268,22 @@ void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) {
delegate_ = delegate;
}
+bool Surface::HasSurfaceDelegate() const {
+ return !!delegate_;
+}
+
+void Surface::AddSurfaceObserver(SurfaceObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void Surface::RemoveSurfaceObserver(SurfaceObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+bool Surface::HasSurfaceObserver(const SurfaceObserver* observer) const {
+ return observers_.HasObserver(observer);
+}
+
scoped_refptr<base::trace_event::TracedValue> Surface::AsTracedValue() const {
scoped_refptr<base::trace_event::TracedValue> value =
new base::trace_event::TracedValue;

Powered by Google App Engine
This is Rietveld 408576698