File: buffer.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 (300 lines) | stat: -rw-r--r-- 10,975 bytes parent folder | download | duplicates (3)
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
// Copyright 2015 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_EXO_BUFFER_H_
#define COMPONENTS_EXO_BUFFER_H_

#include <memory>
#include <string_view>

#include "base/cancelable_callback.h"
#include "base/containers/flat_map.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "components/exo/protected_native_pixmap_query_delegate.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "gpu/ipc/common/surface_handle.h"
#include "media/media_buildflags.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer_handle.h"

namespace exo {

class FrameSinkResourceManager;

// This class provides the content for a Surface. The mechanism by which a
// client provides and updates the contents is the responsibility of the client
// and not defined as part of this class.
class Buffer {
 public:
  Buffer(const Buffer&) = delete;
  Buffer& operator=(const Buffer&) = delete;
  virtual ~Buffer();

  // Clients can use this method to create Buffer using GMBHandles. This is
  // required to move away clients from using GMB directly as a part of
  // MappableSI work.
  static std::unique_ptr<Buffer> CreateBufferFromGMBHandle(
      gfx::GpuMemoryBufferHandle buffer_handle,
      const gfx::Size& buffer_size,
      gfx::BufferFormat buffer_format,
      gfx::BufferUsage buffer_usage,
      unsigned query_type,
      bool use_zero_copy,
      bool is_overlay_candidate,
      bool y_invert);

  static std::unique_ptr<Buffer> CreateBuffer(
      gfx::Size buffer_size,
      gfx::BufferFormat buffer_format,
      gfx::BufferUsage buffer_usage,
      std::string_view debug_label,
      gpu::SurfaceHandle surface_handle,
      base::WaitableEvent* shutdown_event,
      bool is_overlay_candidate = false);

  // Set the callback to run when the buffer is no longer used by the
  // compositor. The client is free to re-use or destroy this buffer and
  // its backing storage after this has been called.
  void set_release_callback(const base::RepeatingClosure& release_callback) {
    release_callback_ = release_callback;
  }

  // The client does not need release_callback_ to notify buffer usage.
  void SkipLegacyRelease();

  // Returns if this buffer's contents are vertically inverted.
  bool y_invert() const { return y_invert_; }

  // This function can be used to acquire a texture mailbox for the contents of
  // buffer. |release_callback| will be called when the contents of the buffer
  // are no longer required.
  using PerCommitExplicitReleaseCallback =
      base::OnceCallback<void(gfx::GpuFenceHandle)>;
  virtual bool ProduceTransferableResource(
      FrameSinkResourceManager* resource_manager,
      std::unique_ptr<gfx::GpuFence> acquire_fence,
      bool secure_output_only,
      viz::TransferableResource* resource,
      gfx::ColorSpace color_space,
      ProtectedNativePixmapQueryDelegate* protected_native_pixmap_query,
      PerCommitExplicitReleaseCallback per_commit_explicit_release_callback);

  // This should be called when the buffer is attached to a Surface.
  void OnAttach();

  // This should be called when the buffer is detached from a surface.
  void OnDetach();

  // Returns the size of the buffer.
  virtual gfx::Size GetSize() const;

  // Returns the format of the buffer.
  gfx::BufferFormat GetFormat() const;

  // Returns the |gpu_memory_buffer_| pointer to be used as id. It can also be
  // used as a bool to identify if |gpu_memory_buffer_| is null or not.
  const void* GetBufferId() const;

  // The default color to be used should transferable resource production fail.
  virtual SkColor4f GetColor() const;

  // Creates a SkBitmap object from |gpu_memory_buffer_|.
  SkBitmap CreateBitmap();

#if BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
  // Returns true if the underlying buffer is hardware protected. This should
  // only be checked if the corresponding surface requires secure output,
  // otherwise it will yield false positives.
  bool NeedsHardwareProtection();
#endif  // BUILDFLAG(USE_ARC_PROTECTED_MEDIA)

  // Set the amount of time to wait for buffer release.
  void set_wait_for_release_delay_for_testing(
      base::TimeDelta wait_for_release_delay) {
    wait_for_release_delay_ = wait_for_release_delay;
  }

  virtual base::WeakPtr<Buffer> AsWeakPtr();

 protected:
  // Currently only derived class access this constructor.
  Buffer();

 private:
  // TODO(vikassoni): Once MappableSI is fully landed, these clients do not need
  // to access the Buffer constructors. So it should be removed from the friend
  // list.
  friend class Display;
  friend class SharedMemory;

  class Texture;

  Buffer(gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle,
         gfx::BufferFormat buffer_format,
         gfx::Size size,
         gfx::BufferUsage buffer_usage,
         unsigned query_type,
         bool use_zero_copy,
         bool is_overlay_candidate,
         bool y_invert);

  struct BufferRelease {
    BufferRelease(
        gfx::GpuFenceHandle release_fence,
        std::unique_ptr<base::FileDescriptorWatcher::Controller> controller,
        base::OnceClosure buffer_release_callback);
    ~BufferRelease();

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

    BufferRelease(BufferRelease&&);
    BufferRelease& operator=(BufferRelease&&);

