Revved to chromium 2a04445358913b81ed786927172647b701b73113 refs/remotes/origin/HEAD
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
index 620ada7..f6bf6d6 100644
--- a/cc/surfaces/surface_aggregator.cc
+++ b/cc/surfaces/surface_aggregator.cc
@@ -21,6 +21,22 @@
 #include "cc/trees/blocking_task_runner.h"
 
 namespace cc {
+namespace {
+
+void MoveMatchingRequests(
+    RenderPassId id,
+    std::multimap<RenderPassId, CopyOutputRequest*>* copy_requests,
+    ScopedPtrVector<CopyOutputRequest>* output_requests) {
+  auto request_range = copy_requests->equal_range(id);
+  for (auto it = request_range.first; it != request_range.second; ++it) {
+    DCHECK(it->second);
+    output_requests->push_back(scoped_ptr<CopyOutputRequest>(it->second));
+    it->second = nullptr;
+  }
+  copy_requests->erase(request_range.first, request_range.second);
+}
+
+}  // namespace
 
 SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager,
                                      ResourceProvider* provider)
@@ -165,16 +181,21 @@
   if (!frame_data)
     return;
 
+  std::multimap<RenderPassId, CopyOutputRequest*> copy_requests;
+  surface->TakeCopyOutputRequests(&copy_requests);
+
   RenderPassList render_pass_list;
   bool invalid_frame = TakeResources(surface, frame_data, &render_pass_list);
-  if (invalid_frame)
+  if (invalid_frame) {
+    for (auto& request : copy_requests) {
+      request.second->SendEmptyResult();
+      delete request.second;
+    }
     return;
+  }
 
   SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
 
-  ScopedPtrVector<CopyOutputRequest> copy_requests;
-  surface->TakeCopyOutputRequests(&copy_requests);
-
   bool merge_pass = copy_requests.empty();
 
   const RenderPassList& referenced_passes = render_pass_list;
@@ -195,6 +216,8 @@
                       source.transform_to_root_target,
                       source.has_transparent_background);
 
+    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
+
     // Contributing passes aggregated in to the pass list need to take the
     // transform of the surface quad into account to update their transform to
     // the root surface.
@@ -226,8 +249,6 @@
   } else {
     RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id);
 
-    dest_pass_list_->back()->copy_requests.swap(copy_requests);
-
     SharedQuadState* shared_quad_state =
         dest_pass->CreateAndAppendSharedQuadState();
     shared_quad_state->CopyFrom(surface_quad->shared_quad_state);
@@ -238,7 +259,8 @@
                  surface_quad->visible_rect,
                  remapped_pass_id,
                  0,
-                 gfx::RectF(),
+                 gfx::Vector2dF(),
+                 gfx::Size(),
                  FilterOperations(),
                  gfx::Vector2dF(),
                  FilterOperations());
@@ -319,8 +341,18 @@
   }
 }
 
-void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list,
-                                   const Surface* surface) {
+void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data,
+                                   Surface* surface) {
+  RenderPassList source_pass_list;
+
+  // The root surface is allowed to have copy output requests, so grab them
+  // off its render passes.
+  std::multimap<RenderPassId, CopyOutputRequest*> copy_requests;
+  surface->TakeCopyOutputRequests(&copy_requests);
+
+  bool invalid_frame = TakeResources(surface, frame_data, &source_pass_list);
+  DCHECK(!invalid_frame);
+
   for (size_t i = 0; i < source_pass_list.size(); ++i) {
     const RenderPass& source = *source_pass_list[i];
 
@@ -328,6 +360,8 @@
     size_t dq_size = source.quad_list.size();
     scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size));
 
+    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
+
     RenderPassId remapped_pass_id =
         RemapPassId(source.id, surface->surface_id());
 
@@ -361,20 +395,12 @@
 
   DCHECK(root_surface_frame->delegated_frame_data);
 
-  RenderPassList source_pass_list;
-
   SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
 
   dest_resource_list_ = &frame->delegated_frame_data->resource_list;
   dest_pass_list_ = &frame->delegated_frame_data->render_pass_list;
 
-  bool invalid_frame =
-      TakeResources(surface,
-                    root_surface_frame->delegated_frame_data.get(),
-                    &source_pass_list);
-  DCHECK(!invalid_frame);
-
-  CopyPasses(source_pass_list, surface);
+  CopyPasses(root_surface_frame->delegated_frame_data.get(), surface);
 
   referenced_surfaces_.erase(it);
   DCHECK(referenced_surfaces_.empty());