| 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/error_state.h" | 15 #include "gpu/command_buffer/service/error_state.h" |
| 16 #include "gpu/command_buffer/service/feature_info.h" | 16 #include "gpu/command_buffer/service/feature_info.h" |
| 17 #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" | 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 class AllSamplesPassedQuery : public QueryManager::Query { | 26 class AbstractIntegerQuery : public QueryManager::Query { |
| 27 public: | 27 public: |
| 28 AllSamplesPassedQuery( | 28 AbstractIntegerQuery( |
| 29 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); | 29 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); |
| 30 bool Begin() override; | 30 bool Begin() override; |
| 31 bool End(base::subtle::Atomic32 submit_count) override; | 31 bool End(base::subtle::Atomic32 submit_count) override; |
| 32 bool QueryCounter(base::subtle::Atomic32 submit_count) override; | 32 bool QueryCounter(base::subtle::Atomic32 submit_count) override; |
| 33 void Pause() override; | 33 void Pause() override; |
| 34 void Resume() override; | 34 void Resume() override; |
| 35 bool Process(bool did_finish) override; | |
| 36 void Destroy(bool have_context) override; | 35 void Destroy(bool have_context) override; |
| 37 | 36 |
| 38 protected: | 37 protected: |
| 39 ~AllSamplesPassedQuery() override; | 38 ~AbstractIntegerQuery() override; |
| 39 bool AreAllResultsAvailable(); |
| 40 | 40 |
| 41 private: | 41 // Service side query ids. |
| 42 // Service side query id. | |
| 43 std::vector<GLuint> service_ids_; | 42 std::vector<GLuint> service_ids_; |
| 44 }; | 43 }; |
| 45 | 44 |
| 46 AllSamplesPassedQuery::AllSamplesPassedQuery( | 45 AbstractIntegerQuery::AbstractIntegerQuery( |
| 47 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) | 46 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) |
| 48 : Query(manager, target, shm_id, shm_offset) { | 47 : Query(manager, target, shm_id, shm_offset) { |
| 49 GLuint service_id = 0; | 48 GLuint service_id = 0; |
| 50 glGenQueries(1, &service_id); | 49 glGenQueries(1, &service_id); |
| 51 DCHECK_NE(0u, service_id); | 50 DCHECK_NE(0u, service_id); |
| 52 service_ids_.push_back(service_id); | 51 service_ids_.push_back(service_id); |
| 53 } | 52 } |
| 54 | 53 |
| 55 bool AllSamplesPassedQuery::Begin() { | 54 bool AbstractIntegerQuery::Begin() { |
| 56 MarkAsActive(); | 55 MarkAsActive(); |
| 57 // Delete all but the first one when beginning a new query. | 56 // Delete all but the first one when beginning a new query. |
| 58 if (service_ids_.size() > 1) { | 57 if (service_ids_.size() > 1) { |
| 59 glDeleteQueries(service_ids_.size() - 1, &service_ids_[1]); | 58 glDeleteQueries(service_ids_.size() - 1, &service_ids_[1]); |
| 60 service_ids_.resize(1); | 59 service_ids_.resize(1); |
| 61 } | 60 } |
| 62 BeginQueryHelper(target(), service_ids_.back()); | 61 BeginQueryHelper(target(), service_ids_.back()); |
| 63 return true; | 62 return true; |
| 64 } | 63 } |
| 65 | 64 |
| 66 bool AllSamplesPassedQuery::End(base::subtle::Atomic32 submit_count) { | 65 bool AbstractIntegerQuery::End(base::subtle::Atomic32 submit_count) { |
| 67 EndQueryHelper(target()); | 66 EndQueryHelper(target()); |
| 68 return AddToPendingQueue(submit_count); | 67 return AddToPendingQueue(submit_count); |
| 69 } | 68 } |
| 70 | 69 |
| 71 bool AllSamplesPassedQuery::QueryCounter(base::subtle::Atomic32 submit_count) { | 70 bool AbstractIntegerQuery::QueryCounter(base::subtle::Atomic32 submit_count) { |
| 72 NOTREACHED(); | 71 NOTREACHED(); |
| 73 return false; | 72 return false; |
| 74 } | 73 } |
| 75 | 74 |
| 76 void AllSamplesPassedQuery::Pause() { | 75 void AbstractIntegerQuery::Pause() { |
| 77 MarkAsPaused(); | 76 MarkAsPaused(); |
| 78 EndQueryHelper(target()); | 77 EndQueryHelper(target()); |
| 79 } | 78 } |
| 80 | 79 |
| 81 void AllSamplesPassedQuery::Resume() { | 80 void AbstractIntegerQuery::Resume() { |
| 82 MarkAsActive(); | 81 MarkAsActive(); |
| 83 | 82 |
| 84 GLuint service_id = 0; | 83 GLuint service_id = 0; |
| 85 glGenQueries(1, &service_id); | 84 glGenQueries(1, &service_id); |
| 86 DCHECK_NE(0u, service_id); | 85 DCHECK_NE(0u, service_id); |
| 87 service_ids_.push_back(service_id); | 86 service_ids_.push_back(service_id); |
| 88 BeginQueryHelper(target(), service_ids_.back()); | 87 BeginQueryHelper(target(), service_ids_.back()); |
| 89 } | 88 } |
| 90 | 89 |
| 91 bool AllSamplesPassedQuery::Process(bool did_finish) { | 90 void AbstractIntegerQuery::Destroy(bool have_context) { |
| 91 if (have_context && !IsDeleted()) { |
| 92 glDeleteQueries(service_ids_.size(), &service_ids_[0]); |
| 93 service_ids_.clear(); |
| 94 MarkAsDeleted(); |
| 95 } |
| 96 } |
| 97 |
| 98 AbstractIntegerQuery::~AbstractIntegerQuery() { |
| 99 } |
| 100 |
| 101 bool AbstractIntegerQuery::AreAllResultsAvailable() { |
| 92 GLuint available = 0; | 102 GLuint available = 0; |
| 93 glGetQueryObjectuiv( | 103 glGetQueryObjectuiv( |
| 94 service_ids_.back(), GL_QUERY_RESULT_AVAILABLE_EXT, &available); | 104 service_ids_.back(), GL_QUERY_RESULT_AVAILABLE_EXT, &available); |
| 95 if (!available) { | 105 return !!available; |
| 106 } |
| 107 |
| 108 class BooleanQuery : public AbstractIntegerQuery { |
| 109 public: |
| 110 BooleanQuery( |
| 111 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); |
| 112 bool Process(bool did_finish) override; |
| 113 |
| 114 protected: |
| 115 ~BooleanQuery() override; |
| 116 }; |
| 117 |
| 118 BooleanQuery::BooleanQuery( |
| 119 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) |
| 120 : AbstractIntegerQuery(manager, target, shm_id, shm_offset) { |
| 121 } |
| 122 |
| 123 BooleanQuery::~BooleanQuery() { |
| 124 } |
| 125 |
| 126 bool BooleanQuery::Process(bool did_finish) { |
| 127 if (!AreAllResultsAvailable()) { |
| 128 // Must return true to avoid generating an error at the command |
| 129 // buffer level. |
| 96 return true; | 130 return true; |
| 97 } | 131 } |
| 98 for (const GLuint& service_id : service_ids_) { | 132 for (const GLuint& service_id : service_ids_) { |
| 99 GLuint result = 0; | 133 GLuint result = 0; |
| 100 glGetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, &result); | 134 glGetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, &result); |
| 101 if (result != 0) | 135 if (result != 0) |
| 102 return MarkAsCompleted(1); | 136 return MarkAsCompleted(1); |
| 103 } | 137 } |
| 104 return MarkAsCompleted(0); | 138 return MarkAsCompleted(0); |
| 105 } | 139 } |
| 106 | 140 |
| 107 void AllSamplesPassedQuery::Destroy(bool have_context) { | 141 class SummedIntegerQuery : public AbstractIntegerQuery { |
| 108 if (have_context && !IsDeleted()) { | 142 public: |
| 109 glDeleteQueries(service_ids_.size(), &service_ids_[0]); | 143 SummedIntegerQuery( |
| 110 service_ids_.clear(); | 144 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); |
| 111 MarkAsDeleted(); | 145 bool Process(bool did_finish) override; |
| 112 } | 146 |
| 147 protected: |
| 148 ~SummedIntegerQuery() override; |
| 149 }; |
| 150 |
| 151 SummedIntegerQuery::SummedIntegerQuery( |
| 152 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) |
| 153 : AbstractIntegerQuery(manager, target, shm_id, shm_offset) { |
| 113 } | 154 } |
| 114 | 155 |
| 115 AllSamplesPassedQuery::~AllSamplesPassedQuery() { | 156 SummedIntegerQuery::~SummedIntegerQuery() { |
| 157 } |
| 158 |
| 159 bool SummedIntegerQuery::Process(bool did_finish) { |
| 160 if (!AreAllResultsAvailable()) { |
| 161 // Must return true to avoid generating an error at the command |
| 162 // buffer level. |
| 163 return true; |
| 164 } |
| 165 GLuint summed_result = 0; |
| 166 for (const GLuint& service_id : service_ids_) { |
| 167 GLuint result = 0; |
| 168 glGetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, &result); |
| 169 summed_result += result; |
| 170 } |
| 171 return MarkAsCompleted(summed_result); |
| 116 } | 172 } |
| 117 | 173 |
| 118 class CommandsIssuedQuery : public QueryManager::Query { | 174 class CommandsIssuedQuery : public QueryManager::Query { |
| 119 public: | 175 public: |
| 120 CommandsIssuedQuery( | 176 CommandsIssuedQuery( |
| 121 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); | 177 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); |
| 122 | 178 |
| 123 bool Begin() override; | 179 bool Begin() override; |
| 124 bool End(base::subtle::Atomic32 submit_count) override; | 180 bool End(base::subtle::Atomic32 submit_count) override; |
| 125 bool QueryCounter(base::subtle::Atomic32 submit_count) override; | 181 bool QueryCounter(base::subtle::Atomic32 submit_count) override; |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 break; | 754 break; |
| 699 case GL_COMMANDS_COMPLETED_CHROMIUM: | 755 case GL_COMMANDS_COMPLETED_CHROMIUM: |
| 700 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); | 756 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); |
| 701 break; | 757 break; |
| 702 case GL_TIME_ELAPSED: | 758 case GL_TIME_ELAPSED: |
| 703 query = new TimeElapsedQuery(this, target, shm_id, shm_offset); | 759 query = new TimeElapsedQuery(this, target, shm_id, shm_offset); |
| 704 break; | 760 break; |
| 705 case GL_TIMESTAMP: | 761 case GL_TIMESTAMP: |
| 706 query = new TimeStampQuery(this, target, shm_id, shm_offset); | 762 query = new TimeStampQuery(this, target, shm_id, shm_offset); |
| 707 break; | 763 break; |
| 764 case GL_ANY_SAMPLES_PASSED: |
| 765 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: |
| 766 query = new BooleanQuery(this, target, shm_id, shm_offset); |
| 767 break; |
| 768 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: |
| 769 query = new SummedIntegerQuery(this, target, shm_id, shm_offset); |
| 770 break; |
| 708 default: { | 771 default: { |
| 709 query = new AllSamplesPassedQuery(this, target, shm_id, shm_offset); | 772 NOTREACHED(); |
| 710 break; | |
| 711 } | 773 } |
| 712 } | 774 } |
| 713 std::pair<QueryMap::iterator, bool> result = | 775 std::pair<QueryMap::iterator, bool> result = |
| 714 queries_.insert(std::make_pair(client_id, query)); | 776 queries_.insert(std::make_pair(client_id, query)); |
| 715 DCHECK(result.second); | 777 DCHECK(result.second); |
| 716 return query.get(); | 778 return query.get(); |
| 717 } | 779 } |
| 718 | 780 |
| 719 scoped_ptr<gfx::GPUTimer> QueryManager::CreateGPUTimer(bool elapsed_time) { | 781 scoped_ptr<gfx::GPUTimer> QueryManager::CreateGPUTimer(bool elapsed_time) { |
| 720 return gpu_timing_client_->CreateGPUTimer(elapsed_time); | 782 return gpu_timing_client_->CreateGPUTimer(elapsed_time); |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) { | 1095 for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) { |
| 1034 if (it.second->IsPaused()) { | 1096 if (it.second->IsPaused()) { |
| 1035 it.second->Resume(); | 1097 it.second->Resume(); |
| 1036 DCHECK(it.second->IsActive()); | 1098 DCHECK(it.second->IsActive()); |
| 1037 } | 1099 } |
| 1038 } | 1100 } |
| 1039 } | 1101 } |
| 1040 | 1102 |
| 1041 } // namespace gles2 | 1103 } // namespace gles2 |
| 1042 } // namespace gpu | 1104 } // namespace gpu |
| OLD | NEW |