1 // 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 5 #ifndef GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_SHARED_H_ 6 #define GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_SHARED_H_ 7 8 #include "command_buffer.h" 9 #include "base/atomicops.h" 10 11 namespace gpu { 12 13 // This is a standard 4-slot asynchronous communication mechanism, used to 14 // ensure that the reader gets a consistent copy of what the writer wrote. 15 template<typename T> 16 class SharedState { 17 T states_[2][2]; 18 base::subtle::Atomic32 reading_; 19 base::subtle::Atomic32 latest_; 20 base::subtle::Atomic32 slots_[2]; 21 22 public: 23 Initialize()24 void Initialize() { 25 for (int i = 0; i < 2; ++i) { 26 for (int j = 0; j < 2; ++j) { 27 states_[i][j] = T(); 28 } 29 } 30 base::subtle::NoBarrier_Store(&reading_, 0); 31 base::subtle::NoBarrier_Store(&latest_, 0); 32 base::subtle::NoBarrier_Store(&slots_[0], 0); 33 base::subtle::Release_Store(&slots_[1], 0); 34 base::subtle::MemoryBarrier(); 35 } 36 Write(const T & state)37 void Write(const T& state) { 38 int towrite = !base::subtle::Acquire_Load(&reading_); 39 int index = !base::subtle::Acquire_Load(&slots_[towrite]); 40 states_[towrite][index] = state; 41 base::subtle::Release_Store(&slots_[towrite], index); 42 base::subtle::Release_Store(&latest_, towrite); 43 base::subtle::MemoryBarrier(); 44 } 45 46 // Attempt to update the state, updating only if the generation counter is 47 // newer. Read(T * state)48 void Read(T* state) { 49 base::subtle::MemoryBarrier(); 50 int toread = !!base::subtle::Acquire_Load(&latest_); 51 base::subtle::Release_Store(&reading_, toread); 52 base::subtle::MemoryBarrier(); 53 int index = !!base::subtle::Acquire_Load(&slots_[toread]); 54 if (states_[toread][index].generation - state->generation < 0x80000000U) 55 *state = states_[toread][index]; 56 } 57 }; 58 59 typedef SharedState<CommandBuffer::State> CommandBufferSharedState; 60 61 } // namespace gpu 62 63 #endif // GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_SHARED_H_ 64