OLD | NEW |
---|---|
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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/layers/render_surface_impl.h" | 5 #include "cc/layers/render_surface_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "cc/base/filter_operations.h" | 13 #include "cc/base/filter_operations.h" |
14 #include "cc/base/math_util.h" | 14 #include "cc/base/math_util.h" |
15 #include "cc/debug/debug_colors.h" | 15 #include "cc/debug/debug_colors.h" |
16 #include "cc/layers/append_quads_data.h" | |
16 #include "cc/layers/layer_impl.h" | 17 #include "cc/layers/layer_impl.h" |
18 #include "cc/quads/content_draw_quad_base.h" | |
17 #include "cc/quads/debug_border_draw_quad.h" | 19 #include "cc/quads/debug_border_draw_quad.h" |
18 #include "cc/quads/render_pass.h" | 20 #include "cc/quads/render_pass.h" |
19 #include "cc/quads/render_pass_draw_quad.h" | 21 #include "cc/quads/render_pass_draw_quad.h" |
20 #include "cc/quads/shared_quad_state.h" | 22 #include "cc/quads/shared_quad_state.h" |
23 #include "cc/quads/solid_color_draw_quad.h" | |
21 #include "cc/trees/damage_tracker.h" | 24 #include "cc/trees/damage_tracker.h" |
22 #include "cc/trees/draw_property_utils.h" | 25 #include "cc/trees/draw_property_utils.h" |
23 #include "cc/trees/effect_node.h" | 26 #include "cc/trees/effect_node.h" |
24 #include "cc/trees/layer_tree_impl.h" | 27 #include "cc/trees/layer_tree_impl.h" |
25 #include "cc/trees/occlusion.h" | 28 #include "cc/trees/occlusion.h" |
26 #include "cc/trees/transform_node.h" | 29 #include "cc/trees/transform_node.h" |
27 #include "third_party/skia/include/core/SkImageFilter.h" | 30 #include "third_party/skia/include/core/SkImageFilter.h" |
28 #include "ui/gfx/geometry/rect_conversions.h" | 31 #include "ui/gfx/geometry/rect_conversions.h" |
29 #include "ui/gfx/transform.h" | 32 #include "ui/gfx/transform.h" |
30 | 33 |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 if (layer_tree_impl_->debug_state().show_debug_borders) { | 393 if (layer_tree_impl_->debug_state().show_debug_borders) { |
391 DebugBorderDrawQuad* debug_border_quad = | 394 DebugBorderDrawQuad* debug_border_quad = |
392 render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>(); | 395 render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>(); |
393 debug_border_quad->SetNew(shared_quad_state, content_rect(), | 396 debug_border_quad->SetNew(shared_quad_state, content_rect(), |
394 visible_layer_rect, GetDebugBorderColor(), | 397 visible_layer_rect, GetDebugBorderColor(), |
395 GetDebugBorderWidth()); | 398 GetDebugBorderWidth()); |
396 } | 399 } |
397 | 400 |
398 ResourceId mask_resource_id = 0; | 401 ResourceId mask_resource_id = 0; |
399 gfx::Size mask_texture_size; | 402 gfx::Size mask_texture_size; |
400 gfx::Vector2dF mask_uv_scale; | 403 gfx::RectF mask_uv_rect; |
401 gfx::Vector2dF surface_contents_scale = | 404 gfx::Vector2dF surface_contents_scale = |
402 OwningEffectNode()->surface_contents_scale; | 405 OwningEffectNode()->surface_contents_scale; |
403 LayerImpl* mask_layer = MaskLayer(); | 406 PictureLayerImpl* mask_layer = static_cast<PictureLayerImpl*>(MaskLayer()); |
404 if (mask_layer && mask_layer->DrawsContent() && | 407 if (mask_layer && mask_layer->DrawsContent() && |
405 !mask_layer->bounds().IsEmpty()) { | 408 !mask_layer->bounds().IsEmpty()) { |
406 // The software renderer applies mask layer and blending in the wrong | 409 // The software renderer applies mask layer and blending in the wrong |
407 // order but kDstIn doesn't commute with masking. It is okay to not | 410 // order but kDstIn doesn't commute with masking. It is okay to not |
408 // support this configuration because kDstIn was introduced to replace | 411 // support this configuration because kDstIn was introduced to replace |
409 // mask layers. | 412 // mask layers. |
410 DCHECK(BlendMode() != SkBlendMode::kDstIn) | 413 DCHECK(BlendMode() != SkBlendMode::kDstIn) |
411 << "kDstIn blend mode with mask layer is unsupported."; | 414 << "kDstIn blend mode with mask layer is unsupported."; |
415 if (mask_layer->mask_type() == Layer::LayerMaskType::MULTI_TEXTURE_MASK) { | |
416 TileMaskLayer(render_pass, shared_quad_state, visible_layer_rect); | |
417 return; | |
418 } | |
412 mask_layer->GetContentsResourceId(&mask_resource_id, &mask_texture_size); | 419 mask_layer->GetContentsResourceId(&mask_resource_id, &mask_texture_size); |
413 gfx::SizeF unclipped_mask_target_size = gfx::ScaleSize( | 420 gfx::SizeF unclipped_mask_target_size = gfx::ScaleSize( |
414 gfx::SizeF(OwningEffectNode()->unscaled_mask_target_size), | 421 gfx::SizeF(OwningEffectNode()->unscaled_mask_target_size), |
415 surface_contents_scale.x(), surface_contents_scale.y()); | 422 surface_contents_scale.x(), surface_contents_scale.y()); |
416 mask_uv_scale = gfx::Vector2dF(1.0f / unclipped_mask_target_size.width(), | 423 // Convert content_rect from target space to normalized space. |
417 1.0f / unclipped_mask_target_size.height()); | 424 // Where unclipped_mask_target_size maps to gfx::Size(1, 1). |
425 mask_uv_rect = gfx::ScaleRect(gfx::RectF(content_rect()), | |
426 1.0f / unclipped_mask_target_size.width(), | |
427 1.0f / unclipped_mask_target_size.height()); | |
418 } | 428 } |
419 | 429 |
430 gfx::RectF tex_coord_rect(0, 0, content_rect().width(), | |
enne (OOO)
2017/03/28 14:10:22
nit: could just be tex_coord_rect(content_rect().s
sunxd
2017/03/29 16:00:23
Done.
| |
431 content_rect().height()); | |
420 RenderPassDrawQuad* quad = | 432 RenderPassDrawQuad* quad = |
421 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 433 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
422 quad->SetNew( | 434 quad->SetNew(shared_quad_state, content_rect(), visible_layer_rect, |
423 shared_quad_state, content_rect(), visible_layer_rect, GetRenderPassId(), | 435 GetRenderPassId(), mask_resource_id, mask_uv_rect, |
424 mask_resource_id, gfx::ScaleRect(gfx::RectF(content_rect()), | 436 mask_texture_size, surface_contents_scale, FiltersOrigin(), |
425 mask_uv_scale.x(), mask_uv_scale.y()), | 437 tex_coord_rect); |
426 mask_texture_size, surface_contents_scale, FiltersOrigin(), gfx::RectF()); | 438 } |
439 | |
440 void RenderSurfaceImpl::TileMaskLayer(RenderPass* render_pass, | |
441 SharedQuadState* shared_quad_state, | |
442 const gfx::Rect& visible_layer_rect) { | |
443 DCHECK(MaskLayer()); | |
444 DCHECK(Filters().IsEmpty()); | |
445 | |
446 LayerImpl* mask_layer = MaskLayer(); | |
447 gfx::Vector2dF owning_layer_to_surface_contents_scale = | |
448 OwningEffectNode()->surface_contents_scale; | |
449 std::unique_ptr<RenderPass> temp_render_pass = RenderPass::Create(); | |
450 AppendQuadsData temp_append_quads_data; | |
451 mask_layer->AppendQuads(temp_render_pass.get(), &temp_append_quads_data); | |
452 | |
453 auto* temp_quad = temp_render_pass->quad_list.front(); | |
454 if (!temp_quad) | |
455 return; | |
456 gfx::Transform mask_quad_to_surface_contents = | |
457 temp_quad->shared_quad_state->quad_to_target_transform; | |
458 // Draw transform of a mask layer should be a 2d scale. | |
459 DCHECK(mask_quad_to_surface_contents.IsScale2d()); | |
460 gfx::Vector2dF mask_quad_to_surface_contents_scale = | |
461 mask_quad_to_surface_contents.Scale2d(); | |
462 shared_quad_state->quad_to_target_transform.matrix().preScale( | |
463 mask_quad_to_surface_contents_scale.x(), | |
464 mask_quad_to_surface_contents_scale.y(), 1.f); | |
465 shared_quad_state->quad_layer_bounds = | |
466 gfx::ScaleToCeiledSize(shared_quad_state->quad_layer_bounds, | |
467 1.f / mask_quad_to_surface_contents_scale.x(), | |
468 1.f / mask_quad_to_surface_contents_scale.y()); | |
469 shared_quad_state->visible_quad_layer_rect = gfx::ToEnclosedRect( | |
enne (OOO)
2017/03/28 14:10:22
gfx::ScaleToEnclosingRect, here and elsewhere
sunxd
2017/03/29 16:00:23
Done.
| |
470 gfx::ScaleRect(gfx::RectF(shared_quad_state->visible_quad_layer_rect), | |
471 mask_quad_to_surface_contents_scale.x(), | |
472 mask_quad_to_surface_contents_scale.y())); | |
473 gfx::Rect content_rect_in_coverage_space = gfx::ToEnclosedRect(gfx::ScaleRect( | |
474 gfx::RectF(content_rect()), 1.f / mask_quad_to_surface_contents_scale.x(), | |
475 1.f / mask_quad_to_surface_contents_scale.y())); | |
476 gfx::Rect visible_layer_rect_in_coverage_space = gfx::ToEnclosedRect( | |
477 gfx::ScaleRect(gfx::RectF(visible_layer_rect), | |
478 1.f / mask_quad_to_surface_contents_scale.x(), | |
479 1.f / mask_quad_to_surface_contents_scale.y())); | |
480 | |
481 for (auto* temp_quad : temp_render_pass->quad_list) { | |
482 gfx::Rect quad_rect = temp_quad->rect; | |
483 gfx::Rect render_quad_rect = quad_rect; | |
484 if (!quad_rect.Intersects(content_rect_in_coverage_space)) | |
485 continue; | |
486 render_quad_rect = | |
487 gfx::IntersectRects(quad_rect, content_rect_in_coverage_space); | |
488 gfx::RectF quad_rect_in_surface_contents_space = gfx::ScaleRect( | |
489 gfx::RectF(render_quad_rect), mask_quad_to_surface_contents_scale.x(), | |
490 mask_quad_to_surface_contents_scale.y()); | |
491 gfx::RectF quad_rect_in_non_normalized_texture_space = | |
492 quad_rect_in_surface_contents_space; | |
493 quad_rect_in_non_normalized_texture_space.Offset( | |
494 -content_rect().OffsetFromOrigin()); | |
enne (OOO)
2017/03/28 14:10:22
Is this logic with a content rect not at the origi
sunxd
2017/03/29 16:00:23
It's tested in LayoutTests/compositing/overflow/ma
enne (OOO)
2017/03/29 16:07:25
Can you add a cc unit test? I don't think layou te
sunxd
2017/03/30 13:56:37
I'll work on this on a separate patch just because
enne (OOO)
2017/03/30 14:36:52
I think this detail here about the content rect no
sunxd
2017/04/04 13:58:04
Done.
| |
495 | |
496 switch (temp_quad->material) { | |
497 case DrawQuad::TILED_CONTENT: { | |
498 DCHECK_EQ(1U, temp_quad->resources.count); | |
499 RenderPassDrawQuad* quad = | |
500 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
501 | |
502 gfx::Size mask_texture_size = | |
503 static_cast<ContentDrawQuadBase*>(temp_quad)->texture_size; | |
504 gfx::RectF temp_tex_coord_rect = | |
505 static_cast<ContentDrawQuadBase*>(temp_quad)->tex_coord_rect; | |
506 gfx::Transform coverage_to_non_normalized_mask = | |
507 gfx::Transform(SkMatrix44(SkMatrix::MakeRectToRect( | |
508 RectToSkRect(quad_rect), RectFToSkRect(temp_tex_coord_rect), | |
509 SkMatrix::kFill_ScaleToFit))); | |
510 gfx::Transform coverage_to_normalized_mask = | |
511 coverage_to_non_normalized_mask; | |
512 coverage_to_normalized_mask.matrix().postScale( | |
513 1.f / mask_texture_size.width(), 1.f / mask_texture_size.height(), | |
514 1.f); | |
515 gfx::RectF mask_uv_rect = gfx::RectF(render_quad_rect); | |
516 coverage_to_normalized_mask.TransformRect(&mask_uv_rect); | |
517 | |
518 quad->SetNew(shared_quad_state, render_quad_rect, | |
519 gfx::IntersectRects(temp_quad->visible_rect, | |
520 visible_layer_rect_in_coverage_space), | |
521 GetRenderPassId(), temp_quad->resources.ids[0], | |
522 mask_uv_rect, mask_texture_size, | |
523 owning_layer_to_surface_contents_scale, FiltersOrigin(), | |
524 quad_rect_in_non_normalized_texture_space); | |
525 } break; | |
526 case DrawQuad::SOLID_COLOR: { | |
527 if (!static_cast<SolidColorDrawQuad*>(temp_quad)->color) | |
528 continue; | |
529 SkAlpha solid = SK_AlphaOPAQUE; | |
530 DCHECK_EQ( | |
531 SkColorGetA(static_cast<SolidColorDrawQuad*>(temp_quad)->color), | |
532 solid); | |
533 RenderPassDrawQuad* quad = | |
534 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
535 quad->SetNew(shared_quad_state, render_quad_rect, | |
536 gfx::IntersectRects(temp_quad->visible_rect, | |
537 visible_layer_rect_in_coverage_space), | |
538 GetRenderPassId(), 0, gfx::RectF(), gfx::Size(), | |
539 owning_layer_to_surface_contents_scale, FiltersOrigin(), | |
540 quad_rect_in_non_normalized_texture_space); | |
541 } break; | |
542 case DrawQuad::DEBUG_BORDER: | |
543 NOTIMPLEMENTED(); | |
544 break; | |
545 default: | |
546 NOTREACHED(); | |
547 break; | |
548 } | |
549 } | |
427 } | 550 } |
428 | 551 |
429 } // namespace cc | 552 } // namespace cc |
OLD | NEW |