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
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// 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 "base/callback.h"
#include "base/cancelable_callback.h"
#include "base/containers/flat_map.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/memory/weak_ptr.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer.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 base::SupportsWeakPtr<Buffer> {
public:
explicit Buffer(std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer);
Buffer(std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer,
unsigned texture_target,
unsigned query_type,
bool use_zero_copy,
bool is_overlay_candidate,
bool y_invert);
Buffer(const Buffer&) = delete;
Buffer& operator=(const Buffer&) = delete;
virtual ~Buffer();
const gfx::GpuMemoryBuffer* gfx_buffer() const {
return gpu_memory_buffer_.get();
}
// 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;
}
// 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,
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;
// The default color to be used should transferable resource production fail.
virtual SkColor4f GetColor() const;
// 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;
}
private:
class Texture;
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;
};
// 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);
// The GPU memory buffer that contains the contents of this buffer.
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
// Texture target that must be used when creating a texture for buffer.
const unsigned texture_target_;
// 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_;
};
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,
PerCommitExplicitReleaseCallback per_commit_explicit_release_callback)
override;
private:
SkColor4f color_;
gfx::Size size_;
};
} // namespace exo
#endif // COMPONENTS_EXO_BUFFER_H_
|