Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <list> | 10 #include <list> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <stack> | 12 #include <stack> |
| 13 #include <string> | 13 #include <string> |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "base/at_exit.h" | 16 #include "base/at_exit.h" |
| 17 #include "base/bind.h" | 17 #include "base/bind.h" |
| 18 #include "base/callback_helpers.h" | |
| 18 #include "base/command_line.h" | 19 #include "base/command_line.h" |
| 19 #include "base/debug/trace_event.h" | 20 #include "base/debug/trace_event.h" |
| 20 #include "base/debug/trace_event_synthetic_delay.h" | 21 #include "base/debug/trace_event_synthetic_delay.h" |
| 21 #include "base/memory/scoped_ptr.h" | 22 #include "base/memory/scoped_ptr.h" |
| 22 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 23 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
| 24 #include "build/build_config.h" | 25 #include "build/build_config.h" |
| 25 #define GLES2_GPU_SERVICE 1 | 26 #define GLES2_GPU_SERVICE 1 |
| 26 #include "gpu/command_buffer/common/debug_marker_manager.h" | 27 #include "gpu/command_buffer/common/debug_marker_manager.h" |
| 27 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 28 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 | 473 |
| 473 struct FenceCallback { | 474 struct FenceCallback { |
| 474 explicit FenceCallback() | 475 explicit FenceCallback() |
| 475 : fence(gfx::GLFence::Create()) { | 476 : fence(gfx::GLFence::Create()) { |
| 476 DCHECK(fence); | 477 DCHECK(fence); |
| 477 } | 478 } |
| 478 std::vector<base::Closure> callbacks; | 479 std::vector<base::Closure> callbacks; |
| 479 scoped_ptr<gfx::GLFence> fence; | 480 scoped_ptr<gfx::GLFence> fence; |
| 480 }; | 481 }; |
| 481 | 482 |
| 483 class AsyncUploadTokenCompletionObserver | |
| 484 : public AsyncPixelTransferCompletionObserver { | |
| 485 public: | |
| 486 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token) | |
| 487 : async_upload_token_(async_upload_token) { | |
| 488 } | |
| 489 | |
| 490 virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE { | |
| 491 void* data = static_cast<int8*>(mem_params.shared_memory->memory()) + | |
| 492 mem_params.shm_data_offset; | |
| 493 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data); | |
| 494 sync->SetAsyncUploadToken(async_upload_token_); | |
| 495 } | |
| 496 | |
| 497 private: | |
| 498 uint32 async_upload_token_; | |
| 499 | |
| 500 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver); | |
| 501 }; | |
| 502 | |
| 482 // } // anonymous namespace. | 503 // } // anonymous namespace. |
| 483 | 504 |
| 484 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, | 505 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, |
| 485 uint32* service_texture_id) { | 506 uint32* service_texture_id) { |
| 486 return false; | 507 return false; |
| 487 } | 508 } |
| 488 | 509 |
| 489 GLES2Decoder::GLES2Decoder() | 510 GLES2Decoder::GLES2Decoder() |
| 490 : initialized_(false), | 511 : initialized_(false), |
| 491 debug_(false), | 512 debug_(false), |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); | 687 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); |
| 667 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); | 688 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); |
| 668 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); | 689 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); |
| 669 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); | 690 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); |
| 670 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); | 691 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); |
| 671 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); | 692 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); |
| 672 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); | 693 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); |
| 673 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); | 694 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
| 674 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); | 695 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); |
| 675 | 696 |
| 697 // Helper for async upload token completion notification callback. | |
| 698 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, | |
| 699 uint32 sync_data_shm_id, | |
| 700 uint32 sync_data_shm_offset); | |
| 701 | |
| 702 | |
| 703 | |
| 676 // Workarounds | 704 // Workarounds |
| 677 void OnFboChanged() const; | 705 void OnFboChanged() const; |
| 678 void OnUseFramebuffer() const; | 706 void OnUseFramebuffer() const; |
| 679 | 707 |
| 680 // TODO(gman): Cache these pointers? | 708 // TODO(gman): Cache these pointers? |
| 681 BufferManager* buffer_manager() { | 709 BufferManager* buffer_manager() { |
| 682 return group_->buffer_manager(); | 710 return group_->buffer_manager(); |
| 683 } | 711 } |
| 684 | 712 |
| 685 RenderbufferManager* renderbuffer_manager() { | 713 RenderbufferManager* renderbuffer_manager() { |
| (...skipping 9597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10283 if (!texture_ref || | 10311 if (!texture_ref || |
| 10284 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { | 10312 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { |
| 10285 LOCAL_SET_GL_ERROR( | 10313 LOCAL_SET_GL_ERROR( |
| 10286 GL_INVALID_OPERATION, | 10314 GL_INVALID_OPERATION, |
| 10287 function_name, "transfer already in progress"); | 10315 function_name, "transfer already in progress"); |
| 10288 return false; | 10316 return false; |
| 10289 } | 10317 } |
| 10290 return true; | 10318 return true; |
| 10291 } | 10319 } |
| 10292 | 10320 |
| 10321 base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure( | |
| 10322 uint32 async_upload_token, | |
| 10323 uint32 sync_data_shm_id, | |
| 10324 uint32 sync_data_shm_offset) { | |
| 10325 AsyncMemoryParams mem_params; | |
| 10326 gpu::Buffer buffer = GetSharedMemoryBuffer(sync_data_shm_id); | |
| 10327 if (!buffer.shared_memory) | |
| 10328 return base::Closure(); | |
| 10329 mem_params.shared_memory = buffer.shared_memory; | |
| 10330 mem_params.shm_size = buffer.size; | |
| 10331 mem_params.shm_data_offset = sync_data_shm_offset; | |
| 10332 mem_params.shm_data_size = sizeof(AsyncUploadSync); | |
| 10333 | |
| 10334 if (mem_params.shm_data_offset + mem_params.shm_data_size > | |
|
piman
2014/03/20 21:18:26
Beware of overflows. If shm_data_offset is UINT32_
| |
| 10335 mem_params.shm_size) | |
| 10336 return base::Closure(); | |
| 10337 | |
| 10338 scoped_refptr<AsyncUploadTokenCompletionObserver> observer( | |
| 10339 new AsyncUploadTokenCompletionObserver(async_upload_token)); | |
| 10340 | |
| 10341 return base::Bind( | |
| 10342 &AsyncPixelTransferManager::AsyncNotifyCompletion, | |
| 10343 base::Unretained(GetAsyncPixelTransferManager()), | |
| 10344 mem_params, | |
| 10345 observer); | |
| 10346 } | |
| 10347 | |
| 10293 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( | 10348 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( |
| 10294 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) { | 10349 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) { |
| 10295 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); | 10350 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); |
| 10296 GLenum target = static_cast<GLenum>(c.target); | 10351 GLenum target = static_cast<GLenum>(c.target); |
| 10297 GLint level = static_cast<GLint>(c.level); | 10352 GLint level = static_cast<GLint>(c.level); |
| 10298 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use | 10353 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use |
| 10299 // unsigned integer for internalformat. | 10354 // unsigned integer for internalformat. |
| 10300 GLenum internal_format = static_cast<GLenum>(c.internalformat); | 10355 GLenum internal_format = static_cast<GLenum>(c.internalformat); |
| 10301 GLsizei width = static_cast<GLsizei>(c.width); | 10356 GLsizei width = static_cast<GLsizei>(c.width); |
| 10302 GLsizei height = static_cast<GLsizei>(c.height); | 10357 GLsizei height = static_cast<GLsizei>(c.height); |
| 10303 GLint border = static_cast<GLint>(c.border); | 10358 GLint border = static_cast<GLint>(c.border); |
| 10304 GLenum format = static_cast<GLenum>(c.format); | 10359 GLenum format = static_cast<GLenum>(c.format); |
| 10305 GLenum type = static_cast<GLenum>(c.type); | 10360 GLenum type = static_cast<GLenum>(c.type); |
| 10306 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); | 10361 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); |
| 10307 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); | 10362 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); |
| 10308 uint32 pixels_size; | 10363 uint32 pixels_size; |
| 10364 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token); | |
| 10365 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id); | |
| 10366 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); | |
| 10367 | |
| 10368 base::ScopedClosureRunner scoped_completion_callback; | |
| 10369 if (async_upload_token) { | |
| 10370 base::Closure completion_closure = | |
| 10371 AsyncUploadTokenCompletionClosure(async_upload_token, | |
| 10372 sync_data_shm_id, | |
| 10373 sync_data_shm_offset); | |
| 10374 if (completion_closure.is_null()) | |
| 10375 return error::kInvalidArguments; | |
| 10376 | |
| 10377 scoped_completion_callback.Reset(completion_closure); | |
| 10378 } | |
| 10309 | 10379 |
| 10310 // TODO(epenner): Move this and copies of this memory validation | 10380 // TODO(epenner): Move this and copies of this memory validation |
| 10311 // into ValidateTexImage2D step. | 10381 // into ValidateTexImage2D step. |
| 10312 if (!GLES2Util::ComputeImageDataSizes( | 10382 if (!GLES2Util::ComputeImageDataSizes( |
| 10313 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, | 10383 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, |
| 10314 NULL)) { | 10384 NULL)) { |
| 10315 return error::kOutOfBounds; | 10385 return error::kOutOfBounds; |
| 10316 } | 10386 } |
| 10317 const void* pixels = NULL; | 10387 const void* pixels = NULL; |
| 10318 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { | 10388 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10393 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) { | 10463 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) { |
| 10394 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); | 10464 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); |
| 10395 GLenum target = static_cast<GLenum>(c.target); | 10465 GLenum target = static_cast<GLenum>(c.target); |
| 10396 GLint level = static_cast<GLint>(c.level); | 10466 GLint level = static_cast<GLint>(c.level); |
| 10397 GLint xoffset = static_cast<GLint>(c.xoffset); | 10467 GLint xoffset = static_cast<GLint>(c.xoffset); |
| 10398 GLint yoffset = static_cast<GLint>(c.yoffset); | 10468 GLint yoffset = static_cast<GLint>(c.yoffset); |
| 10399 GLsizei width = static_cast<GLsizei>(c.width); | 10469 GLsizei width = static_cast<GLsizei>(c.width); |
| 10400 GLsizei height = static_cast<GLsizei>(c.height); | 10470 GLsizei height = static_cast<GLsizei>(c.height); |
| 10401 GLenum format = static_cast<GLenum>(c.format); | 10471 GLenum format = static_cast<GLenum>(c.format); |
| 10402 GLenum type = static_cast<GLenum>(c.type); | 10472 GLenum type = static_cast<GLenum>(c.type); |
| 10473 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token); | |
| 10474 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id); | |
| 10475 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); | |
| 10476 | |
| 10477 base::ScopedClosureRunner scoped_completion_callback; | |
| 10478 if (async_upload_token) { | |
| 10479 base::Closure completion_closure = | |
| 10480 AsyncUploadTokenCompletionClosure(async_upload_token, | |
| 10481 sync_data_shm_id, | |
| 10482 sync_data_shm_offset); | |
| 10483 if (completion_closure.is_null()) | |
| 10484 return error::kInvalidArguments; | |
| 10485 | |
| 10486 scoped_completion_callback.Reset(completion_closure); | |
| 10487 } | |
| 10403 | 10488 |
| 10404 // TODO(epenner): Move this and copies of this memory validation | 10489 // TODO(epenner): Move this and copies of this memory validation |
| 10405 // into ValidateTexSubImage2D step. | 10490 // into ValidateTexSubImage2D step. |
| 10406 uint32 data_size; | 10491 uint32 data_size; |
| 10407 if (!GLES2Util::ComputeImageDataSizes( | 10492 if (!GLES2Util::ComputeImageDataSizes( |
| 10408 width, height, format, type, state_.unpack_alignment, &data_size, | 10493 width, height, format, type, state_.unpack_alignment, &data_size, |
| 10409 NULL, NULL)) { | 10494 NULL, NULL)) { |
| 10410 return error::kOutOfBounds; | 10495 return error::kOutOfBounds; |
| 10411 } | 10496 } |
| 10412 const void* pixels = GetSharedMemoryAs<const void*>( | 10497 const void* pixels = GetSharedMemoryAs<const void*>( |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10503 LOCAL_SET_GL_ERROR( | 10588 LOCAL_SET_GL_ERROR( |
| 10504 GL_INVALID_OPERATION, | 10589 GL_INVALID_OPERATION, |
| 10505 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started"); | 10590 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started"); |
| 10506 return error::kNoError; | 10591 return error::kNoError; |
| 10507 } | 10592 } |
| 10508 delegate->WaitForTransferCompletion(); | 10593 delegate->WaitForTransferCompletion(); |
| 10509 ProcessFinishedAsyncTransfers(); | 10594 ProcessFinishedAsyncTransfers(); |
| 10510 return error::kNoError; | 10595 return error::kNoError; |
| 10511 } | 10596 } |
| 10512 | 10597 |
| 10598 error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM( | |
| 10599 uint32 immediate_data_size, const cmds::WaitAllAsyncTexImage2DCHROMIUM& c) { | |
| 10600 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM"); | |
| 10601 | |
| 10602 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D(); | |
| 10603 ProcessFinishedAsyncTransfers(); | |
| 10604 return error::kNoError; | |
| 10605 } | |
| 10606 | |
| 10513 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( | 10607 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( |
| 10514 TextureRef* texture_ref) { | 10608 TextureRef* texture_ref) { |
| 10515 Texture* texture = texture_ref->texture(); | 10609 Texture* texture = texture_ref->texture(); |
| 10516 DoDidUseTexImageIfNeeded(texture, texture->target()); | 10610 DoDidUseTexImageIfNeeded(texture, texture->target()); |
| 10517 } | 10611 } |
| 10518 | 10612 |
| 10519 // Include the auto-generated part of this file. We split this because it means | 10613 // Include the auto-generated part of this file. We split this because it means |
| 10520 // we can easily edit the non-auto generated parts right here in this file | 10614 // we can easily edit the non-auto generated parts right here in this file |
| 10521 // instead of having to edit some template or the code generator. | 10615 // instead of having to edit some template or the code generator. |
| 10522 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10616 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 10523 | 10617 |
| 10524 } // namespace gles2 | 10618 } // namespace gles2 |
| 10525 } // namespace gpu | 10619 } // namespace gpu |
| OLD | NEW |