Commit 86654512 authored by jaydasika's avatar jaydasika Committed by Commit bot

cc :: Reland compute if layer is drawn from property trees

This CL :
  * deletes is_hidden
  * computes if a layer is drawn using the effect tree

BUG=575413
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

patch from issue 1588093004 at patchset 250001 (http://crrev.com/1588093004#ps250001)

Review URL: https://codereview.chromium.org/1633203002

Cr-Commit-Position: refs/heads/master@{#371807}
parent 477b16c4
......@@ -100,8 +100,7 @@ Layer::Layer(const LayerSettings& settings)
replica_layer_(nullptr),
client_(nullptr),
num_unclipped_descendants_(0),
frame_timing_requests_dirty_(false),
is_hidden_from_property_trees_(false) {
frame_timing_requests_dirty_(false) {
if (!settings.use_compositor_animation_timelines) {
layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
layer_animation_controller_->AddValueObserver(this);
......@@ -539,6 +538,10 @@ void Layer::SetOpacity(float opacity) {
SetNeedsCommit();
}
float Layer::EffectiveOpacity() const {
return hide_layer_and_subtree_ ? 0.f : opacity_;
}
bool Layer::OpacityIsAnimating() const {
DCHECK(layer_tree_host_);
return layer_animation_controller_
......@@ -1241,7 +1244,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
layer->set_user_scrollable_vertical(user_scrollable_vertical_);
layer->SetElementId(element_id_);
layer->SetMutableProperties(mutable_properties_);
layer->set_is_hidden_from_property_trees(is_hidden_from_property_trees_);
LayerImpl* scroll_parent = nullptr;
if (scroll_parent_) {
......
......@@ -141,6 +141,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
void SetOpacity(float opacity);
float opacity() const { return opacity_; }
float EffectiveOpacity() const;
bool OpacityIsAnimating() const;
bool HasPotentiallyRunningOpacityAnimation() const;
virtual bool OpacityCanAnimateOnImplThread() const;
......@@ -560,12 +561,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
bool layer_or_descendant_is_drawn();
void set_sorted_for_recursion(bool sorted_for_recursion);
bool sorted_for_recursion();
void set_is_hidden_from_property_trees(bool is_hidden) {
if (is_hidden == is_hidden_from_property_trees_)
return;
is_hidden_from_property_trees_ = is_hidden;
SetNeedsPushProperties();
}
// LayerAnimationValueProvider implementation.
gfx::ScrollOffset ScrollOffsetForAnimation() const override;
......@@ -792,7 +787,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
std::vector<FrameTimingRequest> frame_timing_requests_;
bool frame_timing_requests_dirty_;
bool is_hidden_from_property_trees_;
DISALLOW_COPY_AND_ASSIGN(Layer);
};
......
......@@ -100,8 +100,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
visited_(false),
layer_or_descendant_is_drawn_(false),
layer_or_descendant_has_input_handler_(false),
sorted_for_recursion_(false),
is_hidden_from_property_trees_(false) {
sorted_for_recursion_(false) {
DCHECK_GT(layer_id_, 0);
DCHECK(layer_tree_impl_);
layer_tree_impl_->RegisterLayer(this);
......@@ -659,7 +658,6 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
layer->SetClipTreeIndex(clip_tree_index_);
layer->SetEffectTreeIndex(effect_tree_index_);
layer->set_offset_to_transform_parent(offset_to_transform_parent_);
layer->set_is_hidden_from_property_trees(is_hidden_from_property_trees_);
LayerImpl* scroll_parent = nullptr;
if (scroll_parent_) {
......@@ -962,7 +960,7 @@ void LayerImpl::UpdatePropertyTreeOpacity() {
// started, but might have finished since then on the compositor thread.
if (node->owner_id != id())
return;
node->data.opacity = opacity_;
node->data.opacity = EffectiveOpacity();
effect_tree.set_needs_update(true);
}
}
......@@ -991,7 +989,10 @@ void LayerImpl::OnFilterAnimated(const FilterOperations& filters) {
void LayerImpl::OnOpacityAnimated(float opacity) {
SetOpacity(opacity);
UpdatePropertyTreeOpacity();
// When hide_layer_and_subtree is true, the effective opacity is zero and we
// need not update the opacity on property trees.
if (!hide_layer_and_subtree_)
UpdatePropertyTreeOpacity();
}
void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) {
......@@ -1248,6 +1249,10 @@ void LayerImpl::SetOpacity(float opacity) {
NoteLayerPropertyChangedForSubtree();
}
float LayerImpl::EffectiveOpacity() const {
return hide_layer_and_subtree_ ? 0.f : opacity_;
}
bool LayerImpl::OpacityIsAnimating() const {
LayerAnimationController::ObserverType observer_type =
IsActive() ? LayerAnimationController::ObserverType::ACTIVE
......@@ -1923,11 +1928,13 @@ gfx::Rect LayerImpl::GetScaledEnclosingRectInTargetSpace(float scale) const {
gfx::Rect(scaled_bounds));
}
bool LayerImpl::LayerIsHidden() const {
bool LayerImpl::IsHidden() const {
if (layer_tree_impl()->settings().use_property_trees) {
return is_hidden_from_property_trees_;
EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree;
EffectNode* node = effect_tree.Node(effect_tree_index_);
return node->data.screen_space_opacity == 0.f;
} else {
return hide_layer_and_subtree_ || (parent() && parent()->LayerIsHidden());
return EffectiveOpacity() == 0.f || (parent() && parent()->IsHidden());
}
}
......
......@@ -321,6 +321,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
void SetOpacity(float opacity);
float opacity() const { return opacity_; }
float EffectiveOpacity() const;
bool OpacityIsAnimating() const;
bool HasPotentiallyRunningOpacityAnimation() const;
bool OpacityIsAnimatingOnImplOnly() const;
......@@ -685,13 +686,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
void UpdatePropertyTreeForScrollingAndAnimationIfNeeded();
void set_is_hidden_from_property_trees(bool is_hidden) {
if (is_hidden == is_hidden_from_property_trees_)
return;
is_hidden_from_property_trees_ = is_hidden;
SetNeedsPushProperties();
}
bool LayerIsHidden() const;
bool IsHidden() const;
float GetIdealContentsScale() const;
......@@ -895,7 +890,6 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
// If true, the layer or one of its descendants has a wheel or touch handler.
bool layer_or_descendant_has_input_handler_;
bool sorted_for_recursion_;
bool is_hidden_from_property_trees_;
DISALLOW_COPY_AND_ASSIGN(LayerImpl);
};
......
......@@ -81,9 +81,13 @@ message EffectNodeData {
optional float opacity = 1;
optional float screen_space_opacity = 2;
optional bool has_render_surface = 3;
optional int64 num_copy_requests_in_subtree = 4;
optional int64 transform_id = 5;
optional int64 clip_id = 6;
optional bool has_copy_request = 4;
optional bool has_background_filters = 5;
optional bool is_drawn = 6;
optional bool screen_space_opacity_is_animating = 7;
optional int64 num_copy_requests_in_subtree = 8;
optional int64 transform_id = 9;
optional int64 clip_id = 10;
}
message ScrollNodeData {
......
......@@ -344,7 +344,7 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer,
// The opacity of a layer always applies to its children (either implicitly
// via a render surface or explicitly if the parent preserves 3D), so the
// entire subtree can be skipped if this layer is fully transparent.
return !layer->opacity();
return !layer->EffectiveOpacity();
}
static inline bool SubtreeShouldBeSkipped(Layer* layer,
......@@ -380,7 +380,8 @@ static inline bool SubtreeShouldBeSkipped(Layer* layer,
// In particular, it should not cause the subtree to be skipped.
// Similarly, for layers that might animate opacity using an impl-only
// animation, their subtree should also not be skipped.
return !layer->opacity() && !layer->HasPotentiallyRunningOpacityAnimation() &&
return !layer->EffectiveOpacity() &&
!layer->HasPotentiallyRunningOpacityAnimation() &&
!layer->OpacityCanAnimateOnImplThread();
}
......@@ -430,18 +431,19 @@ static bool LayerShouldBeSkipped(LayerType* layer,
template <typename LayerType>
void FindLayersThatNeedUpdates(
LayerType* layer,
const TransformTree& tree,
bool subtree_is_visible_from_ancestor,
const TransformTree& transform_tree,
const EffectTree& effect_tree,
typename LayerType::LayerListType* update_layer_list,
std::vector<LayerType*>* visible_layer_list) {
DCHECK_GE(layer->effect_tree_index(), 0);
bool layer_is_drawn =
layer->HasCopyRequest() ||
(subtree_is_visible_from_ancestor && !layer->hide_layer_and_subtree());
effect_tree.Node(layer->effect_tree_index())->data.is_drawn;
if (layer->parent() && SubtreeShouldBeSkipped(layer, layer_is_drawn, tree))
if (layer->parent() &&
SubtreeShouldBeSkipped(layer, layer_is_drawn, transform_tree))
return;
if (!LayerShouldBeSkipped(layer, layer_is_drawn, tree)) {
if (!LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree)) {
visible_layer_list->push_back(layer);
update_layer_list->push_back(layer);
}
......@@ -457,7 +459,7 @@ void FindLayersThatNeedUpdates(
}
for (size_t i = 0; i < layer->children().size(); ++i) {
FindLayersThatNeedUpdates(layer->child_at(i), tree, layer_is_drawn,
FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree,
update_layer_list, visible_layer_list);
}
}
......@@ -679,9 +681,8 @@ static void ComputeVisibleRectsUsingPropertyTreesInternal(
can_render_to_separate_surface);
ComputeEffects(&property_trees->effect_tree);
const bool subtree_is_visible_from_ancestor = true;
FindLayersThatNeedUpdates(root_layer, property_trees->transform_tree,
subtree_is_visible_from_ancestor, update_layer_list,
property_trees->effect_tree, update_layer_list,
visible_layer_list);
CalculateVisibleRects<LayerType>(
*visible_layer_list, property_trees->clip_tree,
......
......@@ -668,7 +668,7 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer,
// The opacity of a layer always applies to its children (either implicitly
// via a render surface or explicitly if the parent preserves 3D), so the
// entire subtree can be skipped if this layer is fully transparent.
return !layer->opacity();
return !layer->EffectiveOpacity();
}
static inline void SavePaintPropertiesLayer(LayerImpl* layer) {}
......@@ -1515,7 +1515,7 @@ static void CalculateDrawPropertiesInternal(
// the right results.
const bool layer_is_visible =
data_from_ancestor.subtree_is_visible_from_ancestor &&
!layer->hide_layer_and_subtree();
layer->EffectiveOpacity() != 0;
const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
// The root layer cannot skip CalcDrawProperties.
......@@ -2327,11 +2327,21 @@ enum PropertyTreeOption {
};
void CalculateRenderTargetInternal(LayerImpl* layer,
PropertyTrees* property_trees,
bool subtree_visible_from_ancestor,
bool can_render_to_separate_surface) {
const bool layer_is_visible =
subtree_visible_from_ancestor && !layer->hide_layer_and_subtree();
const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
bool can_render_to_separate_surface,
bool use_property_trees) {
bool layer_is_drawn;
if (use_property_trees) {
DCHECK_GE(layer->effect_tree_index(), 0);
layer_is_drawn =
property_trees->effect_tree.Node(layer->effect_tree_index())
->data.is_drawn;
} else {
layer_is_drawn =
(subtree_visible_from_ancestor && layer->EffectiveOpacity() != 0) ||
layer->HasCopyRequest();
}
// The root layer cannot be skipped.
if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) {
......@@ -2364,7 +2374,8 @@ void CalculateRenderTargetInternal(LayerImpl* layer,
for (size_t i = 0; i < layer->children().size(); ++i) {
CalculateRenderTargetInternal(
LayerTreeHostCommon::get_layer_as_raw_ptr(layer->children(), i),
layer_is_drawn, can_render_to_separate_surface);
property_trees, layer_is_drawn, can_render_to_separate_surface,
use_property_trees);
}
}
......@@ -2395,14 +2406,17 @@ void CalculateRenderSurfaceLayerListInternal(
// |can_render_to_separate_surface| and |current_render_surface_layer_list_id|
// are settings that should stay the same during recursion.
// Layers that are marked as hidden will hide themselves and their subtree.
// Exception: Layers with copy requests, whether hidden or not, must be drawn
// anyway. In this case, we will inform their subtree they are visible to get
// the right results.
const bool layer_is_visible =
subtree_visible_from_ancestor && !layer->hide_layer_and_subtree();
const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
bool layer_is_drawn = false;
if (use_property_trees) {
DCHECK_GE(layer->effect_tree_index(), 0);
layer_is_drawn =
property_trees->effect_tree.Node(layer->effect_tree_index())
->data.is_drawn;
} else {
layer_is_drawn =
(subtree_visible_from_ancestor && layer->EffectiveOpacity() != 0) ||
layer->HasCopyRequest();
}
// The root layer cannot be skipped.
if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) {
......@@ -2451,10 +2465,14 @@ void CalculateRenderSurfaceLayerListInternal(
// target.
layer->render_surface()->set_contributes_to_drawn_surface(false);
} else {
// Even if the |layer_is_drawn|, it only contributes to a drawn surface
// when the |layer_is_visible|.
bool contributes_to_drawn_surface =
use_property_trees
? property_trees->effect_tree.ContributesToDrawnSurface(
layer->effect_tree_index())
: subtree_visible_from_ancestor &&
layer->EffectiveOpacity() != 0.f;
layer->render_surface()->set_contributes_to_drawn_surface(
layer_is_visible);
contributes_to_drawn_surface);
}
// Ignore occlusion from outside the surface when surface contents need to
......@@ -2619,8 +2637,10 @@ void CalculateRenderSurfaceLayerListInternal(
void CalculateRenderTarget(
LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs) {
CalculateRenderTargetInternal(inputs->root_layer, true,
inputs->can_render_to_separate_surface);
CalculateRenderTargetInternal(
inputs->root_layer, inputs->property_trees, true,
inputs->can_render_to_separate_surface,
inputs->verify_property_trees || inputs->use_property_trees);
}
void CalculateRenderSurfaceLayerList(
......
This diff is collapsed.
......@@ -174,7 +174,7 @@ void OcclusionTracker::FinishedRenderTarget(const LayerImpl* finished_target) {
// Readbacks always happen on render targets so we only need to check
// for readbacks here.
bool target_is_only_for_copy_request =
finished_target->HasCopyRequest() && finished_target->LayerIsHidden();
finished_target->HasCopyRequest() && finished_target->IsHidden();
// If the occlusion within the surface can not be applied to things outside of
// the surface's subtree, then clear the occlusion here so it won't be used.
......
......@@ -415,6 +415,10 @@ EffectNodeData::EffectNodeData()
: opacity(1.f),
screen_space_opacity(1.f),
has_render_surface(false),
has_copy_request(false),
has_background_filters(false),
is_drawn(true),
screen_space_opacity_is_animating(false),
num_copy_requests_in_subtree(0),
transform_id(0),
clip_id(0) {}
......@@ -423,6 +427,11 @@ bool EffectNodeData::operator==(const EffectNodeData& other) const {
return opacity == other.opacity &&
screen_space_opacity == other.screen_space_opacity &&
has_render_surface == other.has_render_surface &&
has_copy_request == other.has_copy_request &&
has_background_filters == other.has_background_filters &&
is_drawn == other.is_drawn &&
screen_space_opacity_is_animating ==
other.screen_space_opacity_is_animating &&
num_copy_requests_in_subtree == other.num_copy_requests_in_subtree &&
transform_id == other.transform_id && clip_id == other.clip_id;
}
......@@ -433,6 +442,11 @@ void EffectNodeData::ToProtobuf(proto::TreeNode* proto) const {
data->set_opacity(opacity);
data->set_screen_space_opacity(screen_space_opacity);
data->set_has_render_surface(has_render_surface);
data->set_has_copy_request(has_copy_request);
data->set_has_background_filters(has_background_filters);
data->set_is_drawn(is_drawn);
data->set_screen_space_opacity_is_animating(
screen_space_opacity_is_animating);
data->set_num_copy_requests_in_subtree(num_copy_requests_in_subtree);
data->set_transform_id(transform_id);
data->set_clip_id(clip_id);
......@@ -445,6 +459,10 @@ void EffectNodeData::FromProtobuf(const proto::TreeNode& proto) {
opacity = data.opacity();
screen_space_opacity = data.screen_space_opacity();
has_render_surface = data.has_render_surface();
has_copy_request = data.has_copy_request();
has_background_filters = data.has_background_filters();
is_drawn = data.is_drawn();
screen_space_opacity_is_animating = data.screen_space_opacity_is_animating();
num_copy_requests_in_subtree = data.num_copy_requests_in_subtree();
transform_id = data.transform_id();
clip_id = data.clip_id();
......@@ -1075,16 +1093,54 @@ void EffectTree::UpdateOpacities(EffectNode* node, EffectNode* parent_node) {
node->data.screen_space_opacity *= parent_node->data.screen_space_opacity;
}
void EffectTree::UpdateIsDrawn(EffectNode* node, EffectNode* parent_node) {
// Nodes that have screen space opacity 0 are hidden. So they are not drawn.
// Exceptions:
// 1) Nodes that contribute to copy requests, whether hidden or not, must be
// drawn.
// 2) Nodes that have a background filter.
// 3) Nodes with animating screen space opacity are drawn if their parent is
// drawn irrespective of their opacity.
if (node->data.has_copy_request || node->data.has_background_filters)
node->data.is_drawn = true;
else if (node->data.screen_space_opacity_is_animating)
node->data.is_drawn = parent_node ? parent_node->data.is_drawn : true;
else if (node->data.opacity == 0.f)
node->data.is_drawn = false;
else if (parent_node)
node->data.is_drawn = parent_node->data.is_drawn;
else
node->data.is_drawn = true;
}
void EffectTree::UpdateEffects(int id) {
EffectNode* node = Node(id);
EffectNode* parent_node = parent(node);
UpdateOpacities(node, parent_node);
UpdateIsDrawn(node, parent_node);
}
void EffectTree::ClearCopyRequests() {
for (auto& node : nodes())
for (auto& node : nodes()) {
node.data.num_copy_requests_in_subtree = 0;
node.data.has_copy_request = false;
}
set_needs_update(true);
}
bool EffectTree::ContributesToDrawnSurface(int id) {
// All drawn nodes contribute to drawn surface.
// Exception : Nodes that are hidden and are drawn only for the sake of
// copy requests.
EffectNode* node = Node(id);
EffectNode* parent_node = parent(node);
bool contributes_to_drawn_surface =
node->data.is_drawn &&
(node->data.opacity != 0.f || node->data.has_background_filters);
if (parent_node && !parent_node->data.is_drawn)
contributes_to_drawn_surface = false;
return contributes_to_drawn_surface;
}
void TransformTree::UpdateNodeAndAncestorsHaveIntegerTranslations(
......
......@@ -244,6 +244,10 @@ struct CC_EXPORT EffectNodeData {
float screen_space_opacity;
bool has_render_surface;
bool has_copy_request;
bool has_background_filters;
bool is_drawn;
bool screen_space_opacity_is_animating;
int num_copy_requests_in_subtree;
int transform_id;
int clip_id;
......@@ -499,11 +503,14 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
void ClearCopyRequests();
bool ContributesToDrawnSurface(int id);
void ToProtobuf(proto::PropertyTree* proto) const;
void FromProtobuf(const proto::PropertyTree& proto);
private:
void UpdateOpacities(EffectNode* node, EffectNode* parent_node);
void UpdateIsDrawn(EffectNode* node, EffectNode* parent_node);
};
class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
......
......@@ -520,7 +520,7 @@ bool ShouldCreateRenderSurface(LayerType* layer,
num_descendants_that_draw_content > 0 &&
(layer->DrawsContent() || num_descendants_that_draw_content > 1);
if (layer->opacity() != 1.f && layer->should_flatten_transform() &&
if (layer->EffectiveOpacity() != 1.f && layer->should_flatten_transform() &&
at_least_two_layers_in_subtree_draw_content) {
TRACE_EVENT_INSTANT0(
"cc", "PropertyTreeBuilder::ShouldCreateRenderSurface opacity",
......@@ -557,7 +557,7 @@ bool AddEffectNodeIfNeeded(
LayerType* layer,
DataForRecursion<LayerType>* data_for_children) {
const bool is_root = !layer->parent();
const bool has_transparency = layer->opacity() != 1.f;
const bool has_transparency = layer->EffectiveOpacity() != 1.f;
const bool has_animated_opacity = IsAnimatingOpacity(layer);
const bool should_create_render_surface = ShouldCreateRenderSurface(
layer, data_from_ancestor.compound_transform_since_render_target,
......@@ -580,9 +580,10 @@ bool AddEffectNodeIfNeeded(
EffectNode node;
node.owner_id = layer->id();
node.data.opacity = layer->opacity();
node.data.screen_space_opacity = layer->opacity();
node.data.opacity = layer->EffectiveOpacity();
node.data.has_render_surface = should_create_render_surface;
node.data.has_copy_request = layer->HasCopyRequest();
node.data.has_background_filters = !layer->background_filters().IsEmpty();
if (!is_root) {
// The effect node's transform id is used only when we create a render
......@@ -597,9 +598,9 @@ bool AddEffectNodeIfNeeded(
}
node.data.clip_id = data_from_ancestor.clip_tree_parent;
node.data.screen_space_opacity *=
data_from_ancestor.effect_tree->Node(parent_id)
->data.screen_space_opacity;
EffectNode* parent = data_from_ancestor.effect_tree->Node(parent_id);
node.data.screen_space_opacity_is_animating =
parent->data.screen_space_opacity_is_animating || has_animated_opacity;
} else {
// Root render surface acts the unbounded and untransformed to draw content
// into. Transform node created from root layer (includes device scale
......@@ -607,6 +608,7 @@ bool AddEffectNodeIfNeeded(
// to root render surface's content, but not root render surface itself.
node.data.transform_id = kRootPropertyTreeNodeId;
node.data.clip_id = kRootPropertyTreeNodeId;
node.data.screen_space_opacity_is_animating = has_animated_opacity;
}
data_for_children->effect_tree_parent =
data_for_children->effect_tree->Insert(node, parent_id);
......@@ -646,10 +648,6 @@ void BuildPropertyTreesInternal(
AddClipNodeIfNeeded(data_from_parent, layer, created_render_surface,
created_transform_node, &data_for_children);
data_for_children.is_hidden =
layer->hide_layer_and_subtree() || data_from_parent.is_hidden;
layer->set_is_hidden_from_property_trees(data_for_children.is_hidden);
for (size_t i = 0; i < layer->children().size(); ++i) {
if (!layer->child_at(i)->scroll_parent()) {
DataForRecursionFromChild<LayerType> data_from_child;
......@@ -768,11 +766,11 @@ void BuildPropertyTreesTopLevelInternal(
property_trees->needs_rebuild = false;
// The transform tree is kept up-to-date as it is built, but the
// combined_clips stored in the clip tree aren't computed during tree
// building.
// combined_clips stored in the clip tree and the screen_space_opacity and
// is_drawn in the effect tree aren't computed during tree building.
property_trees->transform_tree.set_needs_update(false);
property_trees->clip_tree.set_needs_update(true);
property_trees->effect_tree.set_needs_update(false);
property_trees->effect_tree.set_needs_update(true);
}
void PropertyTreeBuilder::BuildPropertyTrees(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment