Home | History | Annotate | Download | only in timer
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "GpuTimer.h"
      9 #include "gl/SkGLContextHelper.h"
     10 #include "gl/GrGLUtil.h"
     11 
     12 GpuTimer::GpuTimer(const SkGLContextHelper* glctx) : fContext(glctx) {
     13     if (fContext) {
     14         fContext->ref();
     15         fContext->makeCurrent();
     16         fStarted = false;
     17         fSupported = GrGLGetVersion(fContext->gl()) > GR_GL_VER(3,3) ||
     18                      fContext->hasExtension("GL_ARB_timer_query") ||
     19                      fContext->hasExtension("GL_EXT_timer_query");
     20 
     21         if (fSupported) {
     22             SK_GL(*fContext, GenQueries(1, &fQuery));
     23         }
     24     }
     25 }
     26 
     27 GpuTimer::~GpuTimer() {
     28     if (fContext) {
     29         if (fSupported) {
     30             fContext->makeCurrent();
     31             SK_GL(*fContext, DeleteQueries(1, &fQuery));
     32         }
     33         fContext->unref();
     34     }
     35 }
     36 
     37 void GpuTimer::start() {
     38     if (fContext && fSupported) {
     39         fContext->makeCurrent();
     40         fStarted = true;
     41         SK_GL(*fContext, BeginQuery(GR_GL_TIME_ELAPSED, fQuery));
     42     }
     43 }
     44 
     45 /**
     46  * It is important to stop the cpu clocks first,
     47  * as this will cpu wait for the gpu to finish.
     48  */
     49 double GpuTimer::end() {
     50     if (fContext && fSupported) {
     51         fStarted = false;
     52         fContext->makeCurrent();
     53         SK_GL(*fContext, EndQuery(GR_GL_TIME_ELAPSED));
     54 
     55         GrGLint available = 0;
     56         while (!available) {
     57             SK_GL_NOERRCHECK(*fContext, GetQueryObjectiv(fQuery,
     58                                                          GR_GL_QUERY_RESULT_AVAILABLE,
     59                                                          &available));
     60             // If GetQueryObjectiv is erroring out we need some alternative
     61             // means of breaking out of this loop
     62             GrGLenum error;
     63             SK_GL_RET_NOERRCHECK(*fContext, error, GetError());
     64             if (GR_GL_NO_ERROR != error) {
     65                 break;
     66             }
     67         }
     68         GrGLuint64 totalGPUTimeElapsed = 0;
     69         SK_GL(*fContext, GetQueryObjectui64v(fQuery,
     70                                              GR_GL_QUERY_RESULT,
     71                                              &totalGPUTimeElapsed));
     72 
     73         return totalGPUTimeElapsed / 1000000.0;
     74     } else {
     75         return 0;
     76     }
     77 }
     78