Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: cc/surfaces/surface_aggregator.cc

Issue 816543004: Update from https://crrev.com/308996 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/surfaces/surface_aggregator.h ('k') | cc/surfaces/surface_aggregator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/surfaces/surface_aggregator.h" 5 #include "cc/surfaces/surface_aggregator.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
(...skipping 30 matching lines...) Expand all
41 } // namespace 41 } // namespace
42 42
43 SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager, 43 SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager,
44 ResourceProvider* provider) 44 ResourceProvider* provider)
45 : manager_(manager), provider_(provider), next_render_pass_id_(1) { 45 : manager_(manager), provider_(provider), next_render_pass_id_(1) {
46 DCHECK(manager_); 46 DCHECK(manager_);
47 } 47 }
48 48
49 SurfaceAggregator::~SurfaceAggregator() {} 49 SurfaceAggregator::~SurfaceAggregator() {}
50 50
51 // Create a clip rect for an aggregated quad from the original clip rect and
52 // the clip rect from the surface it's on.
53 SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect(
54 const ClipData& surface_clip,
55 const ClipData& quad_clip,
56 const gfx::Transform& content_to_target_transform) {
57 ClipData out_clip;
58 if (surface_clip.is_clipped)
59 out_clip = surface_clip;
60
61 if (quad_clip.is_clipped) {
62 // TODO(jamesr): This only works if content_to_target_transform maps integer
63 // rects to integer rects.
64 gfx::Rect final_clip = MathUtil::MapEnclosingClippedRect(
65 content_to_target_transform, quad_clip.rect);
66 if (out_clip.is_clipped)
67 out_clip.rect.Intersect(final_clip);
68 else
69 out_clip.rect = final_clip;
70 out_clip.is_clipped = true;
71 }
72
73 return out_clip;
74 }
75
51 class SurfaceAggregator::RenderPassIdAllocator { 76 class SurfaceAggregator::RenderPassIdAllocator {
52 public: 77 public:
53 explicit RenderPassIdAllocator(int* next_index) : next_index_(next_index) {} 78 explicit RenderPassIdAllocator(int* next_index) : next_index_(next_index) {}
54 ~RenderPassIdAllocator() {} 79 ~RenderPassIdAllocator() {}
55 80
56 void AddKnownPass(RenderPassId id) { 81 void AddKnownPass(RenderPassId id) {
57 if (id_to_index_map_.find(id) != id_to_index_map_.end()) 82 if (id_to_index_map_.find(id) != id_to_index_map_.end())
58 return; 83 return;
59 id_to_index_map_[id] = (*next_index_)++; 84 id_to_index_map_[id] = (*next_index_)++;
60 } 85 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 const RenderPass& source, 181 const RenderPass& source,
157 const gfx::Rect& full_rect) { 182 const gfx::Rect& full_rect) {
158 int previous_index = previous_contained_surfaces_[surface->surface_id()]; 183 int previous_index = previous_contained_surfaces_[surface->surface_id()];
159 if (previous_index == surface->frame_index()) 184 if (previous_index == surface->frame_index())
160 return gfx::Rect(); 185 return gfx::Rect();
161 else if (previous_index == surface->frame_index() - 1) 186 else if (previous_index == surface->frame_index() - 1)
162 return source.damage_rect; 187 return source.damage_rect;
163 return full_rect; 188 return full_rect;
164 } 189 }
165 190
166 void SurfaceAggregator::HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad, 191 void SurfaceAggregator::HandleSurfaceQuad(
167 float opacity, 192 const SurfaceDrawQuad* surface_quad,
168 RenderPass* dest_pass) { 193 const gfx::Transform& content_to_target_transform,
194 const ClipData& clip_rect,
195 RenderPass* dest_pass) {
169 SurfaceId surface_id = surface_quad->surface_id; 196 SurfaceId surface_id = surface_quad->surface_id;
170 // If this surface's id is already in our referenced set then it creates 197 // If this surface's id is already in our referenced set then it creates
171 // a cycle in the graph and should be dropped. 198 // a cycle in the graph and should be dropped.
172 if (referenced_surfaces_.count(surface_id)) 199 if (referenced_surfaces_.count(surface_id))
173 return; 200 return;
174 Surface* surface = manager_->GetSurfaceForId(surface_id); 201 Surface* surface = manager_->GetSurfaceForId(surface_id);
175 if (!surface) { 202 if (!surface) {
176 contained_surfaces_[surface_id] = 0; 203 contained_surfaces_[surface_id] = 0;
177 return; 204 return;
178 } 205 }
(...skipping 13 matching lines...) Expand all
192 if (invalid_frame) { 219 if (invalid_frame) {
193 for (auto& request : copy_requests) { 220 for (auto& request : copy_requests) {
194 request.second->SendEmptyResult(); 221 request.second->SendEmptyResult();
195 delete request.second; 222 delete request.second;
196 } 223 }
197 return; 224 return;
198 } 225 }
199 226
200 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first; 227 SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
201 228
202 bool merge_pass = copy_requests.empty(); 229 bool merge_pass = surface_quad->opacity() == 1.f && copy_requests.empty();
203 230
204 const RenderPassList& referenced_passes = render_pass_list; 231 const RenderPassList& referenced_passes = render_pass_list;
205 size_t passes_to_copy = 232 size_t passes_to_copy =
206 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size(); 233 merge_pass ? referenced_passes.size() - 1 : referenced_passes.size();
207 for (size_t j = 0; j < passes_to_copy; ++j) { 234 for (size_t j = 0; j < passes_to_copy; ++j) {
208 const RenderPass& source = *referenced_passes[j]; 235 const RenderPass& source = *referenced_passes[j];
209 236
210 size_t sqs_size = source.shared_quad_state_list.size(); 237 size_t sqs_size = source.shared_quad_state_list.size();
211 size_t dq_size = source.quad_list.size(); 238 size_t dq_size = source.quad_list.size();
212 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size)); 239 scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size));
213 240
214 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id); 241 RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id);
215 242
216 copy_pass->SetAll(remapped_pass_id, 243 copy_pass->SetAll(remapped_pass_id,
217 source.output_rect, 244 source.output_rect,
218 source.damage_rect, 245 source.damage_rect,
219 source.transform_to_root_target, 246 source.transform_to_root_target,
220 source.has_transparent_background); 247 source.has_transparent_background);
221 248
222 MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests); 249 MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
223 250
224 // Contributing passes aggregated in to the pass list need to take the 251 // Contributing passes aggregated in to the pass list need to take the
225 // transform of the surface quad into account to update their transform to 252 // transform of the surface quad into account to update their transform to
226 // the root surface. 253 // the root surface.
227 // TODO(jamesr): Make sure this is sufficient for surfaces nested several 254 // TODO(jamesr): Make sure this is sufficient for surfaces nested several
228 // levels deep and add tests. 255 // levels deep and add tests.
229 copy_pass->transform_to_root_target.ConcatTransform( 256 copy_pass->transform_to_root_target.ConcatTransform(
230 surface_quad->quadTransform()); 257 surface_quad->quadTransform());
258 copy_pass->transform_to_root_target.ConcatTransform(
259 content_to_target_transform);
231 260
232 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, 261 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
233 gfx::Transform(), 1.f, copy_pass.get(), surface_id); 262 gfx::Transform(), ClipData(), copy_pass.get(), surface_id);
234 263
235 dest_pass_list_->push_back(copy_pass.Pass()); 264 dest_pass_list_->push_back(copy_pass.Pass());
236 } 265 }
237 266
238 const RenderPass& last_pass = *render_pass_list.back(); 267 const RenderPass& last_pass = *render_pass_list.back();
239 if (merge_pass) { 268 if (merge_pass) {
240 // TODO(jamesr): Clean up last pass special casing. 269 // TODO(jamesr): Clean up last pass special casing.
241 const QuadList& quads = last_pass.quad_list; 270 const QuadList& quads = last_pass.quad_list;
242 271
243 // TODO(jamesr): Make sure clipping is enforced. 272 gfx::Transform surface_transform = surface_quad->quadTransform();
244 CopyQuadsToPass(quads, last_pass.shared_quad_state_list, 273 surface_transform.ConcatTransform(content_to_target_transform);
245 surface_quad->quadTransform(), 274
246 surface_quad->opacity() * opacity, dest_pass, surface_id); 275 // Intersect the transformed visible rect and the clip rect to create a
276 // smaller cliprect for the quad.
277 ClipData surface_quad_clip_rect(
278 true, MathUtil::MapEnclosingClippedRect(surface_quad->quadTransform(),
279 surface_quad->visible_rect));
280 if (surface_quad->isClipped())
281 surface_quad_clip_rect.rect.Intersect(surface_quad->clipRect());
282
283 ClipData quads_clip = CalculateClipRect(clip_rect, surface_quad_clip_rect,
284 content_to_target_transform);
285
286 CopyQuadsToPass(quads, last_pass.shared_quad_state_list, surface_transform,
287 quads_clip, dest_pass, surface_id);
247 } else { 288 } else {
248 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id); 289 RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id);
249 290
291 CopySharedQuadState(surface_quad->shared_quad_state,
292 content_to_target_transform, clip_rect, dest_pass);
293
250 SharedQuadState* shared_quad_state = 294 SharedQuadState* shared_quad_state =
251 dest_pass->CreateAndAppendSharedQuadState(); 295 dest_pass->shared_quad_state_list.back();
252 shared_quad_state->CopyFrom(surface_quad->shared_quad_state);
253 shared_quad_state->opacity *= opacity;
254 RenderPassDrawQuad* quad = 296 RenderPassDrawQuad* quad =
255 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); 297 dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
256 quad->SetNew(shared_quad_state, 298 quad->SetNew(shared_quad_state,
257 surface_quad->rect, 299 surface_quad->rect,
258 surface_quad->visible_rect, 300 surface_quad->visible_rect,
259 remapped_pass_id, 301 remapped_pass_id,
260 0, 302 0,
261 gfx::Vector2dF(), 303 gfx::Vector2dF(),
262 gfx::Size(), 304 gfx::Size(),
263 FilterOperations(), 305 FilterOperations(),
264 gfx::Vector2dF(), 306 gfx::Vector2dF(),
265 FilterOperations()); 307 FilterOperations());
266 } 308 }
267 dest_pass->damage_rect = 309 dest_pass->damage_rect =
268 gfx::UnionRects(dest_pass->damage_rect, 310 gfx::UnionRects(dest_pass->damage_rect,
269 MathUtil::MapEnclosingClippedRect( 311 MathUtil::MapEnclosingClippedRect(
270 surface_quad->quadTransform(), 312 surface_quad->quadTransform(),
271 DamageRectForSurface(surface, last_pass, 313 DamageRectForSurface(surface, last_pass,
272 surface_quad->visible_rect))); 314 surface_quad->visible_rect)));
273 315
274 referenced_surfaces_.erase(it); 316 referenced_surfaces_.erase(it);
275 } 317 }
276 318
277 void SurfaceAggregator::CopySharedQuadState( 319 void SurfaceAggregator::CopySharedQuadState(
278 const SharedQuadState* source_sqs, 320 const SharedQuadState* source_sqs,
279 const gfx::Transform& content_to_target_transform, 321 const gfx::Transform& content_to_target_transform,
322 const ClipData& clip_rect,
280 RenderPass* dest_render_pass) { 323 RenderPass* dest_render_pass) {
281 SharedQuadState* copy_shared_quad_state = 324 SharedQuadState* copy_shared_quad_state =
282 dest_render_pass->CreateAndAppendSharedQuadState(); 325 dest_render_pass->CreateAndAppendSharedQuadState();
283 copy_shared_quad_state->CopyFrom(source_sqs); 326 copy_shared_quad_state->CopyFrom(source_sqs);
284 // content_to_target_transform contains any transformation that may exist 327 // content_to_target_transform contains any transformation that may exist
285 // between the context that these quads are being copied from (i.e. the 328 // between the context that these quads are being copied from (i.e. the
286 // surface's draw transform when aggregated from within a surface) to the 329 // surface's draw transform when aggregated from within a surface) to the
287 // target space of the pass. This will be identity except when copying the 330 // target space of the pass. This will be identity except when copying the
288 // root draw pass from a surface into a pass when the surface draw quad's 331 // root draw pass from a surface into a pass when the surface draw quad's
289 // transform is not identity. 332 // transform is not identity.
290 copy_shared_quad_state->content_to_target_transform.ConcatTransform( 333 copy_shared_quad_state->content_to_target_transform.ConcatTransform(
291 content_to_target_transform); 334 content_to_target_transform);
292 if (copy_shared_quad_state->is_clipped) { 335
293 copy_shared_quad_state->clip_rect = MathUtil::MapEnclosingClippedRect( 336 ClipData new_clip_rect = CalculateClipRect(
294 content_to_target_transform, copy_shared_quad_state->clip_rect); 337 clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect),
295 } 338 content_to_target_transform);
339 copy_shared_quad_state->is_clipped = new_clip_rect.is_clipped;
340 copy_shared_quad_state->clip_rect = new_clip_rect.rect;
296 } 341 }
297 342
298 void SurfaceAggregator::CopyQuadsToPass( 343 void SurfaceAggregator::CopyQuadsToPass(
299 const QuadList& source_quad_list, 344 const QuadList& source_quad_list,
300 const SharedQuadStateList& source_shared_quad_state_list, 345 const SharedQuadStateList& source_shared_quad_state_list,
301 const gfx::Transform& content_to_target_transform, 346 const gfx::Transform& content_to_target_transform,
302 float opacity, 347 const ClipData& clip_rect,
303 RenderPass* dest_pass, 348 RenderPass* dest_pass,
304 SurfaceId surface_id) { 349 SurfaceId surface_id) {
305 const SharedQuadState* last_copied_source_shared_quad_state = NULL; 350 const SharedQuadState* last_copied_source_shared_quad_state = NULL;
306 351
307 SharedQuadStateList::ConstIterator sqs_iter = 352 SharedQuadStateList::ConstIterator sqs_iter =
308 source_shared_quad_state_list.begin(); 353 source_shared_quad_state_list.begin();
309 for (const auto& quad : source_quad_list) { 354 for (const auto& quad : source_quad_list) {
310 while (quad->shared_quad_state != *sqs_iter) { 355 while (quad->shared_quad_state != *sqs_iter) {
311 ++sqs_iter; 356 ++sqs_iter;
312 DCHECK(sqs_iter != source_shared_quad_state_list.end()); 357 DCHECK(sqs_iter != source_shared_quad_state_list.end());
313 } 358 }
314 DCHECK_EQ(quad->shared_quad_state, *sqs_iter); 359 DCHECK_EQ(quad->shared_quad_state, *sqs_iter);
315 360
316 if (quad->material == DrawQuad::SURFACE_CONTENT) { 361 if (quad->material == DrawQuad::SURFACE_CONTENT) {
317 const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad); 362 const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
318 HandleSurfaceQuad(surface_quad, opacity, dest_pass); 363 HandleSurfaceQuad(surface_quad, content_to_target_transform, clip_rect,
364 dest_pass);
319 } else { 365 } else {
320 if (quad->shared_quad_state != last_copied_source_shared_quad_state) { 366 if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
321 CopySharedQuadState( 367 CopySharedQuadState(quad->shared_quad_state,
322 quad->shared_quad_state, content_to_target_transform, dest_pass); 368 content_to_target_transform, clip_rect, dest_pass);
323 dest_pass->shared_quad_state_list.back()->opacity *= opacity;
324 last_copied_source_shared_quad_state = quad->shared_quad_state; 369 last_copied_source_shared_quad_state = quad->shared_quad_state;
325 } 370 }
326 if (quad->material == DrawQuad::RENDER_PASS) { 371 if (quad->material == DrawQuad::RENDER_PASS) {
327 const RenderPassDrawQuad* pass_quad = 372 const RenderPassDrawQuad* pass_quad =
328 RenderPassDrawQuad::MaterialCast(quad); 373 RenderPassDrawQuad::MaterialCast(quad);
329 RenderPassId original_pass_id = pass_quad->render_pass_id; 374 RenderPassId original_pass_id = pass_quad->render_pass_id;
330 RenderPassId remapped_pass_id = 375 RenderPassId remapped_pass_id =
331 RemapPassId(original_pass_id, surface_id); 376 RemapPassId(original_pass_id, surface_id);
332 377
333 dest_pass->CopyFromAndAppendRenderPassDrawQuad( 378 dest_pass->CopyFromAndAppendRenderPassDrawQuad(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 410
366 RenderPassId remapped_pass_id = 411 RenderPassId remapped_pass_id =
367 RemapPassId(source.id, surface->surface_id()); 412 RemapPassId(source.id, surface->surface_id());
368 413
369 copy_pass->SetAll(remapped_pass_id, source.output_rect, 414 copy_pass->SetAll(remapped_pass_id, source.output_rect,
370 DamageRectForSurface(surface, source, source.output_rect), 415 DamageRectForSurface(surface, source, source.output_rect),
371 source.transform_to_root_target, 416 source.transform_to_root_target,
372 source.has_transparent_background); 417 source.has_transparent_background);
373 418
374 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, 419 CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
375 gfx::Transform(), 1.f, copy_pass.get(), 420 gfx::Transform(), ClipData(), copy_pass.get(),
376 surface->surface_id()); 421 surface->surface_id());
377 422
378 dest_pass_list_->push_back(copy_pass.Pass()); 423 dest_pass_list_->push_back(copy_pass.Pass());
379 } 424 }
380 } 425 }
381 426
382 void SurfaceAggregator::RemoveUnreferencedChildren() { 427 void SurfaceAggregator::RemoveUnreferencedChildren() {
383 for (const auto& surface : previous_contained_surfaces_) { 428 for (const auto& surface : previous_contained_surfaces_) {
384 if (!contained_surfaces_.count(surface.first)) { 429 if (!contained_surfaces_.count(surface.first)) {
385 SurfaceToResourceChildIdMap::iterator it = 430 SurfaceToResourceChildIdMap::iterator it =
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 void SurfaceAggregator::ReleaseResources(SurfaceId surface_id) { 486 void SurfaceAggregator::ReleaseResources(SurfaceId surface_id) {
442 SurfaceToResourceChildIdMap::iterator it = 487 SurfaceToResourceChildIdMap::iterator it =
443 surface_id_to_resource_child_id_.find(surface_id); 488 surface_id_to_resource_child_id_.find(surface_id);
444 if (it != surface_id_to_resource_child_id_.end()) { 489 if (it != surface_id_to_resource_child_id_.end()) {
445 provider_->DestroyChild(it->second); 490 provider_->DestroyChild(it->second);
446 surface_id_to_resource_child_id_.erase(it); 491 surface_id_to_resource_child_id_.erase(it);
447 } 492 }
448 } 493 }
449 494
450 } // namespace cc 495 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/surface_aggregator.h ('k') | cc/surfaces/surface_aggregator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698