blob: 0252c26b37fcedaccac7c1073b1fb195d55032e6 [file] [log] [blame]
joshualitt74a07db2015-07-01 12:39:07 -07001/*
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 "GLBench.h"
9
10#if SK_SUPPORT_GPU
11#include "GrTest.h"
12#include <stdio.h>
13
14const GrGLContext* GLBench::getGLContext(SkCanvas* canvas) {
15 // This bench exclusively tests GL calls directly
16 if (NULL == canvas->getGrContext()) {
17 return NULL;
18 }
19 GrContext* context = canvas->getGrContext();
jvanverth672bb7f2015-07-13 07:19:57 -070020 GrGpu* gpu = context->getGpu();
21 if (!gpu) {
22 SkDebugf("Couldn't get Gr gpu.");
joshualitt74a07db2015-07-01 12:39:07 -070023 return NULL;
24 }
25
jvanverth672bb7f2015-07-13 07:19:57 -070026 const GrGLContext* ctx = gpu->glContextForTesting();
joshualitt74a07db2015-07-01 12:39:07 -070027 if (!ctx) {
28 SkDebugf("Couldn't get an interface\n");
29 return NULL;
30 }
31
32 return this->onGetGLContext(ctx);
33}
34
35void GLBench::onPerCanvasPreDraw(SkCanvas* canvas) {
36 // This bench exclusively tests GL calls directly
37 const GrGLContext* ctx = this->getGLContext(canvas);
38 if (!ctx) {
39 return;
40 }
41 this->setup(ctx);
42}
43
44void GLBench::onPerCanvasPostDraw(SkCanvas* canvas) {
45 // This bench exclusively tests GL calls directly
46 const GrGLContext* ctx = this->getGLContext(canvas);
47 if (!ctx) {
48 return;
49 }
50 this->teardown(ctx->interface());
51}
52
53void GLBench::onDraw(const int loops, SkCanvas* canvas) {
54 const GrGLContext* ctx = this->getGLContext(canvas);
55 if (!ctx) {
56 return;
57 }
58 this->glDraw(loops, ctx);
59}
60
61GrGLuint GLBench::CompileShader(const GrGLInterface* gl, const char* shaderSrc, GrGLenum type) {
62 GrGLuint shader;
63 // Create the shader object
64 GR_GL_CALL_RET(gl, shader, CreateShader(type));
65
66 // Load the shader source
67 GR_GL_CALL(gl, ShaderSource(shader, 1, &shaderSrc, NULL));
68
69 // Compile the shader
70 GR_GL_CALL(gl, CompileShader(shader));
71
72 // Check for compile time errors
73 GrGLint success;
74 GrGLchar infoLog[512];
75 GR_GL_CALL(gl, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &success));
76 if (!success) {
77 GR_GL_CALL(gl, GetShaderInfoLog(shader, 512, NULL, infoLog));
78 SkDebugf("ERROR::SHADER::COMPLIATION_FAILED: %s\n", infoLog);
79 }
80
81 return shader;
82}
83
84GrGLuint GLBench::CreateProgram(const GrGLInterface* gl, const char* vshader, const char* fshader) {
85
86 GrGLuint vertexShader = CompileShader(gl, vshader, GR_GL_VERTEX_SHADER);
87 GrGLuint fragmentShader = CompileShader(gl, fshader, GR_GL_FRAGMENT_SHADER);
88
89 GrGLuint shaderProgram;
90 GR_GL_CALL_RET(gl, shaderProgram, CreateProgram());
91 GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader));
92 GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader));
93 GR_GL_CALL(gl, LinkProgram(shaderProgram));
94
95 // Check for linking errors
96 GrGLint success;
97 GrGLchar infoLog[512];
98 GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success));
99 if (!success) {
100 GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, NULL, infoLog));
101 SkDebugf("Linker Error: %s\n", infoLog);
102 }
103 GR_GL_CALL(gl, DeleteShader(vertexShader));
104 GR_GL_CALL(gl, DeleteShader(fragmentShader));
105
106 return shaderProgram;
107}
108
109GrGLuint GLBench::SetupFramebuffer(const GrGLInterface* gl, int screenWidth, int screenHeight) {
110 //Setup framebuffer
111 GrGLuint texture;
112 GR_GL_CALL(gl, GenTextures(1, &texture));
113 GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE15));
114 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, texture));
115 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
116 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
117 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
118 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
119 GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D,
120 0, //level
121 GR_GL_RGBA, //internal format
122 screenWidth, // width
123 screenHeight, // height
124 0, //border
125 GR_GL_RGBA, //format
126 GR_GL_UNSIGNED_BYTE, // type
127 NULL));
128
129 // bind framebuffer
130 GrGLuint framebuffer;
131 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
132 GR_GL_CALL(gl, GenFramebuffers(1, &framebuffer));
133 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, framebuffer));
134 GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
135 GR_GL_COLOR_ATTACHMENT0,
136 GR_GL_TEXTURE_2D,
137 texture, 0));
138 GR_GL_CALL(gl, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
139 GR_GL_CALL(gl, Viewport(0, 0, screenWidth, screenHeight));
140 return texture;
141}
142
143
144void GLBench::DumpImage(const GrGLInterface* gl, uint32_t screenWidth, uint32_t screenHeight,
145 const char* filename) {
146 // read back pixels
147 SkAutoTArray<uint32_t> readback(screenWidth * screenHeight);
148 GR_GL_CALL(gl, ReadPixels(0, // x
149 0, // y
150 screenWidth, // width
151 screenHeight, // height
152 GR_GL_RGBA, //format
153 GR_GL_UNSIGNED_BYTE, //type
154 readback.get()));
155
156 // dump png
157 SkBitmap bm;
158 if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(screenWidth, screenHeight))) {
159 SkDebugf("couldn't allocate bitmap\n");
160 return;
161 }
162
163 bm.setPixels(readback.get());
164
165 if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) {
166 SkDebugf("------ failed to encode %s\n", filename);
167 remove(filename); // remove any partial file
168 return;
169 }
170}
171
172#endif