Home | History | Annotate | Download | only in VisualBench
      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 
      9 #include "VisualBench.h"
     10 
     11 #include "GrContext.h"
     12 #include "ProcStats.h"
     13 #include "SkApplication.h"
     14 #include "SkCanvas.h"
     15 #include "SkCommandLineFlags.h"
     16 #include "SkGraphics.h"
     17 #include "SkGr.h"
     18 #include "SkOSFile.h"
     19 #include "SkStream.h"
     20 #include "Stats.h"
     21 #include "VisualDebugModule.h"
     22 #include "VisualLightweightBenchModule.h"
     23 #include "VisualInteractiveModule.h"
     24 #include "gl/GrGLInterface.h"
     25 
     26 #include <stdlib.h>
     27 
     28 DEFINE_bool2(fullscreen, f, true, "Run fullscreen.");
     29 DEFINE_string(mode, "classic", "one of: classic interactive debugger");
     30 DEFINE_bool2(dif, d, false, "Use device-independent fonts.");
     31 
     32 VisualBench::VisualBench(void* hwnd, int argc, char** argv)
     33     : INHERITED(hwnd) {
     34     SkDebugf("Command line arguments: ");
     35     for (int i = 1; i < argc; ++i) {
     36         SkDebugf("%s ", argv[i]);
     37     }
     38     SkDebugf("\n");
     39 
     40     SkCommandLineFlags::Parse(argc, argv);
     41 
     42     if (FLAGS_nvpr && !FLAGS_msaa) {
     43         SkDebugf("Got nvpr without msaa. Exiting.\n");
     44         exit(-1);
     45     }
     46 
     47     // these have to happen after commandline parsing
     48     if (FLAGS_dif) {
     49         const SkSurfaceProps& props(INHERITED::getSurfaceProps());
     50         uint32_t flags = SkSurfaceProps::kUseDeviceIndependentFonts_Flag | props.flags();
     51         INHERITED::setSurfaceProps(SkSurfaceProps(flags, props.pixelGeometry()));
     52     }
     53     fModule.reset(new VisualLightweightBenchModule(this));
     54 
     55     if (FLAGS_mode.count()) {
     56         SkASSERT(FLAGS_mode.count() == 1);
     57         SkString mode(FLAGS_mode[0]);
     58         if (mode == SkString("interactive")) {
     59             fModule.reset(new VisualInteractiveModule(this));
     60         } else if (mode == SkString("debugger")) {
     61             fModule.reset(new VisualDebugModule(this));
     62         }
     63     }
     64 
     65     this->setTitle();
     66     this->setupBackend();
     67 }
     68 
     69 VisualBench::~VisualBench() {
     70     this->tearDownContext();
     71 }
     72 
     73 void VisualBench::setTitle() {
     74     SkString title("VisualBench");
     75     INHERITED::setTitle(title.c_str());
     76 }
     77 
     78 SkSurface* VisualBench::createSurface() {
     79     if (!fSurface) {
     80         SkSurfaceProps props(INHERITED::getSurfaceProps());
     81         fSurface.reset(SkSurface::NewRenderTargetDirect(fRenderTarget, &props));
     82     }
     83 
     84     // The caller will wrap the SkSurface in an SkAutoTUnref
     85     return SkRef(fSurface.get());
     86 }
     87 
     88 bool VisualBench::setupBackend() {
     89     this->setVisibleP(true);
     90     this->setClipToBounds(false);
     91 
     92     if (FLAGS_fullscreen) {
     93         if (!this->makeFullscreen()) {
     94             SkDebugf("Could not go fullscreen!");
     95         }
     96     }
     97 
     98     this->resetContext();
     99     return true;
    100 }
    101 
    102 void VisualBench::resetContext() {
    103     this->tearDownContext();
    104     this->setupContext();
    105 }
    106 
    107 void VisualBench::setupContext() {
    108     int screenSamples = FLAGS_offscreen ? 0 : FLAGS_msaa;
    109     if (!this->attach(kNativeGL_BackEndType, screenSamples, &fAttachmentInfo)) {
    110         SkDebugf("Not possible to create backend.\n");
    111         INHERITED::detach();
    112         SkFAIL("Could not create backend\n");
    113     }
    114 
    115     this->setVsync(false);
    116 
    117     fSurface.reset(nullptr);
    118 
    119     fInterface.reset(GrGLCreateNativeInterface());
    120 
    121     // TODO use the GLContext creation factories and also set this all up in configs
    122     if (!FLAGS_nvpr) {
    123         fInterface.reset(GrGLInterfaceRemoveNVPR(fInterface));
    124     }
    125     SkASSERT(fInterface);
    126 
    127     // setup contexts
    128     fContext.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface.get()));
    129     SkASSERT(fContext);
    130 
    131     // setup rendertargets
    132     this->setupRenderTarget();
    133 }
    134 
    135 void VisualBench::tearDownContext() {
    136     if (fContext) {
    137         // We abandon the context in case SkWindow has kept a ref to the surface
    138         fContext->abandonContext();
    139         fContext.reset();
    140         fSurface.reset();
    141         fInterface.reset();
    142         this->detach();
    143     }
    144 }
    145 
    146 void VisualBench::setupRenderTarget() {
    147     if (fContext) {
    148         fRenderTarget.reset(this->renderTarget(fAttachmentInfo, fInterface, fContext));
    149     }
    150 }
    151 
    152 void VisualBench::draw(SkCanvas* canvas) {
    153     fModule->draw(canvas);
    154 
    155     // Invalidate the window to force a redraw. Poor man's animation mechanism.
    156     this->inval(nullptr);
    157 }
    158 
    159 void VisualBench::clear(SkCanvas* canvas, SkColor color, int frames) {
    160     canvas->clear(color);
    161     for (int i = 0; i < frames - 1; ++i) {
    162         canvas->flush();
    163         this->present();
    164         canvas->clear(color);
    165     }
    166 }
    167 
    168 void VisualBench::onSizeChange() {
    169     this->setupRenderTarget();
    170 }
    171 
    172 bool VisualBench::onHandleChar(SkUnichar unichar) {
    173     static const auto kEscKey = 27;
    174     if (kEscKey == unichar) {
    175         this->closeWindow();
    176         return true;
    177     }
    178 
    179     return fModule->onHandleChar(unichar);
    180 }
    181 
    182 // Externally declared entry points
    183 void application_init() {
    184     SkGraphics::Init();
    185     SkEvent::Init();
    186 }
    187 
    188 void application_term() {
    189     SkEvent::Term();
    190 }
    191 
    192 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
    193     return new VisualBench(hwnd, argc, argv);
    194 }
    195 
    196