#ifndef CC_LAYERS_RENDER_SURFACE_IMPL_H_
#define CC_LAYERS_RENDER_SURFACE_IMPL_H_
#include <stddef.h>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "cc/cc_export.h"
#include "cc/layers/draw_mode.h"
#include "cc/layers/layer_collections.h"
#include "cc/paint/element_id.h"
#include "cc/trees/occlusion.h"
#include "cc/trees/property_tree.h"
#include "components/viz/common/quads/compositor_render_pass.h"
#include "components/viz/common/quads/shared_quad_state.h"
#include "components/viz/common/surfaces/subtree_capture_id.h"
#include "ui/gfx/geometry/mask_filter_info.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/transform.h"
namespace cc {
struct AppendQuadsContext;
class AppendQuadsData;
class DamageTracker;
class FilterOperations;
class Occlusion;
class LayerImpl;
class LayerTreeImpl;
class PictureLayerImpl;
struct RenderSurfacePropertyChangedFlags {
public:
RenderSurfacePropertyChangedFlags() = default;
RenderSurfacePropertyChangedFlags(bool self_changed, bool ancestor_changed)
: self_changed_(self_changed), ancestor_changed_(ancestor_changed) {}
bool self_changed() const { return self_changed_; }
bool ancestor_changed() const { return ancestor_changed_; }
private:
bool self_changed_ = false;
bool ancestor_changed_ = false;
};
class CC_EXPORT RenderSurfaceImpl {
public:
RenderSurfaceImpl(LayerTreeImpl* layer_tree_impl, ElementId stable_id);
RenderSurfaceImpl(const RenderSurfaceImpl&) = delete;
virtual ~RenderSurfaceImpl();
RenderSurfaceImpl& operator=(const RenderSurfaceImpl&) = delete;
RenderSurfaceImpl* render_target();
const RenderSurfaceImpl* render_target() const;
gfx::RectF DrawableContentRect() const;
void SetDrawOpacity(float opacity) {
draw_properties_.draw_opacity = opacity;
}
float draw_opacity() const { return draw_properties_.draw_opacity; }
void SetMaskFilterInfo(const gfx::MaskFilterInfo& mask_filter_info,
bool is_fast_rounded_corner) {
draw_properties_.mask_filter_info = mask_filter_info;
draw_properties_.is_fast_rounded_corner = is_fast_rounded_corner;
}
const gfx::MaskFilterInfo& mask_filter_info() const {
return draw_properties_.mask_filter_info;
}
bool is_fast_rounded_corner() const {
return draw_properties_.is_fast_rounded_corner;
}
SkBlendMode BlendMode() const;
void SetNearestOcclusionImmuneAncestor(const RenderSurfaceImpl* surface) {
nearest_occlusion_immune_ancestor_ = surface;
}
const RenderSurfaceImpl* nearest_occlusion_immune_ancestor() const {
return nearest_occlusion_immune_ancestor_;
}
SkColor4f GetDebugBorderColor() const;
float GetDebugBorderWidth() const;
void SetDrawTransform(const gfx::Transform& draw_transform,
const gfx::Vector2dF& pixel_alignment_offset) {
draw_properties_.draw_transform = draw_transform;
draw_properties_.pixel_alignment_offset = pixel_alignment_offset;
}
const gfx::Transform& draw_transform() const {
return draw_properties_.draw_transform;
}
const gfx::Vector2dF& pixel_alignment_offset() const {
return draw_properties_.pixel_alignment_offset;
}
void SetScreenSpaceTransform(const gfx::Transform& screen_space_transform) {
draw_properties_.screen_space_transform = screen_space_transform;
}
const gfx::Transform& screen_space_transform() const {
return draw_properties_.screen_space_transform;
}
void SetIsClipped(bool is_clipped) {
draw_properties_.is_clipped = is_clipped;
}
bool is_clipped() const { return draw_properties_.is_clipped; }
void SetClipRect(const gfx::Rect& clip_rect);
gfx::Rect clip_rect() const { return draw_properties_.clip_rect; }
bool contributes_to_drawn_surface() const {
return contributes_to_drawn_surface_;
}
void set_contributes_to_drawn_surface(bool contributes_to_drawn_surface) {
contributes_to_drawn_surface_ = contributes_to_drawn_surface;
}
void set_common_ancestor_clip_id(int id) {
DCHECK_NE(id, ClipTreeIndex());
DCHECK(id < ClipTreeIndex() || id == kInvalidPropertyNodeId);
common_ancestor_clip_id_ = id;
}
int common_ancestor_clip_id() const {
return common_ancestor_clip_id_ == kInvalidPropertyNodeId
? ClipTreeIndex()
: common_ancestor_clip_id_;
}
bool has_contributing_layer_that_escapes_clip() const {
return common_ancestor_clip_id_ != kInvalidPropertyNodeId;
}
void set_is_render_surface_list_member(bool is_render_surface_list_member) {
is_render_surface_list_member_ = is_render_surface_list_member;
}
bool is_render_surface_list_member() const {
return is_render_surface_list_member_;
}
void set_intersects_damage_under(bool intersects_damage_under) {
intersects_damage_under_ = intersects_damage_under;
}
bool intersects_damage_under() const { return intersects_damage_under_; }
void CalculateContentRectFromAccumulatedContentRect(int max_texture_size);
void SetContentRectToViewport();
void SetContentRectForTesting(const gfx::Rect& rect);
gfx::Rect content_rect() const { return draw_properties_.content_rect; }
gfx::Rect view_transition_capture_content_rect() const {
return view_transition_capture_content_rect_;
}
void ClearAccumulatedContentRect();
void AccumulateContentRectFromContributingLayer(
LayerImpl* contributing_layer,
const base::flat_set<blink::ViewTransitionToken>&
capture_view_transition_tokens);
void AccumulateContentRectFromContributingRenderSurface(
RenderSurfaceImpl* contributing_surface,
const base::flat_set<blink::ViewTransitionToken>&
capture_view_transition_tokens);
gfx::Rect accumulated_content_rect() const {
return accumulated_content_rect_;
}
void increment_num_contributors() { num_contributors_++; }
void decrement_num_contributors() {
num_contributors_--;
DCHECK_GE(num_contributors_, 0);
}
void reset_num_contributors() { num_contributors_ = 0; }
int num_contributors() const { return num_contributors_; }
const Occlusion& occlusion_in_content_space() const {
return occlusion_in_content_space_;
}
void set_occlusion_in_content_space(const Occlusion& occlusion) {
occlusion_in_content_space_ = occlusion;
}
ElementId id() const { return id_; }
viz::CompositorRenderPassId render_pass_id() const {
return viz::CompositorRenderPassId(id().GetInternalValue());
}
viz::CompositorRenderPassId view_transition_capture_render_pass_id() const {
return viz::CompositorRenderPassId(
RemapElementIdToCcNamespace(id()).GetInternalValue());
}
bool HasMaskingContributingSurface() const;
const FilterOperations& Filters() const;
const FilterOperations& BackdropFilters() const;
std::optional<SkPath> BackdropFilterBounds() const;
LayerImpl* BackdropMaskLayer() const;
gfx::Transform SurfaceScale() const;
bool TrilinearFiltering() const;
bool HasCopyRequest() const;
viz::SubtreeCaptureId SubtreeCaptureId() const;
gfx::Size SubtreeSize() const;
bool ShouldCacheRenderSurface() const;
bool CopyOfOutputRequired() const;
RenderSurfacePropertyChangedFlags GetPropertyChangeFlags() const;
void ApplyPropertyChangeFlags(const RenderSurfacePropertyChangedFlags& flags);
void ResetPropertyChangedFlags();
bool SurfacePropertyChanged() const;
bool AncestorPropertyChanged() const;
void NoteAncestorPropertyChanged();
bool HasDamageFromeContributingContent() const;
DamageTracker* damage_tracker() const { return damage_tracker_.get(); }
gfx::Rect GetDamageRect() const;
std::unique_ptr<viz::CompositorRenderPass> CreateRenderPass(
const base::flat_set<blink::ViewTransitionToken>&
capture_view_transition_tokens = {});
std::unique_ptr<viz::CompositorRenderPass>
CreateViewTransitionCaptureRenderPass(
const base::flat_set<blink::ViewTransitionToken>&
capture_view_transition_tokens = {});
viz::ResourceId GetMaskResourceFromLayer(PictureLayerImpl* mask_layer,
gfx::Size* mask_texture_size,
gfx::RectF* mask_uv_rect) const;
void AppendQuads(const AppendQuadsContext& context,
viz::CompositorRenderPass* render_pass,
AppendQuadsData* append_quads_data);
int TransformTreeIndex() const;
int ClipTreeIndex() const;
void set_effect_tree_index(int index) { effect_tree_index_ = index; }
int EffectTreeIndex() const;
const EffectNode* OwningEffectNode() const;
EffectNode* OwningEffectNodeMutableForTest() const;
bool IsViewTransitionElement() const;
const viz::ViewTransitionElementResourceId& ViewTransitionElementResourceId()
const;
bool has_view_transition_capture_contributions() const {
return has_view_transition_capture_contributions_;
}
void set_has_view_transition_capture_contributions(bool flag) {
has_view_transition_capture_contributions_ = flag;
}
private:
void SetContentRect(const gfx::Rect& content_rect);
gfx::Rect CalculateClippedAccumulatedContentRect();
gfx::Rect CalculateExpandedClipForFilters(
const gfx::Transform& target_to_surface);
void TileMaskLayer(viz::CompositorRenderPass* render_pass,
viz::SharedQuadState* shared_quad_state,
const gfx::Rect& unoccluded_content_rect);
std::unique_ptr<viz::CompositorRenderPass> CreateRenderPassCommon(
viz::CompositorRenderPassId id,
const gfx::Rect& output_rect);
bool ShouldClip() const;
raw_ptr<LayerTreeImpl> layer_tree_impl_;
ElementId id_;
int effect_tree_index_;
const int stable_id_for_shared_quad_state_ = 0;
struct DrawProperties {
DrawProperties();
~DrawProperties();
float draw_opacity = 1.0f;
gfx::Transform draw_transform;
gfx::Vector2dF pixel_alignment_offset;
gfx::Transform screen_space_transform;
gfx::Rect content_rect;
gfx::Rect clip_rect;
bool is_clipped : 1 = false;
gfx::MaskFilterInfo mask_filter_info;
bool is_fast_rounded_corner : 1 = false;
};
DrawProperties draw_properties_;
gfx::Rect accumulated_content_rect_;
int num_contributors_ = 0;
int common_ancestor_clip_id_ = kInvalidPropertyNodeId;
bool surface_property_changed_ : 1 = false;
bool ancestor_property_changed_ : 1 = false;
bool contributes_to_drawn_surface_ : 1 = false;
bool is_render_surface_list_member_ : 1 = false;
bool intersects_damage_under_ : 1 = true;
Occlusion occlusion_in_content_space_;
raw_ptr<const RenderSurfaceImpl, AcrossTasksDanglingUntriaged>
nearest_occlusion_immune_ancestor_ = nullptr;
std::unique_ptr<DamageTracker> damage_tracker_;
std::vector<LayerImpl*> deferred_contributing_layers_;
gfx::Rect view_transition_capture_content_rect_;
bool has_view_transition_capture_contributions_ = false;
};
}
#endif