blob: 8cf41c205665100d173201a0925bd8fe4a154b0a [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
robertphillips87f15c82016-05-20 11:14:33 -070011#include "GrGpu.h"
joshualitt74a07db2015-07-01 12:39:07 -070012#include "GrTest.h"
robertphillips87f15c82016-05-20 11:14:33 -070013#include "gl/GrGLContext.h"
joshualitt74a07db2015-07-01 12:39:07 -070014#include <stdio.h>
15
16const GrGLContext* GLBench::getGLContext(SkCanvas* canvas) {
17 // This bench exclusively tests GL calls directly
halcanary96fcdcc2015-08-27 07:41:13 -070018 if (nullptr == canvas->getGrContext()) {
19 return nullptr;
joshualitt74a07db2015-07-01 12:39:07 -070020 }
21 GrContext* context = canvas->getGrContext();
jvanverth672bb7f2015-07-13 07:19:57 -070022 GrGpu* gpu = context->getGpu();
23 if (!gpu) {
24 SkDebugf("Couldn't get Gr gpu.");
halcanary96fcdcc2015-08-27 07:41:13 -070025 return nullptr;
joshualitt74a07db2015-07-01 12:39:07 -070026 }
27
jvanverth672bb7f2015-07-13 07:19:57 -070028 const GrGLContext* ctx = gpu->glContextForTesting();
joshualitt74a07db2015-07-01 12:39:07 -070029 if (!ctx) {
30 SkDebugf("Couldn't get an interface\n");
halcanary96fcdcc2015-08-27 07:41:13 -070031 return nullptr;
joshualitt74a07db2015-07-01 12:39:07 -070032 }
33
34 return this->onGetGLContext(ctx);
35}
36
joshualitt8a6697a2015-09-30 12:11:07 -070037void GLBench::onPreDraw(SkCanvas* canvas) {
joshualitt74a07db2015-07-01 12:39:07 -070038 // This bench exclusively tests GL calls directly
39 const GrGLContext* ctx = this->getGLContext(canvas);
40 if (!ctx) {
41 return;
42 }
43 this->setup(ctx);
44}
45
joshualitt8a6697a2015-09-30 12:11:07 -070046void GLBench::onPostDraw(SkCanvas* canvas) {
joshualitt74a07db2015-07-01 12:39:07 -070047 // This bench exclusively tests GL calls directly
48 const GrGLContext* ctx = this->getGLContext(canvas);
49 if (!ctx) {
50 return;
51 }
52 this->teardown(ctx->interface());
53}
54
mtkleina1ebeb22015-10-01 09:43:39 -070055void GLBench::onDraw(int loops, SkCanvas* canvas) {
joshualitt74a07db2015-07-01 12:39:07 -070056 const GrGLContext* ctx = this->getGLContext(canvas);
57 if (!ctx) {
58 return;
59 }
60 this->glDraw(loops, ctx);
brianosman393c2ff2016-05-11 08:49:59 -070061 canvas->getGrContext()->resetContext();
joshualitt74a07db2015-07-01 12:39:07 -070062}
63
64GrGLuint GLBench::CompileShader(const GrGLInterface* gl, const char* shaderSrc, GrGLenum type) {
65 GrGLuint shader;
66 // Create the shader object
67 GR_GL_CALL_RET(gl, shader, CreateShader(type));
68
69 // Load the shader source
halcanary96fcdcc2015-08-27 07:41:13 -070070 GR_GL_CALL(gl, ShaderSource(shader, 1, &shaderSrc, nullptr));
joshualitt74a07db2015-07-01 12:39:07 -070071
72 // Compile the shader
73 GR_GL_CALL(gl, CompileShader(shader));
74
75 // Check for compile time errors
hendrikw894a2e42015-09-08 15:18:56 -070076 GrGLint success = GR_GL_INIT_ZERO;
joshualitt74a07db2015-07-01 12:39:07 -070077 GrGLchar infoLog[512];
78 GR_GL_CALL(gl, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &success));
79 if (!success) {
halcanary96fcdcc2015-08-27 07:41:13 -070080 GR_GL_CALL(gl, GetShaderInfoLog(shader, 512, nullptr, infoLog));
joshualitt74a07db2015-07-01 12:39:07 -070081 SkDebugf("ERROR::SHADER::COMPLIATION_FAILED: %s\n", infoLog);
82 }
83
84 return shader;
85}
86
87GrGLuint GLBench::CreateProgram(const GrGLInterface* gl, const char* vshader, const char* fshader) {
88
89 GrGLuint vertexShader = CompileShader(gl, vshader, GR_GL_VERTEX_SHADER);
90 GrGLuint fragmentShader = CompileShader(gl, fshader, GR_GL_FRAGMENT_SHADER);
91
92 GrGLuint shaderProgram;
93 GR_GL_CALL_RET(gl, shaderProgram, CreateProgram());
94 GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader));
95 GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader));
96 GR_GL_CALL(gl, LinkProgram(shaderProgram));
97
98 // Check for linking errors
hendrikw894a2e42015-09-08 15:18:56 -070099 GrGLint success = GR_GL_INIT_ZERO;
joshualitt74a07db2015-07-01 12:39:07 -0700100 GrGLchar infoLog[512];
101 GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success));
102 if (!success) {
halcanary96fcdcc2015-08-27 07:41:13 -0700103 GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, nullptr, infoLog));
joshualitt74a07db2015-07-01 12:39:07 -0700104 SkDebugf("Linker Error: %s\n", infoLog);
105 }
106 GR_GL_CALL(gl, DeleteShader(vertexShader));
107 GR_GL_CALL(gl, DeleteShader(fragmentShader));
108
109 return shaderProgram;
110}
111
112GrGLuint GLBench::SetupFramebuffer(const GrGLInterface* gl, int screenWidth, int screenHeight) {
113 //Setup framebuffer
114 GrGLuint texture;
115 GR_GL_CALL(gl, GenTextures(1, &texture));
joshualittb2351682015-10-02 06:49:23 -0700116 GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE7));
joshualitt74a07db2015-07-01 12:39:07 -0700117 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, texture));
118 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
119 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
120 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
121 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
122 GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D,
123 0, //level
124 GR_GL_RGBA, //internal format
125 screenWidth, // width
126 screenHeight, // height
127 0, //border
128 GR_GL_RGBA, //format
129 GR_GL_UNSIGNED_BYTE, // type
halcanary96fcdcc2015-08-27 07:41:13 -0700130 nullptr));
joshualitt74a07db2015-07-01 12:39:07 -0700131
132 // bind framebuffer
133 GrGLuint framebuffer;
134 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
135 GR_GL_CALL(gl, GenFramebuffers(1, &framebuffer));
136 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, framebuffer));
137 GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
138 GR_GL_COLOR_ATTACHMENT0,
139 GR_GL_TEXTURE_2D,
140 texture, 0));
141 GR_GL_CALL(gl, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
142 GR_GL_CALL(gl, Viewport(0, 0, screenWidth, screenHeight));
143 return texture;
144}
145
146
147void GLBench::DumpImage(const GrGLInterface* gl, uint32_t screenWidth, uint32_t screenHeight,
148 const char* filename) {
149 // read back pixels
150 SkAutoTArray<uint32_t> readback(screenWidth * screenHeight);
151 GR_GL_CALL(gl, ReadPixels(0, // x
152 0, // y
153 screenWidth, // width
154 screenHeight, // height
155 GR_GL_RGBA, //format
156 GR_GL_UNSIGNED_BYTE, //type
157 readback.get()));
158
159 // dump png
160 SkBitmap bm;
161 if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(screenWidth, screenHeight))) {
162 SkDebugf("couldn't allocate bitmap\n");
163 return;
164 }
165
166 bm.setPixels(readback.get());
167
168 if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) {
169 SkDebugf("------ failed to encode %s\n", filename);
170 remove(filename); // remove any partial file
171 return;
172 }
173}
174
175#endif