• 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 "GrTest.h"
12 #include <stdio.h>
13 
getGLContext(SkCanvas * canvas)14 const GrGLContext* GLBench::getGLContext(SkCanvas* canvas) {
15     // This bench exclusively tests GL calls directly
16     if (nullptr == canvas->getGrContext()) {
17         return nullptr;
18     }
19     GrContext* context = canvas->getGrContext();
20     GrGpu* gpu = context->getGpu();
21     if (!gpu) {
22         SkDebugf("Couldn't get Gr gpu.");
23         return nullptr;
24     }
25 
26     const GrGLContext* ctx = gpu->glContextForTesting();
27     if (!ctx) {
28         SkDebugf("Couldn't get an interface\n");
29         return nullptr;
30     }
31 
32     return this->onGetGLContext(ctx);
33 }
34 
onPreDraw(SkCanvas * canvas)35 void GLBench::onPreDraw(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 
onPostDraw(SkCanvas * canvas)44 void GLBench::onPostDraw(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 
onDraw(int loops,SkCanvas * canvas)53 void GLBench::onDraw(int loops, SkCanvas* canvas) {
54     const GrGLContext* ctx = this->getGLContext(canvas);
55     if (!ctx) {
56         return;
57     }
58     this->glDraw(loops, ctx);
59 }
60 
CompileShader(const GrGLInterface * gl,const char * shaderSrc,GrGLenum type)61 GrGLuint 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, nullptr));
68 
69     // Compile the shader
70     GR_GL_CALL(gl, CompileShader(shader));
71 
72     // Check for compile time errors
73     GrGLint success = GR_GL_INIT_ZERO;
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, nullptr, infoLog));
78         SkDebugf("ERROR::SHADER::COMPLIATION_FAILED: %s\n", infoLog);
79     }
80 
81     return shader;
82 }
83 
CreateProgram(const GrGLInterface * gl,const char * vshader,const char * fshader)84 GrGLuint 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 = GR_GL_INIT_ZERO;
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, nullptr, 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 
SetupFramebuffer(const GrGLInterface * gl,int screenWidth,int screenHeight)109 GrGLuint 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_TEXTURE7));
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                               nullptr));
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 
DumpImage(const GrGLInterface * gl,uint32_t screenWidth,uint32_t screenHeight,const char * filename)144 void 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
173