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(©_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(©_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, ©_requests, ©_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(©_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, ©_requests, ©_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());