| Index: cc/layers/render_surface_impl.cc
|
| diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc
|
| index 1e20a4dada9921287713aea12bc92272842479f5..4a37f72ea6ca1f287094e617d248eb362e527688 100644
|
| --- a/cc/layers/render_surface_impl.cc
|
| +++ b/cc/layers/render_surface_impl.cc
|
| @@ -13,11 +13,14 @@
|
| #include "cc/base/filter_operations.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/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());
|
| }
|
|
|
| + gfx::RectF tex_coord_rect(gfx::Rect(content_rect().size()));
|
| 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(),
|
| + tex_coord_rect);
|
| +}
|
| +
|
| +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::ScaleToEnclosedRect(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::ScaleToEnclosedRect(
|
| + 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::ScaleToEnclosedRect(
|
| + 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
|
|
|