diff options
Diffstat (limited to 'chromium/gpu/command_buffer/service/common_decoder.h')
-rw-r--r-- | chromium/gpu/command_buffer/service/common_decoder.h | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/chromium/gpu/command_buffer/service/common_decoder.h b/chromium/gpu/command_buffer/service/common_decoder.h new file mode 100644 index 00000000000..03002c8b06f --- /dev/null +++ b/chromium/gpu/command_buffer/service/common_decoder.h @@ -0,0 +1,175 @@ +// 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_SERVICE_COMMON_DECODER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_COMMON_DECODER_H_ + +#include <map> +#include <stack> +#include <string> +#include "base/memory/linked_ptr.h" +#include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/common/buffer.h" +#include "gpu/command_buffer/service/cmd_parser.h" +#include "gpu/gpu_export.h" + +namespace gpu { + +class CommandBufferEngine; + +// This class is a helper base class for implementing the common parts of the +// o3d/gl2 command buffer decoder. +class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { + public: + typedef error::Error Error; + + static const unsigned int kMaxStackDepth = 32; + + // A bucket is a buffer to help collect memory across a command buffer. When + // creating a command buffer implementation of an existing API, sometimes that + // API has functions that take a pointer to data. A good example is OpenGL's + // glBufferData. Because the data is separated between client and service, + // there are 2 ways to get this data across. 1 is to put all the data in + // shared memory. The problem with this is the data can be arbitarily large + // and the host OS may not support that much shared memory. Another solution + // is to shuffle memory across a little bit at a time, collecting it on the + // service side and when it is all there then call glBufferData. Buckets + // implement this second solution. Using the common commands, SetBucketSize, + // SetBucketData, SetBucketDataImmediate the client can fill a bucket. It can + // then call a command that uses that bucket (like BufferDataBucket in the + // GLES2 command buffer implementation). + // + // If you are designing an API from scratch you can avoid this need for + // Buckets by making your API always take an offset and a size + // similar to glBufferSubData. + // + // Buckets also help pass strings to/from the service. To return a string of + // arbitary size, the service puts the string in a bucket. The client can + // then query the size of a bucket and request sections of the bucket to + // be passed across shared memory. + class GPU_EXPORT Bucket { + public: + Bucket(); + ~Bucket(); + + size_t size() const { + return size_; + } + + // Gets a pointer to a section the bucket. Returns NULL if offset or size is + // out of range. + void* GetData(size_t offset, size_t size) const; + + template <typename T> + T GetDataAs(size_t offset, size_t size) const { + return reinterpret_cast<T>(GetData(offset, size)); + } + + // Sets the size of the bucket. + void SetSize(size_t size); + + // Sets a part of the bucket. + // Returns false if offset or size is out of range. + bool SetData(const void* src, size_t offset, size_t size); + + // Sets the bucket data from a string. Strings are passed NULL terminated to + // distinguish between empty string and no string. + void SetFromString(const char* str); + + // Gets the bucket data as a string. Strings are passed NULL terminated to + // distrinquish between empty string and no string. Returns False if there + // is no string. + bool GetAsString(std::string* str); + + private: + bool OffsetSizeValid(size_t offset, size_t size) const { + size_t temp = offset + size; + return temp <= size_ && temp >= offset; + } + + size_t size_; + ::scoped_ptr<int8[]> data_; + + DISALLOW_COPY_AND_ASSIGN(Bucket); + }; + + CommonDecoder(); + virtual ~CommonDecoder(); + + // Sets the engine, to get shared memory buffers from, and to set the token + // to. + void set_engine(CommandBufferEngine* engine) { + engine_ = engine; + } + CommandBufferEngine* engine() const { return engine_; } + + // Creates a bucket. If the bucket already exists returns that bucket. + Bucket* CreateBucket(uint32 bucket_id); + + // Gets a bucket. Returns NULL if the bucket does not exist. + Bucket* GetBucket(uint32 bucket_id) const; + + // Gets the address of shared memory data, given a shared memory ID and an + // offset. Also checks that the size is consistent with the shared memory + // size. + // Parameters: + // shm_id: the id of the shared memory buffer. + // offset: the offset of the data in the shared memory buffer. + // size: the size of the data. + // Returns: + // NULL if shm_id isn't a valid shared memory buffer ID or if the size + // check fails. Return a pointer to the data otherwise. + void* GetAddressAndCheckSize(unsigned int shm_id, + unsigned int offset, + unsigned int size); + + // Typed version of GetAddressAndCheckSize. + template <typename T> + T GetSharedMemoryAs(unsigned int shm_id, unsigned int offset, + unsigned int size) { + return static_cast<T>(GetAddressAndCheckSize(shm_id, offset, size)); + } + + // Get the actual shared memory buffer. + Buffer GetSharedMemoryBuffer(unsigned int shm_id); + + protected: + // Executes a common command. + // Parameters: + // command: the command index. + // arg_count: the number of CommandBufferEntry arguments. + // cmd_data: the command data. + // Returns: + // error::kNoError if no error was found, one of + // error::Error otherwise. + error::Error DoCommonCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data); + + // Gets an name for a common command. + const char* GetCommonCommandName(cmd::CommandId command_id) const; + + private: + // Generate a member function prototype for each command in an automated and + // typesafe way. + #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ + error::Error Handle##name( \ + uint32 immediate_data_size, \ + const cmd::name& args); \ + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + + CommandBufferEngine* engine_; + + typedef std::map<uint32, linked_ptr<Bucket> > BucketMap; + BucketMap buckets_; +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_COMMON_DECODER_H_ + |