OLD | NEW |
| (Empty) |
1 // 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 | |
7 #include <algorithm> | |
8 | |
9 #include "cc/output/compositor_frame.h" | |
10 #include "cc/output/copy_output_request.h" | |
11 #include "cc/surfaces/surface_factory.h" | |
12 #include "cc/surfaces/surface_id_allocator.h" | |
13 #include "cc/surfaces/surface_manager.h" | |
14 | |
15 namespace 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. | |
19 static const int kFrameIndexStart = 2; | |
20 | |
21 Surface::Surface(SurfaceId id, SurfaceFactory* factory) | |
22 : surface_id_(id), | |
23 factory_(factory->AsWeakPtr()), | |
24 frame_index_(kFrameIndexStart) { | |
25 } | |
26 | |
27 Surface::~Surface() { | |
28 ClearCopyRequests(); | |
29 if (current_frame_ && factory_) { | |
30 ReturnedResourceArray current_resources; | |
31 TransferableResource::ReturnResources( | |
32 current_frame_->delegated_frame_data->resource_list, | |
33 ¤t_resources); | |
34 factory_->UnrefResources(current_resources); | |
35 } | |
36 if (!draw_callback_.is_null()) | |
37 draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED); | |
38 } | |
39 | |
40 void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame, | |
41 const DrawCallback& callback) { | |
42 DCHECK(factory_); | |
43 ClearCopyRequests(); | |
44 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); | |
49 // 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_; | |
54 | |
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()) | |
63 draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED); | |
64 draw_callback_ = callback; | |
65 factory_->manager()->DidSatisfySequences( | |
66 SurfaceIdAllocator::NamespaceForId(surface_id_), | |
67 ¤t_frame_->metadata.satisfies_sequences); | |
68 } | |
69 | |
70 void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) { | |
71 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(); | |
77 } | |
78 | |
79 void Surface::TakeCopyOutputRequests( | |
80 std::multimap<RenderPassId, CopyOutputRequest*>* copy_requests) { | |
81 DCHECK(copy_requests->empty()); | |
82 if (current_frame_) { | |
83 for (const auto& render_pass : | |
84 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 } | |
94 } | |
95 | |
96 const CompositorFrame* Surface::GetEligibleFrame() { | |
97 return current_frame_.get(); | |
98 } | |
99 | |
100 void 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 | |
113 void Surface::RunDrawCallbacks(SurfaceDrawStatus drawn) { | |
114 if (!draw_callback_.is_null()) { | |
115 DrawCallback callback = draw_callback_; | |
116 draw_callback_ = DrawCallback(); | |
117 callback.Run(drawn); | |
118 } | |
119 } | |
120 | |
121 void Surface::AddDestructionDependency(SurfaceSequence sequence) { | |
122 destruction_dependencies_.push_back(sequence); | |
123 } | |
124 | |
125 void 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 | |
134 void Surface::ClearCopyRequests() { | |
135 if (current_frame_) { | |
136 for (const auto& render_pass : | |
137 current_frame_->delegated_frame_data->render_pass_list) { | |
138 for (const auto& copy_request : render_pass->copy_requests) | |
139 copy_request->SendEmptyResult(); | |
140 } | |
141 } | |
142 } | |
143 | |
144 } // namespace cc | |
OLD | NEW |