blob: 1b077d5a022facd9d12755acc9bc4479fadf2702 [file] [log] [blame]
bsalomon@google.com373a6632011-10-19 20:43:20 +00001/*
robertphillips@google.com6177e692013-02-28 20:16:25 +00002 * Copyright 2013 Google Inc.
bsalomon@google.com373a6632011-10-19 20:43:20 +00003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
bsalomon18a2f9d2016-05-11 10:09:18 -07007
bsalomon273c0f52016-03-31 10:59:06 -07008#include "GLTestContext.h"
bsalomon3724e572016-03-30 18:56:19 -07009#include "gl/GrGLUtil.h"
bsalomon@google.com373a6632011-10-19 20:43:20 +000010
csmartdalton421a3c12016-10-04 11:08:45 -070011namespace {
cdaltond416a5b2015-06-23 13:23:44 -070012
csmartdalton421a3c12016-10-04 11:08:45 -070013class GLFenceSync : public sk_gpu_test::FenceSync {
14public:
15 static GLFenceSync* CreateIfSupported(const sk_gpu_test::GLTestContext*);
16
17 sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const override;
18 bool waitFence(sk_gpu_test::PlatformFence fence) const override;
19 void deleteFence(sk_gpu_test::PlatformFence fence) const override;
cdaltond416a5b2015-06-23 13:23:44 -070020
21private:
csmartdalton421a3c12016-10-04 11:08:45 -070022 GLFenceSync(const sk_gpu_test::GLTestContext*, const char* ext = "");
cdaltond416a5b2015-06-23 13:23:44 -070023
csmartdalton421a3c12016-10-04 11:08:45 -070024 bool validate() { return fGLFenceSync && fGLClientWaitSync && fGLDeleteSync; }
25
26 static constexpr GrGLenum GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117;
27 static constexpr GrGLenum GL_WAIT_FAILED = 0x911d;
28 static constexpr GrGLbitfield GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001;
cdaltond416a5b2015-06-23 13:23:44 -070029
30 typedef struct __GLsync *GLsync;
csmartdalton024229a2016-10-04 14:24:23 -070031 GR_STATIC_ASSERT(sizeof(GLsync) <= sizeof(sk_gpu_test::PlatformFence));
cdaltond416a5b2015-06-23 13:23:44 -070032
33 typedef GLsync (GR_GL_FUNCTION_TYPE* GLFenceSyncProc) (GrGLenum, GrGLbitfield);
34 typedef GrGLenum (GR_GL_FUNCTION_TYPE* GLClientWaitSyncProc) (GLsync, GrGLbitfield, GrGLuint64);
35 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GLDeleteSyncProc) (GLsync);
36
37 GLFenceSyncProc fGLFenceSync;
38 GLClientWaitSyncProc fGLClientWaitSync;
39 GLDeleteSyncProc fGLDeleteSync;
40
csmartdalton421a3c12016-10-04 11:08:45 -070041 typedef FenceSync INHERITED;
cdaltond416a5b2015-06-23 13:23:44 -070042};
43
csmartdalton421a3c12016-10-04 11:08:45 -070044GLFenceSync* GLFenceSync::CreateIfSupported(const sk_gpu_test::GLTestContext* ctx) {
45 SkAutoTDelete<GLFenceSync> ret;
46 if (kGL_GrGLStandard == ctx->gl()->fStandard) {
47 if (GrGLGetVersion(ctx->gl()) < GR_GL_VER(3,2) && !ctx->gl()->hasExtension("GL_ARB_sync")) {
48 return nullptr;
49 }
50 ret.reset(new GLFenceSync(ctx));
51 } else {
52 if (!ctx->gl()->hasExtension("GL_APPLE_sync")) {
53 return nullptr;
54 }
55 ret.reset(new GLFenceSync(ctx, "APPLE"));
56 }
57 return ret->validate() ? ret.release() : nullptr;
58}
59
60GLFenceSync::GLFenceSync(const sk_gpu_test::GLTestContext* ctx, const char* ext) {
61 ctx->getGLProcAddress(&fGLFenceSync, "glFenceSync");
62 ctx->getGLProcAddress(&fGLClientWaitSync, "glClientWaitSync");
63 ctx->getGLProcAddress(&fGLDeleteSync, "glDeleteSync");
64}
65
66sk_gpu_test::PlatformFence GLFenceSync::insertFence() const {
67 __GLsync* glsync = fGLFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
68 return reinterpret_cast<sk_gpu_test::PlatformFence>(glsync);
69}
70
71bool GLFenceSync::waitFence(sk_gpu_test::PlatformFence fence) const {
72 GLsync glsync = reinterpret_cast<GLsync>(fence);
73 return GL_WAIT_FAILED != fGLClientWaitSync(glsync, GL_SYNC_FLUSH_COMMANDS_BIT, -1);
74}
75
76void GLFenceSync::deleteFence(sk_gpu_test::PlatformFence fence) const {
77 GLsync glsync = reinterpret_cast<GLsync>(fence);
78 fGLDeleteSync(glsync);
79}
80
81} // anonymous namespace
82
83namespace sk_gpu_test {
84
bsalomon18a2f9d2016-05-11 10:09:18 -070085GLTestContext::GLTestContext() : TestContext() {}
bsalomon@google.com373a6632011-10-19 20:43:20 +000086
bsalomon273c0f52016-03-31 10:59:06 -070087GLTestContext::~GLTestContext() {
halcanary96fcdcc2015-08-27 07:41:13 -070088 SkASSERT(nullptr == fGL.get());
cdaltond416a5b2015-06-23 13:23:44 -070089}
90
csmartdalton421a3c12016-10-04 11:08:45 -070091void GLTestContext::init(const GrGLInterface* gl, FenceSync* fenceSync) {
cdaltond416a5b2015-06-23 13:23:44 -070092 SkASSERT(!fGL.get());
93 fGL.reset(gl);
bsalomon18a2f9d2016-05-11 10:09:18 -070094 fFenceSync = fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this);
cdaltond416a5b2015-06-23 13:23:44 -070095}
96
bsalomon273c0f52016-03-31 10:59:06 -070097void GLTestContext::teardown() {
halcanary96fcdcc2015-08-27 07:41:13 -070098 fGL.reset(nullptr);
bsalomon18a2f9d2016-05-11 10:09:18 -070099 INHERITED::teardown();
bsalomon@google.com373a6632011-10-19 20:43:20 +0000100}
bsalomon944bcf02014-07-29 08:01:52 -0700101
bsalomon273c0f52016-03-31 10:59:06 -0700102void GLTestContext::testAbandon() {
bsalomon18a2f9d2016-05-11 10:09:18 -0700103 INHERITED::testAbandon();
bsalomon49f085d2014-09-05 13:34:00 -0700104 if (fGL) {
bsalomon944bcf02014-07-29 08:01:52 -0700105 fGL->abandon();
106 }
cdaltond416a5b2015-06-23 13:23:44 -0700107}
108
bsalomonc8699322016-05-11 11:55:36 -0700109void GLTestContext::submit() {
110 if (fGL) {
111 GR_GL_CALL(fGL.get(), Flush());
112 }
113}
114
115void GLTestContext::finish() {
116 if (fGL) {
117 GR_GL_CALL(fGL.get(), Finish());
118 }
119}
120
bsalomon273c0f52016-03-31 10:59:06 -0700121GrGLint GLTestContext::createTextureRectangle(int width, int height, GrGLenum internalFormat,
bsalomon3724e572016-03-30 18:56:19 -0700122 GrGLenum externalFormat, GrGLenum externalType,
123 GrGLvoid* data) {
bsalomone179a912016-01-20 06:18:10 -0800124 if (!(kGL_GrGLStandard == fGL->fStandard && GrGLGetVersion(fGL) >= GR_GL_VER(3, 1)) &&
bsalomone5286e02016-01-14 09:24:09 -0800125 !fGL->fExtensions.has("GL_ARB_texture_rectangle")) {
126 return 0;
127 }
bsalomone179a912016-01-20 06:18:10 -0800128
129 if (GrGLGetGLSLVersion(fGL) < GR_GLSL_VER(1, 40)) {
130 return 0;
131 }
132
bsalomone5286e02016-01-14 09:24:09 -0800133 GrGLuint id;
134 GR_GL_CALL(fGL, GenTextures(1, &id));
135 GR_GL_CALL(fGL, BindTexture(GR_GL_TEXTURE_RECTANGLE, id));
136 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MAG_FILTER,
137 GR_GL_NEAREST));
138 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MIN_FILTER,
139 GR_GL_NEAREST));
140 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S,
bsalomon3724e572016-03-30 18:56:19 -0700141 GR_GL_CLAMP_TO_EDGE));
bsalomone5286e02016-01-14 09:24:09 -0800142 GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T,
143 GR_GL_CLAMP_TO_EDGE));
144 GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width, height, 0,
145 externalFormat, externalType, data));
146 return id;
147}
bsalomon3724e572016-03-30 18:56:19 -0700148} // namespace sk_gpu_test