1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/layers/mirror_layer_impl.h"
#include <memory>
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/occlusion.h"
#include "components/viz/common/quads/compositor_render_pass_draw_quad.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "third_party/skia/include/core/SkColor.h"
namespace cc {
MirrorLayerImpl::MirrorLayerImpl(LayerTreeImpl* tree_impl, int id)
: LayerImpl(tree_impl, id) {}
MirrorLayerImpl::~MirrorLayerImpl() = default;
mojom::LayerType MirrorLayerImpl::GetLayerType() const {
return mojom::LayerType::kMirror;
}
std::unique_ptr<LayerImpl> MirrorLayerImpl::CreateLayerImpl(
LayerTreeImpl* tree_impl) const {
return MirrorLayerImpl::Create(tree_impl, id());
}
void MirrorLayerImpl::AppendQuads(const AppendQuadsContext& context,
viz::CompositorRenderPass* render_pass,
AppendQuadsData* append_quads_data) {
// TODO(mohsen): Currently, effects on the mirrored layer (e.g mask and
// opacity) are ignored. Consider applying them here.
auto* mirrored_layer = layer_tree_impl()->LayerById(mirrored_layer_id_);
if (!mirrored_layer) {
// If the mirrored layer is missing then just fill in layer as opaque black.
// This isn't supposed to happen but is happening in
// https://crbug.com/1423091.
viz::SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
PopulateSharedQuadState(shared_quad_state, /*contents_opaque=*/false);
auto* quad =
render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
quad->SetNew(shared_quad_state, shared_quad_state->quad_layer_rect,
shared_quad_state->visible_quad_layer_rect, SkColors::kBlack,
/*anti_aliasing_off=*/false);
return;
}
auto* mirrored_render_surface =
GetEffectTree().GetRenderSurface(mirrored_layer->effect_tree_index());
gfx::Rect content_rect = mirrored_render_surface->content_rect();
gfx::Rect unoccluded_content_rect =
draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
content_rect);
if (unoccluded_content_rect.IsEmpty())
return;
const bool contents_opaque = false;
viz::SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
// TODO(crbug.com/40176440): Support 2D scales in mirror layers.
PopulateScaledSharedQuadStateWithContentRects(
shared_quad_state, mirrored_layer->GetIdealContentsScaleKey(),
content_rect, content_rect, contents_opaque);
AppendDebugBorderQuad(render_pass, content_rect, shared_quad_state,
append_quads_data);
viz::ResourceId mask_resource_id = viz::kInvalidResourceId;
gfx::RectF mask_uv_rect;
gfx::Size mask_texture_size;
auto* mirrored_effect_node = mirrored_render_surface->OwningEffectNode();
auto* quad =
render_pass->CreateAndAppendDrawQuad<viz::CompositorRenderPassDrawQuad>();
quad->SetNew(shared_quad_state, content_rect, unoccluded_content_rect,
mirrored_layer_render_pass_id(), mask_resource_id, mask_uv_rect,
mask_texture_size, mirrored_effect_node->surface_contents_scale,
gfx::PointF(), gfx::RectF(gfx::Rect(content_rect.size())),
!layer_tree_impl()->settings().enable_edge_anti_aliasing, 0.f);
}
void MirrorLayerImpl::PushPropertiesTo(LayerImpl* layer) {
LayerImpl::PushPropertiesTo(layer);
auto* mirror_layer = static_cast<MirrorLayerImpl*>(layer);
mirror_layer->SetMirroredLayerId(mirrored_layer_id_);
}
gfx::Rect MirrorLayerImpl::GetDamageRect() const {
// TOOD(mohsen): Currently, the whole layer is marked as damaged. We should
// only consider the damage from the mirrored layer.
return gfx::Rect(bounds());
}
gfx::Rect MirrorLayerImpl::GetEnclosingVisibleRectInTargetSpace() const {
LayerImpl* mirrored_layer = layer_tree_impl()->LayerById(mirrored_layer_id_);
float scale =
mirrored_layer ? mirrored_layer->GetIdealContentsScaleKey() : 1.0f;
return GetScaledEnclosingVisibleRectInTargetSpace(scale);
}
} // namespace cc
|