File: native_css_paint_definition.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (128 lines) | stat: -rw-r--r-- 4,426 bytes parent folder | download | duplicates (6)
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/csspaint/nativepaint/native_css_paint_definition.h"

#include "third_party/blink/renderer/core/animation/animation_time_delta.h"
#include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/animation/interpolable_value.h"
#include "third_party/blink/renderer/core/css/css_value.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"

namespace blink {

NativeCssPaintDefinition::NativeCssPaintDefinition(
    LocalFrame* local_root,
    PaintWorkletInput::PaintWorkletInputType type)
    : NativePaintDefinition(local_root, type) {}

bool NativeCssPaintDefinition::CanGetValueFromKeyframe(
    const Element* element,
    const PropertySpecificKeyframe* frame,
    const KeyframeEffectModelBase* model,
    ValueFilter filter) {
  if (model->IsStringKeyframeEffectModel()) {
    DCHECK(frame->IsCSSPropertySpecificKeyframe());
    const CSSValue* value = To<CSSPropertySpecificKeyframe>(frame)->Value();
    return filter(element, value, nullptr);
  } else {
    DCHECK(frame->IsTransitionPropertySpecificKeyframe());
    const TransitionKeyframe::PropertySpecificKeyframe* keyframe =
        To<TransitionKeyframe::PropertySpecificKeyframe>(frame);
    InterpolableValue* value =
        keyframe->GetValue()->Value().interpolable_value.Get();
    return filter(element, nullptr, value);
  }
}

Animation* NativeCssPaintDefinition::GetAnimationForProperty(
    const Element* element,
    const CSSProperty& property,
    ValueFilter filter) {
  if (!element->GetElementAnimations()) {
    return nullptr;
  }
  Animation* compositable_animation = nullptr;

  // We'd composite only if it is the only animation of its type on
  // this element.
  unsigned count = 0;
  for (const auto& animation : element->GetElementAnimations()->Animations()) {
    if (animation.key->CalculateAnimationPlayState() ==
            V8AnimationPlayState::Enum::kIdle ||
        !animation.key->Affects(*element, property)) {
      continue;
    }
    count++;
    compositable_animation = animation.key;
  }
  if (!compositable_animation || count > 1) {
    return nullptr;
  }

  if (!AnimationIsValidForPaintWorklets(compositable_animation, element,
                                        property, filter)) {
    return nullptr;
  }

  return compositable_animation;
}

bool NativeCssPaintDefinition::AnimationIsValidForPaintWorklets(
    Animation* compositable_animation,
    const Element* element,
    const CSSProperty& property,
    ValueFilter filter) {
  const AnimationEffect* effect = compositable_animation->effect();

  // TODO(crbug.com/1429770): Implement positive delay fix for bgcolor.
  if (effect->SpecifiedTiming().start_delay.AsTimeValue().InSecondsF() > 0.f) {
    if (property.PropertyID() != CSSPropertyID::kClipPath) {
      return false;
    }
  }

  DCHECK(effect->IsKeyframeEffect());
  const KeyframeEffectModelBase* model =
      static_cast<const KeyframeEffect*>(effect)->Model();
  if (model->AffectedByUnderlyingAnimations()) {
    return false;
  }
  const PropertySpecificKeyframeVector* frames =
      model->GetPropertySpecificKeyframes(PropertyHandle(property));
  DCHECK_GE(frames->size(), 2u);
  for (const auto& frame : *frames) {
    if (!CanGetValueFromKeyframe(element, frame, model, filter)) {
      return false;
    }
  }
  return true;
}

bool NativeCssPaintDefinition::DefaultValueFilter(
    const Element* element,
    const CSSValue* value,
    const InterpolableValue* interpolable_value) {
  return value || interpolable_value;
}

std::optional<double> NativeCssPaintDefinition::Progress(
    const std::optional<double>& main_thread_progress,
    const CompositorPaintWorkletJob::AnimatedPropertyValues&
        animated_property_values) {
  std::optional<double> progress = main_thread_progress;

  // Override the progress from the main thread if the animation has been
  // started on the compositor.
  if (!animated_property_values.empty()) {
    DCHECK_EQ(animated_property_values.size(), 1u);
    const auto& entry = animated_property_values.begin();
    progress = entry->second.float_value.value();
  }

  return progress;
}

}  // namespace blink