diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index 3c8b030c..4f9ebb4 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -378,11 +378,15 @@
   if (widget_) {
     UpdateWidgetBounds();
 
-    // Only allow the shelf to recognize this window if the input bounds
+    gfx::Point surface_origin = GetSurfaceOrigin();
+    gfx::Rect hit_test_bounds =
+        surface_->GetHitTestBounds() + surface_origin.OffsetFromOrigin();
+
+    // Only allow the shelf to recognize this window if the hit-test bounds
     // contains the widget bounds. This prevents shaped windows that might
     // only occupy a small area of the widget from dimming the shelf when
     // maximized.
-    bool ignored_by_shelf = !surface_->GetInputBounds().Contains(
+    bool ignored_by_shelf = !hit_test_bounds.Contains(
         gfx::Rect(widget_->GetNativeWindow()->bounds().size()));
 
     // Update state and shelf visibility if |ignored_by_shelf| changed.
@@ -394,8 +398,7 @@
     }
 
     // Update surface bounds.
-    surface_->SetBounds(
-        gfx::Rect(GetSurfaceOrigin(), surface_->layer()->size()));
+    surface_->SetBounds(gfx::Rect(surface_origin, surface_->layer()->size()));
 
     // Show widget if not already visible.
     if (!widget_->IsClosed() && !widget_->IsVisible())
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 9b63799..880d4de 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -416,14 +416,17 @@
   }
 }
 
-gfx::Rect Surface::GetInputBounds() const {
-  return gfx::SkIRectToRect(input_region_.getBounds());
-}
-
 bool Surface::IsSynchronized() const {
   return delegate_ ? delegate_->IsSurfaceSynchronized() : false;
 }
 
