blob: 524bfe1109ad00b54430416e0192cafdffbe2ba4 [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
halcanary96fcdcc2015-08-27 07:41:13 -070016 if (nullptr == canvas->getGrContext()) {
17 return nullptr;
joshualitt74a07db2015-07-01 12:39:07 -070018 }
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.");
halcanary96fcdcc2015-08-27 07:41:13 -070023 return nullptr;
joshualitt74a07db2015-07-01 12:39:07 -070024 }
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");
halcanary96fcdcc2015-08-27 07:41:13 -070029 return nullptr;
joshualitt74a07db2015-07-01 12:39:07 -070030 }
31
32 return this->onGetGLContext(ctx);
33}
34
joshualitt8a6697a2015-09-30 12:11:07 -070035void GLBench::onPreDraw(SkCanvas* canvas) {
joshualitt74a07db2015-07-01 12:39:07 -070036 // 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
joshualitt8a6697a2015-09-30 12:11:07 -070044void GLBench::onPostDraw(SkCanvas* canvas) {
joshualitt74a07db2015-07-01 12:39:07 -070045 // 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
mtkleina1ebeb22015-10-01 09:43:39 -070053void GLBench::onDraw(int loops, SkCanvas* canvas) {
joshualitt74a07db2015-07-01 12:39:07 -070054 const GrGLContext* ctx = this->getGLContext(canvas);
55 if (!ctx) {
56 return;
57 }
58 this->glDraw(loops, ctx);
brianosman393c2ff2016-05-11 08:49:59 -070059 canvas->getGrContext()->resetContext();
joshualitt74a07db2015-07-01 12:39:07 -070060}
61
62GrGLuint GLBench::CompileShader(const GrGLInterface* gl, const char* shaderSrc, GrGLenum type) {
63 GrGLuint shader;
64 // Create the shader object
65 GR_GL_CALL_RET(gl, shader, CreateShader(type));
66
67 // Load the shader source
halcanary96fcdcc2015-08-27 07:41:13 -070068 GR_GL_CALL(gl, ShaderSource(shader, 1, &shaderSrc, nullptr));
joshualitt74a07db2015-07-01 12:39:07 -070069
70 // Compile the shader
71 GR_GL_CALL(gl, CompileShader(shader));
72
73 // Check for compile time errors
hendrikw894a2e42015-09-08 15:18:56 -070074 GrGLint success = GR_GL_INIT_ZERO;
joshualitt74a07db2015-07-01 12:39:07 -070075 GrGLchar infoLog[512];
76 GR_GL_CALL(gl, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &success));
77 if (!success) {
halcanary96fcdcc2015-08-27 07:41:13 -070078 GR_GL_CALL(gl, GetShaderInfoLog(shader, 512, nullptr, infoLog));
joshualitt74a07db2015-07-01 12:39:07 -070079 SkDebugf("ERROR::SHADER::COMPLIATION_FAILED: %s\n", infoLog);
80 }
81
82 return shader;
83}
84
85GrGLuint GLBench::CreateProgram(const GrGLInterface* gl, const char* vshader, const char* fshader) {
86
87 GrGLuint vertexShader = CompileShader(gl, vshader, GR_GL_VERTEX_SHADER);
88 GrGLuint fragmentShader = CompileShader(gl, fshader, GR_GL_FRAGMENT_SHADER);
89
90 GrGLuint shaderProgram;
91 GR_GL_CALL_RET(gl, shaderProgram, CreateProgram());
92 GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader));
93 GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader));
94 GR_GL_CALL(gl, LinkProgram(shaderProgram));
95
96 // Check for linking errors
hendrikw894a2e42015-09-08 15:18:56 -070097 GrGLint success = GR_GL_INIT_ZERO;
joshualitt74a07db2015-07-01 12:39:07 -070098 GrGLchar infoLog[512];
99 GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success));
100 if (!success) {
halcanary96fcdcc2015-08-27 07:41:13 -0700101 GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, nullptr, infoLog));
joshualitt74a07db2015-07-01 12:39:07 -0700102 SkDebugf("Linker Error: %s\n", infoLog);
103 }
104 GR_GL_CALL(gl, DeleteShader(vertexShader));
105 GR_GL_CALL(gl, DeleteShader(fragmentShader));
106
107 return shaderProgram;
108}
109
110GrGLuint GLBench::SetupFramebuffer(const GrGLInterface* gl, int screenWidth, int screenHeight) {
111 //Setup framebuffer
112 GrGLuint texture;
113 GR_GL_CALL(gl, GenTextures(1, &texture));
joshualittb2351682015-10-02 06:49:23 -0700114 GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE7));
joshualitt74a07db2015-07-01 12:39:07 -0700115 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, texture));
116 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
117 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
118 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
119 GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
120 GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D,
121 0, //level
122 GR_GL_RGBA, //internal format
123 screenWidth, // width
124 screenHeight, // height
125 0, //border
126 GR_GL_RGBA, //format
127 GR_GL_UNSIGNED_BYTE, // type
halcanary96fcdcc2015-08-27 07:41:13 -0700128 nullptr));
joshualitt74a07db2015-07-01 12:39:07 -0700129
130 // bind framebuffer
131 GrGLuint framebuffer;
132 GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
133 GR_GL_CALL(gl, GenFramebuffers(1, &framebuffer));
134 GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, framebuffer));
135 GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
136 GR_GL_COLOR_ATTACHMENT0,
137 GR_GL_TEXTURE_2D,
138 texture, 0));
139 GR_GL_CALL(gl, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
140 GR_GL_CALL(gl, Viewport(0, 0, screenWidth, screenHeight));
141 return texture;
142}
143
144
145void GLBench::DumpImage(const GrGLInterface* gl, uint32_t screenWidth, uint32_t screenHeight,
146 const char* filename) {
147 // read back pixels
148 SkAutoTArray<uint32_t> readback(screenWidth * screenHeight);
149 GR_GL_CALL(gl, ReadPixels(0, // x
150 0, // y
151 screenWidth, // width
152 screenHeight, // height
153 GR_GL_RGBA, //format
154 GR_GL_UNSIGNED_BYTE, //type
155 readback.get()));
156
157 // dump png
158 SkBitmap bm;
159 if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(screenWidth, screenHeight))) {
160 SkDebugf("couldn't allocate bitmap\n");
161 return;
162 }
163
164 bm.setPixels(readback.get());
165
166 if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) {
167 SkDebugf("------ failed to encode %s\n", filename);
168 remove(filename); // remove any partial file
169 return;
170 }
171}
172
173#endif