| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // A class to emluate GLES2 over command buffers. | 5 // A class to emluate GLES2 over command buffers. |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 8 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 8 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 9 | 9 |
| 10 namespace gpu { | 10 namespace gpu { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 GLES2Implementation::GLES2Implementation( | 22 GLES2Implementation::GLES2Implementation( |
| 23 GLES2CmdHelper* helper, | 23 GLES2CmdHelper* helper, |
| 24 size_t transfer_buffer_size, | 24 size_t transfer_buffer_size, |
| 25 void* transfer_buffer, | 25 void* transfer_buffer, |
| 26 int32 transfer_buffer_id) | 26 int32 transfer_buffer_id) |
| 27 : util_(0), // TODO(gman): Get real number of compressed texture formats. | 27 : util_(0), // TODO(gman): Get real number of compressed texture formats. |
| 28 helper_(helper), | 28 helper_(helper), |
| 29 transfer_buffer_(transfer_buffer_size, helper, transfer_buffer), | 29 transfer_buffer_(transfer_buffer_size, helper, transfer_buffer), |
| 30 transfer_buffer_id_(transfer_buffer_id), | 30 transfer_buffer_id_(transfer_buffer_id), |
| 31 pack_alignment_(4), | 31 pack_alignment_(4), |
| 32 unpack_alignment_(4), | 32 unpack_alignment_(4) { |
| 33 error_bits_(0) { | |
| 34 // Eat 1 id so we start at 1 instead of 0. | 33 // Eat 1 id so we start at 1 instead of 0. |
| 35 GLuint eat; | 34 GLuint eat; |
| 36 MakeIds(1, &eat); | 35 MakeIds(1, &eat); |
| 37 // Allocate space for simple GL results. | 36 // Allocate space for simple GL results. |
| 38 result_buffer_ = transfer_buffer_.Alloc(kMaxSizeOfSimpleResult); | 37 result_buffer_ = transfer_buffer_.Alloc(kMaxSizeOfSimpleResult); |
| 39 result_shm_offset_ = transfer_buffer_.GetOffset(result_buffer_); | 38 result_shm_offset_ = transfer_buffer_.GetOffset(result_buffer_); |
| 40 } | 39 } |
| 41 | 40 |
| 42 GLES2Implementation::~GLES2Implementation() { | 41 GLES2Implementation::~GLES2Implementation() { |
| 43 transfer_buffer_.Free(result_buffer_); | 42 transfer_buffer_.Free(result_buffer_); |
| 44 } | 43 } |
| 45 | 44 |
| 46 void GLES2Implementation::MakeIds(GLsizei n, GLuint* ids) { | 45 void GLES2Implementation::MakeIds(GLsizei n, GLuint* ids) { |
| 47 for (GLsizei ii = 0; ii < n; ++ii) { | 46 for (GLsizei ii = 0; ii < n; ++ii) { |
| 48 ids[ii] = id_allocator_.AllocateID(); | 47 ids[ii] = id_allocator_.AllocateID(); |
| 49 } | 48 } |
| 50 } | 49 } |
| 51 | 50 |
| 52 void GLES2Implementation::FreeIds(GLsizei n, const GLuint* ids) { | 51 void GLES2Implementation::FreeIds(GLsizei n, const GLuint* ids) { |
| 53 for (GLsizei ii = 0; ii < n; ++ii) { | 52 for (GLsizei ii = 0; ii < n; ++ii) { |
| 54 id_allocator_.FreeID(ids[ii]); | 53 id_allocator_.FreeID(ids[ii]); |
| 55 } | 54 } |
| 56 } | 55 } |
| 57 | 56 |
| 58 void GLES2Implementation::WaitForCmd() { | 57 void GLES2Implementation::WaitForCmd() { |
| 59 helper_->CommandBufferHelper::Finish(); | 58 helper_->CommandBufferHelper::Finish(); |
| 60 } | 59 } |
| 61 | 60 |
| 62 GLenum GLES2Implementation::GetError() { | |
| 63 return GetGLError(); | |
| 64 } | |
| 65 | |
| 66 GLenum GLES2Implementation::GetGLError() { | |
| 67 // Check the GL error first, then our wrapped error. | |
| 68 typedef gles2::GetError::Result Result; | |
| 69 Result* result = GetResultAs<Result*>(); | |
| 70 *result = GL_NO_ERROR; | |
| 71 helper_->GetError(result_shm_id(), result_shm_offset()); | |
| 72 WaitForCmd(); | |
| 73 GLenum error = *result; | |
| 74 if (error == GL_NO_ERROR && error_bits_ != 0) { | |
| 75 for (uint32 mask = 1; mask != 0; mask = mask << 1) { | |
| 76 if ((error_bits_ & mask) != 0) { | |
| 77 error = GLES2Util::GLErrorBitToGLError(mask); | |
| 78 break; | |
| 79 } | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 if (error != GL_NO_ERROR) { | |
| 84 // There was an error, clear the corresponding wrapped error. | |
| 85 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error); | |
| 86 } | |
| 87 return error; | |
| 88 } | |
| 89 | |
| 90 void GLES2Implementation::SetGLError(GLenum error) { | |
| 91 error_bits_ |= GLES2Util::GLErrorToErrorBit(error); | |
| 92 } | |
| 93 | |
| 94 void GLES2Implementation::GetBucketContents(uint32 bucket_id, | 61 void GLES2Implementation::GetBucketContents(uint32 bucket_id, |
| 95 std::vector<int8>* data) { | 62 std::vector<int8>* data) { |
| 96 DCHECK(data); | 63 DCHECK(data); |
| 97 typedef cmd::GetBucketSize::Result Result; | |
| 98 Result* result = GetResultAs<Result*>(); | |
| 99 *result = 0; | |
| 100 helper_->GetBucketSize(bucket_id, result_shm_id(), result_shm_offset()); | 64 helper_->GetBucketSize(bucket_id, result_shm_id(), result_shm_offset()); |
| 101 WaitForCmd(); | 65 WaitForCmd(); |
| 102 uint32 size = *result; | 66 uint32 size = GetResultAs<cmd::GetBucketSize::Result>(); |
| 103 data->resize(size); | 67 data->resize(size); |
| 104 if (size > 0u) { | 68 if (size > 0u) { |
| 105 uint32 max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); | 69 uint32 max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); |
| 106 uint32 offset = 0; | 70 uint32 offset = 0; |
| 107 while (size) { | 71 while (size) { |
| 108 uint32 part_size = std::min(max_size, size); | 72 uint32 part_size = std::min(max_size, size); |
| 109 void* buffer = transfer_buffer_.Alloc(part_size); | 73 void* buffer = transfer_buffer_.Alloc(part_size); |
| 110 helper_->GetBucketData( | 74 helper_->GetBucketData( |
| 111 bucket_id, offset, part_size, | 75 bucket_id, offset, part_size, |
| 112 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); | 76 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 137 helper_->SetBucketData( | 101 helper_->SetBucketData( |
| 138 bucket_id, offset, part_size, | 102 bucket_id, offset, part_size, |
| 139 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); | 103 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); |
| 140 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); | 104 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); |
| 141 offset += part_size; | 105 offset += part_size; |
| 142 size -= part_size; | 106 size -= part_size; |
| 143 } | 107 } |
| 144 } | 108 } |
| 145 } | 109 } |
| 146 | 110 |
| 147 bool GLES2Implementation::GetBucketAsString( | 111 std::string GLES2Implementation::GetBucketAsString(uint32 bucket_id) { |
| 148 uint32 bucket_id, std::string* str) { | |
| 149 DCHECK(str); | |
| 150 std::vector<int8> data; | 112 std::vector<int8> data; |
| 151 // NOTE: strings are passed NULL terminated. That means the empty | |
| 152 // string will have a size of 1 and no-string will have a size of 0 | |
| 153 GetBucketContents(bucket_id, &data); | 113 GetBucketContents(bucket_id, &data); |
| 154 if (data.empty()) { | 114 return std::string(reinterpret_cast<char*>(&data[0]), data.size()); |
| 155 return false; | |
| 156 } | |
| 157 str->assign(&data[0], &data[0] + data.size() - 1); | |
| 158 return true; | |
| 159 } | 115 } |
| 160 | 116 |
| 161 void GLES2Implementation::SetBucketAsString( | 117 void GLES2Implementation::SetBucketAsString( |
| 162 uint32 bucket_id, const std::string& str) { | 118 uint32 bucket_id, const std::string& str) { |
| 163 // NOTE: strings are passed NULL terminated. That means the empty | 119 SetBucketContents(bucket_id, str.c_str(), str.size()); |
| 164 // string will have a size of 1 and no-string will have a size of 0 | |
| 165 SetBucketContents(bucket_id, str.c_str(), str.size() + 1); | |
| 166 } | 120 } |
| 167 | 121 |
| 168 void GLES2Implementation::DrawElements( | 122 void GLES2Implementation::DrawElements( |
| 169 GLenum mode, GLsizei count, GLenum type, const void* indices) { | 123 GLenum mode, GLsizei count, GLenum type, const void* indices) { |
| 170 helper_->DrawElements(mode, count, type, ToGLuint(indices)); | 124 helper_->DrawElements(mode, count, type, ToGLuint(indices)); |
| 171 } | 125 } |
| 172 | 126 |
| 173 void GLES2Implementation::Flush() { | 127 void GLES2Implementation::Flush() { |
| 174 // Insert the cmd to call glFlush | 128 // Insert the cmd to call glFlush |
| 175 helper_->Flush(); | 129 helper_->Flush(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 196 GLuint index, GLenum pname, void** ptr) { | 150 GLuint index, GLenum pname, void** ptr) { |
| 197 helper_->GetVertexAttribPointerv( | 151 helper_->GetVertexAttribPointerv( |
| 198 index, pname, result_shm_id(), result_shm_offset()); | 152 index, pname, result_shm_id(), result_shm_offset()); |
| 199 WaitForCmd(); | 153 WaitForCmd(); |
| 200 static_cast<gles2::GetVertexAttribPointerv::Result*>( | 154 static_cast<gles2::GetVertexAttribPointerv::Result*>( |
| 201 result_buffer_)->CopyResult(ptr); | 155 result_buffer_)->CopyResult(ptr); |
| 202 }; | 156 }; |
| 203 | 157 |
| 204 GLint GLES2Implementation::GetAttribLocation( | 158 GLint GLES2Implementation::GetAttribLocation( |
| 205 GLuint program, const char* name) { | 159 GLuint program, const char* name) { |
| 206 typedef cmd::GetBucketSize::Result Result; | |
| 207 Result* result = GetResultAs<Result*>(); | |
| 208 *result = -1; | |
| 209 helper_->GetAttribLocationImmediate( | 160 helper_->GetAttribLocationImmediate( |
| 210 program, name, result_shm_id(), result_shm_offset()); | 161 program, name, result_shm_id(), result_shm_offset()); |
| 211 WaitForCmd(); | 162 WaitForCmd(); |
| 212 return *result; | 163 return GetResultAs<GLint>(); |
| 213 } | 164 } |
| 214 | 165 |
| 215 GLint GLES2Implementation::GetUniformLocation( | 166 GLint GLES2Implementation::GetUniformLocation( |
| 216 GLuint program, const char* name) { | 167 GLuint program, const char* name) { |
| 217 typedef cmd::GetBucketSize::Result Result; | |
| 218 Result* result = GetResultAs<Result*>(); | |
| 219 *result = -1; | |
| 220 helper_->GetUniformLocationImmediate( | 168 helper_->GetUniformLocationImmediate( |
| 221 program, name, result_shm_id(), result_shm_offset()); | 169 program, name, result_shm_id(), result_shm_offset()); |
| 222 WaitForCmd(); | 170 WaitForCmd(); |
| 223 return *result; | 171 return GetResultAs<GLint>(); |
| 224 } | 172 } |
| 225 | 173 |
| 226 void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { | 174 void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { |
| 227 switch (pname) { | 175 switch (pname) { |
| 228 case GL_PACK_ALIGNMENT: | 176 case GL_PACK_ALIGNMENT: |
| 229 pack_alignment_ = param; | 177 pack_alignment_ = param; |
| 230 break; | 178 break; |
| 231 case GL_UNPACK_ALIGNMENT: | 179 case GL_UNPACK_ALIGNMENT: |
| 232 unpack_alignment_ = param; | 180 unpack_alignment_ = param; |
| 233 break; | 181 break; |
| 234 default: | 182 default: |
| 235 break; | 183 break; |
| 236 } | 184 } |
| 237 helper_->PixelStorei(pname, param); | 185 helper_->PixelStorei(pname, param); |
| 238 } | 186 } |
| 239 | 187 |
| 240 | 188 |
| 241 void GLES2Implementation::VertexAttribPointer( | 189 void GLES2Implementation::VertexAttribPointer( |
| 242 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, | 190 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, |
| 243 const void* ptr) { | 191 const void* ptr) { |
| 244 helper_->VertexAttribPointer(index, size, type, normalized, stride, | 192 helper_->VertexAttribPointer(index, size, type, normalized, stride, |
| 245 ToGLuint(ptr)); | 193 ToGLuint(ptr)); |
| 246 } | 194 } |
| 247 | 195 |
| 248 void GLES2Implementation::ShaderSource( | 196 void GLES2Implementation::ShaderSource( |
| 249 GLuint shader, GLsizei count, const char** source, const GLint* length) { | 197 GLuint shader, GLsizei count, const char** source, const GLint* length) { |
| 250 if (count < 0) { | |
| 251 SetGLError(GL_INVALID_VALUE); | |
| 252 return; | |
| 253 } | |
| 254 // TODO(gman): change to use buckets and check that there is enough room. | 198 // TODO(gman): change to use buckets and check that there is enough room. |
| 255 | 199 |
| 256 // Compute the total size. | 200 // Compute the total size. |
| 257 uint32 total_size = 0; | 201 uint32 total_size = 0; |
| 258 for (GLsizei ii = 0; ii < count; ++ii) { | 202 for (GLsizei ii = 0; ii < count; ++ii) { |
| 259 total_size += length ? length[ii] : strlen(source[ii]); | 203 total_size += length ? length[ii] : strlen(source[ii]); |
| 260 } | 204 } |
| 261 | 205 |
| 262 // Concatenate all the strings in to the transfer buffer. | 206 // Concatenate all the strings in to the transfer buffer. |
| 263 char* strings = transfer_buffer_.AllocTyped<char>(total_size); | 207 char* strings = transfer_buffer_.AllocTyped<char>(total_size); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 282 // with the actual data in the case of our transfer buffer being big | 226 // with the actual data in the case of our transfer buffer being big |
| 283 // enough? | 227 // enough? |
| 284 helper_->BufferData(target, size, 0, 0, usage); | 228 helper_->BufferData(target, size, 0, 0, usage); |
| 285 if (data != NULL) { | 229 if (data != NULL) { |
| 286 BufferSubData(target, 0, size, data); | 230 BufferSubData(target, 0, size, data); |
| 287 } | 231 } |
| 288 } | 232 } |
| 289 | 233 |
| 290 void GLES2Implementation::BufferSubData( | 234 void GLES2Implementation::BufferSubData( |
| 291 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { | 235 GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { |
| 292 if (size == 0) { | |
| 293 return; | |
| 294 } | |
| 295 | |
| 296 if (size < 0) { | |
| 297 SetGLError(GL_INVALID_VALUE); | |
| 298 return; | |
| 299 } | |
| 300 | |
| 301 const int8* source = static_cast<const int8*>(data); | 236 const int8* source = static_cast<const int8*>(data); |
| 302 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); | 237 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); |
| 303 while (size) { | 238 while (size) { |
| 304 GLsizeiptr part_size = std::min(size, max_size); | 239 GLsizeiptr part_size = std::min(size, max_size); |
| 305 void* buffer = transfer_buffer_.Alloc(part_size); | 240 void* buffer = transfer_buffer_.Alloc(part_size); |
| 306 memcpy(buffer, source, part_size); | 241 memcpy(buffer, source, part_size); |
| 307 helper_->BufferSubData(target, offset, part_size, | 242 helper_->BufferSubData(target, offset, part_size, |
| 308 transfer_buffer_id_, | 243 transfer_buffer_id_, |
| 309 transfer_buffer_.GetOffset(buffer)); | 244 transfer_buffer_.GetOffset(buffer)); |
| 310 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); | 245 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); |
| 311 offset += part_size; | 246 offset += part_size; |
| 312 source += part_size; | 247 source += part_size; |
| 313 size -= part_size; | 248 size -= part_size; |
| 314 } | 249 } |
| 315 } | 250 } |
| 316 | 251 |
| 317 void GLES2Implementation::CompressedTexImage2D( | 252 void GLES2Implementation::CompressedTexImage2D( |
| 318 GLenum target, GLint level, GLenum internalformat, GLsizei width, | 253 GLenum target, GLint level, GLenum internalformat, GLsizei width, |
| 319 GLsizei height, GLint border, GLsizei image_size, const void* data) { | 254 GLsizei height, GLint border, GLsizei image_size, const void* data) { |
| 320 if (width < 0 || height < 0 || level < 0) { | 255 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared |
| 321 SetGLError(GL_INVALID_VALUE); | |
| 322 return; | |
| 323 } | |
| 324 // TODO(gman): Switch to use buckets always or at least if no room in shared | |
| 325 // memory. | 256 // memory. |
| 326 DCHECK_LE(image_size, | 257 DCHECK_LE(image_size, |
| 327 static_cast<GLsizei>( | 258 static_cast<GLsizei>( |
| 328 transfer_buffer_.GetLargestFreeOrPendingSize())); | 259 transfer_buffer_.GetLargestFreeOrPendingSize())); |
| 329 void* buffer = transfer_buffer_.Alloc(image_size); | 260 void* buffer = transfer_buffer_.Alloc(image_size); |
| 330 memcpy(buffer, data, image_size); | 261 memcpy(buffer, data, image_size); |
| 331 helper_->CompressedTexImage2D( | 262 helper_->CompressedTexImage2D( |
| 332 target, level, internalformat, width, height, border, image_size, | 263 target, level, internalformat, width, height, border, image_size, |
| 333 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); | 264 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); |
| 334 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); | 265 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); |
| 335 } | 266 } |
| 336 | 267 |
| 337 void GLES2Implementation::CompressedTexSubImage2D( | 268 void GLES2Implementation::CompressedTexSubImage2D( |
| 338 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 269 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
| 339 GLsizei height, GLenum format, GLsizei image_size, const void* data) { | 270 GLsizei height, GLenum format, GLsizei image_size, const void* data) { |
| 340 if (width < 0 || height < 0 || level < 0) { | 271 // TODO(gman): Switch to use buckets alwayst or at least if no room in shared |
| 341 SetGLError(GL_INVALID_VALUE); | |
| 342 return; | |
| 343 } | |
| 344 // TODO(gman): Switch to use buckets always or at least if no room in shared | |
| 345 // memory. | 272 // memory. |
| 346 DCHECK_LE(image_size, | 273 DCHECK_LE(image_size, |
| 347 static_cast<GLsizei>( | 274 static_cast<GLsizei>( |
| 348 transfer_buffer_.GetLargestFreeOrPendingSize())); | 275 transfer_buffer_.GetLargestFreeOrPendingSize())); |
| 349 void* buffer = transfer_buffer_.Alloc(image_size); | 276 void* buffer = transfer_buffer_.Alloc(image_size); |
| 350 memcpy(buffer, data, image_size); | 277 memcpy(buffer, data, image_size); |
| 351 helper_->CompressedTexSubImage2D( | 278 helper_->CompressedTexSubImage2D( |
| 352 target, level, xoffset, yoffset, width, height, format, image_size, | 279 target, level, xoffset, yoffset, width, height, format, image_size, |
| 353 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); | 280 transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); |
| 354 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); | 281 transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); |
| 355 } | 282 } |
| 356 | 283 |
| 357 void GLES2Implementation::TexImage2D( | 284 void GLES2Implementation::TexImage2D( |
| 358 GLenum target, GLint level, GLint internalformat, GLsizei width, | 285 GLenum target, GLint level, GLint internalformat, GLsizei width, |
| 359 GLsizei height, GLint border, GLenum format, GLenum type, | 286 GLsizei height, GLint border, GLenum format, GLenum type, |
| 360 const void* pixels) { | 287 const void* pixels) { |
| 361 if (level < 0 || height < 0 || width < 0) { | |
| 362 SetGLError(GL_INVALID_VALUE); | |
| 363 return; | |
| 364 } | |
| 365 helper_->TexImage2D( | 288 helper_->TexImage2D( |
| 366 target, level, internalformat, width, height, border, format, type, 0, 0); | 289 target, level, internalformat, width, height, border, format, type, 0, 0); |
| 367 if (pixels) { | 290 if (pixels) { |
| 368 TexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); | 291 TexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); |
| 369 } | 292 } |
| 370 } | 293 } |
| 371 | 294 |
| 372 void GLES2Implementation::TexSubImage2D( | 295 void GLES2Implementation::TexSubImage2D( |
| 373 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, | 296 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, |
| 374 GLsizei height, GLenum format, GLenum type, const void* pixels) { | 297 GLsizei height, GLenum format, GLenum type, const void* pixels) { |
| 375 if (level < 0 || height < 0 || width < 0) { | |
| 376 SetGLError(GL_INVALID_VALUE); | |
| 377 return; | |
| 378 } | |
| 379 const int8* source = static_cast<const int8*>(pixels); | 298 const int8* source = static_cast<const int8*>(pixels); |
| 380 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); | 299 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); |
| 381 GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize( | 300 GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize( |
| 382 width, 1, format, type, unpack_alignment_); | 301 width, 1, format, type, unpack_alignment_); |
| 383 GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize( | 302 GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize( |
| 384 width, 2, format, type, unpack_alignment_) - unpadded_row_size; | 303 width, 2, format, type, unpack_alignment_) - unpadded_row_size; |
| 385 | 304 |
| 386 if (padded_row_size <= max_size) { | 305 if (padded_row_size <= max_size) { |
| 387 // Transfer by rows. | 306 // Transfer by rows. |
| 388 GLint max_rows = max_size / padded_row_size; | 307 GLint max_rows = max_size / padded_row_size; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 } | 348 } |
| 430 | 349 |
| 431 GLenum GLES2Implementation::CheckFramebufferStatus(GLenum target) { | 350 GLenum GLES2Implementation::CheckFramebufferStatus(GLenum target) { |
| 432 // TODO(gman): implement. | 351 // TODO(gman): implement. |
| 433 return 0; | 352 return 0; |
| 434 } | 353 } |
| 435 | 354 |
| 436 void GLES2Implementation::GetActiveAttrib( | 355 void GLES2Implementation::GetActiveAttrib( |
| 437 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, | 356 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, |
| 438 GLenum* type, char* name) { | 357 GLenum* type, char* name) { |
| 439 if (bufsize < 0) { | |
| 440 SetGLError(GL_INVALID_VALUE); | |
| 441 return; | |
| 442 } | |
| 443 // Clear the bucket so if we the command fails nothing will be in it. | |
| 444 helper_->SetBucketSize(kResultBucketId, 0); | |
| 445 typedef gles2::GetActiveAttrib::Result Result; | 358 typedef gles2::GetActiveAttrib::Result Result; |
| 446 Result* result = static_cast<Result*>(result_buffer_); | 359 Result* result = static_cast<Result*>(result_buffer_); |
| 447 // Set as failed so if the command fails we'll recover. | |
| 448 result->success = false; | |
| 449 helper_->GetActiveAttrib(program, index, kResultBucketId, | 360 helper_->GetActiveAttrib(program, index, kResultBucketId, |
| 450 result_shm_id(), result_shm_offset()); | 361 result_shm_id(), result_shm_offset()); |
| 451 WaitForCmd(); | 362 WaitForCmd(); |
| 452 if (result->success) { | 363 if (result->success) { |
| 453 if (size) { | 364 if (size) { |
| 454 *size = result->size; | 365 *size = result->size; |
| 455 } | 366 } |
| 456 if (type) { | 367 if (type) { |
| 457 *type = result->type; | 368 *type = result->type; |
| 458 } | 369 } |
| 459 if (length || name) { | 370 if (length || name) { |
| 460 std::vector<int8> str; | 371 std::vector<int8> str; |
| 461 GetBucketContents(kResultBucketId, &str); | 372 GetBucketContents(kResultBucketId, &str); |
| 462 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, | 373 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, |
| 463 str.size()); | 374 str.size()); |
| 464 if (length) { | 375 if (length) { |
| 465 *length = max_size; | 376 *length = max_size; |
| 466 } | 377 } |
| 467 if (name && bufsize > 0) { | 378 if (name && bufsize > 0) { |
| 468 memcpy(name, &str[0], max_size); | 379 memcpy(name, &str[0], max_size); |
| 469 name[max_size] = '\0'; | 380 name[max_size] = '\0'; |
| 470 } | 381 } |
| 471 } | 382 } |
| 472 } | 383 } |
| 473 } | 384 } |
| 474 | 385 |
| 475 void GLES2Implementation::GetActiveUniform( | 386 void GLES2Implementation::GetActiveUniform( |
| 476 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, | 387 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, |
| 477 GLenum* type, char* name) { | 388 GLenum* type, char* name) { |
| 478 if (bufsize < 0) { | |
| 479 SetGLError(GL_INVALID_VALUE); | |
| 480 return; | |
| 481 } | |
| 482 // Clear the bucket so if we the command fails nothing will be in it. | |
| 483 helper_->SetBucketSize(kResultBucketId, 0); | |
| 484 typedef gles2::GetActiveUniform::Result Result; | 389 typedef gles2::GetActiveUniform::Result Result; |
| 485 Result* result = static_cast<Result*>(result_buffer_); | 390 Result* result = static_cast<Result*>(result_buffer_); |
| 486 // Set as failed so if the command fails we'll recover. | |
| 487 result->success = false; | |
| 488 helper_->GetActiveUniform(program, index, kResultBucketId, | 391 helper_->GetActiveUniform(program, index, kResultBucketId, |
| 489 result_shm_id(), result_shm_offset()); | 392 result_shm_id(), result_shm_offset()); |
| 490 WaitForCmd(); | 393 WaitForCmd(); |
| 491 if (result->success) { | 394 if (result->success) { |
| 492 if (size) { | 395 if (size) { |
| 493 *size = result->size; | 396 *size = result->size; |
| 494 } | 397 } |
| 495 if (type) { | 398 if (type) { |
| 496 *type = result->type; | 399 *type = result->type; |
| 497 } | 400 } |
| 498 if (length || name) { | 401 if (length || name) { |
| 499 std::vector<int8> str; | 402 std::vector<int8> str; |
| 500 GetBucketContents(kResultBucketId, &str); | 403 GetBucketContents(kResultBucketId, &str); |
| 501 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, | 404 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1, |
| 502 str.size()); | 405 str.size()); |
| 503 if (length) { | 406 if (length) { |
| 504 *length = max_size; | 407 *length = max_size; |
| 505 } | 408 } |
| 506 if (name && bufsize > 0) { | 409 if (name && bufsize > 0) { |
| 507 memcpy(name, &str[0], max_size); | 410 memcpy(name, &str[0], max_size); |
| 508 name[max_size] = '\0'; | 411 name[max_size] = '\0'; |
| 509 } | 412 } |
| 510 } | 413 } |
| 511 } | 414 } |
| 512 } | 415 } |
| 513 | 416 |
| 514 void GLES2Implementation::GetAttachedShaders( | 417 void GLES2Implementation::GetAttachedShaders( |
| 515 GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { | 418 GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { |
| 516 if (maxcount < 0) { | |
| 517 SetGLError(GL_INVALID_VALUE); | |
| 518 return; | |
| 519 } | |
| 520 typedef gles2::GetAttachedShaders::Result Result; | 419 typedef gles2::GetAttachedShaders::Result Result; |
| 521 uint32 size = Result::ComputeSize(maxcount); | 420 uint32 size = Result::ComputeSize(maxcount); |
| 522 Result* result = transfer_buffer_.AllocTyped<Result>(size); | 421 Result* result = transfer_buffer_.AllocTyped<Result>(size); |
| 523 helper_->GetAttachedShaders( | 422 helper_->GetAttachedShaders( |
| 524 program, | 423 program, |
| 525 transfer_buffer_id_, | 424 transfer_buffer_id_, |
| 526 transfer_buffer_.GetOffset(result), | 425 transfer_buffer_.GetOffset(result), |
| 527 size); | 426 size); |
| 528 int32 token = helper_->InsertToken(); | 427 int32 token = helper_->InsertToken(); |
| 529 WaitForCmd(); | 428 WaitForCmd(); |
| 530 if (count) { | 429 if (count) { |
| 531 *count = result->GetNumResults(); | 430 *count = result->GetNumResults(); |
| 532 } | 431 } |
| 533 result->CopyResult(shaders); | 432 result->CopyResult(shaders); |
| 534 transfer_buffer_.FreePendingToken(result, token); | 433 transfer_buffer_.FreePendingToken(result, token); |
| 535 } | 434 } |
| 536 | 435 |
| 436 void GLES2Implementation::GetProgramInfoLog( |
| 437 GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) { |
| 438 // TODO(gman): implement. |
| 439 } |
| 440 |
| 441 void GLES2Implementation::GetShaderInfoLog( |
| 442 GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) { |
| 443 // TODO(gman): implement. |
| 444 } |
| 445 |
| 537 void GLES2Implementation::GetShaderPrecisionFormat( | 446 void GLES2Implementation::GetShaderPrecisionFormat( |
| 538 GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { | 447 GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { |
| 539 typedef gles2::GetShaderPrecisionFormat::Result Result; | 448 typedef gles2::GetShaderPrecisionFormat::Result Result; |
| 540 Result* result = static_cast<Result*>(result_buffer_); | 449 Result* result = static_cast<Result*>(result_buffer_); |
| 541 helper_->GetShaderPrecisionFormat( | 450 helper_->GetShaderPrecisionFormat( |
| 542 shadertype, precisiontype, result_shm_id(), result_shm_offset()); | 451 shadertype, precisiontype, result_shm_id(), result_shm_offset()); |
| 543 WaitForCmd(); | 452 WaitForCmd(); |
| 544 if (result->success) { | 453 if (result->success) { |
| 545 if (range) { | 454 if (range) { |
| 546 range[0] = result->min_range; | 455 range[0] = result->min_range; |
| 547 range[1] = result->max_range; | 456 range[1] = result->max_range; |
| 548 } | 457 } |
| 549 if (precision) { | 458 if (precision) { |
| 550 precision[0] = result->precision; | 459 precision[0] = result->precision; |
| 551 } | 460 } |
| 552 } | 461 } |
| 553 } | 462 } |
| 554 | 463 |
| 464 void GLES2Implementation::GetShaderSource( |
| 465 GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { |
| 466 // TODO(gman): implement. |
| 467 } |
| 468 |
| 555 const GLubyte* GLES2Implementation::GetString(GLenum name) { | 469 const GLubyte* GLES2Implementation::GetString(GLenum name) { |
| 556 const char* result; | 470 // TODO(gman): implement. |
| 557 GLStringMap::const_iterator it = gl_strings_.find(name); | 471 return 0; |
| 558 if (it != gl_strings_.end()) { | |
| 559 result = it->second.c_str(); | |
| 560 } else { | |
| 561 // Clear the bucket so if we the command fails nothing will be in it. | |
| 562 helper_->SetBucketSize(kResultBucketId, 0); | |
| 563 helper_->GetString(name, kResultBucketId); | |
| 564 std::string str; | |
| 565 if (GetBucketAsString(kResultBucketId, &str)) { | |
| 566 std::pair<GLStringMap::const_iterator, bool> insert_result = | |
| 567 gl_strings_.insert(std::make_pair(name, str)); | |
| 568 DCHECK(insert_result.second); | |
| 569 result = insert_result.first->second.c_str(); | |
| 570 } else { | |
| 571 result = NULL; | |
| 572 } | |
| 573 } | |
| 574 return reinterpret_cast<const GLubyte*>(result); | |
| 575 } | 472 } |
| 576 | 473 |
| 577 void GLES2Implementation::GetUniformfv( | 474 void GLES2Implementation::GetUniformfv( |
| 578 GLuint program, GLint location, GLfloat* params) { | 475 GLuint program, GLint location, GLfloat* params) { |
| 579 helper_->GetUniformfv( | 476 helper_->GetUniformfv( |
| 580 program, location, result_shm_id(), result_shm_offset()); | 477 program, location, result_shm_id(), result_shm_offset()); |
| 581 WaitForCmd(); | 478 WaitForCmd(); |
| 582 static_cast<gles2::GetUniformfv::Result*>(result_buffer_)->CopyResult(params); | 479 static_cast<gles2::GetUniformfv::Result*>(result_buffer_)->CopyResult(params); |
| 583 } | 480 } |
| 584 | 481 |
| 585 void GLES2Implementation::GetUniformiv( | 482 void GLES2Implementation::GetUniformiv( |
| 586 GLuint program, GLint location, GLint* params) { | 483 GLuint program, GLint location, GLint* params) { |
| 587 helper_->GetUniformiv( | 484 helper_->GetUniformiv( |
| 588 program, location, result_shm_id(), result_shm_offset()); | 485 program, location, result_shm_id(), result_shm_offset()); |
| 589 WaitForCmd(); | 486 WaitForCmd(); |
| 590 static_cast<gles2::GetUniformfv::Result*>(result_buffer_)->CopyResult(params); | 487 static_cast<gles2::GetUniformfv::Result*>(result_buffer_)->CopyResult(params); |
| 591 } | 488 } |
| 592 | 489 |
| 593 void GLES2Implementation::ReadPixels( | 490 void GLES2Implementation::ReadPixels( |
| 594 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, | 491 GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, |
| 595 GLenum type, void* pixels) { | 492 GLenum type, void* pixels) { |
| 596 // Note: Negative widths and heights are not handled here but are handled | 493 // Note: Negative widths and heights are not handled here but are handled |
| 597 // by the service side so the glGetError wrapping works. | 494 // by the service side so the glGetError wrapping works. |
| 598 if (width < 0 || height < 0) { | |
| 599 SetGLError(GL_INVALID_VALUE); | |
| 600 return; | |
| 601 } | |
| 602 if (width == 0 || height == 0) { | 495 if (width == 0 || height == 0) { |
| 603 return; | 496 return; |
| 604 } | 497 } |
| 605 typedef gles2::ReadPixels::Result Result; | 498 typedef gles2::ReadPixels::Result Result; |
| 606 Result* result = static_cast<Result*>(result_buffer_); | 499 Result* result = static_cast<Result*>(result_buffer_); |
| 607 int8* dest = reinterpret_cast<int8*>(pixels); | 500 int8* dest = reinterpret_cast<int8*>(pixels); |
| 608 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); | 501 GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize(); |
| 609 GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize( | 502 GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize( |
| 610 width, 1, format, type, pack_alignment_); | 503 width, 1, format, type, pack_alignment_); |
| 611 GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize( | 504 GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 temp_width -= num_pixels; | 557 temp_width -= num_pixels; |
| 665 } | 558 } |
| 666 ++yoffset; | 559 ++yoffset; |
| 667 dest += padded_row_size; | 560 dest += padded_row_size; |
| 668 } | 561 } |
| 669 } | 562 } |
| 670 } | 563 } |
| 671 | 564 |
| 672 } // namespace gles2 | 565 } // namespace gles2 |
| 673 } // namespace gpu | 566 } // namespace gpu |
| OLD | NEW |