Home | History | Annotate | Download | only in SkV8Example
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  *
      8  */
      9 #include <v8.h>
     10 
     11 using namespace v8;
     12 
     13 #include "SkV8Example.h"
     14 #include "Global.h"
     15 #include "JsContext.h"
     16 #include "Path2D.h"
     17 
     18 #include "gl/GrGLUtil.h"
     19 #include "gl/GrGLDefines.h"
     20 #include "gl/GrGLInterface.h"
     21 #include "GrRenderTarget.h"
     22 #include "GrContext.h"
     23 #include "SkApplication.h"
     24 #include "SkCommandLineFlags.h"
     25 #include "SkData.h"
     26 #include "SkDraw.h"
     27 #include "SkGpuDevice.h"
     28 #include "SkGraphics.h"
     29 #include "SkScalar.h"
     30 #include "SkSurface.h"
     31 
     32 
     33 DEFINE_string2(infile, i, NULL, "Name of file to load JS from.\n");
     34 DEFINE_bool(gpu, true, "Use the GPU for rendering.");
     35 
     36 void application_init() {
     37     SkGraphics::Init();
     38     SkEvent::Init();
     39 }
     40 
     41 void application_term() {
     42     SkEvent::Term();
     43     SkGraphics::Term();
     44 }
     45 
     46 SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsContext* context)
     47     : INHERITED(hwnd)
     48     , fJsContext(context)
     49 #if SK_SUPPORT_GPU
     50     , fCurContext(NULL)
     51     , fCurIntf(NULL)
     52     , fCurRenderTarget(NULL)
     53     , fCurSurface(NULL)
     54 #endif
     55 {
     56     this->setColorType(kBGRA_8888_SkColorType);
     57     this->setVisibleP(true);
     58     this->setClipToBounds(false);
     59 
     60 #if SK_SUPPORT_GPU
     61     this->windowSizeChanged();
     62 #endif
     63 }
     64 
     65 SkV8ExampleWindow::~SkV8ExampleWindow() {
     66 #if SK_SUPPORT_GPU
     67     SkSafeUnref(fCurContext);
     68     SkSafeUnref(fCurIntf);
     69     SkSafeUnref(fCurRenderTarget);
     70     SkSafeUnref(fCurSurface);
     71 #endif
     72 }
     73 
     74 #if SK_SUPPORT_GPU
     75 void SkV8ExampleWindow::windowSizeChanged() {
     76     if (FLAGS_gpu) {
     77         SkOSWindow::AttachmentInfo attachmentInfo;
     78         bool result = this->attach(
     79                 SkOSWindow::kNativeGL_BackEndType, 0, &attachmentInfo);
     80         if (!result) {
     81             printf("Failed to attach.");
     82             exit(1);
     83         }
     84 
     85         fCurIntf = GrGLCreateNativeInterface();
     86         fCurContext = GrContext::Create(
     87                 kOpenGL_GrBackend, (GrBackendContext) fCurIntf);
     88         if (NULL == fCurIntf || NULL == fCurContext) {
     89             printf("Failed to initialize GL.");
     90             exit(1);
     91         }
     92 
     93         GrBackendRenderTargetDesc desc;
     94         desc.fWidth = SkScalarRoundToInt(this->width());
     95         desc.fHeight = SkScalarRoundToInt(this->height());
     96         desc.fConfig = kSkia8888_GrPixelConfig;
     97         desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     98         desc.fSampleCnt = attachmentInfo.fSampleCount;
     99         desc.fStencilBits = attachmentInfo.fStencilBits;
    100         GrGLint buffer;
    101         GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
    102         desc.fRenderTargetHandle = buffer;
    103 
    104         SkSafeUnref(fCurRenderTarget);
    105         fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
    106         SkSafeUnref(fCurSurface);
    107         fCurSurface = SkSurface::NewRenderTargetDirect(fCurRenderTarget);
    108     }
    109 }
    110 #endif
    111 
    112 #if SK_SUPPORT_GPU
    113 SkCanvas* SkV8ExampleWindow::createCanvas() {
    114     if (FLAGS_gpu) {
    115         SkCanvas* c = fCurSurface->getCanvas();
    116         // Increase the ref count since the surface keeps a reference
    117         // to the canvas, but callers of createCanvas put the results
    118         // in a SkAutoTUnref.
    119         c->ref();
    120         return c;
    121     } else {
    122         return this->INHERITED::createCanvas();
    123     }
    124 }
    125 #endif
    126 
    127 void SkV8ExampleWindow::onSizeChange() {
    128     this->INHERITED::onSizeChange();
    129 
    130 #if SK_SUPPORT_GPU
    131     this->windowSizeChanged();
    132 #endif
    133 }
    134 
    135 void SkV8ExampleWindow::onDraw(SkCanvas* canvas) {
    136 
    137     canvas->save();
    138     canvas->drawColor(SK_ColorWHITE);
    139 
    140     // Now jump into JS and call the onDraw(canvas) method defined there.
    141     fJsContext->onDraw(canvas);
    142 
    143     canvas->restore();
    144 
    145     this->INHERITED::onDraw(canvas);
    146 
    147 #if SK_SUPPORT_GPU
    148     if (FLAGS_gpu) {
    149         fCurContext->flush();
    150         this->present();
    151     }
    152 #endif
    153 }
    154 
    155 #ifdef SK_BUILD_FOR_WIN
    156 void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) {
    157     RECT winRect;
    158     winRect.top = rect.top();
    159     winRect.bottom = rect.bottom();
    160     winRect.right = rect.right();
    161     winRect.left = rect.left();
    162     InvalidateRect((HWND)this->getHWND(), &winRect, false);
    163 }
    164 #endif
    165 
    166 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
    167     printf("Started\n");
    168 
    169     SkCommandLineFlags::Parse(argc, argv);
    170 
    171     // Get the default Isolate created at startup.
    172     Isolate* isolate = Isolate::GetCurrent();
    173     Global* global = new Global(isolate);
    174 
    175 
    176     // Set up things to look like a browser by creating
    177     // a console object that invokes our print function.
    178     const char* startupScript =
    179             "function Console() {};                   \n"
    180             "Console.prototype.log = function() {     \n"
    181             "  var args = Array.prototype.slice.call(arguments).join(' '); \n"
    182             "  print(args);                      \n"
    183             "};                                       \n"
    184             "console = new Console();                 \n";
    185 
    186     if (!global->parseScript(startupScript)) {
    187         printf("Failed to parse startup script: %s.\n", FLAGS_infile[0]);
    188         exit(1);
    189     }
    190 
    191     const char* script =
    192             "function onDraw(canvas) {              \n"
    193             "    canvas.fillStyle = '#00FF00';      \n"
    194             "    canvas.fillRect(20, 20, 100, 100); \n"
    195             "    canvas.inval();                    \n"
    196             "}                                      \n";
    197 
    198     SkAutoTUnref<SkData> data;
    199     if (FLAGS_infile.count()) {
    200         data.reset(SkData::NewFromFileName(FLAGS_infile[0]));
    201         script = static_cast<const char*>(data->data());
    202     }
    203     if (NULL == script) {
    204         printf("Could not load file: %s.\n", FLAGS_infile[0]);
    205         exit(1);
    206     }
    207     Path2D::AddToGlobal(global);
    208 
    209     if (!global->parseScript(script)) {
    210         printf("Failed to parse file: %s.\n", FLAGS_infile[0]);
    211         exit(1);
    212     }
    213 
    214 
    215     JsContext* jsContext = new JsContext(global);
    216 
    217     if (!jsContext->initialize()) {
    218         printf("Failed to initialize.\n");
    219         exit(1);
    220     }
    221     SkV8ExampleWindow* win = new SkV8ExampleWindow(hwnd, jsContext);
    222     global->setWindow(win);
    223 
    224     return win;
    225 }
    226