diff options
author | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-15 04:12:57 +0000 |
---|---|---|
committer | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-15 04:12:57 +0000 |
commit | 2f9704c73793a303481b5fa49c76903f9e81eb02 (patch) | |
tree | e72dcd9bc380230eccfa3970e83e9a1791fcfc78 /gpu/command_buffer/common/command_buffer_shared.h | |
parent | e190c9ea6211125a1c836d913d504643678a35c5 (diff) | |
download | chromium_src-2f9704c73793a303481b5fa49c76903f9e81eb02.zip chromium_src-2f9704c73793a303481b5fa49c76903f9e81eb02.tar.gz chromium_src-2f9704c73793a303481b5fa49c76903f9e81eb02.tar.bz2 |
Use shared memory to update the renderer's view of the command buffer state.
The renderer can't receive UpdateState messages while it's executing javascript or NaCl, causing it to eventually flushsync once it fills up the command buffer or transfer buffer. To avoid this, share a piece of memory between the renderer and gpu process that the GPU can asynchronously update the state. A 4-slot asynchronous communication mechanism is used so that the renderer always receives a consistent copy of the state that was put in by the GPU process.
BUG=
TEST=
Review URL: http://codereview.chromium.org/9380037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122034 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/common/command_buffer_shared.h')
-rw-r--r-- | gpu/command_buffer/common/command_buffer_shared.h | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/gpu/command_buffer/common/command_buffer_shared.h b/gpu/command_buffer/common/command_buffer_shared.h new file mode 100644 index 0000000..017a644 --- /dev/null +++ b/gpu/command_buffer/common/command_buffer_shared.h @@ -0,0 +1,61 @@ +// Copyright (c) 2012 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 GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_SHARED_H_ +#define GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_SHARED_H_ + +#include "command_buffer.h" +#include "base/atomicops.h" + +namespace gpu { + +// This is a standard 4-slot asynchronous communication mechanism, used to +// ensure that the reader gets a consistent copy of what the writer wrote. +template<typename T> +class SharedState { + T states_[2][2]; + base::subtle::Atomic32 reading_; + base::subtle::Atomic32 latest_; + base::subtle::Atomic32 slots_[2]; + +public: + + void Initialize() { + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < 2; ++j) { + states_[i][j] = T(); + } + } + base::subtle::NoBarrier_Store(&reading_, 0); + base::subtle::NoBarrier_Store(&latest_, 0); + base::subtle::NoBarrier_Store(&slots_[0], 0); + base::subtle::Acquire_Store(&slots_[1], 0); + } + + void Write(const T& state) { + int towrite = !base::subtle::Acquire_Load(&reading_); + int index = !base::subtle::Acquire_Load(&slots_[towrite]); + states_[towrite][index] = state; + base::subtle::MemoryBarrier(); + base::subtle::Acquire_Store(&slots_[towrite], index); + base::subtle::Acquire_Store(&latest_, towrite); + } + + // Attempt to update the state, updating only if the generation counter is + // newer. + void Read(T* state) { + base::subtle::MemoryBarrier(); + int toread = !!base::subtle::Acquire_Load(&latest_); + base::subtle::Acquire_Store(&reading_, toread); + int index = !!base::subtle::Acquire_Load(&slots_[toread]); + if (states_[toread][index].generation - state->generation < 0x80000000U) + *state = states_[toread][index]; + } +}; + +typedef SharedState<CommandBuffer::State> CommandBufferSharedState; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_SHARED_H_ |