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