diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
new file mode 100644
index 0000000..35107e8
--- /dev/null
+++ b/cc/surfaces/surface_aggregator.cc
@@ -0,0 +1,402 @@
+// Copyright 2014 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 "cc/surfaces/surface_aggregator.h"
+
+#include "base/bind.h"
+#include "base/containers/hash_tables.h"
+#include "base/debug/trace_event.h"
+#include "base/logging.h"
+#include "cc/base/math_util.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/delegated_frame_data.h"
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/render_pass_draw_quad.h"
+#include "cc/quads/shared_quad_state.h"
+#include "cc/quads/surface_draw_quad.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_factory.h"
+#include "cc/surfaces/surface_manager.h"
+#include "cc/trees/blocking_task_runner.h"
+
+namespace cc {
+
+SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager,
+                                     ResourceProvider* provider)
+    : manager_(manager), provider_(provider) {
+  DCHECK(manager_);
+}
+
+SurfaceAggregator::~SurfaceAggregator() {}
+
+class SurfaceAggregator::RenderPassIdAllocator {
+ public:
+  explicit RenderPassIdAllocator(SurfaceId surface_id)
+      : surface_id_(surface_id), next_index_(1) {}
+  ~RenderPassIdAllocator() {}
+
+  void AddKnownPass(RenderPassId id) {
+    if (id_to_index_map_.find(id) != id_to_index_map_.end())
+      return;
+    id_to_index_map_[id] = next_index_++;
+  }
+
+  RenderPassId Remap(RenderPassId id) {
+    DCHECK(id_to_index_map_.find(id) != id_to_index_map_.end());
+    return RenderPassId(surface_id_.id, id_to_index_map_[id]);
+  }
+
+ private:
+  base::hash_map<RenderPassId, int> id_to_index_map_;
+  SurfaceId surface_id_;
+  int next_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(RenderPassIdAllocator);
+};
+
+static void UnrefHelper(base::WeakPtr<SurfaceFactory> surface_factory,
+                        const ReturnedResourceArray& resources,
+                        BlockingTaskRunner* main_thread_task_runner) {
+  if (surface_factory)
+    surface_factory->UnrefResources(resources);
+}
+
+RenderPassId SurfaceAggregator::RemapPassId(RenderPassId surface_local_pass_id,
+                                            SurfaceId surface_id) {
+  RenderPassIdAllocator* allocator = render_pass_allocator_map_.get(surface_id);
+  if (!allocator) {
+    allocator = new RenderPassIdAllocator(surface_id);
+    render_pass_allocator_map_.set(surface_id, make_scoped_ptr(allocator));
+  }
+  allocator->AddKnownPass(surface_local_pass_id);
+  return allocator->Remap(surface_local_pass_id);
+}
+
+int SurfaceAggregator::ChildIdForSurface(Surface* surface) {
+  SurfaceToResourceChildIdMap::iterator it =
+      surface_id_to_resource_child_id_.find(surface->surface_id());
+  if (it == surface_id_to_resource_child_id_.end()) {
+    int child_id = provider_->CreateChild(
+        base::Bind(&UnrefHelper, surface->factory()->AsWeakPtr()));
+    surface_id_to_resource_child_id_[surface->surface_id()] = child_id;
+    return child_id;
+  } else {
+    return it->second;
+  }
+}
+
+static ResourceProvider::ResourceId ResourceRemapHelper(
+    bool* invalid_frame,
+    const ResourceProvider::ResourceIdMap& child_to_parent_map,
+    ResourceProvider::ResourceIdArray* resources_in_frame,
+    ResourceProvider::ResourceId id) {
+  ResourceProvider::ResourceIdMap::const_iterator it =
+      child_to_parent_map.find(id);
+  if (it == child_to_parent_map.end()) {
+    *invalid_frame = true;
+    return 0;
+  }
+
+  DCHECK_EQ(it->first, id);
+  ResourceProvider::ResourceId remapped_id = it->second;
+  resources_in_frame->push_back(id);
+  return remapped_id;
+}
+
+bool SurfaceAggregator::TakeResources(Surface* surface,
+                                      const DelegatedFrameData* frame_data,
+                                      RenderPassList* render_pass_list) {
+  RenderPass::CopyAll(frame_data->render_pass_list, render_pass_list);
+  if (!provider_)  // TODO(jamesr): hack for unit tests that don't set up rp
+    return false;
+
+  int child_id = ChildIdForSurface(surface);
+  provider_->ReceiveFromChild(child_id, frame_data->resource_list);
+  surface->factory()->RefResources(frame_data->resource_list);
+
+  typedef ResourceProvider::ResourceIdArray IdArray;
+  IdArray referenced_resources;
+
+  bool invalid_frame = false;
+  DrawQuad::ResourceIteratorCallback remap =
+      base::Bind(&ResourceRemapHelper,
+                 &invalid_frame,
+                 provider_->GetChildToParentMap(child_id),
+                 &referenced_resources);
+  for (RenderPassList::iterator it = render_pass_list->begin();
+       it != render_pass_list->end();
+       ++it) {
+    QuadList& quad_list = (*it)->quad_list;
+    for (QuadList::Iterator quad_it = quad_list.begin();
+         quad_it != quad_list.end();
+         ++quad_it) {
+      quad_it->IterateResources(remap);
+    }
+  }
+  if (!invalid_frame)
+    provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources);
+
+  return invalid_frame;
+}
+
+gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface,
+                                                  const RenderPass& source) {
+  int previous_index = previous_contained_surfaces_[surface->surface_id()];
+  if (previous_index == surface->frame_index())
+    return gfx::Rect();
+  else if (previous_index == surface->frame_index() - 1)
+    return source.damage_rect;
+  return gfx::Rect(surface->size());
+}
+
+void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
+                                          RenderPass* dest_pass) {
+  SurfaceId surface_id = surface_quad->surface_id;
+  // If this surface's id is already in our referenced set then it creates
+  // a cycle in the graph and should be dropped.
+  if (referenced_surfaces_.count(surface_id))
+    return;
+  Surface* surface = manager_->GetSurfaceForId(surface_id);
+  if (!surface) {
+    contained_surfaces_[surface_id] = 0;
+    return;
+  }
+  contained_surfaces_[surface_id] = surface->frame_index();
+  const CompositorFrame* frame = surface->GetEligibleFrame();
+  if (!frame)
+    return;
+  const DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
+  if (!frame_data)
+    return;
+
+  RenderPassList render_pass_list;
+  bool invalid_frame = TakeResources(surface, frame_data, &render_pass_list);
+  if (invalid_frame)
+    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;
+  size_t passes_to_copy =
+      merge_pass ? referenced_passes.size() - 1 : referenced_passes.size();
+  for (size_t j = 0; j < passes_to_copy; ++j) {
+    const RenderPass& source = *referenced_passes[j];
+
+    scoped_ptr<RenderPass> copy_pass(RenderPass::Create());
+
+    RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id);
+
+    copy_pass->SetAll(remapped_pass_id,
+                      source.output_rect,
+                      source.damage_rect,
+                      source.transform_to_root_target,
+                      source.has_transparent_background);
+
+    // 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.
+    // TODO(jamesr): Make sure this is sufficient for surfaces nested several
+    // levels deep and add tests.
+    copy_pass->transform_to_root_target.ConcatTransform(
+        surface_quad->quadTransform());
+
+    CopyQuadsToPass(source.quad_list,
+                    source.shared_quad_state_list,
+                    gfx::Transform(),
+                    copy_pass.get(),
+                    surface_id);
+
+    dest_pass_list_->push_back(copy_pass.Pass());
+  }
+
+  const RenderPass& last_pass = *render_pass_list.back();
+  if (merge_pass) {
+    // TODO(jamesr): Clean up last pass special casing.
+    const QuadList& quads = last_pass.quad_list;
+
+    // TODO(jamesr): Make sure clipping is enforced.
+    CopyQuadsToPass(quads,
+                    last_pass.shared_quad_state_list,
+                    surface_quad->quadTransform(),
+                    dest_pass,
+                    surface_id);
+  } 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);
+    RenderPassDrawQuad* quad =
+        dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
+    quad->SetNew(shared_quad_state,
+                 surface_quad->rect,
+                 surface_quad->visible_rect,
+                 remapped_pass_id,
+                 0,
+                 gfx::RectF(),
+                 FilterOperations(),
+                 gfx::Vector2dF(),
+                 FilterOperations());
+  }
+  dest_pass->damage_rect =
+      gfx::UnionRects(dest_pass->damage_rect,
+                      MathUtil::MapEnclosingClippedRect(
+                          surface_quad->quadTransform(),
+                          DamageRectForSurface(surface, last_pass)));
+
+  referenced_surfaces_.erase(it);
+}
+
+void SurfaceAggregator::CopySharedQuadState(
+    const SharedQuadState* source_sqs,
+    const gfx::Transform& content_to_target_transform,
+    RenderPass* dest_render_pass) {
+  SharedQuadState* copy_shared_quad_state =
+      dest_render_pass->CreateAndAppendSharedQuadState();
+  copy_shared_quad_state->CopyFrom(source_sqs);
+  // content_to_target_transform contains any transformation that may exist
+  // between the context that these quads are being copied from (i.e. the
+  // surface's draw transform when aggregated from within a surface) to the
+  // target space of the pass. This will be identity except when copying the
+  // root draw pass from a surface into a pass when the surface draw quad's
+  // transform is not identity.
+  copy_shared_quad_state->content_to_target_transform.ConcatTransform(
+      content_to_target_transform);
+  if (copy_shared_quad_state->is_clipped) {
+    copy_shared_quad_state->clip_rect = MathUtil::MapEnclosingClippedRect(
+        content_to_target_transform, copy_shared_quad_state->clip_rect);
+  }
+}
+
+void SurfaceAggregator::CopyQuadsToPass(
+    const QuadList& source_quad_list,
+    const SharedQuadStateList& source_shared_quad_state_list,
+    const gfx::Transform& content_to_target_transform,
+    RenderPass* dest_pass,
+    SurfaceId surface_id) {
+  const SharedQuadState* last_copied_source_shared_quad_state = NULL;
+
+  size_t sqs_i = 0;
+  for (QuadList::ConstIterator iter = source_quad_list.begin();
+       iter != source_quad_list.end();
+       ++iter) {
+    const DrawQuad* quad = &*iter;
+    while (quad->shared_quad_state != source_shared_quad_state_list[sqs_i]) {
+      ++sqs_i;
+      DCHECK_LT(sqs_i, source_shared_quad_state_list.size());
+    }
+    DCHECK_EQ(quad->shared_quad_state, source_shared_quad_state_list[sqs_i]);
+
+    if (quad->material == DrawQuad::SURFACE_CONTENT) {
+      const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
+      HandleSurfaceQuad(surface_quad, dest_pass);
+    } else {
+      if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
+        CopySharedQuadState(
+            quad->shared_quad_state, content_to_target_transform, dest_pass);
+        last_copied_source_shared_quad_state = quad->shared_quad_state;
+      }
+      if (quad->material == DrawQuad::RENDER_PASS) {
+        const RenderPassDrawQuad* pass_quad =
+            RenderPassDrawQuad::MaterialCast(quad);
+        RenderPassId original_pass_id = pass_quad->render_pass_id;
+        RenderPassId remapped_pass_id =
+            RemapPassId(original_pass_id, surface_id);
+
+        dest_pass->CopyFromAndAppendRenderPassDrawQuad(
+            pass_quad,
+            dest_pass->shared_quad_state_list.back(),
+            remapped_pass_id);
+      } else {
+        dest_pass->CopyFromAndAppendDrawQuad(
+            quad, dest_pass->shared_quad_state_list.back());
+      }
+    }
+  }
+}
+
+void SurfaceAggregator::CopyPasses(const RenderPassList& source_pass_list,
+                                   const Surface* surface) {
+  for (size_t i = 0; i < source_pass_list.size(); ++i) {
+    const RenderPass& source = *source_pass_list[i];
+
+    scoped_ptr<RenderPass> copy_pass(RenderPass::Create());
+
+    RenderPassId remapped_pass_id =
+        RemapPassId(source.id, surface->surface_id());
+
+    copy_pass->SetAll(remapped_pass_id,
+                      source.output_rect,
+                      DamageRectForSurface(surface, source),
+                      source.transform_to_root_target,
+                      source.has_transparent_background);
+
+    CopyQuadsToPass(source.quad_list,
+                    source.shared_quad_state_list,
+                    gfx::Transform(),
+                    copy_pass.get(),
+                    surface->surface_id());
+
+    dest_pass_list_->push_back(copy_pass.Pass());
+  }
+}
+
+scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
+  Surface* surface = manager_->GetSurfaceForId(surface_id);
+  DCHECK(surface);
+  contained_surfaces_[surface_id] = surface->frame_index();
+  const CompositorFrame* root_surface_frame = surface->GetEligibleFrame();
+  if (!root_surface_frame)
+    return nullptr;
+  TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate");
+
+  scoped_ptr<CompositorFrame> frame(new CompositorFrame);
+  frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData);
+
+  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);
+
+  referenced_surfaces_.erase(it);
+  DCHECK(referenced_surfaces_.empty());
+
+  dest_pass_list_ = NULL;
+  contained_surfaces_.swap(previous_contained_surfaces_);
+  contained_surfaces_.clear();
+
+  for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin();
+       it != previous_contained_surfaces_.end();
+       ++it) {
+    Surface* surface = manager_->GetSurfaceForId(it->first);
+    if (surface)
+      surface->TakeLatencyInfo(&frame->metadata.latency_info);
+  }
+
+  // TODO(jamesr): Aggregate all resource references into the returned frame's
+  // resource list.
+
+  return frame.Pass();
+}
+
+}  // namespace cc
