123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- // Copyright 2014 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/layers/surface_layer_impl.h"
- #include <stdint.h>
- #include <algorithm>
- #include <utility>
- #include "base/memory/ptr_util.h"
- #include "base/synchronization/waitable_event.h"
- #include "base/trace_event/traced_value.h"
- #include "cc/debug/debug_colors.h"
- #include "cc/layers/append_quads_data.h"
- #include "cc/trees/layer_tree_impl.h"
- #include "cc/trees/occlusion.h"
- #include "components/viz/common/quads/solid_color_draw_quad.h"
- #include "components/viz/common/quads/surface_draw_quad.h"
- namespace cc {
- // static
- std::unique_ptr<SurfaceLayerImpl> SurfaceLayerImpl::Create(
- LayerTreeImpl* tree_impl,
- int id,
- UpdateSubmissionStateCB update_submission_state_callback) {
- return base::WrapUnique(new SurfaceLayerImpl(
- tree_impl, id, std::move(update_submission_state_callback)));
- }
- // static
- std::unique_ptr<SurfaceLayerImpl> SurfaceLayerImpl::Create(
- LayerTreeImpl* tree_impl,
- int id) {
- return base::WrapUnique(new SurfaceLayerImpl(
- tree_impl, id, base::BindRepeating([](bool, base::WaitableEvent* event) {
- if (event)
- event->Signal();
- })));
- }
- SurfaceLayerImpl::SurfaceLayerImpl(
- LayerTreeImpl* tree_impl,
- int id,
- UpdateSubmissionStateCB update_submission_state_callback)
- : LayerImpl(tree_impl, id),
- update_submission_state_callback_(
- std::move(update_submission_state_callback)) {}
- SurfaceLayerImpl::~SurfaceLayerImpl() {
- if (update_submission_state_callback_)
- update_submission_state_callback_.Run(false, nullptr);
- }
- std::unique_ptr<LayerImpl> SurfaceLayerImpl::CreateLayerImpl(
- LayerTreeImpl* tree_impl) const {
- return SurfaceLayerImpl::Create(tree_impl, id(),
- std::move(update_submission_state_callback_));
- }
- void SurfaceLayerImpl::SetRange(const viz::SurfaceRange& surface_range,
- absl::optional<uint32_t> deadline_in_frames) {
- if (surface_range_ == surface_range &&
- deadline_in_frames_ == deadline_in_frames) {
- return;
- }
- if (surface_range_.end() != surface_range.end() &&
- surface_range.end().local_surface_id().is_valid()) {
- TRACE_EVENT_WITH_FLOW2(
- TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
- "LocalSurfaceId.Embed.Flow",
- TRACE_ID_GLOBAL(
- surface_range.end().local_surface_id().embed_trace_id()),
- TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
- "ImplSetSurfaceId", "surface_id", surface_range.end().ToString());
- }
- surface_range_ = surface_range;
- deadline_in_frames_ = deadline_in_frames;
- NoteLayerPropertyChanged();
- }
- void SurfaceLayerImpl::SetStretchContentToFillBounds(bool stretch_content) {
- if (stretch_content_to_fill_bounds_ == stretch_content)
- return;
- stretch_content_to_fill_bounds_ = stretch_content;
- NoteLayerPropertyChanged();
- }
- void SurfaceLayerImpl::SetSurfaceHitTestable(bool surface_hit_testable) {
- if (surface_hit_testable_ == surface_hit_testable)
- return;
- surface_hit_testable_ = surface_hit_testable;
- NoteLayerPropertyChanged();
- }
- void SurfaceLayerImpl::SetHasPointerEventsNone(bool has_pointer_events_none) {
- if (has_pointer_events_none_ == has_pointer_events_none)
- return;
- has_pointer_events_none_ = has_pointer_events_none;
- NoteLayerPropertyChanged();
- }
- void SurfaceLayerImpl::SetIsReflection(bool is_reflection) {
- if (is_reflection_ == is_reflection)
- return;
- is_reflection_ = is_reflection;
- NoteLayerPropertyChanged();
- }
- void SurfaceLayerImpl::PushPropertiesTo(LayerImpl* layer) {
- LayerImpl::PushPropertiesTo(layer);
- SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
- layer_impl->SetRange(surface_range_, std::move(deadline_in_frames_));
- // Unless the client explicitly specifies otherwise, don't block on
- // |surface_range_| more than once.
- deadline_in_frames_ = 0u;
- layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
- layer_impl->SetSurfaceHitTestable(surface_hit_testable_);
- layer_impl->SetHasPointerEventsNone(has_pointer_events_none_);
- layer_impl->SetIsReflection(is_reflection_);
- }
- bool SurfaceLayerImpl::WillDraw(
- DrawMode draw_mode,
- viz::ClientResourceProvider* resource_provider) {
- bool will_draw = LayerImpl::WillDraw(draw_mode, resource_provider);
- // If we have a change in WillDraw (meaning that visibility has changed), we
- // want to inform the VideoFrameSubmitter to start or stop submitting
- // compositor frames.
- if (will_draw_ != will_draw) {
- will_draw_ = will_draw;
- if (update_submission_state_callback_) {
- // If we're in synchronous composite mode, ensure that we finish running
- // the update submission state callback. This is important to avoid race
- // conditions in web_tests which results from a thread hop that happens in
- // the callback.
- if (layer_tree_impl()->IsInSynchronousComposite()) {
- base::WaitableEvent event;
- update_submission_state_callback_.Run(will_draw, &event);
- event.Wait();
- } else {
- update_submission_state_callback_.Run(will_draw, nullptr);
- }
- }
- }
- return will_draw;
- }
- void SurfaceLayerImpl::AppendQuads(viz::CompositorRenderPass* render_pass,
- AppendQuadsData* append_quads_data) {
- AppendRainbowDebugBorder(render_pass);
- float device_scale_factor = layer_tree_impl()->device_scale_factor();
- gfx::Rect quad_rect(gfx::ScaleToEnclosingRect(
- gfx::Rect(bounds()), device_scale_factor, device_scale_factor));
- gfx::Rect visible_quad_rect =
- draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
- gfx::Rect(bounds()));
- visible_quad_rect = gfx::ScaleToEnclosingRect(
- visible_quad_rect, device_scale_factor, device_scale_factor);
- visible_quad_rect = gfx::IntersectRects(quad_rect, visible_quad_rect);
- if (visible_quad_rect.IsEmpty())
- return;
- viz::SharedQuadState* shared_quad_state =
- render_pass->CreateAndAppendSharedQuadState();
- PopulateScaledSharedQuadState(shared_quad_state, device_scale_factor,
- contents_opaque());
- if (surface_range_.IsValid()) {
- auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
- quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
- surface_range_, background_color(),
- stretch_content_to_fill_bounds_);
- quad->is_reflection = is_reflection_;
- // Add the primary surface ID as a dependency.
- append_quads_data->activation_dependencies.push_back(surface_range_.end());
- if (deadline_in_frames_) {
- if (!append_quads_data->deadline_in_frames)
- append_quads_data->deadline_in_frames = 0u;
- append_quads_data->deadline_in_frames = std::max(
- *append_quads_data->deadline_in_frames, *deadline_in_frames_);
- } else {
- append_quads_data->use_default_lower_bound_deadline = true;
- }
- } else {
- auto* quad =
- render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
- background_color(), false /* force_anti_aliasing_off */);
- }
- // Unless the client explicitly specifies otherwise, don't block on
- // |surface_range_| more than once.
- deadline_in_frames_ = 0u;
- }
- bool SurfaceLayerImpl::is_surface_layer() const {
- return true;
- }
- gfx::Rect SurfaceLayerImpl::GetEnclosingVisibleRectInTargetSpace() const {
- return GetScaledEnclosingVisibleRectInTargetSpace(
- layer_tree_impl()->device_scale_factor());
- }
- void SurfaceLayerImpl::GetDebugBorderProperties(SkColor4f* color,
- float* width) const {
- if (color)
- *color = DebugColors::SurfaceLayerBorderColor();
- if (width)
- *width = DebugColors::SurfaceLayerBorderWidth(
- layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1);
- }
- void SurfaceLayerImpl::AppendRainbowDebugBorder(
- viz::CompositorRenderPass* render_pass) {
- if (!ShowDebugBorders(DebugBorderType::SURFACE))
- return;
- viz::SharedQuadState* shared_quad_state =
- render_pass->CreateAndAppendSharedQuadState();
- PopulateSharedQuadState(shared_quad_state, contents_opaque());
- float border_width = DebugColors::SurfaceLayerBorderWidth(
- layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1);
- SkColor4f colors[] = {
- {1.0f, 0.0f, 0.0f, 0.5f}, // Red.
- {1.0f, 0.65f, 0.0f, 0.5f}, // Orange.
- {1.0f, 1.0f, 0.0f, 0.5f}, // Yellow.
- {0.0f, 0.5f, 0.0f, 0.5f}, // Green.
- {0.0f, 0.0f, 1.0f, 0.50f}, // Blue.
- {0.93f, 0.51f, 0.93f, 0.5f}, // Violet.
- };
- const int kNumColors = std::size(colors);
- const int kStripeWidth = 300;
- const int kStripeHeight = 300;
- for (int i = 0;; ++i) {
- // For horizontal lines.
- int x = kStripeWidth * i;
- int width = std::min(kStripeWidth, bounds().width() - x - 1);
- // For vertical lines.
- int y = kStripeHeight * i;
- int height = std::min(kStripeHeight, bounds().height() - y - 1);
- gfx::Rect top(x, 0, width, border_width);
- gfx::Rect bottom(x, bounds().height() - border_width, width, border_width);
- gfx::Rect left(0, y, border_width, height);
- gfx::Rect right(bounds().width() - border_width, y, border_width, height);
- if (top.IsEmpty() && left.IsEmpty())
- break;
- if (!top.IsEmpty()) {
- bool force_anti_aliasing_off = false;
- auto* top_quad =
- render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- top_quad->SetNew(shared_quad_state, top, top, colors[i % kNumColors],
- force_anti_aliasing_off);
- auto* bottom_quad =
- render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- bottom_quad->SetNew(shared_quad_state, bottom, bottom,
- colors[kNumColors - 1 - (i % kNumColors)],
- force_anti_aliasing_off);
- if (contents_opaque()) {
- // Draws a stripe filling the layer vertically with the same color and
- // width as the horizontal stipes along the layer's top border.
- auto* solid_quad =
- render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- // The inner fill is more transparent then the border.
- static const float kFillOpacity = 0.1f;
- SkColor4f fill_color = colors[i % kNumColors];
- fill_color.fA *= kFillOpacity;
- gfx::Rect fill_rect(x, 0, width, bounds().height());
- solid_quad->SetNew(shared_quad_state, fill_rect, fill_rect, fill_color,
- force_anti_aliasing_off);
- }
- }
- if (!left.IsEmpty()) {
- bool force_anti_aliasing_off = false;
- auto* left_quad =
- render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- left_quad->SetNew(shared_quad_state, left, left,
- colors[kNumColors - 1 - (i % kNumColors)],
- force_anti_aliasing_off);
- auto* right_quad =
- render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
- right_quad->SetNew(shared_quad_state, right, right,
- colors[i % kNumColors], force_anti_aliasing_off);
- }
- }
- }
- void SurfaceLayerImpl::AsValueInto(base::trace_event::TracedValue* dict) const {
- LayerImpl::AsValueInto(dict);
- dict->SetString("surface_range", surface_range_.ToString());
- }
- const char* SurfaceLayerImpl::LayerTypeAsString() const {
- return "cc::SurfaceLayerImpl";
- }
- } // namespace cc
|