File: paint_worklet.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (156 lines) | stat: -rw-r--r-- 6,436 bytes parent folder | download | duplicates (5)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_PAINT_WORKLET_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_PAINT_WORKLET_H_

#include <memory>

#include "third_party/blink/renderer/core/css/css_syntax_definition.h"
#include "third_party/blink/renderer/core/workers/worklet.h"
#include "third_party/blink/renderer/modules/csspaint/document_paint_definition.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"

namespace blink {

class CSSPaintImageGeneratorImpl;

// Manages a paint worklet:
// https://drafts.css-houdini.org/css-paint-api/#dom-css-paintworklet
class MODULES_EXPORT PaintWorklet : public Worklet,
                                    public Supplement<LocalDOMWindow> {
 public:
  static const char kSupplementName[];

  // At this moment, paint worklet allows at most two global scopes at any time.
  static const wtf_size_t kNumGlobalScopesPerThread;
  static PaintWorklet* From(LocalDOMWindow&);

  explicit PaintWorklet(LocalDOMWindow&);

  PaintWorklet(const PaintWorklet&) = delete;
  PaintWorklet& operator=(const PaintWorklet&) = delete;

  ~PaintWorklet() override;

  void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*);
  // The |container_size| is without subpixel snapping.
  scoped_refptr<Image> Paint(const String& name,
                             const ImageResourceObserver&,
                             const gfx::SizeF& container_size,
                             const GCedCSSStyleValueVector*);

  int WorkletId() const { return worklet_id_; }
  bool IsOffMainThread() const { return is_paint_off_thread_; }

  void Trace(Visitor*) const override;

  // The DocumentDefinitionMap tracks definitions registered via
  // registerProperty; definitions are only considered valid once all global
  // scopes have registered the same definition for the same thread.
  typedef HashMap<String, std::unique_ptr<DocumentPaintDefinition>>
      DocumentDefinitionMap;
  DocumentDefinitionMap& GetDocumentDefinitionMap() {
    return document_definition_map_;
  }

  // Used for main-thread CSS Paint. Registers a definition for a given painter,
  // ensuring that the same CSSPaintDefinition is registered on all global
  // scopes.
  void RegisterCSSPaintDefinition(const String& name,
                                  CSSPaintDefinition*,
                                  ExceptionState&);

  // Used for off-thread CSS Paint. In this mode we are not responsible for
  // tracking whether a definition is valid - this method should only be called
  // once all global scopes have registered the same |DocumentPaintDefinition|
  // for the same |name|.
  void RegisterMainThreadDocumentPaintDefinition(
      const String& name,
      Vector<CSSPropertyID> native_properties,
      Vector<String> custom_properties,
      Vector<CSSSyntaxDefinition> input_argument_types,
      double alpha);

  HeapVector<Member<WorkletGlobalScopeProxy>>& GetGlobalScopesForTesting() {
    return proxies_;
  }

  void AddGlobalScopeForTesting() { proxies_.push_back(CreateGlobalScope()); }

  bool NeedsToCreateGlobalScopeForTesting() {
    return NeedsToCreateGlobalScope();
  }

  void SetProxyClientForTesting(PaintWorkletProxyClient* proxy_client) {
    proxy_client_ = proxy_client;
  }

  void ResetIsPaintOffThreadForTesting();

 protected:
  // Since paint worklet has more than one global scope, we MUST override this
  // function and provide our own selection logic.
  wtf_size_t SelectGlobalScope() final;
  wtf_size_t GetActiveGlobalScopeForTesting() { return active_global_scope_; }

 private:
  friend class PaintWorkletTest;

  // Implements Worklet.
  bool NeedsToCreateGlobalScope() final;
  WorkletGlobalScopeProxy* CreateGlobalScope() final;

  // This function calculates the number of paints to use before switching
  // global scopes.
  virtual int GetPaintsBeforeSwitching();
  // This function calculates the next global scope to switch to.
  virtual wtf_size_t SelectNewGlobalScope();

  Member<PaintWorkletPendingGeneratorRegistry> pending_generator_registry_;

  // Used for both main and off-thread CSS Paint.
  // For the main thread, this map tracks the definitions created on the main
  // thread, and ensures that all global scopes have the same definition.
  //
  // For the off thread case, both the worklet and main thread have this map.
  // The worklet version is responsible for verifying that all global scopes
  // have the same definition, and the main thread version relies on that.
  //
  // The value of an entry being nullptr means that it is an invalid definition.
  DocumentDefinitionMap document_definition_map_;

  // The last document paint frame a paint worklet painted on. This is used to
  // tell when we begin painting on a new frame.
  size_t active_frame_count_ = 0u;
  // The current global scope being used for painting.
  wtf_size_t active_global_scope_ = 0u;
  // The number of paint calls remaining before Paint will select a new global
  // scope. SelectGlobalScope resets this at the beginning of each frame.
  int paints_before_switching_global_scope_;

  // An atomic sequence number to ensure that it is unique for each paint
  // worklet. This id is integrated in the PaintWorkletInput which will be used
  // in PaintWorkletPaintDispatcher::Paint, to identify the right painter, to
  // paint the image.
  int worklet_id_;

  // The proxy client associated with this PaintWorklet. We keep a reference in
  // to ensure that all global scopes get the same proxy client.
  Member<PaintWorkletProxyClient> proxy_client_;

  // When running layout test, paint worklet has to be on the main thread
  // because "enable-threaded-compositing" is off by default. However, some unit
  // tests may be testing the functionality of the APIs when the paint worklet
  // is off the main thread.
  bool is_paint_off_thread_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_PAINT_WORKLET_H_