Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / surfaces / surface_aggregator.cc
index 679d751..44afaff 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "cc/surfaces/surface_aggregator.h"
 
+#include <map>
+
 #include "base/bind.h"
 #include "base/containers/hash_tables.h"
 #include "base/debug/trace_event.h"
 #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)
-    : manager_(manager), provider_(provider) {
+    : manager_(manager), provider_(provider), next_render_pass_id_(1) {
   DCHECK(manager_);
 }
 
@@ -32,25 +50,23 @@ SurfaceAggregator::~SurfaceAggregator() {}
 
 class SurfaceAggregator::RenderPassIdAllocator {
  public:
-  explicit RenderPassIdAllocator(SurfaceId surface_id)
-      : surface_id_(surface_id), next_index_(1) {}
+  explicit RenderPassIdAllocator(int* next_index) : next_index_(next_index) {}
   ~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_++;
+    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]);
+    return RenderPassId(1, id_to_index_map_[id]);
   }
 
  private:
   base::hash_map<RenderPassId, int> id_to_index_map_;
-  SurfaceId surface_id_;
-  int next_index_;
+  int* next_index_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderPassIdAllocator);
 };
@@ -66,7 +82,7 @@ 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);
+    allocator = new RenderPassIdAllocator(&next_render_pass_id_);
     render_pass_allocator_map_.set(surface_id, make_scoped_ptr(allocator));
   }
   allocator->AddKnownPass(surface_local_pass_id);
@@ -77,8 +93,8 @@ 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()));
+    int child_id =
+        provider_->CreateChild(base::Bind(&UnrefHelper, surface->factory()));
     surface_id_to_resource_child_id_[surface->surface_id()] = child_id;
     return child_id;
   } else {
@@ -113,7 +129,8 @@ bool SurfaceAggregator::TakeResources(Surface* surface,
 
   int child_id = ChildIdForSurface(surface);
   provider_->ReceiveFromChild(child_id, frame_data->resource_list);
-  surface->factory()->RefResources(frame_data->resource_list);
+  if (surface->factory())
+    surface->factory()->RefResources(frame_data->resource_list);
 
   typedef ResourceProvider::ResourceIdArray IdArray;
   IdArray referenced_resources;
@@ -124,16 +141,11 @@ bool SurfaceAggregator::TakeResources(Surface* surface,
                  &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);
-    }
+  for (const auto& render_pass : *render_pass_list) {
+    for (const auto& quad : render_pass->quad_list)
+      quad->IterateResources(remap);
   }
+
   if (!invalid_frame)
     provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources);
 
@@ -170,16 +182,21 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
   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;
@@ -188,7 +205,9 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
   for (size_t j = 0; j < passes_to_copy; ++j) {
     const RenderPass& source = *referenced_passes[j];
 
-    scoped_ptr<RenderPass> copy_pass(RenderPass::Create());
+    size_t sqs_size = source.shared_quad_state_list.size();
+    size_t dq_size = source.quad_list.size();
+    scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size));
 
     RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id);
 
@@ -198,6 +217,8 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
                       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.
@@ -229,8 +250,6 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
   } 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);
@@ -241,7 +260,8 @@ void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
                  surface_quad->visible_rect,
                  remapped_pass_id,
                  0,
-                 gfx::RectF(),
+                 gfx::Vector2dF(),
+                 gfx::Size(),
                  FilterOperations(),
                  gfx::Vector2dF(),
                  FilterOperations());
@@ -284,16 +304,14 @@ void SurfaceAggregator::CopyQuadsToPass(
     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());
+  SharedQuadStateList::ConstIterator sqs_iter =
+      source_shared_quad_state_list.begin();
+  for (const auto& quad : source_quad_list) {
+    while (quad->shared_quad_state != *sqs_iter) {
+      ++sqs_iter;
+      DCHECK(sqs_iter != source_shared_quad_state_list.end());
     }
-    DCHECK_EQ(quad->shared_quad_state, source_shared_quad_state_list[sqs_i]);
+    DCHECK_EQ(quad->shared_quad_state, *sqs_iter);
 
     if (quad->material == DrawQuad::SURFACE_CONTENT) {
       const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
@@ -323,12 +341,26 @@ void SurfaceAggregator::CopyQuadsToPass(
   }
 }
 
-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];
 
-    scoped_ptr<RenderPass> copy_pass(RenderPass::Create());
+    size_t sqs_size = source.shared_quad_state_list.size();
+    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());
@@ -355,7 +387,7 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
   contained_surfaces_[surface_id] = surface->frame_index();
   const CompositorFrame* root_surface_frame = surface->GetEligibleFrame();
   if (!root_surface_frame)
-    return scoped_ptr<CompositorFrame>();
+    return nullptr;
   TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate");
 
   scoped_ptr<CompositorFrame> frame(new CompositorFrame);
@@ -363,20 +395,12 @@ scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
 
   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());