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