| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "Benchmark.h" | 8 #include "Benchmark.h" |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkImageEncoder.h" | 10 #include "SkImageEncoder.h" |
| 11 |
| 11 #if SK_SUPPORT_GPU | 12 #if SK_SUPPORT_GPU |
| 12 #include "GrTest.h" | 13 #include "GLBench.h" |
| 13 #include "gl/GrGLGLSL.h" | 14 #include "gl/GrGLGLSL.h" |
| 14 #include "gl/GrGLInterface.h" | 15 #include "gl/GrGLInterface.h" |
| 15 #include "gl/GrGLShaderVar.h" | 16 #include "gl/GrGLShaderVar.h" |
| 16 #include "gl/GrGLUtil.h" | 17 #include "gl/GrGLUtil.h" |
| 17 #include "glsl/GrGLSLCaps.h" | 18 #include "glsl/GrGLSLCaps.h" |
| 18 #include <stdio.h> | 19 #include <stdio.h> |
| 19 | 20 |
| 20 /* | 21 /* |
| 21 * This is a native GL benchmark for determining the cost of uploading vertex at
tributes | 22 * This is a native GL benchmark for determining the cost of uploading vertex at
tributes |
| 22 */ | 23 */ |
| 23 class GLVertexAttributesBench : public Benchmark { | 24 class GLVertexAttributesBench : public GLBench { |
| 24 public: | 25 public: |
| 25 GLVertexAttributesBench(uint32_t attribs) | 26 GLVertexAttributesBench(uint32_t attribs) |
| 26 : fTexture(0) | 27 : fTexture(0) |
| 27 , fBuffers(0) | 28 , fBuffers(0) |
| 28 , fProgram(0) | 29 , fProgram(0) |
| 29 , fVBO(0) | 30 , fVBO(0) |
| 30 , fAttribs(attribs) | 31 , fAttribs(attribs) |
| 31 , fStride(2 * sizeof(SkPoint) + fAttribs * sizeof(GrGLfloat) * 4) { | 32 , fStride(2 * sizeof(SkPoint) + fAttribs * sizeof(GrGLfloat) * 4) { |
| 32 fName.appendf("GLVertexAttributesBench_%d", fAttribs); | 33 fName.appendf("GLVertexAttributesBench_%d", fAttribs); |
| 33 } | 34 } |
| 34 | 35 |
| 35 protected: | 36 protected: |
| 36 const char* onGetName() override { return fName.c_str(); } | 37 const char* onGetName() override { return fName.c_str(); } |
| 37 void onPerCanvasPreDraw(SkCanvas* canvas) override; | 38 void setup(const GrGLContext*) override; |
| 38 void setup(const GrGLContext*); | 39 void glDraw(const int loops, const GrGLContext*) override; |
| 39 void onDraw(const int loops, SkCanvas*) override; | 40 void teardown(const GrGLInterface*) override; |
| 40 void onPerCanvasPostDraw(SkCanvas* canvas) override; | |
| 41 | 41 |
| 42 static const GrGLuint kScreenWidth = 800; | 42 static const GrGLuint kScreenWidth = 800; |
| 43 static const GrGLuint kScreenHeight = 600; | 43 static const GrGLuint kScreenHeight = 600; |
| 44 static const uint32_t kNumTri = 10000; | 44 static const uint32_t kNumTri = 10000; |
| 45 static const uint32_t kVerticesPerTri = 3; | 45 static const uint32_t kVerticesPerTri = 3; |
| 46 static const uint32_t kDrawMultiplier = 512; | 46 static const uint32_t kDrawMultiplier = 512; |
| 47 static const uint32_t kMaxAttribs = 7; | 47 static const uint32_t kMaxAttribs = 7; |
| 48 | 48 |
| 49 private: | 49 private: |
| 50 GrGLuint setupShader(const GrGLContext*, uint32_t attribs, uint32_t maxAttri
bs); |
| 51 |
| 50 GrGLuint fTexture; | 52 GrGLuint fTexture; |
| 51 SkTArray<GrGLuint> fBuffers; | 53 SkTArray<GrGLuint> fBuffers; |
| 52 GrGLuint fProgram; | 54 GrGLuint fProgram; |
| 53 GrGLuint fVBO; | 55 GrGLuint fVBO; |
| 54 SkTArray<unsigned char> fVertices; | 56 SkTArray<unsigned char> fVertices; |
| 55 uint32_t fAttribs; | 57 uint32_t fAttribs; |
| 56 size_t fStride; | 58 size_t fStride; |
| 57 SkString fName; | 59 SkString fName; |
| 58 typedef Benchmark INHERITED; | 60 typedef Benchmark INHERITED; |
| 59 }; | 61 }; |
| 60 | 62 |
| 61 static const GrGLContext* get_gl_context(SkCanvas* canvas) { | |
| 62 // This bench exclusively tests GL calls directly | |
| 63 if (NULL == canvas->getGrContext()) { | |
| 64 return NULL; | |
| 65 } | |
| 66 GrContext* context = canvas->getGrContext(); | |
| 67 | |
| 68 GrTestTarget tt; | |
| 69 context->getTestTarget(&tt); | |
| 70 if (!tt.target()) { | |
| 71 SkDebugf("Couldn't get Gr test target."); | |
| 72 return NULL; | |
| 73 } | |
| 74 | |
| 75 const GrGLContext* ctx = tt.glContext(); | |
| 76 if (!ctx) { | |
| 77 SkDebugf("Couldn't get an interface\n"); | |
| 78 return NULL; | |
| 79 } | |
| 80 | |
| 81 return ctx; | |
| 82 } | |
| 83 | |
| 84 void GLVertexAttributesBench::onPerCanvasPreDraw(SkCanvas* canvas) { | |
| 85 // This bench exclusively tests GL calls directly | |
| 86 const GrGLContext* ctx = get_gl_context(canvas); | |
| 87 if (!ctx) { | |
| 88 return; | |
| 89 } | |
| 90 this->setup(ctx); | |
| 91 } | |
| 92 | |
| 93 void GLVertexAttributesBench::onPerCanvasPostDraw(SkCanvas* canvas) { | |
| 94 // This bench exclusively tests GL calls directly | |
| 95 const GrGLContext* ctx = get_gl_context(canvas); | |
| 96 if (!ctx) { | |
| 97 return; | |
| 98 } | |
| 99 | |
| 100 const GrGLInterface* gl = ctx->interface(); | |
| 101 | |
| 102 // teardown | |
| 103 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, 0)); | |
| 104 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0)); | |
| 105 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); | |
| 106 GR_GL_CALL(gl, DeleteTextures(1, &fTexture)); | |
| 107 GR_GL_CALL(gl, DeleteProgram(fProgram)); | |
| 108 GR_GL_CALL(gl, DeleteBuffers(fBuffers.count(), fBuffers.begin())); | |
| 109 } | |
| 110 | |
| 111 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 63 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 112 | 64 |
| 113 static GrGLuint load_shader(const GrGLInterface* gl, const char* shaderSrc, GrGL
enum type) { | 65 GrGLuint GLVertexAttributesBench::setupShader(const GrGLContext* ctx, uint32_t a
ttribs, |
| 114 GrGLuint shader; | 66 uint32_t maxAttribs) { |
| 115 // Create the shader object | |
| 116 GR_GL_CALL_RET(gl, shader, CreateShader(type)); | |
| 117 | |
| 118 // Load the shader source | |
| 119 GR_GL_CALL(gl, ShaderSource(shader, 1, &shaderSrc, NULL)); | |
| 120 | |
| 121 // Compile the shader | |
| 122 GR_GL_CALL(gl, CompileShader(shader)); | |
| 123 | |
| 124 // Check for compile time errors | |
| 125 GrGLint success; | |
| 126 GrGLchar infoLog[512]; | |
| 127 GR_GL_CALL(gl, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &success)); | |
| 128 if (!success) { | |
| 129 GR_GL_CALL(gl, GetShaderInfoLog(shader, 512, NULL, infoLog)); | |
| 130 SkDebugf("ERROR::SHADER::COMPLIATION_FAILED: %s\n", infoLog); | |
| 131 } | |
| 132 | |
| 133 return shader; | |
| 134 } | |
| 135 | |
| 136 static GrGLuint compile_shader(const GrGLContext* ctx, uint32_t attribs, uint32_
t maxAttribs) { | |
| 137 const char* version = GrGLGetGLSLVersionDecl(*ctx); | 67 const char* version = GrGLGetGLSLVersionDecl(*ctx); |
| 138 | 68 |
| 139 // setup vertex shader | 69 // setup vertex shader |
| 140 GrGLShaderVar aPosition("a_position", kVec4f_GrSLType, GrShaderVar::kAttribu
te_TypeModifier); | 70 GrGLShaderVar aPosition("a_position", kVec4f_GrSLType, GrShaderVar::kAttribu
te_TypeModifier); |
| 141 SkTArray<GrGLShaderVar> aVars; | 71 SkTArray<GrGLShaderVar> aVars; |
| 142 SkTArray<GrGLShaderVar> oVars; | 72 SkTArray<GrGLShaderVar> oVars; |
| 143 | 73 |
| 144 SkString vshaderTxt(version); | 74 SkString vshaderTxt(version); |
| 145 aPosition.appendDecl(*ctx, &vshaderTxt); | 75 aPosition.appendDecl(*ctx, &vshaderTxt); |
| 146 vshaderTxt.append(";\n"); | 76 vshaderTxt.append(";\n"); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 176 } | 106 } |
| 177 | 107 |
| 178 // Passthrough position as a dummy | 108 // Passthrough position as a dummy |
| 179 for (uint32_t i = attribs; i < maxAttribs; i++) { | 109 for (uint32_t i = attribs; i < maxAttribs; i++) { |
| 180 vshaderTxt.appendf("%s = vec4(0, 0, 0, 1);\n", oVars[i].c_str()); | 110 vshaderTxt.appendf("%s = vec4(0, 0, 0, 1);\n", oVars[i].c_str()); |
| 181 } | 111 } |
| 182 | 112 |
| 183 vshaderTxt.append("}\n"); | 113 vshaderTxt.append("}\n"); |
| 184 | 114 |
| 185 const GrGLInterface* gl = ctx->interface(); | 115 const GrGLInterface* gl = ctx->interface(); |
| 186 GrGLuint vertexShader = load_shader(gl, vshaderTxt.c_str(), GR_GL_VERTEX_SHA
DER); | |
| 187 | 116 |
| 188 // setup fragment shader | 117 // setup fragment shader |
| 189 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T
ypeModifier); | 118 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T
ypeModifier); |
| 190 SkString fshaderTxt(version); | 119 SkString fshaderTxt(version); |
| 191 GrGLAppendGLSLDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, gl->f
Standard, | 120 GrGLAppendGLSLDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, gl->f
Standard, |
| 192 &fshaderTxt); | 121 &fshaderTxt); |
| 193 | 122 |
| 194 const char* fsOutName; | 123 const char* fsOutName; |
| 195 if (ctx->caps()->glslCaps()->mustDeclareFragmentShaderOutput()) { | 124 if (ctx->caps()->glslCaps()->mustDeclareFragmentShaderOutput()) { |
| 196 oFragColor.appendDecl(*ctx, &fshaderTxt); | 125 oFragColor.appendDecl(*ctx, &fshaderTxt); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 212 "%s = ", fsOutName); | 141 "%s = ", fsOutName); |
| 213 | 142 |
| 214 fshaderTxt.appendf("%s", oVars[0].c_str()); | 143 fshaderTxt.appendf("%s", oVars[0].c_str()); |
| 215 for (uint32_t i = 1; i < maxAttribs; i++) { | 144 for (uint32_t i = 1; i < maxAttribs; i++) { |
| 216 fshaderTxt.appendf(" + %s", oVars[i].c_str()); | 145 fshaderTxt.appendf(" + %s", oVars[i].c_str()); |
| 217 } | 146 } |
| 218 | 147 |
| 219 fshaderTxt.append(";\n" | 148 fshaderTxt.append(";\n" |
| 220 "}\n"); | 149 "}\n"); |
| 221 | 150 |
| 222 GrGLuint fragmentShader = load_shader(gl, fshaderTxt.c_str(), GR_GL_FRAGMENT
_SHADER); | 151 return CreateProgram(gl, vshaderTxt.c_str(), fshaderTxt.c_str()); |
| 223 | |
| 224 GrGLint shaderProgram; | |
| 225 GR_GL_CALL_RET(gl, shaderProgram, CreateProgram()); | |
| 226 GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader)); | |
| 227 GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader)); | |
| 228 GR_GL_CALL(gl, LinkProgram(shaderProgram)); | |
| 229 | |
| 230 // Check for linking errors | |
| 231 GrGLint success; | |
| 232 GrGLchar infoLog[512]; | |
| 233 GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success)); | |
| 234 if (!success) { | |
| 235 GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, NULL, infoLog)); | |
| 236 SkDebugf("Linker Error: %s\n", infoLog); | |
| 237 } | |
| 238 GR_GL_CALL(gl, DeleteShader(vertexShader)); | |
| 239 GR_GL_CALL(gl, DeleteShader(fragmentShader)); | |
| 240 | |
| 241 return shaderProgram; | |
| 242 } | |
| 243 | |
| 244 //#define DUMP_IMAGES | |
| 245 #ifdef DUMP_IMAGES | |
| 246 static void dump_image(const GrGLInterface* gl, uint32_t screenWidth, uint32_t s
creenHeight, | |
| 247 const char* filename) { | |
| 248 // read back pixels | |
| 249 uint32_t readback[screenWidth * screenHeight]; | |
| 250 GR_GL_CALL(gl, ReadPixels(0, // x | |
| 251 0, // y | |
| 252 screenWidth, // width | |
| 253 screenHeight, // height | |
| 254 GR_GL_RGBA, //format | |
| 255 GR_GL_UNSIGNED_BYTE, //type | |
| 256 readback)); | |
| 257 | |
| 258 // dump png | |
| 259 SkBitmap bm; | |
| 260 if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(screenWidth, screenHeight)
)) { | |
| 261 SkDebugf("couldn't allocate bitmap\n"); | |
| 262 return; | |
| 263 } | |
| 264 | |
| 265 bm.setPixels(readback); | |
| 266 | |
| 267 if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100
)) { | |
| 268 SkDebugf("------ failed to encode %s\n", filename); | |
| 269 remove(filename); // remove any partial file | |
| 270 return; | |
| 271 } | |
| 272 } | |
| 273 #endif | |
| 274 | |
| 275 static void setup_framebuffer(const GrGLInterface* gl, int screenWidth, int scre
enHeight) { | |
| 276 //Setup framebuffer | |
| 277 GrGLuint texture; | |
| 278 GR_GL_CALL(gl, GenTextures(1, &texture)); | |
| 279 GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE15)); | |
| 280 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, texture)); | |
| 281 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_
GL_NEAREST)); | |
| 282 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_
GL_NEAREST)); | |
| 283 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_S, GR_GL_C
LAMP_TO_EDGE)); | |
| 284 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_T, GR_GL_C
LAMP_TO_EDGE)); | |
| 285 GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D, | |
| 286 0, //level | |
| 287 GR_GL_RGBA, //internal format | |
| 288 screenWidth, // width | |
| 289 screenHeight, // height | |
| 290 0, //border | |
| 291 GR_GL_RGBA, //format | |
| 292 GR_GL_UNSIGNED_BYTE, // type | |
| 293 NULL)); | |
| 294 | |
| 295 // bind framebuffer | |
| 296 GrGLuint framebuffer; | |
| 297 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0)); | |
| 298 GR_GL_CALL(gl, GenFramebuffers(1, &framebuffer)); | |
| 299 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, framebuffer)); | |
| 300 GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER, | |
| 301 GR_GL_COLOR_ATTACHMENT0, | |
| 302 GR_GL_TEXTURE_2D, | |
| 303 texture, 0)); | |
| 304 GR_GL_CALL(gl, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | |
| 305 GR_GL_CALL(gl, Viewport(0, 0, screenWidth, screenHeight)); | |
| 306 } | 152 } |
| 307 | 153 |
| 308 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 154 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 309 | 155 |
| 310 void GLVertexAttributesBench::setup(const GrGLContext* ctx) { | 156 void GLVertexAttributesBench::setup(const GrGLContext* ctx) { |
| 311 const GrGLInterface* gl = ctx->interface(); | 157 const GrGLInterface* gl = ctx->interface(); |
| 312 setup_framebuffer(gl, kScreenWidth, kScreenHeight); | 158 fTexture = SetupFramebuffer(gl, kScreenWidth, kScreenHeight); |
| 313 | 159 |
| 314 fProgram = compile_shader(ctx, fAttribs, kMaxAttribs); | 160 fProgram = setupShader(ctx, fAttribs, kMaxAttribs); |
| 315 | 161 |
| 316 // setup matrices | 162 // setup matrices |
| 317 SkMatrix viewMatrices[kNumTri]; | 163 SkMatrix viewMatrices[kNumTri]; |
| 318 for (uint32_t i = 0 ; i < kNumTri; i++) { | 164 for (uint32_t i = 0 ; i < kNumTri; i++) { |
| 319 SkMatrix m = SkMatrix::I(); | 165 SkMatrix m = SkMatrix::I(); |
| 320 m.setScale(0.0001f, 0.0001f); | 166 m.setScale(0.0001f, 0.0001f); |
| 321 viewMatrices[i] = m; | 167 viewMatrices[i] = m; |
| 322 } | 168 } |
| 323 | 169 |
| 324 // presetup vertex attributes, color is set to be a light gray no matter how
many vertex | 170 // presetup vertex attributes, color is set to be a light gray no matter how
many vertex |
| (...skipping 29 matching lines...) Expand all Loading... |
| 354 fBuffers.push_back(fVBO); | 200 fBuffers.push_back(fVBO); |
| 355 | 201 |
| 356 // clear screen | 202 // clear screen |
| 357 GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f)); | 203 GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f)); |
| 358 GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT)); | 204 GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT)); |
| 359 | 205 |
| 360 // set us up to draw | 206 // set us up to draw |
| 361 GR_GL_CALL(gl, UseProgram(fProgram)); | 207 GR_GL_CALL(gl, UseProgram(fProgram)); |
| 362 } | 208 } |
| 363 | 209 |
| 364 void GLVertexAttributesBench::onDraw(const int loops, SkCanvas* canvas) { | 210 void GLVertexAttributesBench::glDraw(const int loops, const GrGLContext* ctx) { |
| 365 const GrGLContext* ctx = get_gl_context(canvas); | |
| 366 if (!ctx) { | |
| 367 return; | |
| 368 } | |
| 369 | |
| 370 const GrGLInterface* gl = ctx->interface(); | 211 const GrGLInterface* gl = ctx->interface(); |
| 371 | 212 |
| 372 // upload vertex attributes | 213 // upload vertex attributes |
| 373 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, fVBO)); | 214 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, fVBO)); |
| 374 GR_GL_CALL(gl, EnableVertexAttribArray(0)); | 215 GR_GL_CALL(gl, EnableVertexAttribArray(0)); |
| 375 GR_GL_CALL(gl, VertexAttribPointer(0, 4, GR_GL_FLOAT, GR_GL_FALSE, (GrGLsize
i)fStride, | 216 GR_GL_CALL(gl, VertexAttribPointer(0, 4, GR_GL_FLOAT, GR_GL_FALSE, (GrGLsize
i)fStride, |
| 376 (GrGLvoid*)0)); | 217 (GrGLvoid*)0)); |
| 377 | 218 |
| 378 size_t runningStride = 2 * sizeof(SkPoint); | 219 size_t runningStride = 2 * sizeof(SkPoint); |
| 379 for (uint32_t i = 0; i < fAttribs; i++) { | 220 for (uint32_t i = 0; i < fAttribs; i++) { |
| 380 int attribId = i + 1; | 221 int attribId = i + 1; |
| 381 GR_GL_CALL(gl, EnableVertexAttribArray(attribId)); | 222 GR_GL_CALL(gl, EnableVertexAttribArray(attribId)); |
| 382 GR_GL_CALL(gl, VertexAttribPointer(attribId, 4, GR_GL_FLOAT, GR_GL_FALSE
, | 223 GR_GL_CALL(gl, VertexAttribPointer(attribId, 4, GR_GL_FLOAT, GR_GL_FALSE
, |
| 383 (GrGLsizei)fStride, (GrGLvoid*)(runni
ngStride))); | 224 (GrGLsizei)fStride, (GrGLvoid*)(runni
ngStride))); |
| 384 runningStride += sizeof(GrGLfloat) * 4; | 225 runningStride += sizeof(GrGLfloat) * 4; |
| 385 } | 226 } |
| 386 | 227 |
| 387 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, fVertices.count(), fVertices.b
egin(), | 228 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, fVertices.count(), fVertices.b
egin(), |
| 388 GR_GL_STREAM_DRAW)); | 229 GR_GL_STREAM_DRAW)); |
| 389 | 230 |
| 390 uint32_t maxTrianglesPerFlush = kNumTri; | 231 uint32_t maxTrianglesPerFlush = kNumTri; |
| 391 uint32_t trianglesToDraw = loops * kDrawMultiplier; | 232 uint32_t trianglesToDraw = loops * kDrawMultiplier; |
| 392 | 233 |
| 393 while (trianglesToDraw > 0) { | 234 while (trianglesToDraw > 0) { |
| 394 uint32_t triangles = SkTMin(trianglesToDraw, maxTrianglesPerFlush); | 235 uint32_t triangles = SkTMin(trianglesToDraw, maxTrianglesPerFlush); |
| 395 GR_GL_CALL(gl, DrawArrays(GR_GL_TRIANGLES, 0, kVerticesPerTri * triangle
s)); | 236 GR_GL_CALL(gl, DrawArrays(GR_GL_TRIANGLES, 0, kVerticesPerTri * triangle
s)); |
| 396 trianglesToDraw -= triangles; | 237 trianglesToDraw -= triangles; |
| 397 } | 238 } |
| 398 | 239 |
| 399 #ifdef DUMP_IMAGES | 240 #if 0 |
| 400 //const char* filename = "/data/local/tmp/out.png"; | 241 //const char* filename = "/data/local/tmp/out.png"; |
| 401 SkString filename("out"); | 242 SkString filename("out"); |
| 402 filename.appendf("_%s.png", this->getName()); | 243 filename.appendf("_%s.png", this->getName()); |
| 403 dump_image(gl, kScreenWidth, kScreenHeight, filename.c_str()); | 244 DumpImage(gl, kScreenWidth, kScreenHeight, filename.c_str()); |
| 404 #endif | 245 #endif |
| 405 } | 246 } |
| 406 | 247 |
| 248 void GLVertexAttributesBench::teardown(const GrGLInterface* gl) { |
| 249 // teardown |
| 250 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, 0)); |
| 251 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0)); |
| 252 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); |
| 253 GR_GL_CALL(gl, DeleteTextures(1, &fTexture)); |
| 254 GR_GL_CALL(gl, DeleteProgram(fProgram)); |
| 255 GR_GL_CALL(gl, DeleteBuffers(fBuffers.count(), fBuffers.begin())); |
| 256 } |
| 407 | 257 |
| 408 /////////////////////////////////////////////////////////////////////////////// | 258 /////////////////////////////////////////////////////////////////////////////// |
| 409 | 259 |
| 410 DEF_BENCH( return new GLVertexAttributesBench(0) ) | 260 DEF_BENCH( return new GLVertexAttributesBench(0) ) |
| 411 DEF_BENCH( return new GLVertexAttributesBench(1) ) | 261 DEF_BENCH( return new GLVertexAttributesBench(1) ) |
| 412 DEF_BENCH( return new GLVertexAttributesBench(2) ) | 262 DEF_BENCH( return new GLVertexAttributesBench(2) ) |
| 413 DEF_BENCH( return new GLVertexAttributesBench(3) ) | 263 DEF_BENCH( return new GLVertexAttributesBench(3) ) |
| 414 DEF_BENCH( return new GLVertexAttributesBench(4) ) | 264 DEF_BENCH( return new GLVertexAttributesBench(4) ) |
| 415 DEF_BENCH( return new GLVertexAttributesBench(5) ) | 265 DEF_BENCH( return new GLVertexAttributesBench(5) ) |
| 416 DEF_BENCH( return new GLVertexAttributesBench(6) ) | 266 DEF_BENCH( return new GLVertexAttributesBench(6) ) |
| 417 DEF_BENCH( return new GLVertexAttributesBench(7) ) | 267 DEF_BENCH( return new GLVertexAttributesBench(7) ) |
| 418 #endif | 268 #endif |
| OLD | NEW |