Generalize layer mirroring for phantom windows

Previously, the layers of a phantom window were recreated when the
surface changed in the corresponding layers of the original window.
The code also assumed that layers with surfaces are leaves in the
layer tree, but Exosphere surfaces are nested. Recursive layer
cloning would be inefficient for surfaces changing in each frame,
so this CL adds an alternative way to mirror layers. In addition,
the bounds of Exosphere surfaces relative to their parent window
are updated whenever the window moves, so this CL provides a way
to synchronize relative positions of layers in phantom windows.

In addition to implementing phantom windows for ARC apps, this CL
fixes three bugs related to mirroring:

  1) Memory corruption due to the non-recursive layer cloning.
  2) Dangling pointers due to observers sticking around.
  3) Black Alt+Tab previews for ARC windows.

BUG=642894
BUG=649452
BUG=653113
TEST=ARC apps that render continuously (e.g. games, video players)
     can be dragged to external displays, and their content is
     mirrored in phantom windows.
TEST=ARC apps are mirrored in Alt+Tab previews.
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_precise_blink_rel

Review-Url: https://codereview.chromium.org/2383263002
Cr-Commit-Position: refs/heads/master@{#427891}
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 5887bd4..bd92e82 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -476,8 +476,6 @@
     "common/wm/drag_details.h",
     "common/wm/focus_rules.cc",
     "common/wm/focus_rules.h",
-    "common/wm/forwarding_layer_delegate.cc",
-    "common/wm/forwarding_layer_delegate.h",
     "common/wm/fullscreen_window_finder.cc",
     "common/wm/fullscreen_window_finder.h",
     "common/wm/immersive_context_ash.cc",
diff --git a/ash/aura/wm_window_aura.cc b/ash/aura/wm_window_aura.cc
index fb89c25..f43120a 100644
--- a/ash/aura/wm_window_aura.cc
+++ b/ash/aura/wm_window_aura.cc
@@ -498,7 +498,7 @@
   // Specify |set_bounds| to true here to keep the old bounds in the child
   // windows of |window|.
   std::unique_ptr<ui::LayerTreeOwner> old_layer_owner =
-      ::wm::RecreateLayers(window_, nullptr);
+      ::wm::RecreateLayers(window_);
   ui::Layer* old_layer = old_layer_owner->root();
   DCHECK(old_layer);
   ui::Layer* new_layer = window_->layer();
diff --git a/ash/common/wm/forwarding_layer_delegate.cc b/ash/common/wm/forwarding_layer_delegate.cc
deleted file mode 100644
index 50d33c4..0000000
--- a/ash/common/wm/forwarding_layer_delegate.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 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 "ash/common/wm/forwarding_layer_delegate.h"
-
-#include "ash/common/wm_window.h"
-#include "ui/compositor/layer.h"
-#include "ui/compositor/layer_owner.h"
-
-namespace ash {
-namespace wm {
-
-ForwardingLayerDelegate::ForwardingLayerDelegate(ui::Layer* new_layer,
-                                                 ui::Layer* original_layer)
-    : client_layer_(new_layer),
-      original_layer_(original_layer),
-      scoped_observer_(this) {
-  scoped_observer_.Add(original_layer);
-}
-
-ForwardingLayerDelegate::~ForwardingLayerDelegate() {}
-
-void ForwardingLayerDelegate::OnPaintLayer(const ui::PaintContext& context) {
-  if (original_layer_ && original_layer_->delegate())
-    original_layer_->delegate()->OnPaintLayer(context);
-}
-
-void ForwardingLayerDelegate::OnDelegatedFrameDamage(
-    const gfx::Rect& damage_rect_in_dip) {}
-
-void ForwardingLayerDelegate::OnDeviceScaleFactorChanged(
-    float device_scale_factor) {
-  // Don't tell the original delegate about device scale factor change
-  // on cloned layer because the original layer is still on the same display.
-}
-
-void ForwardingLayerDelegate::DidPaintLayer(ui::Layer* layer,
-                                            const gfx::Rect& rect) {
-  client_layer_->SchedulePaint(rect);
-}
-
-void ForwardingLayerDelegate::SurfaceChanged(ui::Layer* layer) {
-  // This will delete the old layer and any descendants.
-  ui::LayerOwner old_client;
-  old_client.SetLayer(client_layer_);
-
-  ui::LayerOwner* owner = layer->owner();
-  // The layer recreation step isn't recursive, but layers with surfaces don't
-  // tend to have children anyway. We may end up missing some children, but we
-  // can also reach that state if layers are ever added or removed.
-  // TODO(estade): address this if it ever becomes a practical issue.
-  std::unique_ptr<ui::Layer> recreated = owner->RecreateLayer();
-  client_layer_ = recreated.get();
-  old_client.layer()->parent()->Add(recreated.release());
-  old_client.layer()->parent()->Remove(old_client.layer());
-
-  scoped_observer_.Remove(original_layer_);
-  original_layer_ = owner->layer();
-  scoped_observer_.Add(original_layer_);
-}
-
-void ForwardingLayerDelegate::LayerDestroyed(ui::Layer* layer) {
-  original_layer_ = nullptr;
-  scoped_observer_.Remove(layer);
-}
-
-}  // namespace wm
-}  // namespace ash
diff --git a/ash/common/wm/forwarding_layer_delegate.h b/ash/common/wm/forwarding_layer_delegate.h
deleted file mode 100644
index 7c68f18..0000000
--- a/ash/common/wm/forwarding_layer_delegate.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2016 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.
-
-#ifndef ASH_COMMON_WM_FORWARDING_LAYER_DELEGATE_H_
-#define ASH_COMMON_WM_FORWARDING_LAYER_DELEGATE_H_
-
-#include "base/macros.h"
-#include "base/scoped_observer.h"
-#include "ui/compositor/layer_delegate.h"
-#include "ui/compositor/layer_observer.h"
-
-namespace ui {
-class Layer;
-}
-
-namespace ash {
-
-class WmWindow;
-
-namespace wm {
-
-// A layer delegate to paint the content of a recreated layer by delegating
-// the paint request to the original delegate. It is a delegate of the recreated
-// layer and an observer of the original layer.
-class ForwardingLayerDelegate : public ui::LayerDelegate,
-                                public ui::LayerObserver {
- public:
-  ForwardingLayerDelegate(ui::Layer* new_layer, ui::Layer* original_layer);
-  ~ForwardingLayerDelegate() override;
-
-  // ui:LayerDelegate:
-  void OnPaintLayer(const ui::PaintContext& context) override;
-  void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override;
-  void OnDeviceScaleFactorChanged(float device_scale_factor) override;
-
-  // ui::LayerObserver:
-  void DidPaintLayer(ui::Layer* layer, const gfx::Rect& rect) override;
-  void SurfaceChanged(ui::Layer* layer) override;
-  void LayerDestroyed(ui::Layer* layer) override;
-
- private:
-  // The layer for which |this| is the delegate.
-  ui::Layer* client_layer_;
-
-  // The layer that was recreated to replace |new_layer_|.
-  ui::Layer* original_layer_;
-
-  ScopedObserver<ui::Layer, ui::LayerObserver> scoped_observer_;
-
-  DISALLOW_COPY_AND_ASSIGN(ForwardingLayerDelegate);
-};
-
-}  // namespace wm
-}  // namespace ash
-
-#endif  // ASH_COMMON_WM_FORWARDING_LAYER_DELEGATE_H_
diff --git a/ash/common/wm/window_cycle_list.cc b/ash/common/wm/window_cycle_list.cc
index da1cf15..33efaac 100644
--- a/ash/common/wm/window_cycle_list.cc
+++ b/ash/common/wm/window_cycle_list.cc
@@ -7,7 +7,6 @@
 #include <list>
 #include <map>
 
-#include "ash/common/wm/forwarding_layer_delegate.h"
 #include "ash/common/wm/mru_window_tracker.h"
 #include "ash/common/wm/window_state.h"
 #include "ash/common/wm_root_window_controller.h"
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc
index bd18d74..3dc5de4 100644
--- a/ash/rotator/screen_rotation_animator.cc
+++ b/ash/rotator/screen_rotation_animator.cc
@@ -169,7 +169,7 @@
   const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN;
 
   std::unique_ptr<ui::LayerTreeOwner> old_layer_tree =
-      ::wm::RecreateLayers(root_window, nullptr);
+      ::wm::RecreateLayers(root_window);
 
   // Add the cloned layer tree in to the root, so it will be rendered.
   root_window->layer()->Add(old_layer_tree->root());
diff --git a/ash/utility/screenshot_controller.cc b/ash/utility/screenshot_controller.cc
index 7503cc5..ce2c799 100644
--- a/ash/utility/screenshot_controller.cc
+++ b/ash/utility/screenshot_controller.cc
@@ -88,7 +88,7 @@
  public:
   ScreenshotLayer(ui::Layer* parent, bool immediate_overlay)
       : draw_inactive_overlay_(immediate_overlay) {
-    SetLayer(new ui::Layer(ui::LAYER_TEXTURED));
+    SetLayer(base::MakeUnique<ui::Layer>(ui::LAYER_TEXTURED));
     layer()->SetFillsBoundsOpaquely(false);
     layer()->SetBounds(parent->bounds());
     parent->Add(layer());
diff --git a/ash/wm/drag_window_controller.cc b/ash/wm/drag_window_controller.cc
index b5b5769..a42fd69d 100644
--- a/ash/wm/drag_window_controller.cc
+++ b/ash/wm/drag_window_controller.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 
 #include "ash/aura/wm_window_aura.h"
-#include "ash/common/wm/forwarding_layer_delegate.h"
 #include "ash/display/window_tree_host_manager.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/screen_util.h"
@@ -33,9 +32,7 @@
 
 // This keeps track of the drag window's state. It creates/destroys/updates
 // bounds and opacity based on the current bounds.
-class DragWindowController::DragWindowDetails
-    : public aura::WindowDelegate,
-      public ::wm::LayerDelegateFactory {
+class DragWindowController::DragWindowDetails : public aura::WindowDelegate {
  public:
   DragWindowDetails(const display::Display& display,
                     aura::Window* original_window)
@@ -115,14 +112,12 @@
 
   void RecreateWindowLayers(aura::Window* original_window) {
     DCHECK(!layer_owner_.get());
-    layer_owner_ = ::wm::RecreateLayers(original_window, this);
+    layer_owner_ = ::wm::MirrorLayers(original_window, true /* sync_bounds */);
     // Place the layer at (0, 0) of the DragWindowController's window.
     gfx::Rect layer_bounds = layer_owner_->root()->bounds();
     layer_bounds.set_origin(gfx::Point(0, 0));
     layer_owner_->root()->SetBounds(layer_bounds);
     layer_owner_->root()->SetVisible(false);
-    // Detach it from the current container.
-    layer_owner_->root()->parent()->Remove(layer_owner_->root());
   }
 
   void SetOpacity(const aura::Window* original_window, float opacity) {
@@ -133,16 +128,6 @@
   }
 
   // aura::WindowDelegate:
-  ui::LayerDelegate* CreateDelegate(ui::Layer* foo, ui::Layer* layer) override {
-    if (!layer || !layer->delegate())
-      return nullptr;
-    wm::ForwardingLayerDelegate* new_delegate =
-        new wm::ForwardingLayerDelegate(foo, layer);
-    delegates_.push_back(base::WrapUnique(new_delegate));
-    return new_delegate;
-  }
-
-  // aura::WindowDelegate:
   gfx::Size GetMinimumSize() const override { return gfx::Size(); }
   gfx::Size GetMaximumSize() const override { return gfx::Size(); }
   void OnBoundsChanged(const gfx::Rect& old_bounds,
@@ -177,8 +162,6 @@
 
   aura::Window* original_window_ = nullptr;
 
-  std::vector<std::unique_ptr<wm::ForwardingLayerDelegate>> delegates_;
-
   // The copy of window_->layer() and its descendants.
   std::unique_ptr<ui::LayerTreeOwner> layer_owner_;
 
diff --git a/ash/wm/window_mirror_view.cc b/ash/wm/window_mirror_view.cc
index d7f0ced..a128a42b 100644
--- a/ash/wm/window_mirror_view.cc
+++ b/ash/wm/window_mirror_view.cc
@@ -5,7 +5,6 @@
 #include "ash/wm/window_mirror_view.h"
 
 #include "ash/aura/wm_window_aura.h"
-#include "ash/common/wm/forwarding_layer_delegate.h"
 #include "ash/common/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
 #include "ui/aura/client/aura_constants.h"
@@ -13,6 +12,7 @@
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_tree_owner.h"
 #include "ui/views/widget/widget.h"
+#include "ui/wm/core/window_util.h"
 
 namespace ash {
 namespace wm {
@@ -74,24 +74,15 @@
     InitLayerOwner();
 }
 
-ui::LayerDelegate* WindowMirrorView::CreateDelegate(ui::Layer* new_layer,
-                                                    ui::Layer* old_layer) {
-  if (!old_layer || !old_layer->delegate())
-    return nullptr;
-  delegates_.push_back(
-      base::MakeUnique<ForwardingLayerDelegate>(new_layer, old_layer));
-  return delegates_.back().get();
-}
-
 void WindowMirrorView::InitLayerOwner() {
   if (!layer_owner_) {
     target_->aura_window()->SetProperty(aura::client::kMirroringEnabledKey,
                                         true);
   }
 
-  layer_owner_ = ::wm::RecreateLayers(target_->aura_window(), this);
+  layer_owner_ =
+      ::wm::MirrorLayers(target_->aura_window(), false /* sync_bounds */);
 
-  GetMirrorLayer()->parent()->Remove(GetMirrorLayer());
   SetPaintToLayer(true);
   layer()->Add(GetMirrorLayer());
   // This causes us to clip the non-client areas of the window.
diff --git a/ash/wm/window_mirror_view.h b/ash/wm/window_mirror_view.h
index 85b990c..5fabd641 100644
--- a/ash/wm/window_mirror_view.h
+++ b/ash/wm/window_mirror_view.h
@@ -6,12 +6,14 @@
 #define ASH_WM_WINDOW_MIRROR_VIEW_H_
 
 #include <memory>
-#include <vector>
 
 #include "ash/ash_export.h"
 #include "base/macros.h"
 #include "ui/views/view.h"
-#include "ui/wm/core/window_util.h"
+
+namespace ui {
+class LayerTreeOwner;
+}
 
 namespace ash {
 
@@ -19,12 +21,8 @@
 
 namespace wm {
 
-class ForwardingLayerDelegate;
-
-// A view that mirrors the client area of a single window. Layers are lifted
-// from the underlying window (which gets new ones in their place). New paint
-// calls, if any, are forwarded to the underlying window.
-class WindowMirrorView : public views::View, public ::wm::LayerDelegateFactory {
+// A view that mirrors the client area of a single window.
+class WindowMirrorView : public views::View {
  public:
   explicit WindowMirrorView(WmWindowAura* window);
   ~WindowMirrorView() override;
@@ -35,10 +33,6 @@
   bool GetNeedsNotificationWhenVisibleBoundsChange() const override;
   void OnVisibleBoundsChanged() override;
 
-  // ::wm::LayerDelegateFactory:
-  ui::LayerDelegate* CreateDelegate(ui::Layer* new_layer,
-                                    ui::Layer* layer) override;
-
  private:
   void InitLayerOwner();
 
@@ -57,8 +51,6 @@
   // the first time the view becomes visible.
   std::unique_ptr<ui::LayerTreeOwner> layer_owner_;
 
-  std::vector<std::unique_ptr<ForwardingLayerDelegate>> delegates_;
-
   DISALLOW_COPY_AND_ASSIGN(WindowMirrorView);
 };
 
diff --git a/cc/layers/surface_layer.h b/cc/layers/surface_layer.h
index 06c84c1..a66257d 100644
--- a/cc/layers/surface_layer.h
+++ b/cc/layers/surface_layer.h
@@ -41,6 +41,13 @@
   void SetLayerTreeHost(LayerTreeHost* host) override;
   void PushPropertiesTo(LayerImpl* layer) override;
 
+  SurfaceId surface_id() const { return surface_id_; }
+  const gfx::Size& surface_size() const { return surface_size_; }
+  float surface_scale() const { return surface_scale_; }
+
+  const SatisfyCallback& satisfy_callback() const { return satisfy_callback_; }
+  const RequireCallback& require_callback() const { return require_callback_; }
+
  protected:
   SurfaceLayer(const SatisfyCallback& satisfy_callback,
                const RequireCallback& require_callback);
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
index cad2fe63..da9c45f3 100644
--- a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
+++ b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
@@ -334,7 +334,7 @@
             // window we encounter.
             found_foreground_maximized_window = true;
             ui::LayerTreeOwner* old_layer =
-                wm::RecreateLayers(window, nullptr).release();
+                wm::RecreateLayers(window).release();
             window->layer()->parent()->StackAtBottom(old_layer->root());
             new MaximizedWindowAnimationWatcher(window->layer()->GetAnimator(),
                                                 old_layer);
diff --git a/chrome/browser/ui/views/frame/contents_web_view.cc b/chrome/browser/ui/views/frame/contents_web_view.cc
index b6b45bd..151823ad 100644
--- a/chrome/browser/ui/views/frame/contents_web_view.cc
+++ b/chrome/browser/ui/views/frame/contents_web_view.cc
@@ -98,8 +98,7 @@
 #if defined(USE_AURA)
   // We don't need to clone the layers on non-Aura (Mac), because closing an
   // NSWindow does not animate.
-  cloned_layer_tree_ =
-      wm::RecreateLayers(web_contents()->GetNativeView(), nullptr);
+  cloned_layer_tree_ = wm::RecreateLayers(web_contents()->GetNativeView());
 #endif
   if (!cloned_layer_tree_ || !cloned_layer_tree_->root()) {
     cloned_layer_tree_.reset();
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 8c0efb7..cec8cc5 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -210,7 +210,6 @@
   window_->SetName("ExoSurface");
   window_->SetProperty(kSurfaceKey, this);
   window_->Init(ui::LAYER_SOLID_COLOR);
-  window_->set_layer_owner_delegate(this);
   window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter));
   window_->set_owned_by_parent(false);
   factory_owner_->surface_ = this;
@@ -488,13 +487,16 @@
 
   if (old_local_frame_id != local_frame_id_) {
     float contents_surface_to_layer_scale = 1.0;
+    // The bounds must be updated before switching to the new surface, because
+    // the layer may be mirrored, in which case a surface change causes the
+    // mirror layer to update its surface using the latest bounds.
+    window_->layer()->SetBounds(
+        gfx::Rect(window_->layer()->bounds().origin(), content_size_));
     window_->layer()->SetShowSurface(
         cc::SurfaceId(factory_owner_->frame_sink_id_, local_frame_id_),
         base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
         base::Bind(&RequireCallback, base::Unretained(surface_manager_)),
         content_size_, contents_surface_to_layer_scale, content_size_);
-    window_->layer()->SetBounds(
-        gfx::Rect(window_->layer()->bounds().origin(), content_size_));
     window_->layer()->SetFillsBoundsOpaquely(
         state_.blend_mode == SkXfermode::kSrc_Mode ||
         state_.opaque_region.contains(
@@ -610,17 +612,6 @@
   return value;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// ui::LayerOwnerDelegate overrides:
-
-void Surface::OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) {
-  if (!current_buffer_.buffer())
-    return;
-
-  // TODO(reveman): Give the client a chance to provide new contents.
-  SetSurfaceLayerContents(new_layer);
-}
-
 void Surface::WillDraw(const cc::LocalFrameId& id) {
   while (!active_frame_callbacks_.empty()) {
     active_frame_callbacks_.front().Run(base::TimeTicks::Now());
@@ -695,20 +686,6 @@
   }
 }
 
-void Surface::SetSurfaceLayerContents(ui::Layer* layer) {
-  if (local_frame_id_.is_null())
-    return;
-
-  gfx::Size layer_size = layer->bounds().size();
-  float contents_surface_to_layer_scale = 1.0f;
-
-  layer->SetShowSurface(
-      cc::SurfaceId(factory_owner_->frame_sink_id_, local_frame_id_),
-      base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
-      base::Bind(&RequireCallback, base::Unretained(surface_manager_)),
-      layer_size, contents_surface_to_layer_scale, layer_size);
-}
-
 void Surface::UpdateResource(bool client_usage) {
   std::unique_ptr<cc::SingleReleaseCallback> texture_mailbox_release_callback;
 
diff --git a/components/exo/surface.h b/components/exo/surface.h
index a370678..744587d 100644
--- a/components/exo/surface.h
+++ b/components/exo/surface.h
@@ -21,7 +21,6 @@
 #include "third_party/skia/include/core/SkXfermode.h"
 #include "ui/aura/window.h"
 #include "ui/compositor/compositor.h"
-#include "ui/compositor/layer_owner_delegate.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace base {
@@ -89,8 +88,7 @@
 
 // This class represents a rectangular area that is displayed on the screen.
 // It has a location, size and pixel contents.
-class Surface : public ui::LayerOwnerDelegate,
-                public ui::ContextFactoryObserver {
+class Surface : public ui::ContextFactoryObserver {
  public:
   using PropertyDeallocator = void (*)(int64_t value);
 
@@ -210,9 +208,6 @@
     return pending_damage_.contains(gfx::RectToSkIRect(damage));
   }
 
-  // Overridden from ui::LayerOwnerDelegate:
-  void OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) override;
-
   // Overridden from ui::ContextFactoryObserver.
   void OnLostResources() override;
 
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc
index 872f03c0..01bbff2 100644
--- a/components/exo/surface_unittest.cc
+++ b/components/exo/surface_unittest.cc
@@ -129,7 +129,7 @@
       surface->content_size().ToString());
 }
 
-TEST_F(SurfaceTest, RecreateLayer) {
+TEST_F(SurfaceTest, MirrorLayers) {
   gfx::Size buffer_size(512, 512);
   std::unique_ptr<Buffer> buffer(
       new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
@@ -141,7 +141,7 @@
   EXPECT_EQ(buffer_size, surface->window()->bounds().size());
   EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size());
   std::unique_ptr<ui::LayerTreeOwner> old_layer_owner =
-      ::wm::RecreateLayers(surface->window(), nullptr);
+      ::wm::MirrorLayers(surface->window(), false /* sync_bounds */);
   EXPECT_EQ(buffer_size, surface->window()->bounds().size());
   EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size());
   EXPECT_EQ(buffer_size, old_layer_owner->root()->bounds().size());
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index 452db53..64ecbd2 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -892,24 +892,4 @@
   delegated_frame_evictor_->UnlockFrame();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// DelegatedFrameHost, ui::LayerOwnerDelegate implementation:
-
-void DelegatedFrameHost::OnLayerRecreated(ui::Layer* old_layer,
-                                          ui::Layer* new_layer) {
-  // The new_layer is the one that will be used by our Window, so that's the one
-  // that should keep our frame. old_layer will be returned to the
-  // RecreateLayer caller, and should have a copy.
-  if (!local_frame_id_.is_null()) {
-    ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
-    cc::SurfaceManager* manager = factory->GetSurfaceManager();
-    new_layer->SetShowSurface(
-        cc::SurfaceId(frame_sink_id_, local_frame_id_),
-        base::Bind(&SatisfyCallback, base::Unretained(manager)),
-        base::Bind(&RequireCallback, base::Unretained(manager)),
-        current_surface_size_, current_scale_factor_,
-        current_frame_size_in_dip_);
-  }
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h
index 15cab24..2afc4ca 100644
--- a/content/browser/renderer_host/delegated_frame_host.h
+++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -23,7 +23,6 @@
 #include "ui/compositor/compositor_observer.h"
 #include "ui/compositor/compositor_vsync_manager.h"
 #include "ui/compositor/layer.h"
-#include "ui/compositor/layer_owner_delegate.h"
 #include "ui/events/event.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
@@ -84,7 +83,6 @@
 class CONTENT_EXPORT DelegatedFrameHost
     : public ui::CompositorObserver,
       public ui::CompositorVSyncManager::Observer,
-      public ui::LayerOwnerDelegate,
       public ui::ContextFactoryObserver,
       public DelegatedFrameEvictorClient,
       public cc::SurfaceFactoryClient,
@@ -106,9 +104,6 @@
   void OnUpdateVSyncParameters(base::TimeTicks timebase,
                                base::TimeDelta interval) override;
 
-  // ui::LayerOwnerObserver implementation.
-  void OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) override;
-
   // ImageTransportFactoryObserver implementation.
   void OnLostResources() override;
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 39bb0898..3d2c227 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1860,7 +1860,6 @@
   aura::client::SetTooltipText(window_, &tooltip_);
   aura::client::SetActivationDelegate(window_, this);
   aura::client::SetFocusChangeObserver(window_, this);
-  window_->set_layer_owner_delegate(delegated_frame_host_.get());
   display::Screen::GetScreen()->AddObserver(this);
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 009b9784..093d822e 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -361,7 +361,7 @@
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, TouchEventSyncAsync);
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, Resize);
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, SwapNotifiesWindow);
-  FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, RecreateLayers);
+  FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, MirrorLayers);
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
                            SkippedDelegatedFrames);
   FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 2b1f615..9c38a75 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -1894,23 +1894,23 @@
   view_->window_->RemoveObserver(&observer);
 }
 
-// Recreating the layers for a window should cause Surface destruction to
+// Mirroring the layers for a window should cause Surface destruction to
 // depend on both layers.
-TEST_F(RenderWidgetHostViewAuraTest, RecreateLayers) {
+TEST_F(RenderWidgetHostViewAuraTest, MirrorLayers) {
   gfx::Size view_size(100, 100);
   gfx::Rect view_rect(view_size);
+  aura::Window* const root = parent_view_->GetNativeView()->GetRootWindow();
 
   view_->InitAsChild(nullptr);
   aura::client::ParentWindowWithContext(
-      view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
-      gfx::Rect());
+      view_->GetNativeView(), root, gfx::Rect());
   view_->SetSize(view_size);
   view_->Show();
 
   view_->OnSwapCompositorFrame(0,
                                MakeDelegatedFrame(1.f, view_size, view_rect));
-  std::unique_ptr<ui::LayerTreeOwner> cloned_owner(
-      wm::RecreateLayers(view_->GetNativeView(), nullptr));
+  std::unique_ptr<ui::LayerTreeOwner> mirror(wm::MirrorLayers(
+      view_->GetNativeView(), false /* sync_bounds */));
 
   cc::SurfaceId id = view_->GetDelegatedFrameHost()->SurfaceIdForTesting();
   if (!id.is_null()) {
@@ -1918,8 +1918,14 @@
     cc::SurfaceManager* manager = factory->GetSurfaceManager();
     cc::Surface* surface = manager->GetSurfaceForId(id);
     EXPECT_TRUE(surface);
-    // Should be a SurfaceSequence for both the original and new layers.
+
+    // An orphaned mirror should not be a destruction dependency.
+    EXPECT_EQ(1u, surface->GetDestructionDependencyCount());
+
+    // Both layers should be destruction dependencies.
+    root->layer()->Add(mirror->root());
     EXPECT_EQ(2u, surface->GetDestructionDependencyCount());
+    root->layer()->Remove(mirror->root());
   }
 }
 
diff --git a/ui/arc/notification/arc_custom_notification_view.cc b/ui/arc/notification/arc_custom_notification_view.cc
index 2189b10..3e927c5 100644
--- a/ui/arc/notification/arc_custom_notification_view.cc
+++ b/ui/arc/notification/arc_custom_notification_view.cc
@@ -113,7 +113,7 @@
   void OnSlideStart() {
     if (!owner_->surface_ || !owner_->surface_->window())
       return;
-    surface_copy_ = ::wm::RecreateLayers(owner_->surface_->window(), nullptr);
+    surface_copy_ = ::wm::RecreateLayers(owner_->surface_->window());
     // |surface_copy_| is at (0, 0) in owner_->layer().
     surface_copy_->root()->SetBounds(gfx::Rect(surface_copy_->root()->size()));
     owner_->layer()->Add(surface_copy_->root());
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 3e3858b..9a901b2d 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -143,7 +143,7 @@
     port_owner_ = Env::GetInstance()->CreateWindowPort(this);
     port_ = port_owner_.get();
   }
-  SetLayer(new ui::Layer(layer_type));
+  SetLayer(base::MakeUnique<ui::Layer>(layer_type));
   std::unique_ptr<WindowPortInitData> init_data = port_->OnPreInit(this);
   layer()->SetVisible(false);
   layer()->set_delegate(this);
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index ac205507..b6f8ad4 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -49,6 +49,42 @@
 
 namespace ui {
 
+class Layer::LayerMirror : public LayerDelegate, LayerObserver {
+ public:
+  LayerMirror(Layer* source, Layer* dest)
+      : source_(source), dest_(dest) {
+    dest->AddObserver(this);
+    dest->set_delegate(this);
+  }
+
+  ~LayerMirror() override {
+    dest_->RemoveObserver(this);
+    dest_->set_delegate(nullptr);
+  }
+
+  Layer* dest() { return dest_; }
+
+  // LayerDelegate:
+  void OnPaintLayer(const PaintContext& context) override {
+    if (auto* delegate = source_->delegate())
+      delegate->OnPaintLayer(context);
+  }
+  void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
+  void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
+
+  // LayerObserver:
+  void LayerDestroyed(Layer* layer) override {
+    DCHECK_EQ(dest_, layer);
+    source_->OnMirrorDestroyed(this);
+  }
+
+ private:
+  Layer* const source_;
+  Layer* const dest_;
+
+  DISALLOW_COPY_AND_ASSIGN(LayerMirror);
+};
+
 Layer::Layer()
     : type_(LAYER_TEXTURED),
       compositor_(NULL),
@@ -119,6 +155,52 @@
     mailbox_release_callback_->Run(gpu::SyncToken(), false);
 }
 
+std::unique_ptr<Layer> Layer::Clone() const {
+  auto clone = base::MakeUnique<Layer>(type_);
+
+  clone->SetTransform(GetTargetTransform());
+  clone->SetBounds(bounds_);
+  clone->SetSubpixelPositionOffset(subpixel_position_offset_);
+  clone->SetMasksToBounds(GetMasksToBounds());
+  clone->SetOpacity(GetTargetOpacity());
+  clone->SetVisible(GetTargetVisibility());
+  clone->SetFillsBoundsOpaquely(fills_bounds_opaquely_);
+  clone->SetFillsBoundsCompletely(fills_bounds_completely_);
+  clone->set_name(name_);
+
+  // Background filters.
+  clone->SetBackgroundBlur(background_blur_radius_);
+  clone->SetBackgroundZoom(zoom_, zoom_inset_);
+
+  // Filters.
+  clone->SetLayerSaturation(layer_saturation_);
+  clone->SetLayerBrightness(GetTargetBrightness());
+  clone->SetLayerGrayscale(GetTargetGrayscale());
+  clone->SetLayerInverted(layer_inverted_);
+  if (alpha_shape_)
+    clone->SetAlphaShape(base::MakeUnique<SkRegion>(*alpha_shape_));
+
+  // cc::Layer state.
+  if (surface_layer_ && !surface_layer_->surface_id().is_null()) {
+    clone->SetShowSurface(
+        surface_layer_->surface_id(),
+        surface_layer_->satisfy_callback(),
+        surface_layer_->require_callback(),
+        surface_layer_->surface_size(),
+        surface_layer_->surface_scale(),
+        frame_size_in_dip_);
+  } else if (type_ == LAYER_SOLID_COLOR) {
+    clone->SetColor(GetTargetColor());
+  }
+  return clone;
+}
+
+std::unique_ptr<Layer> Layer::Mirror() {
+  auto mirror = Clone();
+  mirrors_.emplace_back(base::MakeUnique<LayerMirror>(this, mirror.get()));
+  return mirror;
+}
+
 const Compositor* Layer::GetCompositor() const {
   return GetRoot(this)->compositor_;
 }
@@ -238,7 +320,7 @@
 }
 
 LayerAnimator* Layer::GetAnimator() {
-  if (!animator_.get())
+  if (!animator_)
     SetAnimator(LayerAnimator::CreateDefaultAnimator());
   return animator_.get();
 }
@@ -248,7 +330,7 @@
 }
 
 gfx::Transform Layer::GetTargetTransform() const {
-  if (animator_.get() && animator_->IsAnimatingProperty(
+  if (animator_ && animator_->IsAnimatingProperty(
       LayerAnimationElement::TRANSFORM)) {
     return animator_->GetTargetTransform();
   }
@@ -265,7 +347,7 @@
 }
 
 gfx::Rect Layer::GetTargetBounds() const {
-  if (animator_.get() && animator_->IsAnimatingProperty(
+  if (animator_ && animator_->IsAnimatingProperty(
       LayerAnimationElement::BOUNDS)) {
     return animator_->GetTargetBounds();
   }
@@ -310,7 +392,7 @@
 }
 
 float Layer::GetTargetBrightness() const {
-  if (animator_.get() && animator_->IsAnimatingProperty(
+  if (animator_ && animator_->IsAnimatingProperty(
       LayerAnimationElement::BRIGHTNESS)) {
     return animator_->GetTargetBrightness();
   }
@@ -322,7 +404,7 @@
 }
 
 float Layer::GetTargetGrayscale() const {
-  if (animator_.get() && animator_->IsAnimatingProperty(
+  if (animator_ && animator_->IsAnimatingProperty(
       LayerAnimationElement::GRAYSCALE)) {
     return animator_->GetTargetGrayscale();
   }
@@ -411,7 +493,7 @@
 }
 
 float Layer::GetTargetOpacity() const {
-  if (animator_.get() && animator_->IsAnimatingProperty(
+  if (animator_ && animator_->IsAnimatingProperty(
       LayerAnimationElement::OPACITY))
     return animator_->GetTargetOpacity();
   return opacity();
@@ -422,7 +504,7 @@
 }
 
 bool Layer::GetTargetVisibility() const {
-  if (animator_.get() && animator_->IsAnimatingProperty(
+  if (animator_ && animator_->IsAnimatingProperty(
       LayerAnimationElement::VISIBILITY))
     return animator_->GetTargetVisibility();
   return visible_;
@@ -486,7 +568,7 @@
 
 void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
   // Finish animations being handled by cc_layer_.
-  if (animator_.get()) {
+  if (animator_) {
     animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
     animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY);
     animator_->SwitchToLayer(new_layer);
@@ -593,8 +675,11 @@
   frame_size_in_dip_ = frame_size_in_dip;
   RecomputeDrawsContentAndUVRect();
 
-  for (auto& observer : observer_list_)
-    observer.SurfaceChanged(this);
+  for (const auto& mirror : mirrors_) {
+    mirror->dest()->SetShowSurface(
+        surface_id, satisfy_callback, require_callback,
+        surface_size, scale, frame_size_in_dip);
+  }
 }
 
 void Layer::SetShowSolidColorContent() {
@@ -651,9 +736,10 @@
 
 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
 
-SkColor Layer::GetTargetColor() {
-  if (GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR))
-    return GetAnimator()->GetTargetColor();
+SkColor Layer::GetTargetColor() const {
+  if (animator_ && animator_->IsAnimatingProperty(
+      LayerAnimationElement::COLOR))
+    return animator_->GetTargetColor();
   return cc_layer_->background_color();
 }
 
@@ -720,7 +806,7 @@
 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
   if (device_scale_factor_ == device_scale_factor)
     return;
-  if (animator_.get())
+  if (animator_)
     animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
   device_scale_factor_ = device_scale_factor;
   RecomputeDrawsContentAndUVRect();
@@ -797,8 +883,9 @@
         PaintContext(display_list.get(), device_scale_factor_, invalidation));
   }
   display_list->Finalize();
-  for (auto& observer : observer_list_)
-    observer.DidPaintLayer(this, invalidation);
+  // TODO(domlaskowski): Move mirror invalidation to Layer::SchedulePaint.
+  for (const auto& mirror : mirrors_)
+    mirror->dest()->SchedulePaint(invalidation);
   return display_list;
 }
 
@@ -916,6 +1003,11 @@
     // Always schedule a paint, even if we're invisible.
     SchedulePaint(gfx::Rect(bounds.size()));
   }
+
+  if (sync_bounds_) {
+    for (const auto& mirror : mirrors_)
+      mirror->dest()->SetBounds(bounds);
+  }
 }
 
 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
@@ -1076,4 +1168,14 @@
     child->ResetCompositorForAnimatorsInTree(compositor);
 }
 
+void Layer::OnMirrorDestroyed(LayerMirror* mirror) {
+  const auto it = std::find_if(mirrors_.begin(), mirrors_.end(),
+      [mirror](const std::unique_ptr<LayerMirror>& mirror_ptr) {
+        return mirror_ptr.get() == mirror;
+      });
+
+  DCHECK(it != mirrors_.end());
+  mirrors_.erase(it);
+}
+
 }  // namespace ui
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index 7c7e4e3..e882bbb 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -76,6 +76,16 @@
   explicit Layer(LayerType type);
   ~Layer() override;
 
+  // Note that only solid color and surface content is copied.
+  std::unique_ptr<Layer> Clone() const;
+
+  // Returns a new layer that mirrors this layer and is optionally synchronized
+  // with the bounds thereof. Note that children are not mirrored, and that the
+  // content is only mirrored if painted by a delegate or backed by a surface.
+  std::unique_ptr<Layer> Mirror();
+
+  void set_sync_bounds(bool sync_bounds) { sync_bounds_ = sync_bounds; }
+
   // Retrieves the Layer's compositor. The Layer will walk up its parent chain
   // to locate it. Returns NULL if the Layer is not attached to a compositor.
   Compositor* GetCompositor() {
@@ -303,7 +313,7 @@
 
   // Sets the layer's fill color.  May only be called for LAYER_SOLID_COLOR.
   void SetColor(SkColor color);
-  SkColor GetTargetColor();
+  SkColor GetTargetColor() const;
   SkColor background_color() const;
 
   // Updates the nine patch layer's image, aperture and border. May only be
@@ -383,6 +393,7 @@
 
  private:
   friend class LayerOwner;
+  class LayerMirror;
 
   void CollectAnimators(std::vector<scoped_refptr<LayerAnimator> >* animators);
 
@@ -433,6 +444,8 @@
   void SetCompositorForAnimatorsInTree(Compositor* compositor);
   void ResetCompositorForAnimatorsInTree(Compositor* compositor);
 
+  void OnMirrorDestroyed(LayerMirror* mirror);
+
   const LayerType type_;
 
   Compositor* compositor_;
@@ -442,6 +455,11 @@
   // This layer's children, in bottom-to-top stacking order.
   std::vector<Layer*> children_;
 
+  std::vector<std::unique_ptr<LayerMirror>> mirrors_;
+
+  // If true, changes to the bounds of this layer are propagated to mirrors.
+  bool sync_bounds_ = false;
+
   gfx::Rect bounds_;
   gfx::Vector2dF subpixel_position_offset_;
 
diff --git a/ui/compositor/layer_observer.h b/ui/compositor/layer_observer.h
index e1a7ee5..fa3480b 100644
--- a/ui/compositor/layer_observer.h
+++ b/ui/compositor/layer_observer.h
@@ -11,10 +11,10 @@
 
 class Layer;
 
+// TODO(domlaskowski): This is only used for layer mirroring, so it should be
+// removed and replaced by a private equivalent in the Layer class.
 class COMPOSITOR_EXPORT LayerObserver {
  public:
-  virtual void DidPaintLayer(Layer* layer, const gfx::Rect& region) {}
-  virtual void SurfaceChanged(Layer* layer) {}
   virtual void LayerDestroyed(Layer* layer) {}
 
  protected:
diff --git a/ui/compositor/layer_owner.cc b/ui/compositor/layer_owner.cc
index d94ff2cc..04a053c 100644
--- a/ui/compositor/layer_owner.cc
+++ b/ui/compositor/layer_owner.cc
@@ -17,10 +17,10 @@
 LayerOwner::~LayerOwner() {
 }
 
-void LayerOwner::SetLayer(Layer* layer) {
+void LayerOwner::SetLayer(std::unique_ptr<Layer> layer) {
   DCHECK(!OwnsLayer());
-  layer_owner_.reset(layer);
-  layer_ = layer;
+  layer_owner_ = std::move(layer);
+  layer_ = layer_owner_.get();
   layer_->owner_ = this;
 }
 
@@ -38,33 +38,16 @@
   LayerDelegate* old_delegate = old_layer->delegate();
   old_layer->set_delegate(NULL);
 
-  const gfx::Rect layer_bounds(old_layer->bounds());
-  Layer* new_layer = new ui::Layer(old_layer->type());
-  SetLayer(new_layer);
-  new_layer->SetVisible(old_layer->GetTargetVisibility());
-  new_layer->SetOpacity(old_layer->GetTargetOpacity());
-  new_layer->SetBounds(layer_bounds);
-  new_layer->SetMasksToBounds(old_layer->GetMasksToBounds());
-  new_layer->set_name(old_layer->name());
-  new_layer->SetFillsBoundsOpaquely(old_layer->fills_bounds_opaquely());
-  new_layer->SetFillsBoundsCompletely(old_layer->FillsBoundsCompletely());
-  new_layer->SetSubpixelPositionOffset(old_layer->subpixel_position_offset());
-  new_layer->SetLayerInverted(old_layer->layer_inverted());
-  new_layer->SetTransform(old_layer->GetTargetTransform());
-  if (old_layer->type() == LAYER_SOLID_COLOR)
-    new_layer->SetColor(old_layer->GetTargetColor());
-  SkRegion* alpha_shape = old_layer->alpha_shape();
-  if (alpha_shape)
-    new_layer->SetAlphaShape(base::MakeUnique<SkRegion>(*alpha_shape));
+  SetLayer(old_layer->Clone());
 
   if (old_layer->parent()) {
     // Install new layer as a sibling of the old layer, stacked below it.
-    old_layer->parent()->Add(new_layer);
-    old_layer->parent()->StackBelow(new_layer, old_layer.get());
+    old_layer->parent()->Add(layer_);
+    old_layer->parent()->StackBelow(layer_, old_layer.get());
   } else if (old_layer->GetCompositor()) {
     // If old_layer was the layer tree root then we need to move the Compositor
     // over to the new root.
-    old_layer->GetCompositor()->SetRootLayer(new_layer);
+    old_layer->GetCompositor()->SetRootLayer(layer_);
   }
 
   // Migrate all the child layers over to the new layer. Copy the list because
@@ -74,15 +57,15 @@
        it != children_copy.end();
        ++it) {
     ui::Layer* child = *it;
-    new_layer->Add(child);
+    layer_->Add(child);
   }
 
   // Install the delegate last so that the delegate isn't notified as we copy
   // state to the new layer.
-  new_layer->set_delegate(old_delegate);
+  layer_->set_delegate(old_delegate);
 
   if (layer_owner_delegate_)
-    layer_owner_delegate_->OnLayerRecreated(old_layer.get(), new_layer);
+    layer_owner_delegate_->OnLayerRecreated(old_layer.get(), layer_);
 
   return old_layer;
 }
diff --git a/ui/compositor/layer_owner.h b/ui/compositor/layer_owner.h
index fd0606c..f711c6a 100644
--- a/ui/compositor/layer_owner.h
+++ b/ui/compositor/layer_owner.h
@@ -20,7 +20,7 @@
   LayerOwner();
   virtual ~LayerOwner();
 
-  void SetLayer(Layer* layer);
+  void SetLayer(std::unique_ptr<Layer> layer);
 
   // Releases the owning reference to its layer, and returns it.
   // This is used when you need to animate the presentation of the owner just
@@ -44,11 +44,11 @@
     layer_owner_delegate_ = delegate;
   }
 
+  bool OwnsLayer() const;
+
  protected:
   void DestroyLayer();
 
-  bool OwnsLayer() const;
-
  private:
   // The LayerOwner owns its layer unless ownership is relinquished via a call
   // to AcquireLayer(). After that moment |layer_| will still be valid but
diff --git a/ui/compositor/layer_owner_delegate.h b/ui/compositor/layer_owner_delegate.h
index 68ba92e..86a40399 100644
--- a/ui/compositor/layer_owner_delegate.h
+++ b/ui/compositor/layer_owner_delegate.h
@@ -12,8 +12,7 @@
 
 // Called from RecreateLayer() after the new layer was created. old_layer is
 // the layer that will be returned to the caller of RecreateLayer, new_layer
-// will be the layer now used. Used when the layer has external content
-// (SetTextureMailbox / SetDelegatedFrame was called).
+// will be the layer now used.
 class COMPOSITOR_EXPORT LayerOwnerDelegate {
  public:
   virtual void OnLayerRecreated(Layer* old_layer, Layer* new_layer) = 0;
diff --git a/ui/compositor/layer_owner_unittest.cc b/ui/compositor/layer_owner_unittest.cc
index cdffd2a..5e81fe9 100644
--- a/ui/compositor/layer_owner_unittest.cc
+++ b/ui/compositor/layer_owner_unittest.cc
@@ -85,108 +85,10 @@
 
 }  // namespace
 
-TEST(LayerOwnerTest, RecreateLayerHonorsAnimationTargets) {
-  LayerOwner owner;
-  Layer* layer = new Layer(LAYER_SOLID_COLOR);
-  layer->SetVisible(true);
-  layer->SetOpacity(1.0f);
-  layer->SetColor(SK_ColorRED);
-
-  owner.SetLayer(layer);
-
-  ScopedLayerAnimationSettings settings(layer->GetAnimator());
-  layer->SetVisible(false);
-  layer->SetOpacity(0.0f);
-  layer->SetColor(SK_ColorGREEN);
-  EXPECT_TRUE(layer->visible());
-  EXPECT_EQ(1.0f, layer->opacity());
-  EXPECT_EQ(SK_ColorRED, layer->background_color());
-
-  std::unique_ptr<Layer> old_layer(owner.RecreateLayer());
-  EXPECT_FALSE(owner.layer()->visible());
-  EXPECT_EQ(0.0f, owner.layer()->opacity());
-  EXPECT_EQ(SK_ColorGREEN, owner.layer()->background_color());
-}
-
-// Tests that when a LAYER_SOLID_COLOR which is not backed by a SolidColorLayer
-// that opaqueness and color targets are maintained when the
-// LayerOwner::RecreateLayers is called.
-TEST(LayerOwnerTest, RecreateLayerSolidColorWithChangedCCLayerHonorsTargets) {
-  SkColor transparent = SK_ColorTRANSPARENT;
-  LayerOwner owner;
-  Layer* layer = new Layer(LAYER_SOLID_COLOR);
-  owner.SetLayer(layer);
-  layer->SetFillsBoundsOpaquely(false);
-  layer->SetColor(transparent);
-  // Changing the backing layer takes LAYER_SOLID_COLOR off of the normal layer
-  // flow, need to ensure that set values are maintained.
-  layer->SwitchCCLayerForTest();
-
-  EXPECT_FALSE(layer->fills_bounds_opaquely());
-  EXPECT_EQ(transparent, layer->background_color());
-  EXPECT_EQ(transparent, layer->GetTargetColor());
-
-  std::unique_ptr<Layer> old_layer(owner.RecreateLayer());
-  EXPECT_FALSE(owner.layer()->fills_bounds_opaquely());
-  EXPECT_EQ(transparent, owner.layer()->background_color());
-  EXPECT_EQ(transparent, owner.layer()->GetTargetColor());
-}
-
-TEST(LayerOwnerTest, RecreateRootLayerWithNullCompositor) {
-  LayerOwner owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
-
-  std::unique_ptr<Layer> layer_copy = owner.RecreateLayer();
-
-  EXPECT_EQ(nullptr, owner.layer()->GetCompositor());
-  EXPECT_EQ(nullptr, layer_copy->GetCompositor());
-}
-
-TEST(LayerOwnerTest, InvertPropertyRemainSameWithRecreateLayer) {
-  LayerOwner owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
-
-  layer->SetLayerInverted(true);
-  std::unique_ptr<Layer> old_layer1 = owner.RecreateLayer();
-  EXPECT_EQ(old_layer1->layer_inverted(), owner.layer()->layer_inverted());
-
-  old_layer1->SetLayerInverted(false);
-  std::unique_ptr<Layer> old_layer2 = owner.RecreateLayer();
-  EXPECT_EQ(old_layer2->layer_inverted(), owner.layer()->layer_inverted());
-}
-
-TEST(LayerOwnerTest, RecreateLayerWithTransform) {
-  LayerOwner owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
-
-  gfx::Transform transform;
-  transform.Scale(2, 1);
-  transform.Translate(10, 5);
-
-  layer->SetTransform(transform);
-
-  std::unique_ptr<Layer> old_layer1 = owner.RecreateLayer();
-  // Both new layer and original layer have the same transform.
-  EXPECT_EQ(transform, old_layer1->GetTargetTransform());
-  EXPECT_EQ(transform, owner.layer()->GetTargetTransform());
-
-  // But they're now separated, so changing the old layer's transform
-  // should not affect the owner's.
-  owner.layer()->SetTransform(gfx::Transform());
-  EXPECT_EQ(transform, old_layer1->GetTargetTransform());
-  std::unique_ptr<Layer> old_layer2 = owner.RecreateLayer();
-  EXPECT_TRUE(old_layer2->GetTargetTransform().IsIdentity());
-  EXPECT_TRUE(owner.layer()->GetTargetTransform().IsIdentity());
-}
-
 TEST_F(LayerOwnerTestWithCompositor, RecreateRootLayerWithCompositor) {
   LayerOwner owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
-
+  owner.SetLayer(base::MakeUnique<Layer>());
+  Layer* layer = owner.layer();
   compositor()->SetRootLayer(layer);
 
   std::unique_ptr<Layer> layer_copy = owner.RecreateLayer();
@@ -201,8 +103,8 @@
 // of animations being cancelled.
 TEST_F(LayerOwnerTestWithCompositor, RecreateRootLayerDuringAnimation) {
   LayerOwner owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
+  owner.SetLayer(base::MakeUnique<Layer>());
+  Layer* layer = owner.layer();
   compositor()->SetRootLayer(layer);
 
   std::unique_ptr<Layer> child(new Layer);
@@ -236,8 +138,8 @@
   compositor()->SetRootLayer(root_layer.get());
 
   LayerOwner owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
+  owner.SetLayer(base::MakeUnique<Layer>());
+  Layer* layer = owner.layer();
   root_layer->Add(layer);
 
   std::unique_ptr<Layer> child(new Layer);
@@ -270,8 +172,8 @@
   compositor()->SetRootLayer(root_layer.get());
 
   LayerOwnerForTesting owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
+  owner.SetLayer(base::MakeUnique<Layer>());
+  Layer* layer = owner.layer();
   layer->SetOpacity(0.5f);
   root_layer->Add(layer);
 
@@ -293,8 +195,8 @@
   compositor()->SetRootLayer(root_layer.get());
 
   LayerOwner owner;
-  Layer* layer = new Layer;
-  owner.SetLayer(layer);
+  owner.SetLayer(base::MakeUnique<Layer>());
+  Layer* layer = owner.layer();
   root_layer->Add(layer);
 
   layer->SetOpacity(0.5f);
diff --git a/ui/compositor/layer_tree_owner.cc b/ui/compositor/layer_tree_owner.cc
index ebb0a7f..768c5e3 100644
--- a/ui/compositor/layer_tree_owner.cc
+++ b/ui/compositor/layer_tree_owner.cc
@@ -24,7 +24,8 @@
 
 }  // namespace
 
-LayerTreeOwner::LayerTreeOwner(Layer* root) : root_(root) {}
+LayerTreeOwner::LayerTreeOwner(std::unique_ptr<Layer> root)
+    : root_(root.release()) {}
 
 LayerTreeOwner::~LayerTreeOwner() {
   if (root_)
diff --git a/ui/compositor/layer_tree_owner.h b/ui/compositor/layer_tree_owner.h
index a54142b..4412c22 100644
--- a/ui/compositor/layer_tree_owner.h
+++ b/ui/compositor/layer_tree_owner.h
@@ -5,6 +5,8 @@
 #ifndef UI_COMPOSITOR_LAYER_TREE_OWNER_H_
 #define UI_COMPOSITOR_LAYER_TREE_OWNER_H_
 
+#include <memory>
+
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "ui/compositor/compositor_export.h"
@@ -16,7 +18,7 @@
 // Scoping object that owns a Layer and all its descendants.
 class COMPOSITOR_EXPORT LayerTreeOwner {
  public:
-  explicit LayerTreeOwner(Layer* root);
+  explicit LayerTreeOwner(std::unique_ptr<Layer> root);
   ~LayerTreeOwner();
 
   Layer* release() WARN_UNUSED_RESULT {
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index 3f12bca..46a33b3 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -747,6 +747,131 @@
   EXPECT_TRUE(d3.painted());
 }
 
+TEST_F(LayerWithDelegateTest, Cloning) {
+  std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR));
+
+  gfx::Transform transform;
+  transform.Scale(2, 1);
+  transform.Translate(10, 5);
+
+  layer->SetTransform(transform);
+  layer->SetColor(SK_ColorRED);
+  layer->SetLayerInverted(true);
+
+  auto clone = layer->Clone();
+
+  // Cloning preserves layer state.
+  EXPECT_EQ(transform, clone->GetTargetTransform());
+  EXPECT_EQ(SK_ColorRED, clone->background_color());
+  EXPECT_EQ(SK_ColorRED, clone->GetTargetColor());
+  EXPECT_TRUE(clone->layer_inverted());
+
+  layer->SetTransform(gfx::Transform());
+  layer->SetColor(SK_ColorGREEN);
+  layer->SetLayerInverted(false);
+
+  // The clone is an independent copy, so state changes do not propagate.
+  EXPECT_EQ(transform, clone->GetTargetTransform());
+  EXPECT_EQ(SK_ColorRED, clone->background_color());
+  EXPECT_EQ(SK_ColorRED, clone->GetTargetColor());
+  EXPECT_TRUE(clone->layer_inverted());
+
+  constexpr SkColor kTransparent = SK_ColorTRANSPARENT;
+  layer->SetColor(kTransparent);
+  layer->SetFillsBoundsOpaquely(false);
+  // Color and opaqueness targets should be preserved during cloning, even after
+  // switching away from solid color content.
+  layer->SwitchCCLayerForTest();
+
+  clone = layer->Clone();
+
+  // The clone is a copy of the latest state.
+  EXPECT_TRUE(clone->GetTargetTransform().IsIdentity());
+  EXPECT_EQ(kTransparent, clone->background_color());
+  EXPECT_EQ(kTransparent, clone->GetTargetColor());
+  EXPECT_FALSE(clone->layer_inverted());
+  EXPECT_FALSE(clone->fills_bounds_opaquely());
+
+  layer.reset(CreateLayer(LAYER_SOLID_COLOR));
+  layer->SetVisible(true);
+  layer->SetOpacity(1.0f);
+  layer->SetColor(SK_ColorRED);
+
+  ScopedLayerAnimationSettings settings(layer->GetAnimator());
+  layer->SetVisible(false);
+  layer->SetOpacity(0.0f);
+  layer->SetColor(SK_ColorGREEN);
+
+  EXPECT_TRUE(layer->visible());
+  EXPECT_EQ(1.0f, layer->opacity());
+  EXPECT_EQ(SK_ColorRED, layer->background_color());
+
+  clone = layer->Clone();
+
+  // Cloning copies animation targets.
+  EXPECT_FALSE(clone->visible());
+  EXPECT_EQ(0.0f, clone->opacity());
+  EXPECT_EQ(SK_ColorGREEN, clone->background_color());
+}
+
+TEST_F(LayerWithDelegateTest, Mirroring) {
+  std::unique_ptr<Layer> root(CreateNoTextureLayer(gfx::Rect(0, 0, 100, 100)));
+  std::unique_ptr<Layer> child(CreateLayer(LAYER_TEXTURED));
+
+  const gfx::Rect bounds(0, 0, 50, 50);
+  child->SetBounds(bounds);
+  child->SetVisible(true);
+
+  DrawTreeLayerDelegate delegate(child->bounds());
+  child->set_delegate(&delegate);
+
+  const auto mirror = child->Mirror();
+
+  // Bounds and visibility are preserved.
+  EXPECT_EQ(bounds, mirror->bounds());
+  EXPECT_TRUE(mirror->visible());
+
+  root->Add(child.get());
+  root->Add(mirror.get());
+
+  DrawTree(root.get());
+  EXPECT_TRUE(delegate.painted());
+  delegate.Reset();
+
+  // Both layers should be clean.
+  EXPECT_TRUE(child->damaged_region_for_testing().IsEmpty());
+  EXPECT_TRUE(mirror->damaged_region_for_testing().IsEmpty());
+
+  const gfx::Rect damaged_rect(10, 10, 20, 20);
+  EXPECT_TRUE(child->SchedulePaint(damaged_rect));
+  EXPECT_EQ(damaged_rect, child->damaged_region_for_testing().bounds());
+
+  DrawTree(root.get());
+  EXPECT_TRUE(delegate.painted());
+  delegate.Reset();
+
+  // Damage should be propagated to the mirror.
+  EXPECT_EQ(damaged_rect, mirror->damaged_region_for_testing().bounds());
+  EXPECT_TRUE(child->damaged_region_for_testing().IsEmpty());
+
+  DrawTree(root.get());
+  EXPECT_TRUE(delegate.painted());
+
+  // Mirror should be clean.
+  EXPECT_TRUE(mirror->damaged_region_for_testing().IsEmpty());
+
+  // Bounds are not synchronized by default.
+  const gfx::Rect new_bounds(10, 10, 10, 10);
+  child->SetBounds(new_bounds);
+  EXPECT_EQ(bounds, mirror->bounds());
+  child->SetBounds(bounds);
+
+  // Bounds should be synchronized if requested.
+  child->set_sync_bounds(true);
+  child->SetBounds(new_bounds);
+  EXPECT_EQ(new_bounds, mirror->bounds());
+}
+
 class LayerWithNullDelegateTest : public LayerWithDelegateTest {
  public:
   LayerWithNullDelegateTest() {}
@@ -1721,6 +1846,41 @@
   EXPECT_NE(before.get(), child->cc_layer_for_testing());
 }
 
+TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
+  std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR));
+
+  const auto satisfy_callback = base::Bind(&FakeSatisfyCallback);
+  const auto require_callback = base::Bind(&FakeRequireCallback);
+
+  cc::SurfaceId surface_id(cc::FrameSinkId(0, 1), cc::LocalFrameId(2, 3));
+  layer->SetShowSurface(surface_id, satisfy_callback, require_callback,
+                        gfx::Size(10, 10), 1.0f, gfx::Size(10, 10));
+
+  const auto mirror = layer->Mirror();
+  auto* const cc_layer = mirror->cc_layer_for_testing();
+  const auto* surface = static_cast<cc::SurfaceLayer*>(cc_layer);
+
+  // Mirroring preserves surface state.
+  EXPECT_EQ(surface_id, surface->surface_id());
+  EXPECT_TRUE(satisfy_callback.Equals(surface->satisfy_callback()));
+  EXPECT_TRUE(require_callback.Equals(surface->require_callback()));
+  EXPECT_EQ(gfx::Size(10, 10), surface->surface_size());
+  EXPECT_EQ(1.0f, surface->surface_scale());
+
+  surface_id = cc::SurfaceId(cc::FrameSinkId(1, 2), cc::LocalFrameId(3, 4));
+  layer->SetShowSurface(surface_id, satisfy_callback, require_callback,
+                        gfx::Size(20, 20), 2.0f, gfx::Size(20, 20));
+
+  // A new cc::Layer should be created for the mirror.
+  EXPECT_NE(cc_layer, mirror->cc_layer_for_testing());
+  surface = static_cast<cc::SurfaceLayer*>(mirror->cc_layer_for_testing());
+
+  // Surface updates propagate to the mirror.
+  EXPECT_EQ(surface_id, surface->surface_id());
+  EXPECT_EQ(gfx::Size(20, 20), surface->surface_size());
+  EXPECT_EQ(2.0f, surface->surface_scale());
+}
+
 // Verifies that layer filters still attached after changing implementation
 // layer.
 TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
index c468ce88..ce3731d 100644
--- a/ui/views/cocoa/bridged_native_widget.mm
+++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -12,6 +12,7 @@
 #import "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
 #import "base/mac/sdk_forward_declarations.h"
+#include "base/memory/ptr_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
@@ -962,7 +963,7 @@
   CreateCompositor();
   DCHECK(compositor_);
 
-  SetLayer(new ui::Layer(layer_type));
+  SetLayer(base::MakeUnique<ui::Layer>(layer_type));
   // Note, except for controls, this will set the layer to be hidden, since it
   // is only called during Init().
   layer()->SetVisible(window_visible_);
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 3cb42dc..55acfceb 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -2079,7 +2079,7 @@
   for (int i = 0, count = child_count(); i < count; ++i)
     child_at(i)->UpdateChildLayerVisibility(true);
 
-  SetLayer(new ui::Layer());
+  SetLayer(base::MakeUnique<ui::Layer>());
   layer()->set_delegate(this);
   layer()->set_name(GetClassName());
 
diff --git a/ui/views/view_unittest_aura.cc b/ui/views/view_unittest_aura.cc
index b1e7b2f..531302ae 100644
--- a/ui/views/view_unittest_aura.cc
+++ b/ui/views/view_unittest_aura.cc
@@ -122,7 +122,7 @@
 
   {
     std::unique_ptr<ui::LayerTreeOwner> cloned_owner(
-        wm::RecreateLayers(w1->GetNativeView(), nullptr));
+        wm::RecreateLayers(w1->GetNativeView()));
     EXPECT_EQ(w1_layer, cloned_owner->root());
     EXPECT_NE(w1_layer, w1->GetNativeView()->layer());
 
diff --git a/ui/wm/core/window_animations.cc b/ui/wm/core/window_animations.cc
index 3fd5977..c32da29 100644
--- a/ui/wm/core/window_animations.cc
+++ b/ui/wm/core/window_animations.cc
@@ -84,7 +84,7 @@
   // activation change does not put the window above the animating
   // layer.
   void DetachAndRecreateLayers() {
-    layer_owner_ = RecreateLayers(window_, nullptr);
+    layer_owner_ = RecreateLayers(window_);
     if (window_->parent()) {
       const aura::Window::Windows& transient_children =
           GetTransientChildren(window_);
diff --git a/ui/wm/core/window_util.cc b/ui/wm/core/window_util.cc
index 0dc44d5..39fa162 100644
--- a/ui/wm/core/window_util.cc
+++ b/ui/wm/core/window_util.cc
@@ -4,6 +4,7 @@
 
 #include "ui/wm/core/window_util.h"
 
+#include "base/memory/ptr_util.h"
 #include "ui/aura/window.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_tree_owner.h"
@@ -16,9 +17,7 @@
 // cloned children to |parent|.
 //
 // WARNING: It is assumed that |parent| is ultimately owned by a LayerTreeOwner.
-void CloneChildren(ui::Layer* to_clone,
-                   ui::Layer* parent,
-                   wm::LayerDelegateFactory* factory) {
+void CloneChildren(ui::Layer* to_clone, ui::Layer* parent) {
   typedef std::vector<ui::Layer*> Layers;
   // Make a copy of the children since RecreateLayer() mutates it.
   Layers children(to_clone->children());
@@ -26,17 +25,29 @@
     ui::LayerOwner* owner = (*i)->owner();
     ui::Layer* old_layer = owner ? owner->RecreateLayer().release() : NULL;
     if (old_layer) {
-      if (factory && owner->layer()->delegate())
-        old_layer->set_delegate(
-            factory->CreateDelegate(old_layer, owner->layer()));
       parent->Add(old_layer);
       // RecreateLayer() moves the existing children to the new layer. Create a
       // copy of those.
-      CloneChildren(owner->layer(), old_layer, factory);
+      CloneChildren(owner->layer(), old_layer);
     }
   }
 }
 
+// Invokes Mirror() on all the children of |to_mirror|, adding the newly cloned
+// children to |parent|.
+//
+// WARNING: It is assumed that |parent| is ultimately owned by a LayerTreeOwner.
+void MirrorChildren(ui::Layer* to_mirror,
+                    ui::Layer* parent,
+                    bool sync_bounds) {
+  for (auto* child : to_mirror->children()) {
+    child->set_sync_bounds(sync_bounds);
+    ui::Layer* mirror = child->Mirror().release();
+    parent->Add(mirror);
+    MirrorChildren(child, mirror, sync_bounds);
+  }
+}
+
 }  // namespace
 
 namespace wm {
@@ -85,21 +96,20 @@
   return client ? client->GetToplevelWindow(window) : NULL;
 }
 
-std::unique_ptr<ui::LayerTreeOwner> RecreateLayers(
-    ui::LayerOwner* root,
-    LayerDelegateFactory* factory) {
-  std::unique_ptr<ui::LayerTreeOwner> old_layer(
-      new ui::LayerTreeOwner(root->RecreateLayer().release()));
-  if (old_layer->root()) {
-    if (factory) {
-      old_layer->root()->set_delegate(
-          factory->CreateDelegate(old_layer->root(), root->layer()));
-    }
-    CloneChildren(root->layer(), old_layer->root(), factory);
-  }
+std::unique_ptr<ui::LayerTreeOwner> RecreateLayers(ui::LayerOwner* root) {
+  DCHECK(root->OwnsLayer());
+  auto old_layer = base::MakeUnique<ui::LayerTreeOwner>(root->RecreateLayer());
+  CloneChildren(root->layer(), old_layer->root());
   return old_layer;
 }
 
+std::unique_ptr<ui::LayerTreeOwner> MirrorLayers(
+    ui::LayerOwner* root, bool sync_bounds) {
+  auto mirror = base::MakeUnique<ui::LayerTreeOwner>(root->layer()->Mirror());
+  MirrorChildren(root->layer(), mirror->root(), sync_bounds);
+  return mirror;
+}
+
 aura::Window* GetTransientParent(aura::Window* window) {
   return const_cast<aura::Window*>(GetTransientParent(
                                  const_cast<const aura::Window*>(window)));
diff --git a/ui/wm/core/window_util.h b/ui/wm/core/window_util.h
index eac38798..19e07b6b 100644
--- a/ui/wm/core/window_util.h
+++ b/ui/wm/core/window_util.h
@@ -17,7 +17,6 @@
 
 namespace ui {
 class Layer;
-class LayerDelegate;
 class LayerOwner;
 class LayerTreeOwner;
 }
@@ -37,30 +36,20 @@
 // determination.
 WM_EXPORT aura::Window* GetToplevelWindow(aura::Window* window);
 
-// A factory method to create a delegate for recreated layers.
-class WM_EXPORT LayerDelegateFactory {
- public:
-  virtual ~LayerDelegateFactory() = default;
-  // |original_layer| may already be deleted by the time the new
-  // delegate is created, so if the new delegate has to access it
-  // later, it is the new delegate's responsibility to make sure the
-  // original layer/delegate is alive.
-  virtual ui::LayerDelegate* CreateDelegate(ui::Layer* new_layer,
-                                            ui::Layer* original_layer) = 0;
-};
-
 // Returns the existing Layer for |root| (and all its descendants) and creates
 // a new layer for |root| and all its descendants. This is intended for
 // animations that want to animate between the existing visuals and a new state.
 //
 // As a result of this |root| has freshly created layers, meaning the layers
 // have not yet been painted to.
-//
-// When a non null |delegate_factory| is passed, it will be used to
-// create a delegate for an old layer which had its own delegate.
 WM_EXPORT std::unique_ptr<ui::LayerTreeOwner> RecreateLayers(
-    ui::LayerOwner* root,
-    LayerDelegateFactory* delegate_factory);
+    ui::LayerOwner* root);
+
+// Returns a layer tree that mirrors |root|. Used for live window previews. If
+// |sync_bounds| is true, the bounds of all mirror layers except the root are
+// synchronized. See |sync_bounds_| in ui::Layer.
+WM_EXPORT std::unique_ptr<ui::LayerTreeOwner> MirrorLayers(
+    ui::LayerOwner* root, bool sync_bounds);
 
 // Convenience functions that get the TransientWindowManager for the window and
 // redirect appropriately. These are preferable to calling functions on
diff --git a/ui/wm/core/window_util_unittest.cc b/ui/wm/core/window_util_unittest.cc
index 5cc2b38..4a7fedb 100644
--- a/ui/wm/core/window_util_unittest.cc
+++ b/ui/wm/core/window_util_unittest.cc
@@ -11,58 +11,8 @@
 #include "ui/aura/window.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_tree_owner.h"
-#include "ui/compositor/paint_context.h"
 
 namespace wm {
-namespace {
-
-// Used to check if the delegate for recreated layer is created for
-// the correct delegate.
-class TestLayerDelegate : public ui::LayerDelegate {
- public:
-  explicit TestLayerDelegate(ui::Layer* original_layer)
-      : original_layer_(original_layer) {}
-  ~TestLayerDelegate() override = default;
-
-  // ui::LayerDelegate:
-  void OnPaintLayer(const ui::PaintContext& context) override {}
-  void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
-  void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
-
-  ui::Layer* original_layer() { return original_layer_; }
-
- private:
-  ui::Layer* original_layer_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
-};
-
-// Used to create a TestLayerDelegate for recreated layers.
-class TestLayerDelegateFactory : public ::wm::LayerDelegateFactory {
- public:
-  TestLayerDelegateFactory() = default;
-  ~TestLayerDelegateFactory() override = default;
-
-  // ::wm::LayerDelegateFactory:
-  ui::LayerDelegate* CreateDelegate(ui::Layer* new_layer,
-                                    ui::Layer* original_layer) override {
-    delegates_.push_back(base::MakeUnique<TestLayerDelegate>(original_layer));
-    return delegates_.back().get();
-  }
-
-  size_t delegate_count() const { return delegates_.size(); }
-
-  TestLayerDelegate* GetDelegateAt(int index) {
-    return delegates_[index].get();
-  }
-
- private:
-  std::vector<std::unique_ptr<TestLayerDelegate>> delegates_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestLayerDelegateFactory);
-};
-
-}  // namespace
 
 typedef aura::test::AuraTestBase WindowUtilTest;
 
@@ -82,8 +32,7 @@
   EXPECT_TRUE(acquired.get());
   EXPECT_EQ(acquired.get(), window11->layer());
 
-  std::unique_ptr<ui::LayerTreeOwner> tree =
-      wm::RecreateLayers(window1.get(), nullptr);
+  std::unique_ptr<ui::LayerTreeOwner> tree = wm::RecreateLayers(window1.get());
 
   // The detached layer should not have the layer that has
   // already been detached.
@@ -101,35 +50,4 @@
   window11.reset();
 }
 
-// Test if the LayerDelegateFactory creates new delegates for
-// recreated layers correctly.
-TEST_F(WindowUtilTest, RecreateLayersWithDelegate) {
-  TestLayerDelegateFactory factory;
-  std::unique_ptr<aura::Window> window1(
-      aura::test::CreateTestWindowWithId(0, NULL));
-  std::unique_ptr<aura::Window> window11(
-      aura::test::CreateTestWindowWithId(1, window1.get()));
-  std::unique_ptr<aura::Window> window12(
-      aura::test::CreateTestWindowWithId(2, window1.get()));
-
-  std::unique_ptr<ui::LayerTreeOwner> tree =
-      wm::RecreateLayers(window1.get(), &factory);
-
-  ASSERT_EQ(3u, factory.delegate_count());
-
-  TestLayerDelegate* new_delegate_1 = factory.GetDelegateAt(0);
-  TestLayerDelegate* new_delegate_11 = factory.GetDelegateAt(1);
-  TestLayerDelegate* new_delegate_12 = factory.GetDelegateAt(2);
-
-  EXPECT_EQ(window1->layer(), new_delegate_1->original_layer());
-  EXPECT_EQ(window11->layer(),
-            new_delegate_11->original_layer());
-  EXPECT_EQ(window12->layer(),
-            new_delegate_12->original_layer());
-
-  EXPECT_EQ(tree->root()->delegate(), new_delegate_1);
-  EXPECT_EQ(tree->root()->children()[0]->delegate(), new_delegate_11);
-  EXPECT_EQ(tree->root()->children()[1]->delegate(), new_delegate_12);
-}
-
 }  // namespace wm