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 "BenchGpuTimer_gl.h"
9#include "gl/SkGLContext.h"
10
11BenchGpuTimer::BenchGpuTimer(const SkGLContext* glctx) {
12    fContext = glctx;
13    glctx->ref();
14    glctx->makeCurrent();
15    fStarted = false;
16    fSupported = GrGLGetVersion(glctx->gl()) > GR_GL_VER(3,3) ||
17                 GrGLHasExtension(glctx->gl(), "GL_ARB_timer_query") ||
18                 GrGLHasExtension(glctx->gl(), "GL_EXT_timer_query");
19
20    if (fSupported) {
21        SK_GL(*glctx, GenQueries(1, &fQuery));
22    }
23}
24
25BenchGpuTimer::~BenchGpuTimer() {
26    if (fSupported) {
27        fContext->makeCurrent();
28        SK_GL(*fContext, DeleteQueries(1, &fQuery));
29    }
30    fContext->unref();
31}
32
33void BenchGpuTimer::startGpu() {
34    if (fSupported) {
35        fContext->makeCurrent();
36        fStarted = true;
37        SK_GL(*fContext, BeginQuery(GR_GL_TIME_ELAPSED, fQuery));
38    }
39}
40
41/**
42 * It is important to stop the cpu clocks first,
43 * as this will cpu wait for the gpu to finish.
44 */
45double BenchGpuTimer::endGpu() {
46    if (fSupported) {
47        fStarted = false;
48        fContext->makeCurrent();
49        SK_GL(*fContext, EndQuery(GR_GL_TIME_ELAPSED));
50
51        GrGLint available = 0;
52        while (!available) {
53            SK_GL(*fContext, GetQueryObjectiv(fQuery,
54                                             GR_GL_QUERY_RESULT_AVAILABLE,
55                                             &available));
56        }
57        GrGLuint64 totalGPUTimeElapsed = 0;
58        SK_GL(*fContext, GetQueryObjectui64v(fQuery,
59                                             GR_GL_QUERY_RESULT,
60                                             &totalGPUTimeElapsed));
61
62        return totalGPUTimeElapsed / 1000000.0;
63    } else {
64        return 0;
65    }
66}
67