Home | History | Annotate | Download | only in bench
      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 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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