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 |