joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "Benchmark.h" |
| 9 | #include "SkCanvas.h" |
| 10 | #include "SkImageEncoder.h" |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 11 | |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 12 | #if SK_SUPPORT_GPU |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 13 | #include "GLBench.h" |
egdaniel | f529439 | 2015-10-21 07:14:17 -0700 | [diff] [blame] | 14 | #include "gl/GrGLContext.h" |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 15 | #include "gl/GrGLInterface.h" |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 16 | #include "gl/GrGLUtil.h" |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 17 | #include "glsl/GrGLSL.h" |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 18 | #include "glsl/GrGLSLCaps.h" |
egdaniel | 0d3f061 | 2015-10-21 10:45:48 -0700 | [diff] [blame] | 19 | #include "glsl/GrGLSLShaderVar.h" |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 20 | #include <stdio.h> |
| 21 | |
| 22 | /* |
| 23 | * This is a native GL benchmark for determining the cost of uploading vertex attributes |
| 24 | */ |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 25 | class GLVertexAttributesBench : public GLBench { |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 26 | public: |
| 27 | GLVertexAttributesBench(uint32_t attribs) |
| 28 | : fTexture(0) |
| 29 | , fBuffers(0) |
| 30 | , fProgram(0) |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 31 | , fVBO(0) |
| 32 | , fAttribs(attribs) |
| 33 | , fStride(2 * sizeof(SkPoint) + fAttribs * sizeof(GrGLfloat) * 4) { |
| 34 | fName.appendf("GLVertexAttributesBench_%d", fAttribs); |
| 35 | } |
| 36 | |
| 37 | protected: |
| 38 | const char* onGetName() override { return fName.c_str(); } |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 39 | void setup(const GrGLContext*) override; |
mtklein | a1ebeb2 | 2015-10-01 09:43:39 -0700 | [diff] [blame] | 40 | void glDraw(int loops, const GrGLContext*) override; |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 41 | void teardown(const GrGLInterface*) override; |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 42 | |
| 43 | static const GrGLuint kScreenWidth = 800; |
| 44 | static const GrGLuint kScreenHeight = 600; |
| 45 | static const uint32_t kNumTri = 10000; |
| 46 | static const uint32_t kVerticesPerTri = 3; |
| 47 | static const uint32_t kDrawMultiplier = 512; |
| 48 | static const uint32_t kMaxAttribs = 7; |
| 49 | |
| 50 | private: |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 51 | GrGLuint setupShader(const GrGLContext*, uint32_t attribs, uint32_t maxAttribs); |
| 52 | |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 53 | GrGLuint fTexture; |
| 54 | SkTArray<GrGLuint> fBuffers; |
| 55 | GrGLuint fProgram; |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 56 | GrGLuint fVBO; |
| 57 | SkTArray<unsigned char> fVertices; |
| 58 | uint32_t fAttribs; |
| 59 | size_t fStride; |
| 60 | SkString fName; |
| 61 | typedef Benchmark INHERITED; |
| 62 | }; |
| 63 | |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 64 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
| 65 | |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 66 | GrGLuint GLVertexAttributesBench::setupShader(const GrGLContext* ctx, uint32_t attribs, |
| 67 | uint32_t maxAttribs) { |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 68 | const GrGLSLCaps* glslCaps = ctx->caps()->glslCaps(); |
| 69 | const char* version = glslCaps->versionDeclString(); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 70 | |
| 71 | // setup vertex shader |
egdaniel | 0d3f061 | 2015-10-21 10:45:48 -0700 | [diff] [blame] | 72 | GrGLSLShaderVar aPosition("a_position", kVec4f_GrSLType, GrShaderVar::kAttribute_TypeModifier); |
| 73 | SkTArray<GrGLSLShaderVar> aVars; |
| 74 | SkTArray<GrGLSLShaderVar> oVars; |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 75 | |
| 76 | SkString vshaderTxt(version); |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 77 | aPosition.appendDecl(glslCaps, &vshaderTxt); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 78 | vshaderTxt.append(";\n"); |
| 79 | |
| 80 | for (uint32_t i = 0; i < attribs; i++) { |
| 81 | SkString aname; |
| 82 | aname.appendf("a_color_%d", i); |
egdaniel | 0d3f061 | 2015-10-21 10:45:48 -0700 | [diff] [blame] | 83 | aVars.push_back(GrGLSLShaderVar(aname.c_str(), |
egdaniel | f529439 | 2015-10-21 07:14:17 -0700 | [diff] [blame] | 84 | kVec4f_GrSLType, |
| 85 | GrShaderVar::kAttribute_TypeModifier)); |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 86 | aVars.back().appendDecl(glslCaps, &vshaderTxt); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 87 | vshaderTxt.append(";\n"); |
| 88 | |
| 89 | } |
| 90 | |
| 91 | for (uint32_t i = 0; i < maxAttribs; i++) { |
| 92 | SkString oname; |
| 93 | oname.appendf("o_color_%d", i); |
egdaniel | 0d3f061 | 2015-10-21 10:45:48 -0700 | [diff] [blame] | 94 | oVars.push_back(GrGLSLShaderVar(oname.c_str(), |
egdaniel | f529439 | 2015-10-21 07:14:17 -0700 | [diff] [blame] | 95 | kVec4f_GrSLType, |
| 96 | GrShaderVar::kVaryingOut_TypeModifier)); |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 97 | oVars.back().appendDecl(glslCaps, &vshaderTxt); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 98 | vshaderTxt.append(";\n"); |
| 99 | } |
| 100 | |
| 101 | vshaderTxt.append( |
| 102 | "void main()\n" |
| 103 | "{\n" |
| 104 | "gl_Position = a_position;\n"); |
| 105 | |
| 106 | for (uint32_t i = 0; i < attribs; i++) { |
| 107 | vshaderTxt.appendf("%s = %s;\n", oVars[i].c_str(), aVars[i].c_str()); |
| 108 | } |
| 109 | |
| 110 | // Passthrough position as a dummy |
| 111 | for (uint32_t i = attribs; i < maxAttribs; i++) { |
joshualitt | bd929d9 | 2015-07-01 08:34:50 -0700 | [diff] [blame] | 112 | vshaderTxt.appendf("%s = vec4(0, 0, 0, 1);\n", oVars[i].c_str()); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | vshaderTxt.append("}\n"); |
| 116 | |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 117 | // setup fragment shader |
egdaniel | 0d3f061 | 2015-10-21 10:45:48 -0700 | [diff] [blame] | 118 | GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 119 | SkString fshaderTxt(version); |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 120 | GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *glslCaps, &fshaderTxt); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 121 | |
| 122 | const char* fsOutName; |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 123 | if (glslCaps->mustDeclareFragmentShaderOutput()) { |
| 124 | oFragColor.appendDecl(glslCaps, &fshaderTxt); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 125 | fshaderTxt.append(";\n"); |
| 126 | fsOutName = oFragColor.c_str(); |
| 127 | } else { |
ethannicholas | dcfe6db | 2016-10-10 10:09:00 -0700 | [diff] [blame^] | 128 | fsOutName = "sk_FragColor"; |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 129 | } |
| 130 | |
| 131 | for (uint32_t i = 0; i < maxAttribs; i++) { |
| 132 | oVars[i].setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier); |
egdaniel | cb7ba1e | 2015-10-26 08:38:25 -0700 | [diff] [blame] | 133 | oVars[i].appendDecl(glslCaps, &fshaderTxt); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 134 | fshaderTxt.append(";\n"); |
| 135 | } |
| 136 | |
| 137 | fshaderTxt.appendf( |
| 138 | "void main()\n" |
| 139 | "{\n" |
| 140 | "%s = ", fsOutName); |
| 141 | |
| 142 | fshaderTxt.appendf("%s", oVars[0].c_str()); |
| 143 | for (uint32_t i = 1; i < maxAttribs; i++) { |
| 144 | fshaderTxt.appendf(" + %s", oVars[i].c_str()); |
| 145 | } |
| 146 | |
| 147 | fshaderTxt.append(";\n" |
| 148 | "}\n"); |
| 149 | |
ethannicholas | dcfe6db | 2016-10-10 10:09:00 -0700 | [diff] [blame^] | 150 | return CreateProgram(ctx, vshaderTxt.c_str(), fshaderTxt.c_str()); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 151 | } |
| 152 | |
| 153 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
| 154 | |
| 155 | void GLVertexAttributesBench::setup(const GrGLContext* ctx) { |
| 156 | const GrGLInterface* gl = ctx->interface(); |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 157 | fTexture = SetupFramebuffer(gl, kScreenWidth, kScreenHeight); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 158 | |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 159 | fProgram = setupShader(ctx, fAttribs, kMaxAttribs); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 160 | |
| 161 | // setup matrices |
| 162 | SkMatrix viewMatrices[kNumTri]; |
| 163 | for (uint32_t i = 0 ; i < kNumTri; i++) { |
| 164 | SkMatrix m = SkMatrix::I(); |
| 165 | m.setScale(0.0001f, 0.0001f); |
| 166 | viewMatrices[i] = m; |
| 167 | } |
| 168 | |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 169 | // presetup vertex attributes, color is set to be a light gray no matter how many vertex |
| 170 | // attributes are used |
| 171 | float targetColor = 0.9f; |
| 172 | float colorContribution = targetColor / fAttribs; |
| 173 | fVertices.reset(static_cast<int>(kVerticesPerTri * kNumTri * fStride)); |
| 174 | for (uint32_t i = 0; i < kNumTri; i++) { |
| 175 | unsigned char* ptr = &fVertices[static_cast<int>(i * kVerticesPerTri * fStride)]; |
| 176 | SkPoint* p = reinterpret_cast<SkPoint*>(ptr); |
| 177 | p->set(-1.0f, -1.0f); p++; p->set( 0.0f, 1.0f); |
| 178 | p = reinterpret_cast<SkPoint*>(ptr + fStride); |
| 179 | p->set( 1.0f, -1.0f); p++; p->set( 0.0f, 1.0f); |
| 180 | p = reinterpret_cast<SkPoint*>(ptr + fStride * 2); |
| 181 | p->set( 1.0f, 1.0f); p++; p->set( 0.0f, 1.0f); |
| 182 | |
| 183 | SkPoint* position = reinterpret_cast<SkPoint*>(ptr); |
| 184 | viewMatrices[i].mapPointsWithStride(position, fStride, kVerticesPerTri); |
| 185 | |
| 186 | // set colors |
| 187 | for (uint32_t j = 0; j < kVerticesPerTri; j++) { |
| 188 | GrGLfloat* f = reinterpret_cast<GrGLfloat*>(ptr + 2 * sizeof(SkPoint) + fStride * j); |
| 189 | for (uint32_t k = 0; k < fAttribs * 4; k += 4) { |
| 190 | f[k] = colorContribution; |
| 191 | f[k + 1] = colorContribution; |
| 192 | f[k + 2] = colorContribution; |
| 193 | f[k + 3] = 1.0f; |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | GR_GL_CALL(gl, GenBuffers(1, &fVBO)); |
| 199 | fBuffers.push_back(fVBO); |
| 200 | |
| 201 | // clear screen |
| 202 | GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f)); |
| 203 | GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT)); |
| 204 | |
| 205 | // set us up to draw |
| 206 | GR_GL_CALL(gl, UseProgram(fProgram)); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 207 | } |
| 208 | |
mtklein | a1ebeb2 | 2015-10-01 09:43:39 -0700 | [diff] [blame] | 209 | void GLVertexAttributesBench::glDraw(int loops, const GrGLContext* ctx) { |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 210 | const GrGLInterface* gl = ctx->interface(); |
| 211 | |
| 212 | // upload vertex attributes |
| 213 | GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, fVBO)); |
| 214 | GR_GL_CALL(gl, EnableVertexAttribArray(0)); |
| 215 | GR_GL_CALL(gl, VertexAttribPointer(0, 4, GR_GL_FLOAT, GR_GL_FALSE, (GrGLsizei)fStride, |
| 216 | (GrGLvoid*)0)); |
| 217 | |
| 218 | size_t runningStride = 2 * sizeof(SkPoint); |
| 219 | for (uint32_t i = 0; i < fAttribs; i++) { |
| 220 | int attribId = i + 1; |
| 221 | GR_GL_CALL(gl, EnableVertexAttribArray(attribId)); |
| 222 | GR_GL_CALL(gl, VertexAttribPointer(attribId, 4, GR_GL_FLOAT, GR_GL_FALSE, |
| 223 | (GrGLsizei)fStride, (GrGLvoid*)(runningStride))); |
| 224 | runningStride += sizeof(GrGLfloat) * 4; |
| 225 | } |
| 226 | |
| 227 | GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, fVertices.count(), fVertices.begin(), |
| 228 | GR_GL_STREAM_DRAW)); |
| 229 | |
| 230 | uint32_t maxTrianglesPerFlush = kNumTri; |
| 231 | uint32_t trianglesToDraw = loops * kDrawMultiplier; |
| 232 | |
| 233 | while (trianglesToDraw > 0) { |
| 234 | uint32_t triangles = SkTMin(trianglesToDraw, maxTrianglesPerFlush); |
| 235 | GR_GL_CALL(gl, DrawArrays(GR_GL_TRIANGLES, 0, kVerticesPerTri * triangles)); |
| 236 | trianglesToDraw -= triangles; |
| 237 | } |
| 238 | |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 239 | #if 0 |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 240 | //const char* filename = "/data/local/tmp/out.png"; |
| 241 | SkString filename("out"); |
| 242 | filename.appendf("_%s.png", this->getName()); |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 243 | DumpImage(gl, kScreenWidth, kScreenHeight, filename.c_str()); |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 244 | #endif |
| 245 | } |
| 246 | |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 247 | void GLVertexAttributesBench::teardown(const GrGLInterface* gl) { |
| 248 | // teardown |
| 249 | GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, 0)); |
| 250 | GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0)); |
| 251 | GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); |
| 252 | GR_GL_CALL(gl, DeleteTextures(1, &fTexture)); |
| 253 | GR_GL_CALL(gl, DeleteProgram(fProgram)); |
| 254 | GR_GL_CALL(gl, DeleteBuffers(fBuffers.count(), fBuffers.begin())); |
joshualitt | 31b21f6 | 2015-07-16 13:40:51 -0700 | [diff] [blame] | 255 | fBuffers.reset(); |
joshualitt | 74a07db | 2015-07-01 12:39:07 -0700 | [diff] [blame] | 256 | } |
joshualitt | f06c389 | 2015-07-01 06:20:13 -0700 | [diff] [blame] | 257 | |
| 258 | /////////////////////////////////////////////////////////////////////////////// |
| 259 | |
| 260 | DEF_BENCH( return new GLVertexAttributesBench(0) ) |
| 261 | DEF_BENCH( return new GLVertexAttributesBench(1) ) |
| 262 | DEF_BENCH( return new GLVertexAttributesBench(2) ) |
| 263 | DEF_BENCH( return new GLVertexAttributesBench(3) ) |
| 264 | DEF_BENCH( return new GLVertexAttributesBench(4) ) |
| 265 | DEF_BENCH( return new GLVertexAttributesBench(5) ) |
| 266 | DEF_BENCH( return new GLVertexAttributesBench(6) ) |
| 267 | DEF_BENCH( return new GLVertexAttributesBench(7) ) |
| 268 | #endif |