| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2013 Google Inc. | 2  * Copyright 2013 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "GLTestContext.h" | 8 #include "GLTestContext.h" | 
|  | 9 | 
|  | 10 #include "GpuTimer.h" | 
| 9 #include "gl/GrGLUtil.h" | 11 #include "gl/GrGLUtil.h" | 
| 10 | 12 | 
| 11 namespace { | 13 namespace { | 
| 12 | 14 | 
| 13 class GLFenceSync : public sk_gpu_test::FenceSync { | 15 class GLFenceSync : public sk_gpu_test::FenceSync { | 
| 14 public: | 16 public: | 
| 15     static GLFenceSync* CreateIfSupported(const sk_gpu_test::GLTestContext*); | 17     static GLFenceSync* CreateIfSupported(const sk_gpu_test::GLTestContext*); | 
| 16 | 18 | 
| 17     sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const overrid
     e; | 19     sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const overrid
     e; | 
| 18     bool waitFence(sk_gpu_test::PlatformFence fence) const override; | 20     bool waitFence(sk_gpu_test::PlatformFence fence) const override; | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 71 bool GLFenceSync::waitFence(sk_gpu_test::PlatformFence fence) const { | 73 bool GLFenceSync::waitFence(sk_gpu_test::PlatformFence fence) const { | 
| 72     GLsync glsync = reinterpret_cast<GLsync>(fence); | 74     GLsync glsync = reinterpret_cast<GLsync>(fence); | 
| 73     return GL_WAIT_FAILED != fGLClientWaitSync(glsync, GL_SYNC_FLUSH_COMMANDS_BI
     T, -1); | 75     return GL_WAIT_FAILED != fGLClientWaitSync(glsync, GL_SYNC_FLUSH_COMMANDS_BI
     T, -1); | 
| 74 } | 76 } | 
| 75 | 77 | 
| 76 void GLFenceSync::deleteFence(sk_gpu_test::PlatformFence fence) const { | 78 void GLFenceSync::deleteFence(sk_gpu_test::PlatformFence fence) const { | 
| 77     GLsync glsync = reinterpret_cast<GLsync>(fence); | 79     GLsync glsync = reinterpret_cast<GLsync>(fence); | 
| 78     fGLDeleteSync(glsync); | 80     fGLDeleteSync(glsync); | 
| 79 } | 81 } | 
| 80 | 82 | 
|  | 83 class GLGpuTimer : public sk_gpu_test::GpuTimer { | 
|  | 84 public: | 
|  | 85     static GLGpuTimer* CreateIfSupported(const sk_gpu_test::GLTestContext*); | 
|  | 86 | 
|  | 87     QueryStatus checkQueryStatus(sk_gpu_test::PlatformTimerQuery) override; | 
|  | 88     std::chrono::nanoseconds getTimeElapsed(sk_gpu_test::PlatformTimerQuery) ove
     rride; | 
|  | 89     void deleteQuery(sk_gpu_test::PlatformTimerQuery) override; | 
|  | 90 | 
|  | 91 private: | 
|  | 92     GLGpuTimer(bool disjointSupport, const sk_gpu_test::GLTestContext*, const ch
     ar* ext = ""); | 
|  | 93 | 
|  | 94     bool validate() const; | 
|  | 95 | 
|  | 96     sk_gpu_test::PlatformTimerQuery onQueueTimerStart() const override; | 
|  | 97     void onQueueTimerStop(sk_gpu_test::PlatformTimerQuery) const override; | 
|  | 98 | 
|  | 99     static constexpr GrGLenum GL_QUERY_RESULT            = 0x8866; | 
|  | 100     static constexpr GrGLenum GL_QUERY_RESULT_AVAILABLE  = 0x8867; | 
|  | 101     static constexpr GrGLenum GL_TIME_ELAPSED            = 0x88bf; | 
|  | 102     static constexpr GrGLenum GL_GPU_DISJOINT            = 0x8fbb; | 
|  | 103 | 
|  | 104     typedef void (GR_GL_FUNCTION_TYPE* GLGetIntegervProc) (GrGLenum, GrGLint*); | 
|  | 105     typedef void (GR_GL_FUNCTION_TYPE* GLGenQueriesProc) (GrGLsizei, GrGLuint*); | 
|  | 106     typedef void (GR_GL_FUNCTION_TYPE* GLDeleteQueriesProc) (GrGLsizei, const Gr
     GLuint*); | 
|  | 107     typedef void (GR_GL_FUNCTION_TYPE* GLBeginQueryProc) (GrGLenum, GrGLuint); | 
|  | 108     typedef void (GR_GL_FUNCTION_TYPE* GLEndQueryProc) (GrGLenum); | 
|  | 109     typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryObjectuivProc) (GrGLuint, GrGLe
     num, GrGLuint*); | 
|  | 110     typedef void (GR_GL_FUNCTION_TYPE* GLGetQueryObjectui64vProc) (GrGLuint, GrG
     Lenum, GrGLuint64*); | 
|  | 111 | 
|  | 112     GLGetIntegervProc           fGLGetIntegerv; | 
|  | 113     GLGenQueriesProc            fGLGenQueries; | 
|  | 114     GLDeleteQueriesProc         fGLDeleteQueries; | 
|  | 115     GLBeginQueryProc            fGLBeginQuery; | 
|  | 116     GLEndQueryProc              fGLEndQuery; | 
|  | 117     GLGetQueryObjectuivProc     fGLGetQueryObjectuiv; | 
|  | 118     GLGetQueryObjectui64vProc   fGLGetQueryObjectui64v; | 
|  | 119 | 
|  | 120 | 
|  | 121     typedef sk_gpu_test::GpuTimer INHERITED; | 
|  | 122 }; | 
|  | 123 | 
|  | 124 GLGpuTimer* GLGpuTimer::CreateIfSupported(const sk_gpu_test::GLTestContext* ctx)
      { | 
|  | 125     SkAutoTDelete<GLGpuTimer> ret; | 
|  | 126     const GrGLInterface* gl = ctx->gl(); | 
|  | 127     if (gl->fExtensions.has("GL_EXT_disjoint_timer_query")) { | 
|  | 128         ret.reset(new GLGpuTimer(true, ctx, "EXT")); | 
|  | 129     } else if (kGL_GrGLStandard == gl->fStandard && | 
|  | 130                (GrGLGetVersion(gl) > GR_GL_VER(3,3) || gl->fExtensions.has("GL_A
     RB_timer_query"))) { | 
|  | 131         ret.reset(new GLGpuTimer(false, ctx)); | 
|  | 132     } else if (gl->fExtensions.has("GL_EXT_timer_query")) { | 
|  | 133         ret.reset(new GLGpuTimer(false, ctx, "EXT")); | 
|  | 134     } | 
|  | 135     return ret && ret->validate() ? ret.release() : nullptr; | 
|  | 136 } | 
|  | 137 | 
|  | 138 GLGpuTimer::GLGpuTimer(bool disjointSupport, const sk_gpu_test::GLTestContext* c
     tx, const char* ext) | 
|  | 139     : INHERITED(disjointSupport) { | 
|  | 140     ctx->getGLProcAddress(&fGLGetIntegerv, "glGetIntegerv"); | 
|  | 141     ctx->getGLProcAddress(&fGLGenQueries, "glGenQueries", ext); | 
|  | 142     ctx->getGLProcAddress(&fGLDeleteQueries, "glDeleteQueries", ext); | 
|  | 143     ctx->getGLProcAddress(&fGLBeginQuery, "glBeginQuery", ext); | 
|  | 144     ctx->getGLProcAddress(&fGLEndQuery, "glEndQuery", ext); | 
|  | 145     ctx->getGLProcAddress(&fGLGetQueryObjectuiv, "glGetQueryObjectuiv", ext); | 
|  | 146     ctx->getGLProcAddress(&fGLGetQueryObjectui64v, "glGetQueryObjectui64v", ext)
     ; | 
|  | 147 } | 
|  | 148 | 
|  | 149 bool GLGpuTimer::validate() const { | 
|  | 150     return fGLGetIntegerv && fGLGenQueries && fGLDeleteQueries && fGLBeginQuery 
     && fGLEndQuery && | 
|  | 151            fGLGetQueryObjectuiv && fGLGetQueryObjectui64v; | 
|  | 152 } | 
|  | 153 | 
|  | 154 sk_gpu_test::PlatformTimerQuery GLGpuTimer::onQueueTimerStart() const { | 
|  | 155     GrGLuint queryID; | 
|  | 156     fGLGenQueries(1, &queryID); | 
|  | 157     if (!queryID) { | 
|  | 158         return sk_gpu_test::kInvalidTimerQuery; | 
|  | 159     } | 
|  | 160     if (this->disjointSupport()) { | 
|  | 161         // Clear the disjoint flag. | 
|  | 162         GrGLint disjoint; | 
|  | 163         fGLGetIntegerv(GL_GPU_DISJOINT, &disjoint); | 
|  | 164     } | 
|  | 165     fGLBeginQuery(GL_TIME_ELAPSED, queryID); | 
|  | 166     return static_cast<sk_gpu_test::PlatformTimerQuery>(queryID); | 
|  | 167 } | 
|  | 168 | 
|  | 169 void GLGpuTimer::onQueueTimerStop(sk_gpu_test::PlatformTimerQuery platformTimer)
      const { | 
|  | 170     if (sk_gpu_test::kInvalidTimerQuery == platformTimer) { | 
|  | 171         return; | 
|  | 172     } | 
|  | 173     fGLEndQuery(GL_TIME_ELAPSED); | 
|  | 174 } | 
|  | 175 | 
|  | 176 sk_gpu_test::GpuTimer::QueryStatus | 
|  | 177 GLGpuTimer::checkQueryStatus(sk_gpu_test::PlatformTimerQuery platformTimer) { | 
|  | 178     const GrGLuint queryID = static_cast<GrGLuint>(platformTimer); | 
|  | 179     if (!queryID) { | 
|  | 180         return QueryStatus::kInvalid; | 
|  | 181     } | 
|  | 182     GrGLuint available = 0; | 
|  | 183     fGLGetQueryObjectuiv(queryID, GL_QUERY_RESULT_AVAILABLE, &available); | 
|  | 184     if (!available) { | 
|  | 185         return QueryStatus::kPending; | 
|  | 186     } | 
|  | 187     if (this->disjointSupport()) { | 
|  | 188         GrGLint disjoint = 1; | 
|  | 189         fGLGetIntegerv(GL_GPU_DISJOINT, &disjoint); | 
|  | 190         if (disjoint) { | 
|  | 191             return QueryStatus::kDisjoint; | 
|  | 192         } | 
|  | 193     } | 
|  | 194     return QueryStatus::kAccurate; | 
|  | 195 } | 
|  | 196 | 
|  | 197 std::chrono::nanoseconds GLGpuTimer::getTimeElapsed(sk_gpu_test::PlatformTimerQu
     ery platformTimer) { | 
|  | 198     SkASSERT(this->checkQueryStatus(platformTimer) >= QueryStatus::kDisjoint); | 
|  | 199     const GrGLuint queryID = static_cast<GrGLuint>(platformTimer); | 
|  | 200     GrGLuint64 nanoseconds; | 
|  | 201     fGLGetQueryObjectui64v(queryID, GL_QUERY_RESULT, &nanoseconds); | 
|  | 202     return std::chrono::nanoseconds(nanoseconds); | 
|  | 203 } | 
|  | 204 | 
|  | 205 void GLGpuTimer::deleteQuery(sk_gpu_test::PlatformTimerQuery platformTimer) { | 
|  | 206     const GrGLuint queryID = static_cast<GrGLuint>(platformTimer); | 
|  | 207     fGLDeleteQueries(1, &queryID); | 
|  | 208 } | 
|  | 209 | 
|  | 210 GR_STATIC_ASSERT(sizeof(GrGLuint) <= sizeof(sk_gpu_test::PlatformTimerQuery)); | 
|  | 211 | 
| 81 }  // anonymous namespace | 212 }  // anonymous namespace | 
| 82 | 213 | 
| 83 namespace sk_gpu_test { | 214 namespace sk_gpu_test { | 
| 84 | 215 | 
| 85 GLTestContext::GLTestContext() : TestContext() {} | 216 GLTestContext::GLTestContext() : TestContext() {} | 
| 86 | 217 | 
| 87 GLTestContext::~GLTestContext() { | 218 GLTestContext::~GLTestContext() { | 
| 88     SkASSERT(nullptr == fGL.get()); | 219     SkASSERT(nullptr == fGL.get()); | 
| 89 } | 220 } | 
| 90 | 221 | 
| 91 void GLTestContext::init(const GrGLInterface* gl, FenceSync* fenceSync) { | 222 void GLTestContext::init(const GrGLInterface* gl, FenceSync* fenceSync) { | 
| 92     SkASSERT(!fGL.get()); | 223     SkASSERT(!fGL.get()); | 
| 93     fGL.reset(gl); | 224     fGL.reset(gl); | 
| 94     fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this); | 225     fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this); | 
|  | 226     fGpuTimer = GLGpuTimer::CreateIfSupported(this); | 
| 95 } | 227 } | 
| 96 | 228 | 
| 97 void GLTestContext::teardown() { | 229 void GLTestContext::teardown() { | 
| 98     fGL.reset(nullptr); | 230     fGL.reset(nullptr); | 
| 99     INHERITED::teardown(); | 231     INHERITED::teardown(); | 
| 100 } | 232 } | 
| 101 | 233 | 
| 102 void GLTestContext::testAbandon() { | 234 void GLTestContext::testAbandon() { | 
| 103     INHERITED::testAbandon(); | 235     INHERITED::testAbandon(); | 
| 104     if (fGL) { | 236     if (fGL) { | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 139                                   GR_GL_NEAREST)); | 271                                   GR_GL_NEAREST)); | 
| 140     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S, | 272     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S, | 
| 141                                   GR_GL_CLAMP_TO_EDGE)); | 273                                   GR_GL_CLAMP_TO_EDGE)); | 
| 142     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T, | 274     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T, | 
| 143                                   GR_GL_CLAMP_TO_EDGE)); | 275                                   GR_GL_CLAMP_TO_EDGE)); | 
| 144     GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width
     , height, 0, | 276     GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width
     , height, 0, | 
| 145                                externalFormat, externalType, data)); | 277                                externalFormat, externalType, data)); | 
| 146     return id; | 278     return id; | 
| 147 } | 279 } | 
| 148 }  // namespace sk_gpu_test | 280 }  // namespace sk_gpu_test | 
| OLD | NEW | 
|---|