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_SERVICE_COMMON_DECODER_H_ 6 #define GPU_COMMAND_BUFFER_SERVICE_COMMON_DECODER_H_ 7 8 #include <map> 9 #include <stack> 10 #include <string> 11 #include "base/memory/linked_ptr.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "gpu/command_buffer/common/buffer.h" 14 #include "gpu/command_buffer/service/cmd_parser.h" 15 #include "gpu/gpu_export.h" 16 17 namespace gpu { 18 19 class CommandBufferEngine; 20 21 // This class is a helper base class for implementing the common parts of the 22 // o3d/gl2 command buffer decoder. 23 class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) { 24 public: 25 typedef error::Error Error; 26 27 static const unsigned int kMaxStackDepth = 32; 28 29 // A bucket is a buffer to help collect memory across a command buffer. When 30 // creating a command buffer implementation of an existing API, sometimes that 31 // API has functions that take a pointer to data. A good example is OpenGL's 32 // glBufferData. Because the data is separated between client and service, 33 // there are 2 ways to get this data across. 1 is to put all the data in 34 // shared memory. The problem with this is the data can be arbitarily large 35 // and the host OS may not support that much shared memory. Another solution 36 // is to shuffle memory across a little bit at a time, collecting it on the 37 // service side and when it is all there then call glBufferData. Buckets 38 // implement this second solution. Using the common commands, SetBucketSize, 39 // SetBucketData, SetBucketDataImmediate the client can fill a bucket. It can 40 // then call a command that uses that bucket (like BufferDataBucket in the 41 // GLES2 command buffer implementation). 42 // 43 // If you are designing an API from scratch you can avoid this need for 44 // Buckets by making your API always take an offset and a size 45 // similar to glBufferSubData. 46 // 47 // Buckets also help pass strings to/from the service. To return a string of 48 // arbitary size, the service puts the string in a bucket. The client can 49 // then query the size of a bucket and request sections of the bucket to 50 // be passed across shared memory. 51 class GPU_EXPORT Bucket { 52 public: 53 Bucket(); 54 ~Bucket(); 55 56 size_t size() const { 57 return size_; 58 } 59 60 // Gets a pointer to a section the bucket. Returns NULL if offset or size is 61 // out of range. 62 void* GetData(size_t offset, size_t size) const; 63 64 template <typename T> 65 T GetDataAs(size_t offset, size_t size) const { 66 return reinterpret_cast<T>(GetData(offset, size)); 67 } 68 69 // Sets the size of the bucket. 70 void SetSize(size_t size); 71 72 // Sets a part of the bucket. 73 // Returns false if offset or size is out of range. 74 bool SetData(const void* src, size_t offset, size_t size); 75 76 // Sets the bucket data from a string. Strings are passed NULL terminated to 77 // distinguish between empty string and no string. 78 void SetFromString(const char* str); 79 80 // Gets the bucket data as a string. Strings are passed NULL terminated to 81 // distrinquish between empty string and no string. Returns False if there 82 // is no string. 83 bool GetAsString(std::string* str); 84 85 private: 86 bool OffsetSizeValid(size_t offset, size_t size) const { 87 size_t temp = offset + size; 88 return temp <= size_ && temp >= offset; 89 } 90 91 size_t size_; 92 ::scoped_ptr<int8[]> data_; 93 94 DISALLOW_COPY_AND_ASSIGN(Bucket); 95 }; 96 97 CommonDecoder(); 98 virtual ~CommonDecoder(); 99 100 // Sets the engine, to get shared memory buffers from, and to set the token 101 // to. 102 void set_engine(CommandBufferEngine* engine) { 103 engine_ = engine; 104 } 105 CommandBufferEngine* engine() const { return engine_; } 106 107 // Creates a bucket. If the bucket already exists returns that bucket. 108 Bucket* CreateBucket(uint32 bucket_id); 109 110 // Gets a bucket. Returns NULL if the bucket does not exist. 111 Bucket* GetBucket(uint32 bucket_id) const; 112 113 // Gets the address of shared memory data, given a shared memory ID and an 114 // offset. Also checks that the size is consistent with the shared memory 115 // size. 116 // Parameters: 117 // shm_id: the id of the shared memory buffer. 118 // offset: the offset of the data in the shared memory buffer. 119 // size: the size of the data. 120 // Returns: 121 // NULL if shm_id isn't a valid shared memory buffer ID or if the size 122 // check fails. Return a pointer to the data otherwise. 123 void* GetAddressAndCheckSize(unsigned int shm_id, 124 unsigned int offset, 125 unsigned int size); 126 127 // Typed version of GetAddressAndCheckSize. 128 template <typename T> 129 T GetSharedMemoryAs(unsigned int shm_id, unsigned int offset, 130 unsigned int size) { 131 return static_cast<T>(GetAddressAndCheckSize(shm_id, offset, size)); 132 } 133 134 // Get the actual shared memory buffer. 135 Buffer GetSharedMemoryBuffer(unsigned int shm_id); 136 137 protected: 138 // Executes a common command. 139 // Parameters: 140 // command: the command index. 141 // arg_count: the number of CommandBufferEntry arguments. 142 // cmd_data: the command data. 143 // Returns: 144 // error::kNoError if no error was found, one of 145 // error::Error otherwise. 146 error::Error DoCommonCommand( 147 unsigned int command, 148 unsigned int arg_count, 149 const void* cmd_data); 150 151 // Gets an name for a common command. 152 const char* GetCommonCommandName(cmd::CommandId command_id) const; 153 154 private: 155 // Generate a member function prototype for each command in an automated and 156 // typesafe way. 157 #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ 158 error::Error Handle##name( \ 159 uint32 immediate_data_size, \ 160 const cmd::name& args); \ 161 162 COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) 163 164 #undef COMMON_COMMAND_BUFFER_CMD_OP 165 166 CommandBufferEngine* engine_; 167 168 typedef std::map<uint32, linked_ptr<Bucket> > BucketMap; 169 BucketMap buckets_; 170 }; 171 172 } // namespace gpu 173 174 #endif // GPU_COMMAND_BUFFER_SERVICE_COMMON_DECODER_H_ 175 176