| Index: ui/gl/gpu_timing.cc
|
| diff --git a/ui/gl/gpu_timing.cc b/ui/gl/gpu_timing.cc
|
| index a3b697fe306b0afaaac1c48787e8049c76276163..a744164d91f6a1205518ccda6d92e90596a0d5e4 100644
|
| --- a/ui/gl/gpu_timing.cc
|
| +++ b/ui/gl/gpu_timing.cc
|
| @@ -20,6 +20,8 @@ GPUTiming::GPUTiming(GLContextReal* context) {
|
| timer_type_ = kTimerTypeDisjoint;
|
| } else if (context->HasExtension("GL_ARB_timer_query")) {
|
| timer_type_ = kTimerTypeARB;
|
| + } else if (context->HasExtension("GL_EXT_timer_query")) {
|
| + timer_type_ = kTimerTypeEXT;
|
| }
|
| }
|
|
|
| @@ -46,14 +48,35 @@ GPUTimer::~GPUTimer() {
|
| }
|
|
|
| void GPUTimer::Start() {
|
| - // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
|
| - glQueryCounter(queries_[0], GL_TIMESTAMP);
|
| + switch (gpu_timing_client_->gpu_timing_->timer_type_) {
|
| + case GPUTiming::kTimerTypeARB:
|
| + case GPUTiming::kTimerTypeDisjoint:
|
| + // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
|
| + glQueryCounter(queries_[0], GL_TIMESTAMP);
|
| + break;
|
| + case GPUTiming::kTimerTypeEXT:
|
| + glBeginQuery(GL_TIME_ELAPSED_EXT, queries_[0]);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| }
|
|
|
| void GPUTimer::End() {
|
| end_requested_ = true;
|
| - offset_ = gpu_timing_client_->CalculateTimerOffset();
|
| - glQueryCounter(queries_[1], GL_TIMESTAMP);
|
| + DCHECK(gpu_timing_client_->gpu_timing_);
|
| + switch (gpu_timing_client_->gpu_timing_->timer_type_) {
|
| + case GPUTiming::kTimerTypeARB:
|
| + case GPUTiming::kTimerTypeDisjoint:
|
| + offset_ = gpu_timing_client_->CalculateTimerOffset();
|
| + glQueryCounter(queries_[1], GL_TIMESTAMP);
|
| + break;
|
| + case GPUTiming::kTimerTypeEXT:
|
| + glEndQuery(GL_TIME_ELAPSED_EXT);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| }
|
|
|
| bool GPUTimer::IsAvailable() {
|
| @@ -61,13 +84,17 @@ bool GPUTimer::IsAvailable() {
|
| return false;
|
| }
|
| GLint done = 0;
|
| - glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
|
| + glGetQueryObjectivARB(queries_[1] ? queries_[1] : queries_[0],
|
| + GL_QUERY_RESULT_AVAILABLE, &done);
|
| return done != 0;
|
| }
|
|
|
| void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
|
| DCHECK(start && end);
|
| DCHECK(IsAvailable());
|
| + DCHECK(gpu_timing_client_->gpu_timing_);
|
| + DCHECK(gpu_timing_client_->gpu_timing_->timer_type_ !=
|
| + GPUTiming::kTimerTypeEXT);
|
| GLuint64 begin_stamp = 0;
|
| GLuint64 end_stamp = 0;
|
| // TODO(dsinclair): It's possible for the timer to wrap during the start/end.
|
| @@ -81,17 +108,44 @@ void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
|
| }
|
|
|
| int64 GPUTimer::GetDeltaElapsed() {
|
| - int64 start = 0;
|
| - int64 end = 0;
|
| - GetStartEndTimestamps(&start, &end);
|
| - return end - start;
|
| + DCHECK(gpu_timing_client_->gpu_timing_);
|
| + switch (gpu_timing_client_->gpu_timing_->timer_type_) {
|
| + case GPUTiming::kTimerTypeARB:
|
| + case GPUTiming::kTimerTypeDisjoint: {
|
| + int64 start = 0;
|
| + int64 end = 0;
|
| + GetStartEndTimestamps(&start, &end);
|
| + return end - start;
|
| + } break;
|
| + case GPUTiming::kTimerTypeEXT: {
|
| + GLuint64 delta = 0;
|
| + glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &delta);
|
| + return static_cast<int64>(delta / base::Time::kNanosecondsPerMicrosecond);
|
| + } break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| + return 0;
|
| }
|
|
|
| GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client)
|
| : gpu_timing_client_(gpu_timing_client) {
|
| DCHECK(gpu_timing_client_);
|
| memset(queries_, 0, sizeof(queries_));
|
| - glGenQueriesARB(2, queries_);
|
| + int queries = 0;
|
| + DCHECK(gpu_timing_client_->gpu_timing_);
|
| + switch (gpu_timing_client_->gpu_timing_->timer_type_) {
|
| + case GPUTiming::kTimerTypeARB:
|
| + case GPUTiming::kTimerTypeDisjoint:
|
| + queries = 2;
|
| + break;
|
| + case GPUTiming::kTimerTypeEXT:
|
| + queries = 1;
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| + glGenQueriesARB(queries, queries_);
|
| }
|
|
|
| GPUTimingClient::GPUTimingClient(GPUTiming* gpu_timing)
|
| @@ -110,12 +164,19 @@ bool GPUTimingClient::IsAvailable() {
|
| return timer_type_ != GPUTiming::kTimerTypeInvalid;
|
| }
|
|
|
| +bool GPUTimingClient::IsTimerOffsetAvailable() {
|
| + return timer_type_ == GPUTiming::kTimerTypeARB ||
|
| + timer_type_ == GPUTiming::kTimerTypeDisjoint;
|
| +}
|
| +
|
| const char* GPUTimingClient::GetTimerTypeName() const {
|
| switch (timer_type_) {
|
| case GPUTiming::kTimerTypeDisjoint:
|
| return "GL_EXT_disjoint_timer_query";
|
| case GPUTiming::kTimerTypeARB:
|
| return "GL_ARB_timer_query";
|
| + case GPUTiming::kTimerTypeEXT:
|
| + return "GL_EXT_timer_query";
|
| default:
|
| return "Unknown";
|
| }
|
| @@ -133,6 +194,7 @@ bool GPUTimingClient::CheckAndResetTimerErrors() {
|
| }
|
|
|
| int64 GPUTimingClient::CalculateTimerOffset() {
|
| + DCHECK(IsTimerOffsetAvailable());
|
| if (!offset_valid_) {
|
| GLint64 gl_now = 0;
|
| glGetInteger64v(GL_TIMESTAMP, &gl_now);
|
|
|