File: transferable_resource_tracker.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,122,156 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 (123 lines) | stat: -rw-r--r-- 4,993 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
// 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.

#ifndef COMPONENTS_VIZ_SERVICE_TRANSITIONS_TRANSFERABLE_RESOURCE_TRACKER_H_
#define COMPONENTS_VIZ_SERVICE_TRANSITIONS_TRANSFERABLE_RESOURCE_TRACKER_H_

#include <map>
#include <memory>
#include <optional>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "components/viz/common/resources/release_callback.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/service/surfaces/surface_saved_frame.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"

namespace viz {

// This class is a simple transferable resource generator and lifetime tracker.
// Note that TransferableResourceTracker uses reserved range ResourceIds.
class VIZ_SERVICE_EXPORT TransferableResourceTracker {
 public:
  // This represents a resource that is positioned somewhere on screen.
  struct VIZ_SERVICE_EXPORT PositionedResource {
    TransferableResource resource;
  };

  // A SurfaceSavedFrame can be converted to a ResourceFrame via
  // ImportResources.
  struct VIZ_SERVICE_EXPORT ResourceFrame {
    ResourceFrame();
    ResourceFrame(ResourceFrame&& other);
    ~ResourceFrame();

    ResourceFrame& operator=(ResourceFrame&& other);

    // The cached resource for each shared element. The entries here are
    // optional since copy request for an element may fail or a
    // [src_element, dst_element] has a null src_element.
    std::vector<std::optional<PositionedResource>> shared;

    // A map from renderer generated ViewTransitionElementResourceId to the
    // corresponding cached resource. The resources are the same as |shared|
    // above.
    base::flat_map<ViewTransitionElementResourceId, TransferableResource>
        element_id_to_resource;
  };

  explicit TransferableResourceTracker(
      ReservedResourceIdTracker* id_tracker);
  TransferableResourceTracker(const TransferableResourceTracker&) = delete;
  ~TransferableResourceTracker();

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

  // This call converts a SurfaceSavedFrame into a ResourceFrame by converting
  // each of the resources into a TransferableResource. Note that `this` keeps
  // a ref on each of the TransferableResources returned in the ResourceFrame.
  // The ref count can be managed by calls to RefResource and UnrefResource
  // below. Note that a convenience function, `ReturnFrame`, is also provided
  // below which will unref every resource in a given ResourceFrame. Using the
  // convenience function is not a guarantee that the resources will be
  // released: it only removes one ref from each resource. The resources will
  // be released when the ref count reaches 0.
  // TODO(vmpstr): Instead of providing a convenience function, we should
  // convert ResourceFrame to be RAII so that it can be automatically
  // "returned".
  ResourceFrame ImportResources(SurfaceSavedFrame::FrameResult frame_result,
                                CompositorFrameTransitionDirective directive);

  // Return a frame back to the tracker. This unrefs all of the resources.
  void ReturnFrame(const ResourceFrame& frame);

  // Ref count management for the resources returned by `ImportResources`.
  void RefResource(ResourceId id);
  void UnrefResource(ResourceId id,
                     int count,
                     const gpu::SyncToken& sync_token);

  bool is_empty() const { return managed_resources_.empty(); }

 private:
  friend class TransferableResourceTrackerTest;

  PositionedResource ImportResource(
      SurfaceSavedFrame::OutputCopyResult output_copy);

  static_assert(std::is_same<decltype(kInvalidResourceId.GetUnsafeValue()),
                             uint32_t>::value,
                "ResourceId underlying type should be uint32_t");

  struct TransferableResourceHolder {
    using ResourceReleaseCallback =
        base::OnceCallback<void(const TransferableResource&,
                                const gpu::SyncToken&)>;

    TransferableResourceHolder();
    TransferableResourceHolder(const TransferableResource& resource,
                               ResourceReleaseCallback release_callback);
    TransferableResourceHolder(TransferableResourceHolder&& other);
    TransferableResourceHolder& operator=(TransferableResourceHolder&& other);
    ~TransferableResourceHolder();

    TransferableResource resource;
    ResourceReleaseCallback release_callback;
    gpu::SyncToken release_sync_token;
  };

  raw_ptr<ReservedResourceIdTracker> id_tracker_;

  std::map<ResourceId, TransferableResourceHolder> managed_resources_;
};

}  // namespace viz

#endif  // COMPONENTS_VIZ_SERVICE_TRANSITIONS_TRANSFERABLE_RESOURCE_TRACKER_H_