1 // Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef GPU_COMMAND_BUFFER_CLIENT_CLIENT_DISCARDABLE_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_CLIENT_CLIENT_DISCARDABLE_MANAGER_H_
7 
8 #include <map>
9 #include <set>
10 
11 #include "base/containers/queue.h"
12 #include "gpu/command_buffer/common/command_buffer.h"
13 #include "gpu/command_buffer/common/discardable_handle.h"
14 #include "gpu/gpu_export.h"
15 
16 namespace gpu {
17 
18 // ClientDiscardableManager is a helper class used by the
19 // ClientDiscardableTextureManager. It allows for the creation and management
20 // of ClientDiscardableHandles.
21 class GPU_EXPORT ClientDiscardableManager {
22  public:
23   ClientDiscardableManager();
24   ~ClientDiscardableManager();
25 
26   // Note that the handles bound to an id are not guaranteed to outlive the
27   // handle id. GetHandle may return an empty handle if the corresponding handle
28   // was deleted on the service.
29   ClientDiscardableHandle::Id CreateHandle(CommandBuffer* command_buffer);
30   bool LockHandle(ClientDiscardableHandle::Id handle_id);
31   void FreeHandle(ClientDiscardableHandle::Id handle_id);
32   bool HandleIsValid(ClientDiscardableHandle::Id handle_id) const;
33   ClientDiscardableHandle GetHandle(ClientDiscardableHandle::Id handle_id);
34   bool HandleIsDeleted(ClientDiscardableHandle::Id handle_id);
35 
36   // For diagnostic tracing only.
37   bool HandleIsDeletedForTracing(ClientDiscardableHandle::Id handle_id) const;
38 
39   // Test only functions.
CheckPendingForTesting(CommandBuffer * command_buffer)40   void CheckPendingForTesting(CommandBuffer* command_buffer) {
41     CheckPending(command_buffer);
42   }
SetElementCountForTesting(uint32_t count)43   void SetElementCountForTesting(uint32_t count) {
44     elements_per_allocation_ = count;
45     allocation_size_ = count * element_size_;
46   }
47 
48  private:
49   bool FindAllocation(CommandBuffer* command_buffer,
50                       scoped_refptr<Buffer>* buffer,
51                       int32_t* shm_id,
52                       uint32_t* offset);
53   bool FindExistingAllocation(CommandBuffer* command_buffer,
54                               scoped_refptr<Buffer>* buffer,
55                               int32_t* shm_id,
56                               uint32_t* offset);
57   void ReturnAllocation(CommandBuffer* command_buffer,
58                         const ClientDiscardableHandle& handle);
59   void CheckPending(CommandBuffer* command_buffer);
60   // Return true if we found at least one deleted entry.
61   bool CheckDeleted(CommandBuffer* command_buffer);
62   bool CreateNewAllocation(CommandBuffer* command_buffer);
63 
64  private:
65   uint32_t allocation_size_;
66   size_t element_size_ = sizeof(base::subtle::Atomic32);
67   uint32_t elements_per_allocation_ = allocation_size_ / element_size_;
68 
69   struct Allocation;
70   std::vector<std::unique_ptr<Allocation>> allocations_;
71   std::map<ClientDiscardableHandle::Id, ClientDiscardableHandle> handles_;
72 
73   // Handles that are pending service deletion, and can be re-used once
74   // ClientDiscardableHandle::CanBeReUsed returns true.
75   base::queue<ClientDiscardableHandle> pending_handles_;
76 
77   DISALLOW_COPY_AND_ASSIGN(ClientDiscardableManager);
78 };
79 
80 }  // namespace gpu
81 
82 #endif  // GPU_COMMAND_BUFFER_CLIENT_CLIENT_DISCARDABLE_MANAGER_H_
83