• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GLBench.h"
9 
10 #if SK_SUPPORT_GPU
11 #include "GrGpu.h"
12 #include "GrTest.h"
13 #include "gl/GrGLContext.h"
14 #include "gl/builders/GrGLShaderStringBuilder.h"
15 #include "SkSLCompiler.h"
16 #include <stdio.h>
17 
18 #include "sk_tool_utils.h"
19 
getGLContext(SkCanvas * canvas)20 const GrGLContext* GLBench::getGLContext(SkCanvas* canvas) {
21     // This bench exclusively tests GL calls directly
22     if (nullptr == canvas->getGrContext()) {
23         return nullptr;
24     }
25     GrContext* context = canvas->getGrContext();
26     GrGpu* gpu = context->getGpu();
27     if (!gpu) {
28         SkDebugf("Couldn't get Gr gpu.");
29         return nullptr;
30     }
31 
32     const GrGLContext* ctx = gpu->glContextForTesting();
33     if (!ctx) {
34         SkDebugf("Couldn't get an interface\n");
35         return nullptr;
36     }
37 
38     return this->onGetGLContext(ctx);
39 }
40 
onPreDraw(SkCanvas * canvas)41 void GLBench::onPreDraw(SkCanvas* canvas) {
42     // This bench exclusively tests GL calls directly
43     const GrGLContext* ctx = this->getGLContext(canvas);
44     if (!ctx) {
45         return;
46     }
47     this->setup(ctx);
48 }
49 
onPostDraw(SkCanvas * canvas)50 void GLBench::onPostDraw(SkCanvas* canvas) {
51     // This bench exclusively tests GL calls directly
52     const GrGLContext* ctx = this->getGLContext(canvas);
53     if (!ctx) {
54         return;
55     }
56     this->teardown(ctx->interface());
57 }
58 
onDraw(int loops,SkCanvas * canvas)59 void GLBench::onDraw(int loops, SkCanvas* canvas) {
60     const GrGLContext* ctx = this->getGLContext(canvas);
61     if (!ctx) {
62         return;
63     }
64     this->glDraw(loops, ctx);
65     canvas->getGrContext()->resetContext();
66 }
67 
CompileShader(const GrGLContext * context,const char * sksl,GrGLenum type)68 GrGLuint GLBench::CompileShader(const GrGLContext* context, const char* sksl, GrGLenum type) {
69     const GrGLInterface* gl = context->interface();
70     SkSL::String glsl;
71     SkSL::Program::Settings settings;
72     settings.fCaps = context->caps()->shaderCaps();
73     std::unique_ptr<SkSL::Program> program = context->compiler()->convertProgram(
74                                         type == GR_GL_VERTEX_SHADER ? SkSL::Program::kVertex_Kind
75                                                                     : SkSL::Program::kFragment_Kind,
76                                         SkString(sksl),
77                                         settings);
78     if (!program || !context->compiler()->toGLSL(*program, &glsl)) {
79         SkDebugf("SkSL compilation failed:\n%s\n%s\n", sksl,
80                  context->compiler()->errorText().c_str());
81     }
82     GrGLuint shader;
83     // Create the shader object
84     GR_GL_CALL_RET(gl, shader, CreateShader(type));
85 
86     // Load the shader source
87     const char* glslPtr = glsl.c_str();
88     GR_GL_CALL(gl, ShaderSource(shader, 1, (const char**) &glslPtr, nullptr));
89 
90     // Compile the shader
91     GR_GL_CALL(gl, CompileShader(shader));
92 
93     // Check for compile time errors
94     GrGLint success = GR_GL_INIT_ZERO;
95     GrGLchar infoLog[512];
96     GR_GL_CALL(gl, GetShaderiv(shader, GR_GL_COMPILE_STATUS, &success));
97     if (!success) {
98         GR_GL_CALL(gl, GetShaderInfoLog(shader, 512, nullptr, infoLog));
99         SkDebugf("ERROR::SHADER::COMPLIATION_FAILED: %s\n", infoLog);
100     }
101 
102     return shader;
103 }
104 
CreateProgram(const GrGLContext * context,const char * vshader,const char * fshader)105 GrGLuint GLBench::CreateProgram(const GrGLContext* context, const char* vshader,
106                                 const char* fshader) {
107     const GrGLInterface* gl = context->interface();
108     GrGLuint vertexShader = CompileShader(context, vshader, GR_GL_VERTEX_SHADER);
109     GrGLuint fragmentShader = CompileShader(context, fshader, GR_GL_FRAGMENT_SHADER);
110 
111     GrGLuint shaderProgram;
112     GR_GL_CALL_RET(gl, shaderProgram, CreateProgram());
113     GR_GL_CALL(gl, AttachShader(shaderProgram, vertexShader));
114     GR_GL_CALL(gl, AttachShader(shaderProgram, fragmentShader));
115     GR_GL_CALL(gl, LinkProgram(shaderProgram));
116 
117     // Check for linking errors
118     GrGLint success = GR_GL_INIT_ZERO;
119     GrGLchar infoLog[512];
120     GR_GL_CALL(gl, GetProgramiv(shaderProgram, GR_GL_LINK_STATUS, &success));
121     if (!success) {
122         GR_GL_CALL(gl, GetProgramInfoLog(shaderProgram, 512, nullptr, infoLog));
123         SkDebugf("Linker Error: %s\n", infoLog);
124     }
125     GR_GL_CALL(gl, DeleteShader(vertexShader));
126     GR_GL_CALL(gl, DeleteShader(fragmentShader));
127 
128     return shaderProgram;
129 }
130 
SetupFramebuffer(const GrGLInterface * gl,int screenWidth,int screenHeight)131 GrGLuint GLBench::SetupFramebuffer(const GrGLInterface* gl, int screenWidth, int screenHeight) {
132     //Setup framebuffer
133     GrGLuint texture;
134     GR_GL_CALL(gl, GenTextures(1, &texture));
135     GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE7));
136     GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, texture));
137     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
138     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
139     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
140     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
141     GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D,
142                               0, //level
143                               GR_GL_RGBA, //internal format
144                               screenWidth, // width
145                               screenHeight, // height
146                               0, //border
147                               GR_GL_RGBA, //format
148                               GR_GL_UNSIGNED_BYTE, // type
149                               nullptr));
150 
151     // bind framebuffer
152     GrGLuint framebuffer;
153     GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
154     GR_GL_CALL(gl, GenFramebuffers(1, &framebuffer));
155     GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, framebuffer));
156     GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
157                                         GR_GL_COLOR_ATTACHMENT0,
158                                         GR_GL_TEXTURE_2D,
159                                         texture, 0));
160     GR_GL_CALL(gl, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
161     GR_GL_CALL(gl, Viewport(0, 0, screenWidth, screenHeight));
162     return texture;
163 }
164 
165 
DumpImage(const GrGLInterface * gl,uint32_t screenWidth,uint32_t screenHeight,const char * filename)166 void GLBench::DumpImage(const GrGLInterface* gl, uint32_t screenWidth, uint32_t screenHeight,
167                         const char* filename) {
168     // read back pixels
169     SkAutoTArray<uint32_t> readback(screenWidth * screenHeight);
170     GR_GL_CALL(gl, ReadPixels(0, // x
171                               0, // y
172                               screenWidth, // width
173                               screenHeight, // height
174                               GR_GL_RGBA, //format
175                               GR_GL_UNSIGNED_BYTE, //type
176                               readback.get()));
177 
178     // dump png
179     SkBitmap bm;
180     if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(screenWidth, screenHeight))) {
181         SkDebugf("couldn't allocate bitmap\n");
182         return;
183     }
184 
185     bm.setPixels(readback.get());
186 
187     if (!sk_tool_utils::EncodeImageToFile(filename, bm, SkEncodedImageFormat::kPNG, 100)) {
188         SkDebugf("------ failed to encode %s\n", filename);
189         remove(filename);   // remove any partial file
190         return;
191     }
192 }
193 
194 #endif
195