blob: c71dbe12f7bf6d0d17cd04ab456b8124d30863d0 [file] [log] [blame]
[email protected]1c3c9f62012-03-28 04:01:551// Copyright (c) 2012 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
penghuang346a46f92016-03-31 21:37:525#ifndef GPU_IPC_CLIENT_COMMAND_BUFFER_PROXY_IMPL_H_
6#define GPU_IPC_CLIENT_COMMAND_BUFFER_PROXY_IMPL_H_
[email protected]1c3c9f62012-03-28 04:01:557
avia9aa7a82015-12-25 03:06:318#include <stddef.h>
9#include <stdint.h>
10
[email protected]1c3c9f62012-03-28 04:01:5511#include <map>
mostynb6682b1c42016-04-19 10:17:3012#include <memory>
[email protected]1c3c9f62012-03-28 04:01:5513#include <queue>
14#include <string>
15
[email protected]1c3c9f62012-03-28 04:01:5516#include "base/callback.h"
[email protected]3541d302012-05-17 06:53:3517#include "base/compiler_specific.h"
Klaus Weidnere66cc7d2017-12-09 17:26:3018#include "base/containers/flat_map.h"
[email protected]14c1c232013-06-11 17:52:4419#include "base/containers/hash_tables.h"
avia9aa7a82015-12-25 03:06:3120#include "base/macros.h"
[email protected]3541d302012-05-17 06:53:3521#include "base/memory/ref_counted.h"
Alexandr Ilin15bb7032018-07-13 10:09:0622#include "base/memory/shared_memory_mapping.h"
23#include "base/memory/unsafe_shared_memory_region.h"
[email protected]1c3c9f62012-03-28 04:01:5524#include "base/memory/weak_ptr.h"
[email protected]9df34882013-04-26 05:13:5825#include "base/observer_list.h"
gab10ae4362016-11-02 23:34:5326#include "base/single_thread_task_runner.h"
dyen4d075d22016-04-29 01:53:5727#include "base/threading/thread_checker.h"
[email protected]01952a62014-05-02 05:22:0128#include "gpu/command_buffer/client/gpu_control.h"
[email protected]1c3c9f62012-03-28 04:01:5529#include "gpu/command_buffer/common/command_buffer.h"
lukasza2573ce7d2016-02-16 19:17:2230#include "gpu/command_buffer/common/command_buffer_id.h"
[email protected]1c3c9f62012-03-28 04:01:5531#include "gpu/command_buffer/common/command_buffer_shared.h"
danakj45cfd232017-10-18 19:31:3132#include "gpu/command_buffer/common/context_result.h"
[email protected]f44d5552013-10-29 04:56:2933#include "gpu/command_buffer/common/gpu_memory_allocation.h"
sunnyps8f9139e2017-05-12 17:53:2534#include "gpu/command_buffer/common/scheduling_priority.h"
penghuang346a46f92016-03-31 21:37:5235#include "gpu/gpu_export.h"
pimanac97d0cd2016-05-16 23:11:0636#include "gpu/ipc/common/surface_handle.h"
[email protected]d84effeb2012-06-25 17:03:1037#include "ipc/ipc_listener.h"
achaulkec8c2db2015-05-29 16:35:0338#include "ui/gfx/swap_result.h"
pimanac97d0cd2016-05-16 23:11:0639#include "ui/gl/gpu_preference.h"
[email protected]1c3c9f62012-03-28 04:01:5540
[email protected]1c3c9f62012-03-28 04:01:5541struct GPUCommandBufferConsoleMessage;
pimanac97d0cd2016-05-16 23:11:0642class GURL;
[email protected]1c3c9f62012-03-28 04:01:5543
Peng Huang6bf92772017-11-30 18:57:0844namespace gfx {
Klaus Weidnere66cc7d2017-12-09 17:26:3045struct GpuFenceHandle;
Peng Huang6bf92772017-11-30 18:57:0846struct PresentationFeedback;
47}
48
[email protected]1738e542013-03-06 13:16:3949namespace gpu {
Antoine Labourfeab2392017-12-21 20:28:3950struct ContextCreationAttribs;
[email protected]1738e542013-03-06 13:16:3951struct Mailbox;
Christopher Cameron4bc282bb2017-12-03 11:24:0552struct SwapBuffersCompleteParams;
dyen6f3b439c2015-10-22 20:17:2353struct SyncToken;
[email protected]1738e542013-03-06 13:16:3954}
55
penghuang346a46f92016-03-31 21:37:5256namespace gpu {
[email protected]eb398192012-10-22 20:16:1957class GpuChannelHost;
Antoine Labour5ac65db2017-12-19 18:02:5858class GpuMemoryBufferManager;
[email protected]eb398192012-10-22 20:16:1959
[email protected]1c3c9f62012-03-28 04:01:5560// Client side proxy that forwards messages synchronously to a
61// CommandBufferStub.
Uzair Jaleel52c44f32017-08-01 08:21:1562class GPU_EXPORT CommandBufferProxyImpl : public gpu::CommandBuffer,
63 public gpu::GpuControl,
64 public IPC::Listener {
[email protected]1c3c9f62012-03-28 04:01:5565 public:
[email protected]9df34882013-04-26 05:13:5866 class DeletionObserver {
67 public:
68 // Called during the destruction of the CommandBufferProxyImpl.
69 virtual void OnWillDeleteImpl() = 0;
70
71 protected:
Chris Watkins81030772017-12-07 01:20:5672 virtual ~DeletionObserver() = default;
[email protected]9df34882013-04-26 05:13:5873 };
74
penghuang346a46f92016-03-31 21:37:5275 typedef base::Callback<void(const std::string& msg, int id)>
76 GpuConsoleMessageCallback;
[email protected]1c3c9f62012-03-28 04:01:5577
danakj45cfd232017-10-18 19:31:3178 CommandBufferProxyImpl(
79 scoped_refptr<GpuChannelHost> channel,
Antoine Labour5ac65db2017-12-19 18:02:5880 GpuMemoryBufferManager* gpu_memory_buffer_manager,
pimanac97d0cd2016-05-16 23:11:0681 int32_t stream_id,
pimanac97d0cd2016-05-16 23:11:0682 scoped_refptr<base::SingleThreadTaskRunner> task_runner);
dchenge933b3eb2014-10-21 11:44:0983 ~CommandBufferProxyImpl() override;
[email protected]1c3c9f62012-03-28 04:01:5584
danakj45cfd232017-10-18 19:31:3185 // Connect to a command buffer in the GPU process.
Antoine Labourfeab2392017-12-21 20:28:3986 ContextResult Initialize(gpu::SurfaceHandle surface_handle,
87 CommandBufferProxyImpl* share_group,
88 gpu::SchedulingPriority stream_priority,
89 const gpu::ContextCreationAttribs& attribs,
90 const GURL& active_url);
danakj45cfd232017-10-18 19:31:3191
[email protected]d84effeb2012-06-25 17:03:1092 // IPC::Listener implementation:
dchenge933b3eb2014-10-21 11:44:0993 bool OnMessageReceived(const IPC::Message& message) override;
94 void OnChannelError() override;
[email protected]1c3c9f62012-03-28 04:01:5595
[email protected]1c3c9f62012-03-28 04:01:5596 // CommandBuffer implementation:
dchenge933b3eb2014-10-21 11:44:0997 State GetLastState() override;
avia9aa7a82015-12-25 03:06:3198 void Flush(int32_t put_offset) override;
99 void OrderingBarrier(int32_t put_offset) override;
sunnyps128566052016-12-09 21:06:43100 State WaitForTokenInRange(int32_t start, int32_t end) override;
Antoine Labourd3469942017-05-16 21:23:42101 State WaitForGetOffsetInRange(uint32_t set_get_buffer_count,
102 int32_t start,
103 int32_t end) override;
avia9aa7a82015-12-25 03:06:31104 void SetGetBuffer(int32_t shm_id) override;
dchenge933b3eb2014-10-21 11:44:09105 scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
avia9aa7a82015-12-25 03:06:31106 int32_t* id) override;
107 void DestroyTransferBuffer(int32_t id) override;
[email protected]1c3c9f62012-03-28 04:01:55108
[email protected]744e0792013-09-27 01:18:35109 // gpu::GpuControl implementation:
danakj10057772016-04-12 19:35:44110 void SetGpuControlClient(GpuControlClient* client) override;
Zhenyao Moeb86a1712017-10-06 14:17:52111 const gpu::Capabilities& GetCapabilities() const override;
avia9aa7a82015-12-25 03:06:31112 int32_t CreateImage(ClientBuffer buffer,
113 size_t width,
114 size_t height,
115 unsigned internal_format) override;
116 void DestroyImage(int32_t id) override;
Jonathan Backerbd345c1f2018-02-14 21:44:23117 void SignalQuery(uint32_t query, base::OnceClosure callback) override;
Klaus Weidnere66cc7d2017-12-09 17:26:30118 void CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) override;
119 void GetGpuFence(uint32_t gpu_fence_id,
120 base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>
121 callback) override;
122
jbauman6875d4e02015-02-12 00:44:59123 void SetLock(base::Lock* lock) override;
dyen293de3c2016-01-05 02:08:05124 void EnsureWorkVisible() override;
dyen12e45962015-09-18 00:13:51125 gpu::CommandBufferNamespace GetNamespaceID() const override;
lukasza2573ce7d2016-02-16 19:17:22126 gpu::CommandBufferId GetCommandBufferID() const override;
Sunny Sachanandani9b8fb342017-08-26 00:49:56127 void FlushPendingWork() override;
dyen5c38a032015-10-07 18:58:31128 uint64_t GenerateFenceSyncRelease() override;
sunnyps128566052016-12-09 21:06:43129 bool IsFenceSyncReleased(uint64_t release) override;
dyen6f3b439c2015-10-22 20:17:23130 void SignalSyncToken(const gpu::SyncToken& sync_token,
Jonathan Backerbd345c1f2018-02-14 21:44:23131 base::OnceClosure callback) override;
sunnyps74996292017-03-15 02:35:48132 void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override;
133 bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override;
erikchen438b0442016-05-11 18:33:30134 void TakeFrontBuffer(const gpu::Mailbox& mailbox);
135 void ReturnFrontBuffer(const gpu::Mailbox& mailbox,
136 const gpu::SyncToken& sync_token,
137 bool is_lost);
[email protected]b47f1b62013-09-26 17:57:04138
[email protected]9df34882013-04-26 05:13:58139 void AddDeletionObserver(DeletionObserver* observer);
140 void RemoveDeletionObserver(DeletionObserver* observer);
141
[email protected]bc390f12012-10-28 13:05:26142 bool EnsureBackbuffer();
143
danakj5c83e362015-02-20 16:51:35144 using UpdateVSyncParametersCallback =
145 base::Callback<void(base::TimeTicks timebase, base::TimeDelta interval)>;
146 void SetUpdateVSyncParametersCallback(
147 const UpdateVSyncParametersCallback& callback);
148
avia9aa7a82015-12-25 03:06:31149 int32_t route_id() const { return route_id_; }
sunnyps4e9da312015-08-10 19:35:14150
piman9fc22f32016-05-02 22:21:22151 const scoped_refptr<GpuChannelHost>& channel() const { return channel_; }
[email protected]1c3c9f62012-03-28 04:01:55152
Alexandr Ilin15bb7032018-07-13 10:09:06153 const base::UnsafeSharedMemoryRegion& GetSharedStateRegion() const {
154 return shared_state_shm_;
penghuanga206fb492014-09-09 21:27:32155 }
avia9aa7a82015-12-25 03:06:31156 uint32_t CreateStreamTexture(uint32_t texture_id);
penghuanga206fb492014-09-09 21:27:32157
[email protected]1c3c9f62012-03-28 04:01:55158 private:
avia9aa7a82015-12-25 03:06:31159 typedef std::map<int32_t, scoped_refptr<gpu::Buffer>> TransferBufferMap;
Jonathan Backerbd345c1f2018-02-14 21:44:23160 typedef base::hash_map<uint32_t, base::OnceClosure> SignalTaskMap;
[email protected]5ab44ef2012-06-19 00:03:51161
jbauman6875d4e02015-02-12 00:44:59162 void CheckLock() {
dyen4d075d22016-04-29 01:53:57163 if (lock_) {
jbauman6875d4e02015-02-12 00:44:59164 lock_->AssertAcquired();
dyen4d075d22016-04-29 01:53:57165 } else {
166 DCHECK(lockless_thread_checker_.CalledOnValidThread());
167 }
jbauman6875d4e02015-02-12 00:44:59168 }
169
Sunny Sachanandani9b8fb342017-08-26 00:49:56170 void OrderingBarrierHelper(int32_t put_offset);
171
[email protected]1c3c9f62012-03-28 04:01:55172 // Send an IPC message over the GPU channel. This is private to fully
173 // encapsulate the channel; all callers of this function must explicitly
174 // verify that the context has not been lost.
175 bool Send(IPC::Message* msg);
176
Alexandr Ilin15bb7032018-07-13 10:09:06177 std::pair<base::UnsafeSharedMemoryRegion, base::WritableSharedMemoryMapping>
178 AllocateAndMapSharedMemory(size_t size);
Antoine Labour7590844d2017-11-29 17:49:18179
[email protected]1c3c9f62012-03-28 04:01:55180 // Message handlers:
sieversfbaa5dc2015-04-28 00:45:31181 void OnDestroyed(gpu::error::ContextLostReason reason,
182 gpu::error::Error error);
[email protected]1c3c9f62012-03-28 04:01:55183 void OnConsoleMessage(const GPUCommandBufferConsoleMessage& message);
Sunny Sachanandani249fd0302017-09-23 02:30:11184 void OnSignalAck(uint32_t id, const CommandBuffer::State& state);
Christopher Cameron4bc282bb2017-12-03 11:24:05185 void OnSwapBuffersCompleted(const SwapBuffersCompleteParams& params);
Peng Huang6bf92772017-11-30 18:57:08186 void OnBufferPresented(uint64_t swap_id,
187 const gfx::PresentationFeedback& feedback);
Klaus Weidnere66cc7d2017-12-09 17:26:30188 void OnGetGpuFenceHandleComplete(uint32_t gpu_fence_id,
189 const gfx::GpuFenceHandle&);
[email protected]1c3c9f62012-03-28 04:01:55190
danakj90fcc5e2016-04-29 04:21:00191 // Try to read an updated copy of the state from shared memory, and calls
192 // OnGpuStateError() if the new state has an error.
193 void TryUpdateState();
sunnyps128566052016-12-09 21:06:43194 // Like above but calls the error handler and disconnects channel by posting
195 // a task.
196 void TryUpdateStateThreadSafe();
danakj90fcc5e2016-04-29 04:21:00197 // Like the above but does not call the error event handler if the new state
198 // has an error.
199 void TryUpdateStateDontReportError();
200 // Sets the state, and calls OnGpuStateError() if the new state has an error.
Sunny Sachanandani249fd0302017-09-23 02:30:11201 void SetStateFromMessageReply(const CommandBuffer::State& state);
piman79010e272016-01-14 19:40:55202
203 // Loses the context after we received an invalid reply from the GPU
danakj90fcc5e2016-04-29 04:21:00204 // process.
205 void OnGpuSyncReplyError();
piman79010e272016-01-14 19:40:55206
danakj90fcc5e2016-04-29 04:21:00207 // Loses the context when receiving a message from the GPU process.
208 void OnGpuAsyncMessageError(gpu::error::ContextLostReason reason,
209 gpu::error::Error error);
210
211 // Loses the context after we receive an error state from the GPU process.
212 void OnGpuStateError();
213
214 // Sets an error on the last_state_ and loses the context due to client-side
215 // errors.
216 void OnClientError(gpu::error::Error error);
217
218 // Helper methods, don't call these directly.
219 void DisconnectChannelInFreshCallStack();
220 void LockAndDisconnectChannel();
221 void DisconnectChannel();
piman79010e272016-01-14 19:40:55222
[email protected]67c80782012-12-21 01:16:52223 // The shared memory area used to update state.
[email protected]1a8b20bf2014-04-03 12:12:04224 gpu::CommandBufferSharedState* shared_state() const;
[email protected]67c80782012-12-21 01:16:52225
Alexandr Ilin15bb7032018-07-13 10:09:06226 // The shared memory region used to update state.
227 base::UnsafeSharedMemoryRegion shared_state_shm_;
228 base::WritableSharedMemoryMapping shared_state_mapping_;
sunnyps128566052016-12-09 21:06:43229
230 // The last cached state received from the service.
231 State last_state_;
232
233 // Lock to access shared state e.g. sync token release count across multiple
234 // threads. This allows tracking command buffer progress from another thread.
235 base::Lock last_state_lock_;
236
dyen4d075d22016-04-29 01:53:57237 // There should be a lock_ if this is going to be used across multiple
238 // threads, or we guarantee it is used by a single thread by using a thread
239 // checker if no lock_ is set.
Sunny Sachanandani57130e02017-06-07 00:08:56240 base::Lock* lock_ = nullptr;
dyen4d075d22016-04-29 01:53:57241 base::ThreadChecker lockless_thread_checker_;
jbauman6875d4e02015-02-12 00:44:59242
danakj10057772016-04-12 19:35:44243 // Client that wants to listen for important events on the GpuControl.
Sunny Sachanandani57130e02017-06-07 00:08:56244 gpu::GpuControlClient* gpu_control_client_ = nullptr;
danakj10057772016-04-12 19:35:44245
[email protected]9df34882013-04-26 05:13:58246 // Unowned list of DeletionObservers.
Trent Apteda250ec3ab2018-08-19 08:52:19247 base::ObserverList<DeletionObserver>::Unchecked deletion_observers_;
[email protected]1c3c9f62012-03-28 04:01:55248
piman9fc22f32016-05-02 22:21:22249 scoped_refptr<GpuChannelHost> channel_;
Antoine Labour5ac65db2017-12-19 18:02:58250 GpuMemoryBufferManager* gpu_memory_buffer_manager_;
danakj1c7840a12017-10-18 02:28:17251 bool disconnected_ = false;
Sunny Sachanandani57130e02017-06-07 00:08:56252 const int channel_id_;
avia9aa7a82015-12-25 03:06:31253 const int32_t route_id_;
254 const int32_t stream_id_;
danakj45cfd232017-10-18 19:31:31255 const gpu::CommandBufferId command_buffer_id_;
Sunny Sachanandani9b8fb342017-08-26 00:49:56256 uint32_t last_flush_id_ = 0;
sunnyps74996292017-03-15 02:35:48257 int32_t last_put_offset_ = -1;
Antoine Labour1a9ef392017-08-24 19:40:33258 bool has_buffer_ = false;
[email protected]1c3c9f62012-03-28 04:01:55259
dyen5c38a032015-10-07 18:58:31260 // Next generated fence sync.
sunnyps74996292017-03-15 02:35:48261 uint64_t next_fence_sync_release_ = 1;
262
Sunny Sachanandani9b8fb342017-08-26 00:49:56263 // Sync token waits that haven't been flushed yet.
sunnyps74996292017-03-15 02:35:48264 std::vector<SyncToken> pending_sync_token_fences_;
dyen5c38a032015-10-07 18:58:31265
dyen5c38a032015-10-07 18:58:31266 // Last flushed fence sync release, same as last item in queue if not empty.
sunnyps74996292017-03-15 02:35:48267 uint64_t flushed_fence_sync_release_ = 0;
dyen5c38a032015-10-07 18:58:31268
269 // Last verified fence sync.
sunnyps74996292017-03-15 02:35:48270 uint64_t verified_fence_sync_release_ = 0;
dyen5c38a032015-10-07 18:58:31271
[email protected]1c3c9f62012-03-28 04:01:55272 GpuConsoleMessageCallback console_message_callback_;
273
[email protected]5ab44ef2012-06-19 00:03:51274 // Tasks to be invoked in SignalSyncPoint responses.
sunnyps74996292017-03-15 02:35:48275 uint32_t next_signal_id_ = 0;
[email protected]5ab44ef2012-06-19 00:03:51276 SignalTaskMap signal_tasks_;
277
[email protected]6d668892013-12-04 21:37:12278 gpu::Capabilities capabilities_;
279
danakj5c83e362015-02-20 16:51:35280 UpdateVSyncParametersCallback update_vsync_parameters_completion_callback_;
sieversdf212b32014-10-09 20:40:14281
Klaus Weidnere66cc7d2017-12-09 17:26:30282 using GetGpuFenceTaskMap =
283 base::flat_map<uint32_t,
284 base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>>;
285 GetGpuFenceTaskMap get_gpu_fence_tasks_;
286
danakj45cfd232017-10-18 19:31:31287 scoped_refptr<base::SingleThreadTaskRunner> callback_thread_;
Uzair Jaleel52c44f32017-08-01 08:21:15288 base::WeakPtrFactory<CommandBufferProxyImpl> weak_ptr_factory_;
piman79010e272016-01-14 19:40:55289
[email protected]1c3c9f62012-03-28 04:01:55290 DISALLOW_COPY_AND_ASSIGN(CommandBufferProxyImpl);
291};
292
penghuang346a46f92016-03-31 21:37:52293} // namespace gpu
[email protected]eb398192012-10-22 20:16:19294
penghuang346a46f92016-03-31 21:37:52295#endif // GPU_IPC_CLIENT_COMMAND_BUFFER_PROXY_IMPL_H_