|  | // 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 <stddef.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <string> | 
|  |  | 
|  | #include "base/macros.h" | 
|  | #include "gpu/command_buffer/common/buffer.h" | 
|  | #include "gpu/command_buffer/service/cmd_parser.h" | 
|  | #include "gpu/gpu_export.h" | 
|  |  | 
|  | // Forwardly declare a few GL types to avoid including GL header files. | 
|  | typedef int GLsizei; | 
|  | typedef int GLint; | 
|  |  | 
|  | 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); | 
|  |  | 
|  | // Gets the bucket data as strings. | 
|  | // On success, the number of strings are in |_count|, the string data are | 
|  | // in |_string|, and string sizes are in |_length|.. | 
|  | bool GetAsStrings(GLsizei* _count, | 
|  | std::vector<char*>* _string, | 
|  | std::vector<GLint>* _length); | 
|  |  | 
|  | private: | 
|  | bool OffsetSizeValid(size_t offset, size_t size) const { | 
|  | size_t temp = offset + size; | 
|  | return temp <= size_ && temp >= offset; | 
|  | } | 
|  |  | 
|  | size_t size_; | 
|  | ::std::unique_ptr<int8_t[]> data_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(Bucket); | 
|  | }; | 
|  |  | 
|  | CommonDecoder(); | 
|  | ~CommonDecoder() override; | 
|  |  | 
|  | // 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_; } | 
|  |  | 
|  | // Sets the maximum size for buckets. | 
|  | void set_max_bucket_size(size_t max_bucket_size) { | 
|  | max_bucket_size_ = max_bucket_size; | 
|  | } | 
|  |  | 
|  | // Creates a bucket. If the bucket already exists returns that bucket. | 
|  | Bucket* CreateBucket(uint32_t bucket_id); | 
|  |  | 
|  | // Gets a bucket. Returns NULL if the bucket does not exist. | 
|  | Bucket* GetBucket(uint32_t 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)); | 
|  | } | 
|  |  | 
|  | void* GetAddressAndSize(unsigned int shm_id, | 
|  | unsigned int offset, | 
|  | unsigned int* size); | 
|  |  | 
|  | template <typename T> | 
|  | T GetSharedMemoryAndSizeAs(unsigned int shm_id, | 
|  | unsigned int offset, | 
|  | unsigned int* size) { | 
|  | return static_cast<T>(GetAddressAndSize(shm_id, offset, size)); | 
|  | } | 
|  |  | 
|  | unsigned int GetSharedMemorySize(unsigned int shm_id, unsigned int offset); | 
|  |  | 
|  | // Get the actual shared memory buffer. | 
|  | scoped_refptr<gpu::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_t immediate_data_size, const void* data); | 
|  |  | 
|  | COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) | 
|  |  | 
|  | #undef COMMON_COMMAND_BUFFER_CMD_OP | 
|  |  | 
|  | CommandBufferEngine* engine_; | 
|  | size_t max_bucket_size_; | 
|  |  | 
|  | typedef std::map<uint32_t, std::unique_ptr<Bucket>> BucketMap; | 
|  | BucketMap buckets_; | 
|  |  | 
|  | typedef Error (CommonDecoder::*CmdHandler)(uint32_t immediate_data_size, | 
|  | const void* data); | 
|  |  | 
|  | // A struct to hold info about each command. | 
|  | struct CommandInfo { | 
|  | CmdHandler cmd_handler; | 
|  | uint8_t arg_flags;   // How to handle the arguments for this command | 
|  | uint8_t cmd_flags;   // How to handle this command | 
|  | uint16_t arg_count;  // How many arguments are expected for this command. | 
|  | }; | 
|  |  | 
|  | // A table of CommandInfo for all the commands. | 
|  | static const CommandInfo command_info[]; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(CommonDecoder); | 
|  | }; | 
|  |  | 
|  | }  // namespace gpu | 
|  |  | 
|  | #endif  // GPU_COMMAND_BUFFER_SERVICE_COMMON_DECODER_H_ | 
|  |  |