+gfx::Rect Surface::GetHitTestBounds() const {
+  SkIRect bounds = input_region_.getBounds();
+  if (!bounds.intersect(gfx::RectToSkIRect(gfx::Rect(layer()->size()))))
+    return gfx::Rect();
+  return gfx::SkIRectToRect(bounds);
+}
+
 bool Surface::HitTestRect(const gfx::Rect& rect) const {
   if (HasHitTestMask())
     return input_region_.intersects(gfx::RectToSkIRect(rect));
diff --git a/components/exo/surface.h b/components/exo/surface.h
index b4cbf92..a7be89e 100644
--- a/components/exo/surface.h
+++ b/components/exo/surface.h
@@ -101,8 +101,8 @@
   // Returns true if surface is in synchronized mode.
   bool IsSynchronized() const;
 
-  // Returns the input bounds of the surface.
-  gfx::Rect GetInputBounds() const;
+  // Returns the bounds of the current input region of surface.
+  gfx::Rect GetHitTestBounds() const;
 
   // Returns true if |rect| intersects this surface's bounds.
   bool HitTestRect(const gfx::Rect& rect) const;
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.h b/gpu/ipc/service/image_transport_surface_overlay_mac.h
index dde6109..e455cf00 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.h
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.h
@@ -45,7 +45,6 @@
   gfx::Size GetSize() override;
   void* GetHandle() override;
   bool OnMakeCurrent(gfx::GLContext* context) override;
-  bool SetBackbufferAllocation(bool allocated) override;
   bool ScheduleOverlayPlane(int z_order,
                             gfx::OverlayTransform transform,
                             gl::GLImage* image,
@@ -67,9 +66,6 @@
   void OnGpuSwitched() override;
 
  private:
-  class PendingSwap;
-  class OverlayPlane;
-
   ~ImageTransportSurfaceOverlayMac() override;
 
   void SetLatencyInfo(const std::vector<ui::LatencyInfo>& latency_info);
@@ -85,31 +81,6 @@
       std::vector<ui::LatencyInfo> latency_info);
   gfx::SwapResult SwapBuffersInternal(const gfx::Rect& pixel_damage_rect);
 
-  // Returns true if the front of |pending_swaps_| has completed, or has timed
-  // out by |now|.
-  bool IsFirstPendingSwapReadyToDisplay(
-    const base::TimeTicks& now);
-  // Sets the CALayer contents to the IOSurface for the front of
-  // |pending_swaps_|, and removes it from the queue.
-  void DisplayFirstPendingSwapImmediately();
-  // Force that all of |pending_swaps_| displayed immediately, and the list be
-  // cleared.
-  void DisplayAndClearAllPendingSwaps();
-  // Callback issued during the next vsync period ofter a SwapBuffers call,
-  // to check if the swap is completed, and display the frame. Note that if
-  // another SwapBuffers happens before this callback, the pending swap will
-  // be tested at that time, too.
-  void CheckPendingSwapsCallback();
-  // Function to post the above callback. The argument |now| is passed as an
-  // argument to avoid redundant calls to base::TimeTicks::Now.
-  void PostCheckPendingSwapsCallbackIfNeeded(const base::TimeTicks& now);
-
-  // Return the time of |interval_fraction| of the way through the next
-  // vsync period that starts after |from|. If the vsync parameters are not
-  // valid then return |from|.
-  base::TimeTicks GetNextVSyncTimeAfter(
-      const base::TimeTicks& from, double interval_fraction);
-
   GpuChannelManager* manager_;
   base::WeakPtr<GpuCommandBufferStub> stub_;
   SurfaceHandle handle_;
@@ -131,26 +102,14 @@
   scoped_ptr<CALayerPartialDamageTree> pending_partial_damage_tree_;
   scoped_ptr<CALayerTree> pending_ca_layer_tree_;
 
-  // A queue of all frames that have been created by SwapBuffersInternal but
-  // have not yet been displayed. This queue is checked at the beginning of
-  // every swap and also by a callback.
-  std::deque<linked_ptr<PendingSwap>> pending_swaps_;
-
   // The planes that are currently being displayed on the screen.
   scoped_ptr<CALayerPartialDamageTree> current_partial_damage_tree_;
   scoped_ptr<CALayerTree> current_ca_layer_tree_;
 
-  // The time of the last swap was issued. If this is more than two vsyncs, then
-  // use the simpler non-smooth animation path.
-  base::TimeTicks last_swap_time_;
-
   // The vsync information provided by the browser.
   bool vsync_parameters_valid_;
   base::TimeTicks vsync_timebase_;
   base::TimeDelta vsync_interval_;
-
-  base::Timer display_pending_swap_timer_;
-  base::WeakPtrFactory<ImageTransportSurfaceOverlayMac> weak_factory_;
 };
 
 }  // namespace gpu
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
index 4eea4a1..876b23ed 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
@@ -42,25 +42,6 @@
 
 namespace {
 
-// Don't let a frame draw until 5% of the way through the next vsync interval
-// after the call to SwapBuffers. This slight offset is to ensure that skew
-// doesn't result in the frame being presented to the previous vsync interval.
-const double kVSyncIntervalFractionForEarliestDisplay = 0.05;
-
-// After doing a glFlush and putting in a fence in SwapBuffers, post a task to
-// query the fence 50% of the way through the next vsync interval. If we are
-// trying to animate smoothly, then want to query the fence at the next
-// SwapBuffers. For this reason we schedule the callback for a long way into
-// the next frame.
-const double kVSyncIntervalFractionForDisplayCallback = 0.5;
-
-// If swaps arrive regularly and nearly at the vsync rate, then attempt to
-// make animation smooth (each frame is shown for one vsync interval) by sending
-// them to the window server only when their GL work completes. If frames are
-// not coming in with each vsync, then just throw them at the window server as
-// they come.
-const double kMaximumVSyncsBetweenSwapsForSmoothAnimation = 1.5;
-
 void CheckGLErrors(const char* msg) {
   GLenum gl_error;
   while ((gl_error = glGetError()) != GL_NO_ERROR) {
@@ -73,10 +54,6 @@
 
 }  // namespace
 
-@interface CALayer(Private)
--(void)setContentsChanged;
-@end
-
 namespace gpu {
 
 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface(
@@ -86,33 +63,6 @@
   return new ImageTransportSurfaceOverlayMac(manager, stub, handle);
 }
 
-class ImageTransportSurfaceOverlayMac::PendingSwap {
- public:
-  PendingSwap() {}
-  ~PendingSwap() { DCHECK(!gl_fence); }
-
-  gfx::Size pixel_size;
-  float scale_factor;
-  gfx::Rect pixel_damage_rect;
-
-  scoped_ptr<CALayerPartialDamageTree> partial_damage_tree;
-  scoped_ptr<CALayerTree> ca_layer_tree;
-  std::vector<ui::LatencyInfo> latency_info;
-
-  // A fence object, and the CGL context it was issued in.
-  base::ScopedTypeRef<CGLContextObj> cgl_context;
-  scoped_ptr<gfx::GLFence> gl_fence;
-
-  // The earliest time that this frame may be drawn. A frame is not allowed
-  // to draw until a fraction of the way through the vsync interval after its
-  // This extra latency is to allow wiggle-room for smoothness.
-  base::TimeTicks earliest_display_time_allowed;
-
-  // The time that this will wake up and draw, if a following swap does not
-  // cause it to draw earlier.
-  base::TimeTicks target_display_time;
-};
-
 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac(
     GpuChannelManager* manager,
     GpuCommandBufferStub* stub,
@@ -123,9 +73,7 @@
       use_remote_layer_api_(ui::RemoteLayerAPISupported()),
       scale_factor_(1),
       gl_renderer_id_(0),
-      vsync_parameters_valid_(false),
-      display_pending_swap_timer_(true, false),
-      weak_factory_(this) {
+      vsync_parameters_valid_(false) {
   manager_->AddBufferPresentedCallback(
       handle_, base::Bind(&ImageTransportSurfaceOverlayMac::BufferPresented,
                           base::Unretained(this)));
@@ -166,8 +114,6 @@
 }
 
 void ImageTransportSurfaceOverlayMac::Destroy() {
-  DisplayAndClearAllPendingSwaps();
-
   current_partial_damage_tree_.reset();
   current_ca_layer_tree_.reset();
 }
@@ -220,130 +166,33 @@
     const gfx::Rect& pixel_damage_rect) {
   TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal");
 
-  // Use the same concept of 'now' for the entire function. The duration of
-  // this function only affect the result if this function lasts across a vsync
-  // boundary, in which case smooth animation is out the window anyway.
-  const base::TimeTicks now = base::TimeTicks::Now();
-
-  // Decide if the frame should be drawn immediately, or if we should wait until
-  // its work finishes before drawing immediately.
-  bool display_immediately = false;
-  if (vsync_parameters_valid_ &&
-      now - last_swap_time_ >
-          kMaximumVSyncsBetweenSwapsForSmoothAnimation * vsync_interval_) {
-    display_immediately = true;
-  }
-  last_swap_time_ = now;
-
-  // If the previous swap is ready to display, do it before flushing the
-  // new swap. It is desirable to always be hitting this path when trying to
-  // animate smoothly with vsync.
-  if (!pending_swaps_.empty()) {
-    if (IsFirstPendingSwapReadyToDisplay(now))
-      DisplayFirstPendingSwapImmediately();
-  }
-
-  // The remainder of the function will populate the PendingSwap structure and
-  // then enqueue it.
-  linked_ptr<PendingSwap> new_swap(new PendingSwap);
-  new_swap->pixel_size = pixel_size_;
-  new_swap->scale_factor = scale_factor_;
-  new_swap->pixel_damage_rect = pixel_damage_rect;
-  new_swap->partial_damage_tree.swap(pending_partial_damage_tree_);
-  new_swap->ca_layer_tree.swap(pending_ca_layer_tree_);
-  new_swap->latency_info.swap(latency_info_);
-
-  // A flush is required to ensure that all content appears in the layer.
+  // A glFlush is necessary to ensure correct content appears. A glFinish
+  // appears empirically to be the best way to get maximum performance when
+  // GPU bound.
   {
     gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
-    TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::glFlush");
-    CheckGLErrors("before flushing frame");
-    new_swap->cgl_context.reset(CGLGetCurrentContext(),
-                                base::scoped_policy::RETAIN);
-    if (gfx::GLFence::IsSupported() && !display_immediately)
-      new_swap->gl_fence.reset(gfx::GLFence::Create());
-    else
-      glFlush();
-    CheckGLErrors("while flushing frame");
+    TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::glFinish");
+    CheckGLErrors("Before finish");
+    glFinish();
+    CheckGLErrors("After finish");
   }
 
-  // Compute the deadlines for drawing this frame.
-  if (display_immediately) {
-    new_swap->earliest_display_time_allowed = now;
-    new_swap->target_display_time = now;
-  } else {
-    new_swap->earliest_display_time_allowed =
-        GetNextVSyncTimeAfter(now, kVSyncIntervalFractionForEarliestDisplay);
-    new_swap->target_display_time =
-        GetNextVSyncTimeAfter(now, kVSyncIntervalFractionForDisplayCallback);
-  }
-
-  pending_swaps_.push_back(new_swap);
-  if (display_immediately)
-    DisplayFirstPendingSwapImmediately();
-  else
-    PostCheckPendingSwapsCallbackIfNeeded(now);
-  return gfx::SwapResult::SWAP_ACK;
-}
-
-bool ImageTransportSurfaceOverlayMac::IsFirstPendingSwapReadyToDisplay(
-    const base::TimeTicks& now) {
-  DCHECK(!pending_swaps_.empty());
-  linked_ptr<PendingSwap> swap = pending_swaps_.front();
-
-  // Frames are disallowed from drawing until the vsync interval after their
-  // swap is issued.
-  if (now < swap->earliest_display_time_allowed)
-    return false;
-
-  // If we've passed that marker, then wait for the work behind the fence to
-  // complete.
-  if (swap->gl_fence) {
-    gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
-    gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
-
-    CheckGLErrors("before waiting on fence");
-    if (!swap->gl_fence->HasCompleted()) {
-      TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::ClientWait");
-      swap->gl_fence->ClientWait();
-    }
-    swap->gl_fence.reset();
-    CheckGLErrors("after waiting on fence");
-  }
-  return true;
-}
-
-void ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately() {
-  TRACE_EVENT0("gpu",
-      "ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately");
-  DCHECK(!pending_swaps_.empty());
-  linked_ptr<PendingSwap> swap = pending_swaps_.front();
-
-  // If there is a fence for this object, delete it.
-  if (swap->gl_fence) {
-    gfx::ScopedSetGLToRealGLApi scoped_set_gl_api;
-    gfx::ScopedCGLSetCurrentContext scoped_set_current(swap->cgl_context);
-
-    CheckGLErrors("before deleting active fence");
-    swap->gl_fence.reset();
-    CheckGLErrors("while deleting active fence");
-  }
+  base::TimeTicks finish_time = base::TimeTicks::Now();
 
   // Update the CALayer hierarchy.
   {
-    gfx::RectF pixel_damage_rect = gfx::RectF(swap->pixel_damage_rect);
     ScopedCAActionDisabler disabler;
-    if (swap->ca_layer_tree) {
-      swap->ca_layer_tree->CommitScheduledCALayers(
+    if (pending_ca_layer_tree_) {
+      pending_ca_layer_tree_->CommitScheduledCALayers(
           ca_root_layer_.get(), std::move(current_ca_layer_tree_),
-          swap->scale_factor);
-      current_ca_layer_tree_.swap(swap->ca_layer_tree);
+          scale_factor_);
+      current_ca_layer_tree_.swap(pending_ca_layer_tree_);
       current_partial_damage_tree_.reset();
-    } else if (swap->partial_damage_tree) {
-      swap->partial_damage_tree->CommitCALayers(
+    } else if (pending_partial_damage_tree_) {
+      pending_partial_damage_tree_->CommitCALayers(
           ca_root_layer_.get(), std::move(current_partial_damage_tree_),
-          swap->scale_factor, swap->pixel_damage_rect);
-      current_partial_damage_tree_.swap(swap->partial_damage_tree);
+          scale_factor_, pixel_damage_rect);
+      current_partial_damage_tree_.swap(pending_partial_damage_tree_);
       current_ca_layer_tree_.reset();
     } else {
       TRACE_EVENT0("gpu", "Blank frame: No overlays or CALayers");
@@ -351,18 +200,15 @@
       current_partial_damage_tree_.reset();
       current_ca_layer_tree_.reset();
     }
-    swap->ca_layer_tree.reset();
-    swap->partial_damage_tree.reset();
   }
 
   // Update the latency info to reflect the swap time.
-  base::TimeTicks swap_time = base::TimeTicks::Now();
-  for (auto latency_info : swap->latency_info) {
+  for (auto latency_info : latency_info_) {
     latency_info.AddLatencyNumberWithTimestamp(
-        ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1);
+        ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, finish_time, 1);
     latency_info.AddLatencyNumberWithTimestamp(
         ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0,
-        swap_time, 1);
+        finish_time, 1);
   }
 
   // Send acknowledgement to the browser.
@@ -374,51 +220,15 @@
     io_surface.reset(IOSurfaceCreateMachPort(
         current_partial_damage_tree_->RootLayerIOSurface()));
   }
-  gfx::Size size = swap->pixel_size;
-  float scale_factor = swap->scale_factor;
-  std::vector<ui::LatencyInfo> latency_info;
-  latency_info.swap(swap->latency_info);
-  SendAcceleratedSurfaceBuffersSwapped(handle_, ca_context_id, io_surface, size,
-                                       scale_factor, std::move(latency_info));
+  SendAcceleratedSurfaceBuffersSwapped(handle_, ca_context_id, io_surface,
+                                       pixel_size_, scale_factor_,
+                                       std::move(latency_info_));
 
-  // Remove this from the queue, and reset any callback timers.
-  pending_swaps_.pop_front();
-}
-
-void ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps() {
-  TRACE_EVENT0("gpu",
-      "ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps");
-  while (!pending_swaps_.empty())
-    DisplayFirstPendingSwapImmediately();
-}
-
-void ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback() {
-  TRACE_EVENT0("gpu",
-      "ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback");
-
-  if (pending_swaps_.empty())
-    return;
-
-  const base::TimeTicks now = base::TimeTicks::Now();
-  if (IsFirstPendingSwapReadyToDisplay(now))
-    DisplayFirstPendingSwapImmediately();
-  PostCheckPendingSwapsCallbackIfNeeded(now);
-}
-
-void ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded(
-    const base::TimeTicks& now) {
-  TRACE_EVENT0("gpu",
-      "ImageTransportSurfaceOverlayMac::PostCheckPendingSwapsCallbackIfNeeded");
-
-  if (pending_swaps_.empty()) {
-    display_pending_swap_timer_.Stop();
-  } else {
-    display_pending_swap_timer_.Start(
-        FROM_HERE,
-        pending_swaps_.front()->target_display_time - now,
-        base::Bind(&ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback,
-                       weak_factory_.GetWeakPtr()));
-  }
+  // Reset all state for the next frame.
+  latency_info_.clear();
+  pending_ca_layer_tree_.reset();
+  pending_partial_damage_tree_.reset();
+  return gfx::SwapResult::SWAP_ACK;
 }
 
 gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffers() {
@@ -453,14 +263,6 @@
   return true;
 }
 
-bool ImageTransportSurfaceOverlayMac::SetBackbufferAllocation(bool allocated) {
-  if (!allocated) {
-    DisplayAndClearAllPendingSwaps();
-    last_swap_time_ = base::TimeTicks();
-  }
-  return true;
-}
-
 bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane(
     int z_order,
     gfx::OverlayTransform transform,
@@ -518,7 +320,6 @@
                                              float scale_factor,
                                              bool has_alpha) {
   // Flush through any pending frames.
-  DisplayAndClearAllPendingSwaps();
   pixel_size_ = pixel_size;
   scale_factor_ = scale_factor;
   return true;
@@ -546,18 +347,4 @@
       FROM_HERE, base::Bind(&IOSurfaceContextNoOp, context_on_new_gpu));
 }
 
-base::TimeTicks ImageTransportSurfaceOverlayMac::GetNextVSyncTimeAfter(
-    const base::TimeTicks& from, double interval_fraction) {
-  if (!vsync_parameters_valid_)
-    return from;
-
-  // Compute the previous vsync time.
-  base::TimeTicks previous_vsync =
-      vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) +
-      vsync_timebase_;
-
-  // Return |interval_fraction| through the next vsync.
-  return previous_vsync + (1 + interval_fraction) * vsync_interval_;
-}
-
 }  // namespace gpu