| 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/query_manager.h" | 5 #include "gpu/command_buffer/service/query_manager.h" |
| 6 | 6 |
| 7 #include "base/atomicops.h" | 7 #include "base/atomicops.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
| 11 #include "base/numerics/safe_math.h" | 11 #include "base/numerics/safe_math.h" |
| 12 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
| 13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 14 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| 15 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" | |
| 16 #include "gpu/command_buffer/service/error_state.h" | 15 #include "gpu/command_buffer/service/error_state.h" |
| 17 #include "gpu/command_buffer/service/feature_info.h" | 16 #include "gpu/command_buffer/service/feature_info.h" |
| 18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 17 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 18 #include "ui/gl/gl_bindings.h" |
| 19 #include "ui/gl/gl_context.h" | 19 #include "ui/gl/gl_context.h" |
| 20 #include "ui/gl/gl_fence.h" | 20 #include "ui/gl/gl_fence.h" |
| 21 #include "ui/gl/gpu_timing.h" | 21 #include "ui/gl/gpu_timing.h" |
| 22 | 22 |
| 23 namespace gpu { | 23 namespace gpu { |
| 24 namespace gles2 { | 24 namespace gles2 { |
| 25 | 25 |
| 26 namespace { | |
| 27 | |
| 28 class AsyncPixelTransferCompletionObserverImpl | |
| 29 : public AsyncPixelTransferCompletionObserver { | |
| 30 public: | |
| 31 AsyncPixelTransferCompletionObserverImpl(base::subtle::Atomic32 submit_count) | |
| 32 : submit_count_(submit_count), cancelled_(false) {} | |
| 33 | |
| 34 void Cancel() { | |
| 35 base::AutoLock locked(lock_); | |
| 36 cancelled_ = true; | |
| 37 } | |
| 38 | |
| 39 void DidComplete(const AsyncMemoryParams& mem_params) override { | |
| 40 base::AutoLock locked(lock_); | |
| 41 if (!cancelled_) { | |
| 42 DCHECK(mem_params.buffer().get()); | |
| 43 void* data = mem_params.GetDataAddress(); | |
| 44 QuerySync* sync = static_cast<QuerySync*>(data); | |
| 45 base::subtle::Release_Store(&sync->process_count, submit_count_); | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 private: | |
| 50 ~AsyncPixelTransferCompletionObserverImpl() override {} | |
| 51 | |
| 52 base::subtle::Atomic32 submit_count_; | |
| 53 | |
| 54 base::Lock lock_; | |
| 55 bool cancelled_; | |
| 56 | |
| 57 DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferCompletionObserverImpl); | |
| 58 }; | |
| 59 | |
| 60 class AsyncPixelTransfersCompletedQuery | |
| 61 : public QueryManager::Query, | |
| 62 public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> { | |
| 63 public: | |
| 64 AsyncPixelTransfersCompletedQuery( | |
| 65 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); | |
| 66 | |
| 67 bool Begin() override; | |
| 68 bool End(base::subtle::Atomic32 submit_count) override; | |
| 69 bool QueryCounter(base::subtle::Atomic32 submit_count) override; | |
| 70 void Pause() override; | |
| 71 void Resume() override; | |
| 72 bool Process(bool did_finish) override; | |
| 73 void Destroy(bool have_context) override; | |
| 74 | |
| 75 protected: | |
| 76 ~AsyncPixelTransfersCompletedQuery() override; | |
| 77 | |
| 78 scoped_refptr<AsyncPixelTransferCompletionObserverImpl> observer_; | |
| 79 }; | |
| 80 | |
| 81 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery( | |
| 82 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) | |
| 83 : Query(manager, target, shm_id, shm_offset) { | |
| 84 } | |
| 85 | |
| 86 bool AsyncPixelTransfersCompletedQuery::Begin() { | |
| 87 MarkAsActive(); | |
| 88 return true; | |
| 89 } | |
| 90 | |
| 91 void AsyncPixelTransfersCompletedQuery::Pause() { | |
| 92 MarkAsPaused(); | |
| 93 } | |
| 94 | |
| 95 void AsyncPixelTransfersCompletedQuery::Resume() { | |
| 96 MarkAsActive(); | |
| 97 } | |
| 98 | |
| 99 bool AsyncPixelTransfersCompletedQuery::End( | |
| 100 base::subtle::Atomic32 submit_count) { | |
| 101 // Get the real shared memory since it might need to be duped to prevent | |
| 102 // use-after-free of the memory. | |
| 103 scoped_refptr<Buffer> buffer = | |
| 104 manager()->decoder()->GetSharedMemoryBuffer(shm_id()); | |
| 105 if (!buffer.get()) | |
| 106 return false; | |
| 107 AsyncMemoryParams mem_params(buffer, shm_offset(), sizeof(QuerySync)); | |
| 108 if (!mem_params.GetDataAddress()) | |
| 109 return false; | |
| 110 | |
| 111 observer_ = new AsyncPixelTransferCompletionObserverImpl(submit_count); | |
| 112 | |
| 113 // Ask AsyncPixelTransferDelegate to run completion callback after all | |
| 114 // previous async transfers are done. No guarantee that callback is run | |
| 115 // on the current thread. | |
| 116 manager()->decoder()->GetAsyncPixelTransferManager()->AsyncNotifyCompletion( | |
| 117 mem_params, observer_.get()); | |
| 118 | |
| 119 return AddToPendingTransferQueue(submit_count); | |
| 120 } | |
| 121 | |
| 122 bool AsyncPixelTransfersCompletedQuery::QueryCounter( | |
| 123 base::subtle::Atomic32 submit_count) { | |
| 124 NOTREACHED(); | |
| 125 return false; | |
| 126 } | |
| 127 | |
| 128 bool AsyncPixelTransfersCompletedQuery::Process(bool did_finish) { | |
| 129 QuerySync* sync = manager()->decoder()->GetSharedMemoryAs<QuerySync*>( | |
| 130 shm_id(), shm_offset(), sizeof(*sync)); | |
| 131 if (!sync) | |
| 132 return false; | |
| 133 | |
| 134 // Check if completion callback has been run. sync->process_count atomicity | |
| 135 // is guaranteed as this is already used to notify client of a completed | |
| 136 // query. | |
| 137 if (base::subtle::Acquire_Load(&sync->process_count) != submit_count()) | |
| 138 return true; | |
| 139 | |
| 140 UnmarkAsPending(); | |
| 141 return true; | |
| 142 } | |
| 143 | |
| 144 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { | |
| 145 if (!IsDeleted()) { | |
| 146 MarkAsDeleted(); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { | |
| 151 if (observer_.get()) | |
| 152 observer_->Cancel(); | |
| 153 } | |
| 154 | |
| 155 } // namespace | |
| 156 | |
| 157 class AllSamplesPassedQuery : public QueryManager::Query { | 26 class AllSamplesPassedQuery : public QueryManager::Query { |
| 158 public: | 27 public: |
| 159 AllSamplesPassedQuery( | 28 AllSamplesPassedQuery( |
| 160 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); | 29 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); |
| 161 bool Begin() override; | 30 bool Begin() override; |
| 162 bool End(base::subtle::Atomic32 submit_count) override; | 31 bool End(base::subtle::Atomic32 submit_count) override; |
| 163 bool QueryCounter(base::subtle::Atomic32 submit_count) override; | 32 bool QueryCounter(base::subtle::Atomic32 submit_count) override; |
| 164 void Pause() override; | 33 void Pause() override; |
| 165 void Resume() override; | 34 void Resume() override; |
| 166 bool Process(bool did_finish) override; | 35 bool Process(bool did_finish) override; |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 QueryManager::Query* QueryManager::CreateQuery( | 682 QueryManager::Query* QueryManager::CreateQuery( |
| 814 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset) { | 683 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset) { |
| 815 scoped_refptr<Query> query; | 684 scoped_refptr<Query> query; |
| 816 switch (target) { | 685 switch (target) { |
| 817 case GL_COMMANDS_ISSUED_CHROMIUM: | 686 case GL_COMMANDS_ISSUED_CHROMIUM: |
| 818 query = new CommandsIssuedQuery(this, target, shm_id, shm_offset); | 687 query = new CommandsIssuedQuery(this, target, shm_id, shm_offset); |
| 819 break; | 688 break; |
| 820 case GL_LATENCY_QUERY_CHROMIUM: | 689 case GL_LATENCY_QUERY_CHROMIUM: |
| 821 query = new CommandLatencyQuery(this, target, shm_id, shm_offset); | 690 query = new CommandLatencyQuery(this, target, shm_id, shm_offset); |
| 822 break; | 691 break; |
| 823 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM: | |
| 824 // Currently async pixel transfer delegates only support uploads. | |
| 825 query = new AsyncPixelTransfersCompletedQuery( | |
| 826 this, target, shm_id, shm_offset); | |
| 827 break; | |
| 828 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM: | 692 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM: |
| 829 query = new AsyncReadPixelsCompletedQuery( | 693 query = new AsyncReadPixelsCompletedQuery( |
| 830 this, target, shm_id, shm_offset); | 694 this, target, shm_id, shm_offset); |
| 831 break; | 695 break; |
| 832 case GL_GET_ERROR_QUERY_CHROMIUM: | 696 case GL_GET_ERROR_QUERY_CHROMIUM: |
| 833 query = new GetErrorQuery(this, target, shm_id, shm_offset); | 697 query = new GetErrorQuery(this, target, shm_id, shm_offset); |
| 834 break; | 698 break; |
| 835 case GL_COMMANDS_COMPLETED_CHROMIUM: | 699 case GL_COMMANDS_COMPLETED_CHROMIUM: |
| 836 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); | 700 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); |
| 837 break; | 701 break; |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) { | 1033 for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) { |
| 1170 if (it.second->IsPaused()) { | 1034 if (it.second->IsPaused()) { |
| 1171 it.second->Resume(); | 1035 it.second->Resume(); |
| 1172 DCHECK(it.second->IsActive()); | 1036 DCHECK(it.second->IsActive()); |
| 1173 } | 1037 } |
| 1174 } | 1038 } |
| 1175 } | 1039 } |
| 1176 | 1040 |
| 1177 } // namespace gles2 | 1041 } // namespace gles2 |
| 1178 } // namespace gpu | 1042 } // namespace gpu |
| OLD | NEW |