Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(999)

Side by Side Diff: bench/GLInstancedArraysBench.cpp

Issue 1216663002: Benchmark to test native perf of GL Instanced Ararys (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "GrTest.h"
bsalomon 2015/06/26 19:20:15 #if SK_SUPPORT_GPU?
10 #include "SkCanvas.h"
11 #include "SkImageEncoder.h"
12 #include "gl/GrGLGLSL.h"
13 #include "gl/GrGLInterface.h"
14 #include "gl/GrGLShaderVar.h"
15 #include "gl/GrGLUtil.h"
16 #include "glsl/GrGLSLCaps.h"
17 #include <stdio.h>
18
19 /*
20 * This is a native GL benchmark for instanced arrays
21 */
22 class GLInstancedArraysBench : public Benchmark {
23 protected:
24 void onPerCanvasPreDraw(SkCanvas* canvas) override;
25 virtual void setup(const GrGLContext*)=0;
26 void onPerCanvasPostDraw(SkCanvas* canvas) override;
27
28 static const GrGLuint kScreenWidth = 800;
29 static const GrGLuint kScreenHeight = 600;
30 static const uint32_t kNumTri = 2;
31 static const uint32_t kVerticesPerTri = 3;
32
33 private:
34 typedef Benchmark INHERITED;
35 };
36
37 #if 0
38 class GLGpuPosInstancedArraysBench : public GLInstancedArraysBench {
39 protected:
40 const char* onGetName() override {
41 return "GLInstancedArraysBench_gpupos";
42 }
43
44 void setup(const GrGLContext*) override;
45 void onDraw(const int loops, SkCanvas* canvas) override;
46 };
47 #endif
48
49 class GLCpuPosInstancedArraysBench : public GLInstancedArraysBench {
50 public:
51 enum VboSetup {
52 kUseOne_VboSetup,
53 kUseTwo_VboSetup,
54 kUseInstance_VboSetup,
55 };
56
57 GLCpuPosInstancedArraysBench(VboSetup vboSetup, bool multipleDraws)
58 : fVboSetup(vboSetup)
59 , fMultipleDraws(multipleDraws) {
60 fName = VboSetupToStr(vboSetup, fMultipleDraws);
61 }
62
63 protected:
64 const char* onGetName() override {
65 return fName.c_str();
66 }
67
68 void setup(const GrGLContext*) override;
69 void onDraw(const int loops, SkCanvas* canvas) override;
70
71 private:
72 void setupInstanceVbo(const GrGLInterface*, const SkMatrix*);
73 void setupDoubleVbo(const GrGLInterface*, const SkMatrix*);
74 void setupSingleVbo(const GrGLInterface*, const SkMatrix*);
75
76 static SkString VboSetupToStr(VboSetup vboSetup, bool multiDraw) {
77 SkString name("GLInstancedArraysBench");
78 switch (vboSetup) {
79 default:
80 case kUseOne_VboSetup:
81 name.appendf("_one_%s", multiDraw ? "multipledraws" : "singledra w");
82 break;
83 case kUseTwo_VboSetup:
84 name.appendf("_two_%s", multiDraw ? "multipledraws" : "singledra w");
85 break;
86 case kUseInstance_VboSetup:
87 name.append("_instance");
88 break;
89 }
90 return name;
91 }
92
93 SkString fName;
94 VboSetup fVboSetup;
95 bool fMultipleDraws;
96 };
97
98 static const GrGLContext* get_gl_context(SkCanvas* canvas) {
99 // This bench exclusively tests GL calls directly
100 if (NULL == canvas->getGrContext()) {
101 return NULL;
102 }
103 GrContext* context = canvas->getGrContext();
104
105 GrTestTarget tt;
106 context->getTestTarget(&tt);
107 if (!tt.target()) {
108 SkDebugf("Couldn't get Gr test target.");
109 return NULL;
110 }
111
112 const GrGLContext* ctx = tt.glContext();
113 if (!ctx) {
114 SkDebugf("Couldn't get an interface\n");
115 return NULL;
116 }
117
118 // We only care about gpus with drawArraysInstanced support
119 if (!ctx->interface()->fFunctions.fDrawArraysInstanced) {
120 return NULL;
121 }
122 return ctx;
123 }
124
125 void GLInstancedArraysBench::onPerCanvasPreDraw(SkCanvas* canvas) {
126 // This bench exclusively tests GL calls directly
127 const GrGLContext* ctx = get_gl_context(canvas);
128 if (!ctx) {
129 return;
130 }
131 this->setup(ctx);
132 }
133
134 void GLInstancedArraysBench::onPerCanvasPostDraw(SkCanvas* canvas) {
135 // This bench exclusively tests GL calls directly
136 const GrGLContext* ctx = get_gl_context(canvas);
137 if (!ctx) {
138 return;
139 }
140
141 const GrGLInterface* gl = ctx->interface();
142
143 // teardown
144 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, 0));
145 GR_GL_CALL(gl, BindVertexArray(0));
146 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
147 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
148 }
bsalomon 2015/06/26 19:20:15 don't you need to delete the buffers somewhere? an
149
150 //////////////////////////////////////////////////////////////////////////////// ///////////////////
151
152 // TODO move all of the gpu positioning stuff to a new file
153 #ifdef GPU_POS
154 static const char* gpu_vertex_shader =
155 "layout (location = 0) in vec2 position;\n"
156 "layout (location = 1) in vec3 color;\n"
157 "layout (location = 2) in mat3 offset;\n"
158
159 "out vec3 fColor;\n"
160
161 "void main()\n"
162 "{\n"
163 "gl_Position = vec4(offset * vec3(position, 1.0f), 1.f);\n"
164 "fColor = color;\n"
165 "}\n";
166 #endif
167
168 static GrGLuint load_shader(const GrGLInterface* gl, const char* shaderSrc, GrGL enum type) {
169 GrGLuint shader;
170 // Create the shader object
171 GR_GL_CALL_RET(gl, shader, CreateShader(type));
172
173 // Load the shader source
174 GR_GL_CALL(gl, ShaderSource(shader, 1, &shaderSrc, NULL));
175
176 // Compile the shader
177 GR_GL_CALL(gl, CompileShader(shader));
178
179 // Check for compile time errors
180 GrGLint success;
181 GrGLchar infoLog[512];
182 GR_GL_CALL(gl, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &success));
183 if (!success)
184 {
185 GR_GL_CALL(gl, GetShaderInfoLog(shader, 512, NULL, infoLog));
186 SkDebugf("ERROR::SHADER::COMPLIATION_FAILED: %s\n", infoLog);
187 }
188
189 return shader;
190 }
191
192 static GrGLuint compile_shader(const GrGLContext* ctx) {
193 const char* version = GrGLGetGLSLVersionDecl(*ctx);
194
195 // setup vertex shader
196 GrGLShaderVar aPosition("a_position", kVec2f_GrSLType, GrShaderVar::kAttribu te_TypeModifier);
197 GrGLShaderVar aColor("a_color", kVec3f_GrSLType, GrShaderVar::kAttribute_Typ eModifier);
198 GrGLShaderVar oColor("o_color", kVec3f_GrSLType, GrShaderVar::kVaryingOut_Ty peModifier);
199
200 SkString vshaderTxt(version);
201 aPosition.appendDecl(*ctx, &vshaderTxt);
202 vshaderTxt.append(";\n");
203 aColor.appendDecl(*ctx, &vshaderTxt);
204 vshaderTxt.append(";\n");
205 oColor.appendDecl(*ctx, &vshaderTxt);
206 vshaderTxt.append(";\n");
207
208 vshaderTxt.append(
209 "void main()\n"
210 "{\n"
211 "gl_Position = vec4(a_position, 0.f, 1.f);\n"
212 "o_color = a_color;\n"
213 "}\n");
214
215 const GrGLInterface* gl = ctx->interface();
216 GrGLuint vertexShader = load_shader(gl, vshaderTxt.c_str(), GR_GL_VERTEX_SHA DER);
217
218 // setup fragment shader
219 GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_T ypeModifier);
220 SkString fshaderTxt(version);
221 GrGLAppendGLSLDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, gl->f Standard,
222 &fshaderTxt);
223 oColor.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
224 oColor.appendDecl(*ctx, &fshaderTxt);
225 fshaderTxt.append(";\n");
226
227 const char* fsOutName;
228 if (ctx->caps()->glslCaps()->mustDeclareFragmentShaderOutput()) {
229 oFragColor.appendDecl(*ctx, &fshaderTxt);
230 fshaderTxt.append(";\n");
231 fsOutName = oFragColor.c_str();
232 } else {
233 fsOutName = "gl_FragColor";
234 }
235
236 fshaderTxt.appendf(
237 "void main()\n"
238 "{\n"
239 "%s = vec4(o_color, 1.0f);\n"
240 "}\n", fsOutName);
241
242 GrGLuint fragmentShader = load_shader(gl, fshaderTxt.c_str(), GR_GL_FRAGMENT _SHADER);
243
244 GrGLint shaderProgram;
245 GR_GL_CALL_RET(gl, shaderProgram, CreateProgram());
246 GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader));
247 GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader));
248 GR_GL_CALL(gl, LinkProgram(shaderProgram));
249
250 // Check for linking errors
251 GrGLint success;
252 GrGLchar infoLog[512];
253 GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success));
254 if (!success) {
255 GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, NULL, infoLog));
256 SkDebugf("Linker Error: %s\n", infoLog);
257 }
258 GR_GL_CALL(gl, DeleteShader(vertexShader));
259 GR_GL_CALL(gl, DeleteShader(fragmentShader));
260
261 return shaderProgram;
262 }
263
264 //#define DUMP_IMAGES
265 #ifdef DUMP_IMAGES
266 static void dump_image(const GrGLInterface* gl, uint32_t screenWidth, uint32_t s creenHeight,
267 const char* filename) {
268 // read back pixels
269 uint32_t readback[screenWidth * screenHeight];
270 GR_GL_CALL(gl, ReadPixels(0, // x
271 0, // y
272 screenWidth, // width
273 screenHeight, // height
274 GR_GL_RGBA, //format
275 GR_GL_UNSIGNED_BYTE, //type
276 readback));
277
278 // dump png
279 SkBitmap bm;
280 if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(screenWidth, screenHeight) )) {
281 SkDebugf("couldn't allocate bitmap\n");
282 return;
283 }
284
285 bm.setPixels(readback);
286
287 if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100 )) {
288 SkDebugf("------ failed to encode %s\n", filename);
289 remove(filename); // remove any partial file
290 return;
291 }
292 }
293 #endif
294
295 static void setup_framebuffer(const GrGLInterface* gl, int screenWidth, int scre enHeight) {
296 //Setup framebuffer
297 GrGLuint texture;
298 GR_GL_CALL(gl, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
299 GR_GL_CALL(gl, PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
300 GR_GL_CALL(gl, GenTextures(1, &texture));
301 GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE15));
302 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, texture));
303 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_ GL_NEAREST));
304 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_ GL_NEAREST));
305 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_S, GR_GL_C LAMP_TO_EDGE));
306 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_T, GR_GL_C LAMP_TO_EDGE));
307 GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D,
308 0, //level
309 GR_GL_RGBA8, //internal format
310 screenWidth, // width
311 screenHeight, // height
312 0, //border
313 GR_GL_RGBA, //format
314 GR_GL_UNSIGNED_BYTE, // type
315 NULL));
316
317 // bind framebuffer
318 GrGLuint framebuffer;
319 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
320 GR_GL_CALL(gl, GenFramebuffers(1, &framebuffer));
321 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, framebuffer));
322 GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
323 GR_GL_COLOR_ATTACHMENT0,
324 GR_GL_TEXTURE_2D,
325 texture, 0));
326 GR_GL_CALL(gl, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
327 GR_GL_CALL(gl, Viewport(0, 0, screenWidth, screenHeight));
328 }
329
330 template<typename Func>
331 static void setup_matrices(int numQuads, Func f) {
332 #if 0
333 float max = sqrt(numQuads);
334 float pos = 1.f / (2 * max);
335 GrGLfloat offset = pos * 2;
336 for(GrGLint row = 0; row < max; row++) {
337 for(GrGLint col = 0; col < max; col++) {
338 SkScalar xOffset = col / max * 2.f - 1.f + offset;
339 SkScalar yOffset = row / max * 2.f - 1.f + offset;
340 SkMatrix translation;
341 SkRandom random;
342 translation.setScale(pos, pos);
343 translation.postTranslate(xOffset, yOffset);
344 f(translation);
345 }
346 }
347 #endif
348 // We draw a really small triangle so we are not fill rate limited
349 for (int i = 0 ; i < numQuads; i++) {
350 SkMatrix m = SkMatrix::I();
351 m.setScale(0.0001f, 0.0001f);
352 f(m);
353 }
354 }
355
356 #ifdef GPU_POS
357 void GLGpuPosInstancedArraysBench::setup(const GrGLInterface* gl) {
358 setup_framebuffer(gl, kScreenWidth, kScreenHeight);
359
360 // compile and use shaders
361 GrGLint shaderProgram = compile_shader(gl, gpu_vertex_shader, fragment_shade r);
362
363 // translations
364 int index = 0;
365 GrGLfloat viewMatrices[fNumQuads * fSkMatrixNumCells];
366 setup_matrices(fNumQuads, [&index, &viewMatrices](const SkMatrix& m) {
367 GrGLGetMatrix<3>(&viewMatrices[index], m);
368 index += fSkMatrixNumCells;
369 });
370
371 // Constants for our various shader programs
372 GrGLfloat quad_vertices[] = {
373 // Positions // Colors
374 -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
375 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
376 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
377
378 -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
379 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
380 1.0f, 1.0f, 0.0f, 1.0f, 1.0f
381 };
382
383 // update vertex data
384 GrGLuint quadVAO, quadVBO;
385 GR_GL_CALL(gl, GenVertexArrays(1, &quadVAO));
386 GR_GL_CALL(gl, GenBuffers(1, &quadVBO));
387 GR_GL_CALL(gl, BindVertexArray(quadVAO));
388 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, quadVBO));
389 GR_GL_CALL(gl, EnableVertexAttribArray(0));
390 GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, 5 * sizeo f(GrGLfloat), (GrGLvoid*)0));
391 GR_GL_CALL(gl, EnableVertexAttribArray(1));
392 GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, 5 * sizeo f(GrGLfloat), (GrGLvoid*)(2 * sizeof(GrGLfloat))));
393 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_ve rtices, GR_GL_STATIC_DRAW));
394
395 // Also set instance data
396 GrGLuint instanceVBO;
397 GR_GL_CALL(gl, GenBuffers(1, &instanceVBO));
398 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, instanceVBO));
399 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(GrGLfloat) * fSkMatrixN umCells * fNumQuads,
400 &viewMatrices[0], GR_GL_STATIC_DRAW));
401 GR_GL_CALL(gl, EnableVertexAttribArray(2));
402 GR_GL_CALL(gl, EnableVertexAttribArray(3));
403 GR_GL_CALL(gl, EnableVertexAttribArray(4));
404 GR_GL_CALL(gl, VertexAttribPointer(2, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeo f(GrGLfloat), (GrGLvoid*)0));
405 GR_GL_CALL(gl, VertexAttribPointer(3, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeo f(GrGLfloat), (GrGLvoid*)(3 * sizeof(GrGLfloat))));
406 GR_GL_CALL(gl, VertexAttribPointer(4, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeo f(GrGLfloat), (GrGLvoid*)(6 * sizeof(GrGLfloat))));
407 GR_GL_CALL(gl, VertexAttribDivisor(2, 1));
408 GR_GL_CALL(gl, VertexAttribDivisor(3, 1));
409 GR_GL_CALL(gl, VertexAttribDivisor(4, 1));
410
411 // draw
412 GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f));
413 GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT));
414
415 // set us up to draw
416 GR_GL_CALL(gl, UseProgram(shaderProgram));
417 GR_GL_CALL(gl, BindVertexArray(quadVAO));
418 }
419
420 void GLGpuPosInstancedArraysBench::onDraw(const int loops, SkCanvas* canvas) {
421 const GrGLInterface* gl = get_interface(canvas);
422 if (!gl) {
423 return;
424 }
425
426 GR_GL_CALL(gl, DrawArraysInstanced(GR_GL_TRIANGLES, 0, 6, fNumQuads));
427
428 #ifdef DUMP_IMAGES
429 const char* filename = "out.png";
430 dump_image(gl, kScreenWidth, kScreenHeight, filename);
431 #endif
432 SkFAIL("done\n");
433 }
434
435 static uint32_t setup_quad_index_buffer(const GrGLInterface* gl) {
436 static const int kMaxQuads = 1;//1 << 12; // max possible: (1 << 14) - 1;
437 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
438 static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 };
439 static const int kPatternSize = 6;
440 static const int kVertCount = 4;
441 static const int kIndicesCount = kPatternSize * kMaxQuads;
442 int size = kPatternSize * kMaxQuads * sizeof(uint16_t);
443
444 uint16_t* data = SkNEW_ARRAY(uint16_t, kMaxQuads * kPatternSize);
445
446 for (int i = 0; i < kMaxQuads; ++i) {
447 int baseIdx = i * kPatternSize;
448 uint16_t baseVert = (uint16_t)(i * kVertCount);
449 for (int j = 0; j < kPatternSize; ++j) {
450 data[baseIdx+j] = baseVert + kPattern[j];
451 }
452 }
453
454 GrGLuint quadIBO;
455 GR_GL_CALL(gl, GenBuffers(1, &quadIBO));
456 GR_GL_CALL(gl, BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, quadIBO));
457 GR_GL_CALL(gl, BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, size, data, GR_GL_STAT IC_DRAW));
458
459 SkDELETE_ARRAY(data);
460 return kIndicesCount;
461 }
462 #endif
463
464 //////////////////////////////////////////////////////////////////////////////// ///////////////////
465
466 void GLCpuPosInstancedArraysBench::setupInstanceVbo(const GrGLInterface* gl,
467 const SkMatrix* viewMatrices ) {
468 // We draw all of the instances at a single place because we aren't allowed to have per vertex
469 // per instance attributes
470 SkPoint positions[kVerticesPerTri];
471 positions[0].set(-1.0f, -1.0f);
472 positions[1].set( 1.0f, -1.0f);
473 positions[2].set( 1.0f, 1.0f);
474 viewMatrices[0].mapPointsWithStride(positions, sizeof(SkPoint), kVerticesPer Tri);
475
476 // setup colors so we can detect we are actually drawing instances(the last triangle will be
477 // a different color)
478 GrGLfloat colors[kVerticesPerTri * kNumTri];
479 for (uint32_t i = 0; i < kNumTri; i++) {
480 // set colors
481 uint32_t offset = i * kVerticesPerTri;
482 float color = i == kNumTri - 1 ? 1.0f : 0.0f;
483 colors[offset++] = color; colors[offset++] = 0.0f; colors[offset++] = 0. 0f;
484 }
485
486 GrGLuint posVBO;
487 // setup position VBO
488 GR_GL_CALL(gl, GenBuffers(1, &posVBO));
489 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, posVBO));
490 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(positions), positions, GR_GL_STATIC_DRAW));
491 GR_GL_CALL(gl, EnableVertexAttribArray(0));
492 GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, 2 * sizeo f(GrGLfloat),
493 (GrGLvoid*)0));
494
495 // setup color VBO
496 GrGLuint instanceVBO;
497 GR_GL_CALL(gl, GenBuffers(1, &instanceVBO));
498 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, instanceVBO));
499 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(colors), colors, GR_GL_ STATIC_DRAW));
500 GR_GL_CALL(gl, EnableVertexAttribArray(1));
501 GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, 3 * sizeo f(GrGLfloat),
502 (GrGLvoid*)0));
503 GR_GL_CALL(gl, VertexAttribDivisor(1, 1));
504 }
505
506 void GLCpuPosInstancedArraysBench::setupDoubleVbo(const GrGLInterface* gl,
507 const SkMatrix* viewMatrices) {
508 // Constants for our various shader programs
509 SkPoint positions[kVerticesPerTri * kNumTri];
510 GrGLfloat colors[kVerticesPerTri * kNumTri * 3];
511 for (uint32_t i = 0; i < kNumTri; i++) {
512 SkPoint* position = &positions[i * kVerticesPerTri];
513 position[0].set(-1.0f, -1.0f);
514 position[1].set( 1.0f, -1.0f);
515 position[2].set( 1.0f, 1.0f);
516 viewMatrices[i].mapPointsWithStride(position, sizeof(SkPoint), kVertices PerTri);
517
518 // set colors
519 float color = i == kNumTri - 1 ? 1.0f : 0.0f;
520 uint32_t offset = i * kVerticesPerTri * 3;
521 for (uint32_t j = 0; j < kVerticesPerTri; j++) {
522 colors[offset++] = color; colors[offset++] = 0.0f; colors[offset++] = 0.0f;
523 }
524 }
525
526 GrGLuint posVBO, colorVBO;
527 // setup position VBO
528 GR_GL_CALL(gl, GenBuffers(1, &posVBO));
529 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, posVBO));
530 GR_GL_CALL(gl, EnableVertexAttribArray(0));
531 GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, 2 * sizeo f(GrGLfloat),
532 (GrGLvoid*)0));
533 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(positions), positions, GR_GL_STATIC_DRAW));
534
535 // setup color VBO
536 GR_GL_CALL(gl, GenBuffers(1, &colorVBO));
537 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, colorVBO));
538 GR_GL_CALL(gl, EnableVertexAttribArray(1));
539 GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, 3 * sizeo f(GrGLfloat),
540 (GrGLvoid*)0));
541 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(colors), colors, GR_GL_ STATIC_DRAW));
542 }
543
544 struct Vertex {
545 SkPoint fPositions;
546 GrGLfloat fColors[3];
547 };
548
549 void GLCpuPosInstancedArraysBench::setupSingleVbo(const GrGLInterface* gl,
550 const SkMatrix* viewMatrices) {
551 // Constants for our various shader programs
552 Vertex vertices[kVerticesPerTri * kNumTri];
553 for (uint32_t i = 0; i < kNumTri; i++) {
554 Vertex* v = &vertices[i * kVerticesPerTri];
555 v[0].fPositions.set(-1.0f, -1.0f);
556 v[1].fPositions.set( 1.0f, -1.0f);
557 v[2].fPositions.set( 1.0f, 1.0f);
558
559 SkPoint* position = reinterpret_cast<SkPoint*>(v);
560 viewMatrices[i].mapPointsWithStride(position, sizeof(Vertex), kVerticesP erTri);
561
562 // set colors
563 float color = i == kNumTri - 1 ? 1.0f : 0.0f;
564 for (uint32_t j = 0; j < kVerticesPerTri; j++) {
565 uint32_t offset = 0;
566 v->fColors[offset++] = color; v->fColors[offset++] = 0.0f; v->fColor s[offset++] = 0.0f;
567 v++;
568 }
569 }
570
571 GrGLuint vbo;
572 // setup VBO
573 GR_GL_CALL(gl, GenBuffers(1, &vbo));
574 GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, vbo));
575 GR_GL_CALL(gl, EnableVertexAttribArray(0));
576 GR_GL_CALL(gl, EnableVertexAttribArray(1));
577 GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Ve rtex),
578 (GrGLvoid*)0));
579 GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Ve rtex),
580 (GrGLvoid*)(sizeof(SkPoint))));
581 GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(vertices), vertices, GR _GL_STATIC_DRAW));
582 }
583
584 void GLCpuPosInstancedArraysBench::setup(const GrGLContext* ctx) {
585 const GrGLInterface* gl = ctx->interface();
586 setup_framebuffer(gl, kScreenWidth, kScreenHeight);
587
588 GrGLint shaderProgram = compile_shader(ctx);
589
590 // setup matrices
591 int index = 0;
592 SkMatrix viewMatrices[kNumTri];
593 setup_matrices(kNumTri, [&index, &viewMatrices](const SkMatrix& m) {
594 viewMatrices[index++] = m;
595 });
596
597 // setup VAO
598 GrGLuint quadVAO;
599 GR_GL_CALL(gl, GenVertexArrays(1, &quadVAO));
600 GR_GL_CALL(gl, BindVertexArray(quadVAO));
601
602 switch (fVboSetup) {
603 case kUseOne_VboSetup:
604 this->setupSingleVbo(gl, viewMatrices);
605 break;
606 case kUseTwo_VboSetup:
607 this->setupDoubleVbo(gl, viewMatrices);
608 break;
609 case kUseInstance_VboSetup:
610 this->setupInstanceVbo(gl, viewMatrices);
611 break;
612 }
613
614 // clear screen
615 GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f));
616 GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT));
617
618 // set us up to draw
619 GR_GL_CALL(gl, UseProgram(shaderProgram));
620 GR_GL_CALL(gl, BindVertexArray(quadVAO));
621 }
622
623 void GLCpuPosInstancedArraysBench::onDraw(const int loops, SkCanvas* canvas) {
624 const GrGLContext* ctx = get_gl_context(canvas);
625 if (!ctx) {
626 return;
627 }
628
629 const GrGLInterface* gl = ctx->interface();
630
631 if (kUseInstance_VboSetup == fVboSetup) {
632 for (int i = 0; i < loops; i++) {
633 GR_GL_CALL(gl, DrawArraysInstanced(GR_GL_TRIANGLES, 0, 3, kNumTri));
634 }
635 } else if (fMultipleDraws){
636 for (int i = 0; i < loops; i++) {
637 for (uint32_t j = 0; j < kNumTri; j++) {
638 GR_GL_CALL(gl, DrawArrays(GR_GL_TRIANGLES, 0, kVerticesPerTri));
639 }
640 }
641 } else {
642 for (int i = 0; i < loops; i++) {
643 GR_GL_CALL(gl, DrawArrays(GR_GL_TRIANGLES, 0, kVerticesPerTri * kNum Tri));
644 }
645 }
646
647 #ifdef DUMP_IMAGES
648 //const char* filename = "/data/local/tmp/out.png";
649 SkString filename("out");
650 filename.appendf("_%s.png", this->getName());
651 dump_image(gl, kScreenWidth, kScreenHeight, filename.c_str());
652 #endif
653 }
654
655 ///////////////////////////////////////////////////////////////////////////////
656
657 DEF_BENCH( return new GLCpuPosInstancedArraysBench(GLCpuPosInstancedArraysBench: :kUseInstance_VboSetup, false) )
658 DEF_BENCH( return new GLCpuPosInstancedArraysBench(GLCpuPosInstancedArraysBench: :kUseOne_VboSetup, false) )
659 DEF_BENCH( return new GLCpuPosInstancedArraysBench(GLCpuPosInstancedArraysBench: :kUseTwo_VboSetup, false) )
660 DEF_BENCH( return new GLCpuPosInstancedArraysBench(GLCpuPosInstancedArraysBench: :kUseOne_VboSetup, true) )
661 DEF_BENCH( return new GLCpuPosInstancedArraysBench(GLCpuPosInstancedArraysBench: :kUseTwo_VboSetup, true) )
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698