// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/exo/sub_surface.h" #include "base/logging.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "components/exo/surface.h" namespace exo { //////////////////////////////////////////////////////////////////////////////// // SubSurface, public: SubSurface::SubSurface(Surface* surface, Surface* parent) : surface_(surface), parent_(parent), is_synchronized_(true) { surface_->SetSurfaceDelegate(this); surface_->AddSurfaceObserver(this); parent_->AddSurfaceObserver(this); parent_->AddSubSurface(surface_); } SubSurface::~SubSurface() { if (surface_) { if (parent_) parent_->RemoveSubSurface(surface_); surface_->SetSurfaceDelegate(nullptr); surface_->RemoveSurfaceObserver(this); } if (parent_) parent_->RemoveSurfaceObserver(this); } void SubSurface::SetPosition(const gfx::Point& position) { TRACE_EVENT1("exo", "SubSurface::SetPosition", "position", position.ToString()); if (!parent_ || !surface_) return; parent_->SetSubSurfacePosition(surface_, position); } void SubSurface::PlaceAbove(Surface* reference) { TRACE_EVENT1("exo", "SubSurface::PlaceAbove", "reference", reference->AsTracedValue()); if (!parent_ || !surface_) return; if (reference == surface_) { DLOG(WARNING) << "Client tried to place sub-surface above itself"; return; } parent_->PlaceSubSurfaceAbove(surface_, reference); } void SubSurface::PlaceBelow(Surface* sibling) { TRACE_EVENT1("exo", "SubSurface::PlaceBelow", "sibling", sibling->AsTracedValue()); if (!parent_ || !surface_) return; if (sibling == surface_) { DLOG(WARNING) << "Client tried to place sub-surface below itself"; return; } parent_->PlaceSubSurfaceBelow(surface_, sibling); } void SubSurface::SetCommitBehavior(bool synchronized) { TRACE_EVENT1("exo", "SubSurface::SetCommitBehavior", "synchronized", synchronized); is_synchronized_ = synchronized; } scoped_refptr SubSurface::AsTracedValue() const { scoped_refptr value = new base::trace_event::TracedValue; value->SetBoolean("is_synchronized", is_synchronized_); return value; } //////////////////////////////////////////////////////////////////////////////// // SurfaceDelegate overrides: void SubSurface::OnSurfaceCommit() { // Early out if commit should be synchronized with parent. if (IsSurfaceSynchronized()) return; surface_->CommitSurfaceHierarchy(); } bool SubSurface::IsSurfaceSynchronized() const { // A sub-surface is effectively synchronized if either its parent is // synchronized or itself is in synchronized mode. if (is_synchronized_) return true; return parent_ ? parent_->IsSynchronized() : false; } //////////////////////////////////////////////////////////////////////////////// // SurfaceObserver overrides: void SubSurface::OnSurfaceDestroying(Surface* surface) { surface->RemoveSurfaceObserver(this); if (surface == parent_) { parent_ = nullptr; return; } DCHECK(surface == surface_); if (parent_) parent_->RemoveSubSurface(surface_); surface_ = nullptr; } } // namespace exo