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
ash / components / arc / video_accelerator / protected_buffer_manager.h [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_COMPONENTS_ARC_VIDEO_ACCELERATOR_PROTECTED_BUFFER_MANAGER_H_
#define ASH_COMPONENTS_ARC_VIDEO_ACCELERATOR_PROTECTED_BUFFER_MANAGER_H_
#include <map>
#include <memory>
#include <set>
#include "base/files/scoped_file.h"
#include "base/memory/ref_counted.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_pixmap.h"
namespace arc {
class ProtectedBufferAllocator;
// A DecoderProtectedBufferManager provides functionality for a decoder to
// translate dummy handles into usable handles that can be used as the input and
// output for the decoder.
class DecoderProtectedBufferManager
: public base::RefCountedThreadSafe<DecoderProtectedBufferManager> {
public:
// Calls |response_cb| with a duplicate of the PlatformSharedMemoryRegion
// associated with |dummy_fd| if one exists, or an invalid handle otherwise
// (or if an error occurs). The client is responsible for closing the handle
// after use. |response_cb| is called on the calling sequence and may be
// called before this method returns.
using GetProtectedSharedMemoryRegionForResponseCB =
base::OnceCallback<void(base::UnsafeSharedMemoryRegion)>;
virtual void GetProtectedSharedMemoryRegionFor(
base::ScopedFD dummy_fd,
GetProtectedSharedMemoryRegionForResponseCB response_cb) = 0;
// Calls |response_cb| with a duplicate of the NativePixmapHandle associated
// with |dummy_fd| if one exists, or an empty handle otherwise (or if an error
// occurs). The client is responsible for closing the handle after use.
// |response_cb| is called on the calling sequence and may be called before
// this method returns.
using GetProtectedNativePixmapHandleForResponseCB =
base::OnceCallback<void(gfx::NativePixmapHandle)>;
virtual void GetProtectedNativePixmapHandleFor(
base::ScopedFD dummy_fd,
GetProtectedNativePixmapHandleForResponseCB response_cb) = 0;
protected:
friend class base::RefCountedThreadSafe<DecoderProtectedBufferManager>;
virtual ~DecoderProtectedBufferManager() {}
};
class ProtectedBufferManager : public DecoderProtectedBufferManager {
public:
ProtectedBufferManager();
ProtectedBufferManager(const ProtectedBufferManager&) = delete;
ProtectedBufferManager& operator=(const ProtectedBufferManager&) = delete;
// Creates ProtectedBufferAllocatorImpl and return it as
// unique_ptr<ProtectedBufferAllocator>.
// The created PBA would call the function |protected_buffer_manager|.
static std::unique_ptr<ProtectedBufferAllocator>
CreateProtectedBufferAllocator(
scoped_refptr<ProtectedBufferManager> protected_buffer_manager);
// Return a duplicated UnsafeSharedMemoryRegion associated with the
// |dummy_fd|, if one exists, or an invalid handle otherwise. The client is
// responsible for closing the handle after use.
base::UnsafeSharedMemoryRegion GetProtectedSharedMemoryRegionFor(
base::ScopedFD dummy_fd);
// Return a duplicated NativePixmapHandle associated with the |dummy_fd|,
// if one exists, or an empty handle otherwise.
// The client is responsible for closing the handle after use.
gfx::NativePixmapHandle GetProtectedNativePixmapHandleFor(
base::ScopedFD dummy_fd);
// DecoderProtectedBufferManager implementation.
// TODO(b/195769334): remove the synchronous versions above and migrate all
// callers to use these asynchronous methods.
void GetProtectedSharedMemoryRegionFor(
base::ScopedFD dummy_fd,
GetProtectedSharedMemoryRegionForResponseCB response_cb) override;
void GetProtectedNativePixmapHandleFor(
base::ScopedFD dummy_fd,
GetProtectedNativePixmapHandleForResponseCB response_cb) override;
// Return a protected NativePixmap for a dummy |handle|, if one exists, or
// nullptr otherwise.
scoped_refptr<gfx::NativePixmap> GetProtectedNativePixmapFor(
const gfx::NativePixmapHandle& handle);
// Returns true if dummy |handle| corresponds to a protected native pixmap,
// false otherwise.
bool IsProtectedNativePixmapHandle(base::ScopedFD dummy_fd);
private:
// Used internally to maintain the association between the dummy handle and
// the underlying buffer.
class ProtectedBuffer;
class ProtectedSharedMemory;
class ProtectedNativePixmap;
class ProtectedBufferAllocatorImpl;
// Be friend with ProtectedBufferAllocatorImpl so that private functions can
// be called in ProtectedBufferAllocatorImpl.
friend class ProtectedBufferAllocatorImpl;
// Destructor must be private for base::RefCounted class.
~ProtectedBufferManager() override;
// Returns whether the number of active protected buffer allocators is less
// than the predetermined threshold (kMaxConcurrentProtectedBufferAllocators).
// This also returns current available allocator id through |allocator_id|.
bool GetAllocatorId(uint64_t* const allocator_id);
// Allocates a ProtectedSharedMemory buffer of |size| bytes, to be referred to
// via |dummy_fd| as the dummy handle.
// |allocator_id| is the allocator id of the caller.
// Returns whether allocation is successful.
bool AllocateProtectedSharedMemory(uint64_t allocator_id,
base::ScopedFD dummy_fd,
size_t size);
// Allocates a ProtectedNativePixmap of |format| and |size|, to be referred to
// via |dummy_fd| as the dummy handle.
// |allocator_id| is the allocator id of the caller.
// Returns whether allocation is successful.
bool AllocateProtectedNativePixmap(uint64_t allocator_id,
base::ScopedFD dummy_fd,
gfx::BufferFormat format,
const gfx::Size& size);
// Releases reference to ProtectedSharedMemory or ProtectedNativePixmap
// referred via |dummy_fd|. |allocator_id| is the allocator id of the caller.
void ReleaseProtectedBuffer(uint64_t allocator_id, base::ScopedFD dummy_fd);
// Releases all the references of protected buffers which is allocated by PBA
// whose allocator id is |allocator_id|.
void ReleaseAllProtectedBuffers(uint64_t allocator_id);
// Imports the |dummy_fd| as a NativePixmap. This returns a unique |id|,
// which is guaranteed to be the same for all future imports of any fd
// referring to the buffer to which |dummy_fd| refers to, regardless of
// whether it is the same fd as the original one, or not, for the lifetime
// of the buffer.
//
// This allows us to have an unambiguous mapping from any fd referring to
// the same memory buffer to the same unique id.
//
// Returns nullptr on failure, in which case the returned id is not valid.
scoped_refptr<gfx::NativePixmap> ImportDummyFd(base::ScopedFD dummy_fd,
uint32_t* id) const;
// Removes an entry for given |id| from buffer_map_.
void RemoveEntry(uint32_t id) EXCLUSIVE_LOCKS_REQUIRED(buffer_map_lock_);
// Returns whether a protected buffer whose unique id is |id| can be
// allocated by PBA whose allocator id is |allocator_id|.
bool CanAllocateFor(uint64_t allocator_id, uint32_t id)
EXCLUSIVE_LOCKS_REQUIRED(buffer_map_lock_);
// A map of unique ids to the ProtectedBuffers associated with them.
using ProtectedBufferMap =
std::map<uint32_t, std::unique_ptr<ProtectedBuffer>>;
ProtectedBufferMap buffer_map_ GUARDED_BY(buffer_map_lock_);
// A map of allocator ids to the unique ids of ProtectedBuffers allocated by
// the allocator with the allocator id. The size is equal to the number of
// active protected buffer allocators.
std::map<uint64_t, std::set<uint32_t>> allocator_to_buffers_map_
GUARDED_BY(buffer_map_lock_);
uint64_t next_protected_buffer_allocator_id_ GUARDED_BY(buffer_map_lock_);
base::Lock buffer_map_lock_;
};
} // namespace arc
#endif // ASH_COMPONENTS_ARC_VIDEO_ACCELERATOR_PROTECTED_BUFFER_MANAGER_H_