    // |release_fence| must be kept above |controller| to keep the file
    // descriptor valid during destruction.
    gfx::GpuFenceHandle release_fence;
    std::unique_ptr<base::FileDescriptorWatcher::Controller> controller;
    base::OnceClosure buffer_release_callback;
  };

#if BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
  // For ARC protected content support this tracks the state of the
  // asynchronous query to determine if the GMB is using a protected buffer or
  // not.
  enum class ProtectedBufferState { UNKNOWN, QUERYING, PROTECTED, UNPROTECTED };
#endif  // BUILDFLAG(USE_ARC_PROTECTED_MEDIA)

  // This should be called when buffer is released and will notify the
  // client that buffer has been released.
  void Release();

  // This is used by ProduceTransferableResource() to produce a release callback
  // that releases a texture so it can be destroyed or reused.
  void ReleaseTexture(std::unique_ptr<Texture> texture,
                      gfx::GpuFenceHandle release_fence);

  // This is used by ProduceTransferableResource() to produce a release callback
  // that releases the buffer contents referenced by a texture before the
  // texture is destroyed or reused.
  void ReleaseContentsTexture(std::unique_ptr<Texture> texture,
                              base::OnceClosure callback,
                              uint64_t commit_id,
                              gfx::GpuFenceHandle release_fence);

  // Notifies the client that buffer has been released if no longer attached to
  // a surface.
  void ReleaseContents();

  void MaybeRunPerCommitRelease(uint64_t commit_id,
                                gfx::GpuFenceHandle release_fence,
                                base::OnceClosure buffer_release_callback);

  void FenceSignalled(uint64_t commit_id);

#if BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
  void OnIsProtectedNativePixmapHandle(bool is_protected);
#endif  // BUILDFLAG(USE_ARC_PROTECTED_MEDIA)

  // Contains the content of this buffer instead of |gpu_memory_buffer_| when
  // MappableSI is enabled.
  gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle_;
  const gfx::BufferFormat buffer_format_;
  const gfx::Size size_;
  gfx::BufferUsage buffer_usage_;

  // Query type that must be used when releasing buffer from a texture.
  const unsigned query_type_;

  // True if zero copy is used when producing a texture mailbox for buffer.
  const bool use_zero_copy_;

  // True if this buffer is an overlay candidate.
  const bool is_overlay_candidate_;

  // True if buffer content is vertically inverted.
  const bool y_invert_;

  // This keeps track of how many Surfaces the buffer is attached to.
  unsigned attach_count_ = 0;

  // The last used texture. ProduceTransferableResource() will use this
  // instead of creating a new texture when possible.
  std::unique_ptr<Texture> texture_;

  // The last used contents texture. ProduceTransferableResource() will use this
  // instead of creating a new texture when possible.
  std::unique_ptr<Texture> contents_texture_;

  // The client release callback.
  base::RepeatingClosure release_callback_;

  // Cancelable release contents callback. This is set when a release callback
  // is pending.
  base::CancelableOnceClosure release_contents_callback_;

  // The amount of time to wait for buffer release.
  base::TimeDelta wait_for_release_delay_;

  // Because viz can release buffers out of order, it's necessary to map
  // releases to specific commits. Identify commits via a incrementing counter.
  uint64_t next_commit_id_ = 0;

  // Maps commit count to the callback to call when we receive a release from
  // viz.
  base::flat_map<uint64_t, PerCommitExplicitReleaseCallback>
      pending_explicit_releases_;

  // Maps commit count to information required to send regular buffer releases.
  // Even if we send explicit synchronization release information, Wayland
  // protocol requires us to send regular buffer release events.
  base::flat_map<uint64_t, BufferRelease> buffer_releases_;

  bool legacy_release_skippable_ = false;

#if BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
  ProtectedBufferState protected_buffer_state_ = ProtectedBufferState::UNKNOWN;
#endif  // BUILDFLAG(USE_ARC_PROTECTED_MEDIA)

  base::WeakPtrFactory<Buffer> weak_ptr_factory_{this};
};

class SolidColorBuffer : public Buffer {
 public:
  SolidColorBuffer(const SkColor4f& color, const gfx::Size& size);
  SolidColorBuffer(const SolidColorBuffer& buffer) = delete;
  SolidColorBuffer& operator=(const SolidColorBuffer&) = delete;
  ~SolidColorBuffer() override;

  SkColor4f GetColor() const override;
  gfx::Size GetSize() const override;
  bool ProduceTransferableResource(
      FrameSinkResourceManager* resource_manager,
      std::unique_ptr<gfx::GpuFence> acquire_fence,
      bool secure_output_only,
      viz::TransferableResource* resource,
      gfx::ColorSpace color_space,
      ProtectedNativePixmapQueryDelegate* protected_native_pixmap_query,
      PerCommitExplicitReleaseCallback per_commit_explicit_release_callback)
      override;

  base::WeakPtr<Buffer> AsWeakPtr() override;

 private:
  SkColor4f color_;
  gfx::Size size_;

  base::WeakPtrFactory<SolidColorBuffer> weak_ptr_factory_{this};
};

}  // namespace exo

#endif  // COMPONENTS_EXO_BUFFER_H_