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

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: address review feedback 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
« no previous file with comments | « components/exo/surface.h ('k') | components/exo/surface_delegate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/exo/surface.cc
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 6e21edc3b10fe86422022d86413811c2a64b2d0f..3f06238588078c265ef61a1321cc270a55285072 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -11,23 +11,48 @@
#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"
namespace exo {
+namespace {
+
+// Helper function that returns an iterator to the first entry in |list|
+// with |key|.
+template <typename T, typename U>
+typename T::iterator FindListEntry(T& list, U key) {
+ return std::find_if(list.begin(), list.end(),
+ [key](const typename T::value_type& entry) {
+ return entry.first == key;
+ });
+}
+
+// Helper function that returns true if |list| contains an entry with |key|.
+template <typename T, typename U>
+bool ListContainsEntry(T& list, U key) {
+ return FindListEntry(list, key) != list.end();
+}
+
+} // namespace
////////////////////////////////////////////////////////////////////////////////
// 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 +94,108 @@ 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);
+
+ DCHECK(!ListContainsEntry(pending_sub_surfaces_, sub_surface));
+ pending_sub_surfaces_.push_back(std::make_pair(sub_surface, gfx::Point()));
+}
+
+void Surface::RemoveSubSurface(Surface* sub_surface) {
+ TRACE_EVENT1("exo", "Surface::AddSubSurface", "sub_surface",
+ sub_surface->AsTracedValue());
+
+ RemoveChildView(sub_surface);
+
+ DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
+ pending_sub_surfaces_.erase(
+ FindListEntry(pending_sub_surfaces_, sub_surface));
+}
+
+void Surface::SetSubSurfacePosition(Surface* sub_surface,
+ const gfx::Point& position) {
+ TRACE_EVENT2("exo", "Surface::SetSubSurfacePosition", "sub_surface",
+ sub_surface->AsTracedValue(), "position", position.ToString());
+
+ auto it = FindListEntry(pending_sub_surfaces_, 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());
+
+ if (sub_surface == reference) {
+ DLOG(WARNING) << "Client tried to place sub-surface above itself";
+ return;
+ }
+
+ auto position_it = pending_sub_surfaces_.begin();
+ if (reference != this) {
+ position_it = FindListEntry(pending_sub_surfaces_, 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 a sibling";
+ return;
+ }
+
+ // Advance iterator to have |position_it| point to the sibling surface
+ // above |reference|.
+ ++position_it;
+ }
+
+ DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
+ pending_sub_surfaces_.splice(
+ position_it, pending_sub_surfaces_,
+ FindListEntry(pending_sub_surfaces_, sub_surface));
+}
+
+void Surface::PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling) {
+ TRACE_EVENT2("exo", "Surface::PlaceSubSurfaceBelow", "sub_surface",
+ sub_surface->AsTracedValue(), "sibling",
+ sibling->AsTracedValue());
+
+ if (sub_surface == sibling) {
+ DLOG(WARNING) << "Client tried to place sub-surface below itself";
+ return;
+ }
+
+ auto sibling_it = FindListEntry(pending_sub_surfaces_, 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;
+ }
+
+ DCHECK(ListContainsEntry(pending_sub_surfaces_, sub_surface));
+ pending_sub_surfaces_.splice(
+ sibling_it, pending_sub_surfaces_,
+ FindListEntry(pending_sub_surfaces_, sub_surface));
+}
+
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 +203,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 +237,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 +274,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;
« no previous file with comments | « components/exo/surface.h ('k') | components/exo/surface_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698