Index: cc/layers/render_surface_impl.cc |
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc |
index 4b6355631c136132effbc5ef218dd955f3d3e009..b2e380185a4be133dc0c4cc858a5012adc834653 100644 |
--- a/cc/layers/render_surface_impl.cc |
+++ b/cc/layers/render_surface_impl.cc |
@@ -12,13 +12,16 @@ |
#include "base/strings/stringprintf.h" |
#include "cc/base/math_util.h" |
#include "cc/debug/debug_colors.h" |
+#include "cc/layers/append_quads_data.h" |
#include "cc/layers/layer_impl.h" |
#include "cc/layers/render_pass_sink.h" |
#include "cc/output/filter_operations.h" |
+#include "cc/quads/content_draw_quad_base.h" |
#include "cc/quads/debug_border_draw_quad.h" |
#include "cc/quads/render_pass.h" |
#include "cc/quads/render_pass_draw_quad.h" |
#include "cc/quads/shared_quad_state.h" |
+#include "cc/quads/solid_color_draw_quad.h" |
#include "cc/trees/damage_tracker.h" |
#include "cc/trees/draw_property_utils.h" |
#include "cc/trees/effect_node.h" |
@@ -396,10 +399,10 @@ void RenderSurfaceImpl::AppendQuads(RenderPass* render_pass, |
ResourceId mask_resource_id = 0; |
gfx::Size mask_texture_size; |
- gfx::Vector2dF mask_uv_scale; |
+ gfx::RectF mask_uv_rect; |
gfx::Vector2dF surface_contents_scale = |
OwningEffectNode()->surface_contents_scale; |
- LayerImpl* mask_layer = MaskLayer(); |
+ PictureLayerImpl* mask_layer = static_cast<PictureLayerImpl*>(MaskLayer()); |
if (mask_layer && mask_layer->DrawsContent() && |
!mask_layer->bounds().IsEmpty()) { |
// The software renderer applies mask layer and blending in the wrong |
@@ -408,21 +411,139 @@ void RenderSurfaceImpl::AppendQuads(RenderPass* render_pass, |
// mask layers. |
DCHECK(BlendMode() != SkBlendMode::kDstIn) |
<< "kDstIn blend mode with mask layer is unsupported."; |
+ if (mask_layer->mask_type() == Layer::LayerMaskType::MULTI_TEXTURE_MASK) { |
+ TileMaskLayer(render_pass, shared_quad_state, visible_layer_rect); |
+ return; |
+ } |
mask_layer->GetContentsResourceId(&mask_resource_id, &mask_texture_size); |
gfx::SizeF unclipped_mask_target_size = gfx::ScaleSize( |
gfx::SizeF(OwningEffectNode()->unscaled_mask_target_size), |
surface_contents_scale.x(), surface_contents_scale.y()); |
- mask_uv_scale = gfx::Vector2dF(1.0f / unclipped_mask_target_size.width(), |
- 1.0f / unclipped_mask_target_size.height()); |
+ // Convert content_rect from target space to normalized space. |
+ // Where unclipped_mask_target_size maps to gfx::Size(1, 1). |
+ mask_uv_rect = gfx::ScaleRect(gfx::RectF(content_rect()), |
+ 1.0f / unclipped_mask_target_size.width(), |
+ 1.0f / unclipped_mask_target_size.height()); |
} |
RenderPassDrawQuad* quad = |
render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
- quad->SetNew( |
- shared_quad_state, content_rect(), visible_layer_rect, GetRenderPassId(), |
- mask_resource_id, gfx::ScaleRect(gfx::RectF(content_rect()), |
- mask_uv_scale.x(), mask_uv_scale.y()), |
- mask_texture_size, surface_contents_scale, FiltersOrigin(), gfx::RectF()); |
+ quad->SetNew(shared_quad_state, content_rect(), visible_layer_rect, |
+ GetRenderPassId(), mask_resource_id, mask_uv_rect, |
+ mask_texture_size, surface_contents_scale, FiltersOrigin(), |
+ 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
|
+} |
+ |
+void RenderSurfaceImpl::TileMaskLayer(RenderPass* render_pass, |
+ SharedQuadState* shared_quad_state, |
+ const gfx::Rect& visible_layer_rect) { |
+ DCHECK(MaskLayer()); |
+ DCHECK(Filters().IsEmpty()); |
+ |
+ LayerImpl* mask_layer = MaskLayer(); |
+ gfx::Vector2dF owning_layer_to_surface_contents_scale = |
+ OwningEffectNode()->surface_contents_scale; |
+ std::unique_ptr<RenderPass> temp_render_pass = RenderPass::Create(); |
+ AppendQuadsData temp_append_quads_data; |
+ mask_layer->AppendQuads(temp_render_pass.get(), &temp_append_quads_data); |
+ |
+ auto* temp_quad = temp_render_pass->quad_list.front(); |
+ if (!temp_quad) |
+ return; |
+ gfx::Transform mask_quad_to_surface_contents = |
+ temp_quad->shared_quad_state->quad_to_target_transform; |
+ // Draw transform of a mask layer should be a 2d scale. |
+ DCHECK(mask_quad_to_surface_contents.IsScale2d()); |
+ gfx::Vector2dF mask_quad_to_surface_contents_scale = |
+ mask_quad_to_surface_contents.Scale2d(); |
+ shared_quad_state->quad_to_target_transform.matrix().preScale( |
+ mask_quad_to_surface_contents_scale.x(), |
+ mask_quad_to_surface_contents_scale.y(), 1.f); |
+ shared_quad_state->quad_layer_bounds = |
+ gfx::ScaleToCeiledSize(shared_quad_state->quad_layer_bounds, |
+ 1.f / mask_quad_to_surface_contents_scale.x(), |
+ 1.f / mask_quad_to_surface_contents_scale.y()); |
+ shared_quad_state->visible_quad_layer_rect = gfx::ToEnclosedRect( |
+ gfx::ScaleRect(gfx::RectF(shared_quad_state->visible_quad_layer_rect), |
+ mask_quad_to_surface_contents_scale.x(), |
+ mask_quad_to_surface_contents_scale.y())); |
+ gfx::Rect content_rect_in_coverage_space = gfx::ToEnclosedRect(gfx::ScaleRect( |
+ gfx::RectF(content_rect()), 1.f / mask_quad_to_surface_contents_scale.x(), |
+ 1.f / mask_quad_to_surface_contents_scale.y())); |
+ gfx::Rect visible_layer_rect_in_coverage_space = gfx::ToEnclosedRect( |
+ gfx::ScaleRect(gfx::RectF(visible_layer_rect), |
+ 1.f / mask_quad_to_surface_contents_scale.x(), |
+ 1.f / mask_quad_to_surface_contents_scale.y())); |
+ |
+ for (auto* temp_quad : temp_render_pass->quad_list) { |
+ gfx::Rect quad_rect = temp_quad->rect; |
+ gfx::Rect render_quad_rect = quad_rect; |
+ if (!quad_rect.Intersects(content_rect_in_coverage_space)) |
+ continue; |
+ render_quad_rect = |
+ gfx::IntersectRects(quad_rect, content_rect_in_coverage_space); |
+ gfx::RectF quad_rect_in_surface_contents_space = gfx::ScaleRect( |
+ gfx::RectF(render_quad_rect), mask_quad_to_surface_contents_scale.x(), |
+ mask_quad_to_surface_contents_scale.y()); |
+ gfx::RectF quad_rect_in_non_normalized_texture_space = |
+ quad_rect_in_surface_contents_space; |
+ quad_rect_in_non_normalized_texture_space.Offset( |
+ -content_rect().OffsetFromOrigin()); |
+ |
+ switch (temp_quad->material) { |
+ case DrawQuad::TILED_CONTENT: { |
+ DCHECK_EQ(1U, temp_quad->resources.count); |
+ RenderPassDrawQuad* quad = |
+ render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
+ |
+ gfx::Size mask_texture_size = |
+ static_cast<ContentDrawQuadBase*>(temp_quad)->texture_size; |
+ gfx::RectF temp_tex_coord_rect = |
+ static_cast<ContentDrawQuadBase*>(temp_quad)->tex_coord_rect; |
+ gfx::Transform coverage_to_non_normalized_mask = |
+ gfx::Transform(SkMatrix44(SkMatrix::MakeRectToRect( |
+ RectToSkRect(quad_rect), RectFToSkRect(temp_tex_coord_rect), |
+ SkMatrix::kFill_ScaleToFit))); |
+ gfx::Transform coverage_to_normalized_mask = |
+ coverage_to_non_normalized_mask; |
+ coverage_to_normalized_mask.matrix().postScale( |
+ 1.f / mask_texture_size.width(), 1.f / mask_texture_size.height(), |
+ 1.f); |
+ gfx::RectF mask_uv_rect = gfx::RectF(render_quad_rect); |
+ coverage_to_normalized_mask.TransformRect(&mask_uv_rect); |
+ |
+ quad->SetNew(shared_quad_state, render_quad_rect, |
+ gfx::IntersectRects(temp_quad->visible_rect, |
+ visible_layer_rect_in_coverage_space), |
+ GetRenderPassId(), temp_quad->resources.ids[0], |
+ mask_uv_rect, mask_texture_size, |
+ owning_layer_to_surface_contents_scale, FiltersOrigin(), |
+ quad_rect_in_non_normalized_texture_space); |
+ } break; |
+ case DrawQuad::SOLID_COLOR: { |
+ if (!static_cast<SolidColorDrawQuad*>(temp_quad)->color) |
+ continue; |
+ SkAlpha solid = SK_AlphaOPAQUE; |
+ DCHECK_EQ( |
+ SkColorGetA(static_cast<SolidColorDrawQuad*>(temp_quad)->color), |
+ solid); |
+ RenderPassDrawQuad* quad = |
+ render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); |
+ quad->SetNew(shared_quad_state, render_quad_rect, |
+ gfx::IntersectRects(temp_quad->visible_rect, |
+ visible_layer_rect_in_coverage_space), |
+ GetRenderPassId(), 0, gfx::RectF(), gfx::Size(), |
+ owning_layer_to_surface_contents_scale, FiltersOrigin(), |
+ quad_rect_in_non_normalized_texture_space); |
+ } break; |
+ case DrawQuad::DEBUG_BORDER: |
+ NOTIMPLEMENTED(); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ } |
} |
} // namespace cc |