summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/client/cmd_buffer_helper.h
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/client/cmd_buffer_helper.h')
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h
new file mode 100644
index 0000000..7cac568
--- /dev/null
+++ b/gpu/command_buffer/client/cmd_buffer_helper.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+// This file contains the command buffer helper class.
+
+#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_
+#define GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_
+
+#include "gpu/command_buffer/common/logging.h"
+#include "gpu/command_buffer/common/constants.h"
+#include "gpu/command_buffer/common/cmd_buffer_common.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+
+namespace command_buffer {
+
+// Command buffer helper class. This class simplifies ring buffer management:
+// it will allocate the buffer, give it to the buffer interface, and let the
+// user add commands to it, while taking care of the synchronization (put and
+// get). It also provides a way to ensure commands have been executed, through
+// the token mechanism:
+//
+// helper.AddCommand(...);
+// helper.AddCommand(...);
+// int32 token = helper.InsertToken();
+// helper.AddCommand(...);
+// helper.AddCommand(...);
+// [...]
+//
+// helper.WaitForToken(token); // this doesn't return until the first two
+// // commands have been executed.
+class CommandBufferHelper {
+ public:
+ explicit CommandBufferHelper(command_buffer::CommandBuffer* command_buffer);
+ virtual ~CommandBufferHelper();
+
+ bool Initialize();
+
+ // Flushes the commands, setting the put pointer to let the buffer interface
+ // know that new commands have been added. After a flush returns, the command
+ // buffer service is aware of all pending commands and it is guaranteed to
+ // have made some progress in processing them. Returns whether the flush was
+ // successful. The flush will fail if the command buffer service has
+ // disconnected.
+ bool Flush();
+
+ // Waits until all the commands have been executed. Returns whether it
+ // was successful. The function will fail if the command buffer service has
+ // disconnected.
+ bool Finish();
+
+ // Waits until a given number of available entries are available.
+ // Parameters:
+ // count: number of entries needed. This value must be at most
+ // the size of the buffer minus one.
+ void WaitForAvailableEntries(int32 count);
+
+ // Adds a command data to the command buffer. This may wait until sufficient
+ // space is available.
+ // Parameters:
+ // entries: The command entries to add.
+ // count: The number of entries.
+ void AddCommandData(const CommandBufferEntry* entries, int32 count) {
+ WaitForAvailableEntries(count);
+ for (; count > 0; --count) {
+ entries_[put_++] = *entries++;
+ }
+ DCHECK_LE(put_, entry_count_);
+ if (put_ == entry_count_) put_ = 0;
+ }
+
+ // A typed version of AddCommandData.
+ template <typename T>
+ void AddTypedCmdData(const T& cmd) {
+ AddCommandData(reinterpret_cast<const CommandBufferEntry*>(&cmd),
+ ComputeNumEntries(sizeof(cmd)));
+ }
+
+ // Adds a command to the command buffer. This may wait until sufficient space
+ // is available.
+ // Parameters:
+ // command: the command index.
+ // arg_count: the number of arguments for the command.
+ // args: the arguments for the command (these are copied before the
+ // function returns).
+ void AddCommand(int32 command,
+ int32 arg_count,
+ const CommandBufferEntry *args) {
+ CommandHeader header;
+ header.size = arg_count + 1;
+ header.command = command;
+ WaitForAvailableEntries(header.size);
+ entries_[put_++].value_header = header;
+ for (int i = 0; i < arg_count; ++i) {
+ entries_[put_++] = args[i];
+ }
+ DCHECK_LE(put_, entry_count_);
+ if (put_ == entry_count_) put_ = 0;
+ }
+
+ // Inserts a new token into the command buffer. This token either has a value
+ // different from previously inserted tokens, or ensures that previously
+ // inserted tokens with that value have already passed through the command
+ // stream.
+ // Returns:
+ // the value of the new token or -1 if the command buffer reader has
+ // shutdown.
+ int32 InsertToken();
+
+ // Waits until the token of a particular value has passed through the command
+ // stream (i.e. commands inserted before that token have been executed).
+ // NOTE: This will call Flush if it needs to block.
+ // Parameters:
+ // the value of the token to wait for.
+ void WaitForToken(int32 token);
+
+ // Waits for a certain amount of space to be available. Returns address
+ // of space.
+ CommandBufferEntry* GetSpace(uint32 entries);
+
+ // Typed version of GetSpace. Gets enough room for the given type and returns
+ // a reference to it.
+ template <typename T>
+ T& GetCmdSpace() {
+ COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed);
+ uint32 space_needed = ComputeNumEntries(sizeof(T));
+ void* data = GetSpace(space_needed);
+ return *reinterpret_cast<T*>(data);
+ }
+
+ // Typed version of GetSpace for immediate commands.
+ template <typename T>
+ T& GetImmediateCmdSpace(size_t data_space) {
+ COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
+ uint32 space_needed = ComputeNumEntries(sizeof(T) + data_space);
+ void* data = GetSpace(space_needed);
+ return *reinterpret_cast<T*>(data);
+ }
+
+ // Typed version of GetSpace for immediate commands.
+ template <typename T>
+ T& GetImmediateCmdSpaceTotalSize(size_t total_space) {
+ COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
+ uint32 space_needed = ComputeNumEntries(total_space);
+ void* data = GetSpace(space_needed);
+ return *reinterpret_cast<T*>(data);
+ }
+
+ parse_error::ParseError GetParseError();
+
+ // Common Commands
+ void Noop(uint32 skip_count) {
+ cmd::Noop& cmd = GetImmediateCmdSpace<cmd::Noop>(
+ skip_count * sizeof(CommandBufferEntry));
+ cmd.Init(skip_count);
+ }
+
+ void SetToken(uint32 token) {
+ cmd::SetToken& cmd = GetCmdSpace<cmd::SetToken>();
+ cmd.Init(token);
+ }
+
+
+ private:
+ // Waits until get changes, updating the value of get_.
+ void WaitForGetChange();
+
+ // Returns the number of available entries (they may not be contiguous).
+ int32 AvailableEntries() {
+ return (get_ - put_ - 1 + entry_count_) % entry_count_;
+ }
+
+ command_buffer::CommandBuffer* command_buffer_;
+ ::base::SharedMemory* ring_buffer_;
+ CommandBufferEntry *entries_;
+ int32 entry_count_;
+ int32 token_;
+ int32 last_token_read_;
+ int32 get_;
+ int32 put_;
+
+ friend class CommandBufferHelperTest;
+ DISALLOW_COPY_AND_ASSIGN(CommandBufferHelper);
+};
+
+} // namespace command_buffer
+
+#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_