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