15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains the command buffer helper class. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GPU_COMMAND_BUFFER_CLIENT_CMD_BUFFER_HELPER_H_ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPU_COMMAND_BUFFER_CLIENT_CMD_BUFFER_HELPER_H_ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/time/time.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/common/cmd_buffer_common.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/common/command_buffer.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/common/constants.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/gpu_export.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_ANDROID) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define CMD_HELPER_PERIODIC_FLUSH_CHECK 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kCommandsPerFlushCheck = 100; 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kPeriodicFlushDelayInMicroseconds = 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Time::kMicrosecondsPerSecond / (5 * 60); 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAutoFlushSmall = 16; // 1/16 of the buffer 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAutoFlushBig = 2; // 1/2 of the buffer 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Command buffer helper class. This class simplifies ring buffer management: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it will allocate the buffer, give it to the buffer interface, and let the 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// user add commands to it, while taking care of the synchronization (put and 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// get). It also provides a way to ensure commands have been executed, through 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the token mechanism: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// helper.AddCommand(...); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// helper.AddCommand(...); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int32 token = helper.InsertToken(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// helper.AddCommand(...); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// helper.AddCommand(...); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [...] 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// helper.WaitForToken(token); // this doesn't return until the first two 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // commands have been executed. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GPU_EXPORT CommandBufferHelper { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit CommandBufferHelper(CommandBuffer* command_buffer); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CommandBufferHelper(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the CommandBufferHelper. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parameters: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ring_buffer_size: The size of the ring buffer portion of the command 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffer. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Initialize(int32 ring_buffer_size); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets whether the command buffer should automatically flush periodically 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to try to increase performance. Defaults to true. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetAutomaticFlushes(bool enabled); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if the context is lost. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsContextLost(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Asynchronously flushes the commands, setting the put pointer to let the 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffer interface know that new commands have been added. After a flush 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns, the command buffer service is aware of all pending commands. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Flush(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Waits until all the commands have been executed. Returns whether it 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was successful. The function will fail if the command buffer service has 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disconnected. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Finish(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Waits until a given number of available entries are available. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parameters: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // count: number of entries needed. This value must be at most 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the size of the buffer minus one. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForAvailableEntries(int32 count); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inserts a new token into the command buffer. This token either has a value 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // different from previously inserted tokens, or ensures that previously 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inserted tokens with that value have already passed through the command 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stream. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the value of the new token or -1 if the command buffer reader has 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shutdown. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 InsertToken(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 894ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Returns true if the token has passed. 904ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Parameters: 914ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // the value of the token to check whether it has passed 924ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch bool HasTokenPassed(int32 token) const { 934ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch if (token > token_) 944ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return true; // we wrapped 954ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return last_token_read() >= token; 964ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch } 974ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Waits until the token of a particular value has passed through the command 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stream (i.e. commands inserted before that token have been executed). 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: This will call Flush if it needs to block. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parameters: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the value of the token to wait for. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForToken(int32 token); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called prior to each command being issued. Waits for a certain amount of 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // space to be available. Returns address of space. 107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch void* GetSpace(int32 entries) { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Allow this command buffer to be pre-empted by another if a "reasonable" 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // amount of work has been done. On highend machines, this reduces the 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // latency of GPU commands. However, on Android, this can cause the 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // kernel to thrash between generating GPU commands and executing them. 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++commands_issued_; 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (flush_automatically_ && 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (commands_issued_ % kCommandsPerFlushCheck == 0)) { 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PeriodicFlushCheck(); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Test for immediate entries. 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (entries > immediate_entry_count_) { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WaitForAvailableEntries(entries); 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (entries > immediate_entry_count_) 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_LE(entries, immediate_entry_count_); 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Allocate space and advance put_. 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CommandBufferEntry* space = &entries_[put_]; 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) put_ += entries; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) immediate_entry_count_ -= entries; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_LE(put_, total_entry_count_); 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return space; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu template <typename T> 1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void ForceNullCheck(T* data) { 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) 1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // 64-bit MSVC's alias analysis was determining that the command buffer 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // entry couldn't be NULL, so it optimized out the NULL check. 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Dereferencing the same datatype through a volatile pointer seems to 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // prevent that from happening. http://crbug.com/361936 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (data) 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static_cast<volatile T*>(data)->header; 1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Typed version of GetSpace. Gets enough room for the given type and returns 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a reference to it. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* GetCmdSpace() { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 space_needed = ComputeNumEntries(sizeof(T)); 1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu T* data = static_cast<T*>(GetSpace(space_needed)); 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ForceNullCheck(data); 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return data; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Typed version of GetSpace for immediate commands. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* GetImmediateCmdSpace(size_t data_space) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 space_needed = ComputeNumEntries(sizeof(T) + data_space); 1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu T* data = static_cast<T*>(GetSpace(space_needed)); 1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ForceNullCheck(data); 1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return data; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Typed version of GetSpace for immediate commands. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* GetImmediateCmdSpaceTotalSize(size_t total_space) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 space_needed = ComputeNumEntries(total_space); 1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu T* data = static_cast<T*>(GetSpace(space_needed)); 1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ForceNullCheck(data); 1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return data; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 last_token_read() const { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return command_buffer_->GetLastToken(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 get_offset() const { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer_->GetLastState().get_offset; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Common Commands 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Noop(uint32 skip_count) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd::Noop* cmd = GetImmediateCmdSpace<cmd::Noop>( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (skip_count - 1) * sizeof(CommandBufferEntry)); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cmd) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd->Init(skip_count); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetToken(uint32 token) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd::SetToken* cmd = GetCmdSpace<cmd::SetToken>(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cmd) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd->Init(token); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetBucketSize(uint32 bucket_id, uint32 size) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd::SetBucketSize* cmd = GetCmdSpace<cmd::SetBucketSize>(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cmd) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd->Init(bucket_id, size); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetBucketData(uint32 bucket_id, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 offset, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 size, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 shared_memory_id, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 shared_memory_offset) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd::SetBucketData* cmd = GetCmdSpace<cmd::SetBucketData>(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cmd) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd->Init(bucket_id, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_memory_id, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_memory_offset); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetBucketDataImmediate( 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 bucket_id, uint32 offset, const void* data, uint32 size) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd::SetBucketDataImmediate* cmd = 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetImmediateCmdSpace<cmd::SetBucketDataImmediate>(size); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cmd) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd->Init(bucket_id, offset, size); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(ImmediateDataAddress(cmd), data, size); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetBucketStart(uint32 bucket_id, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 result_memory_id, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 result_memory_offset, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 data_memory_size, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 data_memory_id, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 data_memory_offset) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd::GetBucketStart* cmd = GetCmdSpace<cmd::GetBucketStart>(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cmd) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd->Init(bucket_id, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_memory_id, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_memory_offset, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_memory_size, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_memory_id, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_memory_offset); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetBucketData(uint32 bucket_id, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 offset, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 size, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 shared_memory_id, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 shared_memory_offset) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd::GetBucketData* cmd = GetCmdSpace<cmd::GetBucketData>(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cmd) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd->Init(bucket_id, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_memory_id, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_memory_offset); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBuffer* command_buffer() const { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer_; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<Buffer> get_ring_buffer() const { return ring_buffer_; } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 flush_generation() const { return flush_generation_; } 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FreeRingBuffer(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HaveRingBuffer() const { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ring_buffer_id_ != -1; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool usable () const { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return usable_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClearUsable() { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usable_ = false; 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CalcImmediateEntries(0); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of available entries (they may not be contiguous). 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 AvailableEntries() { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (get_offset() - put_ - 1 + total_entry_count_) % total_entry_count_; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CalcImmediateEntries(int waiting_count); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AllocateRingBuffer(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FreeResources(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Waits for the get offset to be in a specific range, inclusive. Returns 30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // false if there was an error. 30423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool WaitForGetOffsetInRange(int32 start, int32 end); 30523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calls Flush if automatic flush conditions are met. 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PeriodicFlushCheck(); 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBuffer* command_buffer_; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 ring_buffer_id_; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 ring_buffer_size_; 314effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<gpu::Buffer> ring_buffer_; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferEntry* entries_; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 total_entry_count_; // the total number of entries 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32 immediate_entry_count_; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 token_; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 put_; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 last_put_sent_; 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int commands_issued_; 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool usable_; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool context_lost_; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool flush_automatically_; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::TimeTicks last_flush_time_; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Incremented every time the helper flushes the command buffer. 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Can be used to track when prior commands have been flushed. 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 flush_generation_; 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class CommandBufferHelperTest; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CommandBufferHelper); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gpu 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // GPU_COMMAND_BUFFER_CLIENT_CMD_BUFFER_HELPER_H_ 343