blob: 065aa3822895dec4fdd64bb8d520c1aa80d45b58 [file] [log] [blame]
James Robinson646469d2014-10-03 15:33:28 -07001// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/surfaces/surface.h"
6
James Robinson7f480212014-10-31 10:28:08 -07007#include <algorithm>
8
James Robinson646469d2014-10-03 15:33:28 -07009#include "cc/output/compositor_frame.h"
10#include "cc/output/copy_output_request.h"
11#include "cc/surfaces/surface_factory.h"
James Robinson1ae030a2014-11-07 08:32:47 -080012#include "cc/surfaces/surface_id_allocator.h"
James Robinsone2ac7e82014-10-15 13:21:59 -070013#include "cc/surfaces/surface_manager.h"
James Robinson646469d2014-10-03 15:33:28 -070014
15namespace cc {
16
17// The frame index starts at 2 so that empty frames will be treated as
18// completely damaged the first time they're drawn from.
19static const int kFrameIndexStart = 2;
20
James Robinson6a64b812014-12-03 13:38:42 -080021Surface::Surface(SurfaceId id, SurfaceFactory* factory)
James Robinson646469d2014-10-03 15:33:28 -070022 : surface_id_(id),
James Robinsone2ac7e82014-10-15 13:21:59 -070023 factory_(factory->AsWeakPtr()),
James Robinson646469d2014-10-03 15:33:28 -070024 frame_index_(kFrameIndexStart) {
25}
26
27Surface::~Surface() {
James Robinson80d418c2014-10-16 16:00:02 -070028 ClearCopyRequests();
James Robinsone2ac7e82014-10-15 13:21:59 -070029 if (current_frame_ && factory_) {
James Robinson646469d2014-10-03 15:33:28 -070030 ReturnedResourceArray current_resources;
31 TransferableResource::ReturnResources(
32 current_frame_->delegated_frame_data->resource_list,
33 &current_resources);
34 factory_->UnrefResources(current_resources);
35 }
Etienne Membrivesb1556b32014-12-16 13:56:09 +010036 if (!draw_callback_.is_null())
Elliot Glayshereae49292015-01-28 10:47:32 -080037 draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED);
James Robinson646469d2014-10-03 15:33:28 -070038}
39
40void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
Etienne Membrivesb1556b32014-12-16 13:56:09 +010041 const DrawCallback& callback) {
James Robinsone2ac7e82014-10-15 13:21:59 -070042 DCHECK(factory_);
James Robinson80d418c2014-10-16 16:00:02 -070043 ClearCopyRequests();
James Robinson646469d2014-10-03 15:33:28 -070044 TakeLatencyInfo(&frame->metadata.latency_info);
45 scoped_ptr<CompositorFrame> previous_frame = current_frame_.Pass();
46 current_frame_ = frame.Pass();
47 factory_->ReceiveFromChild(
48 current_frame_->delegated_frame_data->resource_list);
James Robinson7b766f42015-02-06 15:14:04 -080049 // Empty frames shouldn't be drawn and shouldn't contribute damage, so don't
50 // increment frame index for them.
51 if (!current_frame_ ||
52 !current_frame_->delegated_frame_data->render_pass_list.empty())
53 ++frame_index_;
James Robinson646469d2014-10-03 15:33:28 -070054
55 if (previous_frame) {
56 ReturnedResourceArray previous_resources;
57 TransferableResource::ReturnResources(
58 previous_frame->delegated_frame_data->resource_list,
59 &previous_resources);
60 factory_->UnrefResources(previous_resources);
61 }
62 if (!draw_callback_.is_null())
Elliot Glayshereae49292015-01-28 10:47:32 -080063 draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED);
James Robinson646469d2014-10-03 15:33:28 -070064 draw_callback_ = callback;
James Robinsone2ac7e82014-10-15 13:21:59 -070065 factory_->manager()->DidSatisfySequences(
James Robinson1ae030a2014-11-07 08:32:47 -080066 SurfaceIdAllocator::NamespaceForId(surface_id_),
67 &current_frame_->metadata.satisfies_sequences);
James Robinson646469d2014-10-03 15:33:28 -070068}
69
70void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) {
James Robinson80d418c2014-10-16 16:00:02 -070071 if (current_frame_ &&
72 !current_frame_->delegated_frame_data->render_pass_list.empty())
73 current_frame_->delegated_frame_data->render_pass_list.back()
74 ->copy_requests.push_back(copy_request.Pass());
75 else
76 copy_request->SendEmptyResult();
James Robinson646469d2014-10-03 15:33:28 -070077}
78
79void Surface::TakeCopyOutputRequests(
James Robinson80d418c2014-10-16 16:00:02 -070080 std::multimap<RenderPassId, CopyOutputRequest*>* copy_requests) {
James Robinson646469d2014-10-03 15:33:28 -070081 DCHECK(copy_requests->empty());
James Robinson80d418c2014-10-16 16:00:02 -070082 if (current_frame_) {
James Robinson7f480212014-10-31 10:28:08 -070083 for (const auto& render_pass :
James Robinson80d418c2014-10-16 16:00:02 -070084 current_frame_->delegated_frame_data->render_pass_list) {
85 while (!render_pass->copy_requests.empty()) {
86 scoped_ptr<CopyOutputRequest> request =
87 render_pass->copy_requests.take_back();
88 render_pass->copy_requests.pop_back();
89 copy_requests->insert(
90 std::make_pair(render_pass->id, request.release()));
91 }
92 }
93 }
James Robinson646469d2014-10-03 15:33:28 -070094}
95
96const CompositorFrame* Surface::GetEligibleFrame() {
97 return current_frame_.get();
98}
99
100void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) {
101 if (!current_frame_)
102 return;
103 if (latency_info->empty()) {
104 current_frame_->metadata.latency_info.swap(*latency_info);
105 return;
106 }
107 std::copy(current_frame_->metadata.latency_info.begin(),
108 current_frame_->metadata.latency_info.end(),
109 std::back_inserter(*latency_info));
110 current_frame_->metadata.latency_info.clear();
111}
112
Elliot Glayshereae49292015-01-28 10:47:32 -0800113void Surface::RunDrawCallbacks(SurfaceDrawStatus drawn) {
James Robinson646469d2014-10-03 15:33:28 -0700114 if (!draw_callback_.is_null()) {
Etienne Membrivesb1556b32014-12-16 13:56:09 +0100115 DrawCallback callback = draw_callback_;
116 draw_callback_ = DrawCallback();
Elliot Glayshereae49292015-01-28 10:47:32 -0800117 callback.Run(drawn);
James Robinson646469d2014-10-03 15:33:28 -0700118 }
119}
120
James Robinson1ae030a2014-11-07 08:32:47 -0800121void Surface::AddDestructionDependency(SurfaceSequence sequence) {
122 destruction_dependencies_.push_back(sequence);
123}
124
125void Surface::SatisfyDestructionDependencies(
126 base::hash_set<SurfaceSequence>* sequences) {
127 destruction_dependencies_.erase(
128 std::remove_if(
129 destruction_dependencies_.begin(), destruction_dependencies_.end(),
130 [sequences](SurfaceSequence seq) { return !!sequences->erase(seq); }),
131 destruction_dependencies_.end());
132}
133
James Robinson80d418c2014-10-16 16:00:02 -0700134void Surface::ClearCopyRequests() {
135 if (current_frame_) {
James Robinson7f480212014-10-31 10:28:08 -0700136 for (const auto& render_pass :
James Robinson80d418c2014-10-16 16:00:02 -0700137 current_frame_->delegated_frame_data->render_pass_list) {
James Robinson7f480212014-10-31 10:28:08 -0700138 for (const auto& copy_request : render_pass->copy_requests)
James Robinson80d418c2014-10-16 16:00:02 -0700139 copy_request->SendEmptyResult();
140 }
141 }
142}
143
James Robinson646469d2014-10-03 15:33:28 -0700144} // namespace cc