Chromium Code Reviews| Index: cc/output/ca_layer_overlay.cc |
| diff --git a/cc/output/ca_layer_overlay.cc b/cc/output/ca_layer_overlay.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f51c8ff86f2756ddcb39a20a20ded0d98addfc2d |
| --- /dev/null |
| +++ b/cc/output/ca_layer_overlay.cc |
| @@ -0,0 +1,187 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "cc/output/ca_layer_overlay.h" |
| + |
| +#include "cc/quads/io_surface_draw_quad.h" |
| +#include "cc/quads/solid_color_draw_quad.h" |
| +#include "cc/quads/stream_video_draw_quad.h" |
| +#include "cc/quads/texture_draw_quad.h" |
| +#include "cc/quads/tile_draw_quad.h" |
| +#include "cc/resources/resource_provider.h" |
| + |
| +namespace cc { |
| + |
| +namespace { |
| + |
| +bool FromIOSurfaceQuad(ResourceProvider* resource_provider, |
|
alexst (slow to review)
2015/11/12 14:36:18
const ResourceProvider? I don't see anything chang
ccameron
2015/11/12 17:31:47
It's true -- ResourceProvider has lots of const-co
|
| + const IOSurfaceDrawQuad* quad, |
| + CALayerOverlay* ca_layer_overlay) { |
| + unsigned resource_id = quad->io_surface_resource_id(); |
| + if (!resource_provider->IsOverlayCandidate(resource_id)) |
| + return false; |
| + ca_layer_overlay->contents_resource_id = resource_id; |
| + ca_layer_overlay->contents_rect = gfx::RectF(0, 0, 1, 1); |
| + return true; |
| +} |
| + |
| +bool FromStreamVideoQuad(ResourceProvider* resource_provider, |
| + const StreamVideoDrawQuad* quad, |
| + CALayerOverlay* ca_layer_overlay) { |
| + unsigned resource_id = quad->resource_id(); |
| + if (!resource_provider->IsOverlayCandidate(resource_id)) |
| + return false; |
| + ca_layer_overlay->contents_resource_id = resource_id; |
| + // TODO(ccameron): Support merging at least some basic transforms into the |
| + // layer transform. |
| + if (!quad->matrix.IsIdentity()) |
| + return false; |
| + ca_layer_overlay->contents_rect = gfx::RectF(0, 0, 1, 1); |
| + return true; |
| +} |
| + |
| +bool FromSolidColorDrawQuad(const SolidColorDrawQuad* quad, |
| + CALayerOverlay* ca_layer_overlay, |
| + bool* skip) { |
| + // Do not generate quads that are completely transparent. |
| + if (SkColorGetA(quad->color) == 0) { |
| + *skip = true; |
| + return true; |
| + } |
| + ca_layer_overlay->background_color = quad->color; |
| + return true; |
| +} |
| + |
| +bool FromTextureQuad(ResourceProvider* resource_provider, |
| + const TextureDrawQuad* quad, |
| + CALayerOverlay* ca_layer_overlay) { |
| + unsigned resource_id = quad->resource_id(); |
| + if (!resource_provider->IsOverlayCandidate(resource_id)) |
| + return false; |
| + // TODO(ccameron): Merge the y flip into the layer transform. |
| + if (quad->y_flipped) |
| + return false; |
| + ca_layer_overlay->contents_resource_id = resource_id; |
| + ca_layer_overlay->contents_rect = |
| + BoundingRect(quad->uv_top_left, quad->uv_bottom_right); |
| + ca_layer_overlay->background_color = quad->background_color; |
| + return true; |
| +} |
| + |
| +bool FromTileQuad(ResourceProvider* resource_provider, |
| + const TileDrawQuad* quad, |
| + CALayerOverlay* ca_layer_overlay) { |
| + unsigned resource_id = quad->resource_id(); |
| + if (!resource_provider->IsOverlayCandidate(resource_id)) |
| + return false; |
| + ca_layer_overlay->contents_resource_id = resource_id; |
| + ca_layer_overlay->contents_rect = quad->tex_coord_rect; |
| + ca_layer_overlay->contents_rect.Scale(1.f / quad->texture_size.width(), |
| + 1.f / quad->texture_size.height()); |
| + return true; |
| +} |
| + |
| +bool FromDrawQuad(ResourceProvider* resource_provider, |
| + const gfx::RectF& display_rect, |
| + const DrawQuad* quad, |
| + CALayerOverlay* ca_layer_overlay, |
| + bool* skip) { |
| + if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) |
| + return false; |
| + |
| + // TODO(ccameron): Handle 3D transforms. |
| + if (!quad->shared_quad_state->quad_to_target_transform.IsFlat()) |
| + return false; |
| + |
| + // Early-out for invisible quads. |
| + if (quad->shared_quad_state->opacity == 0.f) { |
| + *skip = true; |
| + return true; |
| + } |
| + |
| + // Check rect clipping. |
| + gfx::RectF quad_rect(quad->rect); |
| + if (quad->shared_quad_state->is_clipped) { |
| + gfx::RectF clip_rect = gfx::RectF(quad->shared_quad_state->clip_rect); |
| + gfx::RectF quad_rect_in_clip_space = gfx::RectF(quad->rect); |
| + quad->shared_quad_state->quad_to_target_transform.TransformRect( |
| + &quad_rect_in_clip_space); |
| + quad_rect_in_clip_space.Intersect(display_rect); |
| + // Skip quads that are entirely clipped. |
| + if (!quad_rect_in_clip_space.Intersects(clip_rect)) { |
| + *skip = true; |
| + return true; |
| + } |
| + // Fall back if the clip rect actually has an effect. |
| + // TODO(ccameron): Handle more clip rects. |
| + if (!clip_rect.Contains(quad_rect_in_clip_space)) { |
| + return false; |
| + } |
| + } |
| + |
| + ca_layer_overlay->opacity = quad->shared_quad_state->opacity; |
| + ca_layer_overlay->bounds_size = gfx::SizeF(quad->rect.size()); |
| + ca_layer_overlay->transform.setTranslate(quad->rect.x(), quad->rect.y(), 0); |
| + ca_layer_overlay->transform.postConcat( |
| + quad->shared_quad_state->quad_to_target_transform.matrix()); |
| + |
| + switch (quad->material) { |
| + case DrawQuad::IO_SURFACE_CONTENT: |
| + return FromIOSurfaceQuad(resource_provider, |
| + IOSurfaceDrawQuad::MaterialCast(quad), |
| + ca_layer_overlay); |
| + case DrawQuad::TEXTURE_CONTENT: |
| + return FromTextureQuad(resource_provider, |
| + TextureDrawQuad::MaterialCast(quad), |
| + ca_layer_overlay); |
| + case DrawQuad::TILED_CONTENT: |
| + return FromTileQuad(resource_provider, TileDrawQuad::MaterialCast(quad), |
| + ca_layer_overlay); |
| + case DrawQuad::SOLID_COLOR: |
| + return FromSolidColorDrawQuad(SolidColorDrawQuad::MaterialCast(quad), |
| + ca_layer_overlay, skip); |
| + case DrawQuad::STREAM_VIDEO_CONTENT: |
| + return FromStreamVideoQuad(resource_provider, |
| + StreamVideoDrawQuad::MaterialCast(quad), |
| + ca_layer_overlay); |
| + default: |
| + return false; |
| + break; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +} // namespace |
| + |
| +CALayerOverlay::CALayerOverlay() |
| + : contents_resource_id(0), |
| + opacity(1), |
| + background_color(SK_ColorTRANSPARENT), |
| + transform(SkMatrix44::kIdentity_Constructor) {} |
| + |
| +CALayerOverlay::~CALayerOverlay() {} |
| + |
| +bool ProcessForCALayerOverlays(ResourceProvider* resource_provider, |
| + const gfx::RectF& display_rect, |
| + const QuadList& quad_list, |
| + CALayerOverlayList* ca_layer_overlays) { |
| + for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd(); |
| + ++it) { |
| + const DrawQuad* quad = *it; |
| + CALayerOverlay ca_layer_overlay; |
| + bool skip = false; |
| + if (!FromDrawQuad(resource_provider, display_rect, quad, &ca_layer_overlay, |
| + &skip)) { |
| + ca_layer_overlays->clear(); |
| + return false; |
| + } |
| + if (skip) |
| + continue; |
| + ca_layer_overlays->push_back(ca_layer_overlay); |
| + } |
| + return true; |
| +} |
| + |
| +} // namespace cc |