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