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 #include <include/libplatform/libplatform.h>
     11 
     12 #include "SkV8Example.h"
     13 #include "Global.h"
     14 #include "JsContext.h"
     15 #include "Path2D.h"
     16 #include "Path2DBuilder.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 }
     44 
     45 SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsContext* context)
     46     : INHERITED(hwnd)
     47     , fJsContext(context)
     48 #if SK_SUPPORT_GPU
     49     , fCurContext(NULL)
     50     , fCurIntf(NULL)
     51     , fCurRenderTarget(NULL)
     52     , fCurSurface(NULL)
     53 #endif
     54 {
     55     this->setVisibleP(true);
     56     this->setClipToBounds(false);
     57 
     58 #if SK_SUPPORT_GPU
     59     this->windowSizeChanged();
     60 #endif
     61 }
     62 
     63 SkV8ExampleWindow::~SkV8ExampleWindow() {
     64 #if SK_SUPPORT_GPU
     65     SkSafeUnref(fCurContext);
     66     SkSafeUnref(fCurIntf);
     67     SkSafeUnref(fCurRenderTarget);
     68     SkSafeUnref(fCurSurface);
     69 #endif
     70 }
     71 
     72 #if SK_SUPPORT_GPU
     73 void SkV8ExampleWindow::windowSizeChanged() {
     74     if (FLAGS_gpu) {
     75         SkOSWindow::AttachmentInfo attachmentInfo;
     76         bool result = this->attach(
     77                 SkOSWindow::kNativeGL_BackEndType, 0, &attachmentInfo);
     78         if (!result) {
     79             printf("Failed to attach.");
     80             exit(1);
     81         }
     82 
     83         fCurIntf = GrGLCreateNativeInterface();
     84         fCurContext = GrContext::Create(
     85                 kOpenGL_GrBackend, (GrBackendContext) fCurIntf);
     86         if (NULL == fCurIntf || NULL == fCurContext) {
     87             printf("Failed to initialize GL.");
     88             exit(1);
     89         }
     90 
     91         GrBackendRenderTargetDesc desc;
     92         desc.fWidth = SkScalarRoundToInt(this->width());
     93         desc.fHeight = SkScalarRoundToInt(this->height());
     94         desc.fConfig = kSkia8888_GrPixelConfig;
     95         desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     96         desc.fSampleCnt = attachmentInfo.fSampleCount;
     97         desc.fStencilBits = attachmentInfo.fStencilBits;
     98         GrGLint buffer;
     99         GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
    100         desc.fRenderTargetHandle = buffer;
    101 
    102         SkSafeUnref(fCurRenderTarget);
    103         fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
    104         SkSafeUnref(fCurSurface);
    105         fCurSurface = SkSurface::NewRenderTargetDirect(fCurRenderTarget);
    106     }
    107 }
    108 #endif
    109 
    110 #if SK_SUPPORT_GPU
    111 SkSurface* SkV8ExampleWindow::createSurface() {
    112     if (FLAGS_gpu) {
    113         // Increase the ref count since callers of createSurface put the
    114         // results in a SkAutoTUnref.
    115         fCurSurface->ref();
    116         return fCurSurface;
    117     } else {
    118         return this->INHERITED::createSurface();
    119     }
    120 }
    121 #endif
    122 
    123 void SkV8ExampleWindow::onSizeChange() {
    124     this->INHERITED::onSizeChange();
    125 
    126 #if SK_SUPPORT_GPU
    127     this->windowSizeChanged();
    128 #endif
    129 }
    130 
    131 Global* global = NULL;
    132 
    133 void SkV8ExampleWindow::onDraw(SkCanvas* canvas) {
    134 
    135     canvas->save();
    136     canvas->drawColor(SK_ColorWHITE);
    137 
    138     // Now jump into JS and call the onDraw(canvas) method defined there.
    139     fJsContext->onDraw(canvas);
    140 
    141     canvas->restore();
    142 
    143     this->INHERITED::onDraw(canvas);
    144 
    145 #if SK_SUPPORT_GPU
    146     if (FLAGS_gpu) {
    147         fCurContext->flush();
    148         this->present();
    149     }
    150 #endif
    151 }
    152 
    153 #ifdef SK_BUILD_FOR_WIN
    154 void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) {
    155     RECT winRect;
    156     winRect.top = rect.top();
    157     winRect.bottom = rect.bottom();
    158     winRect.right = rect.right();
    159     winRect.left = rect.left();
    160     InvalidateRect((HWND)this->getHWND(), &winRect, false);
    161 }
    162 #endif
    163 
    164 
    165 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
    166     printf("Started\n");
    167 
    168     v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
    169     SkCommandLineFlags::Parse(argc, argv);
    170 
    171     v8::V8::InitializeICU();
    172     v8::Platform* platform = v8::platform::CreateDefaultPlatform();
    173     v8::V8::InitializePlatform(platform);
    174     v8::V8::Initialize();
    175 
    176     v8::Isolate* isolate = v8::Isolate::New();
    177     v8::Isolate::Scope isolate_scope(isolate);
    178     v8::HandleScope handle_scope(isolate);
    179     isolate->Enter();
    180 
    181     global = new Global(isolate);
    182 
    183 
    184     // Set up things to look like a browser by creating
    185     // a console object that invokes our print function.
    186     const char* startupScript =
    187             "function Console() {};                   \n"
    188             "Console.prototype.log = function() {     \n"
    189             "  var args = Array.prototype.slice.call(arguments).join(' '); \n"
    190             "  print(args);                      \n"
    191             "};                                       \n"
    192             "console = new Console();                 \n";
    193 
    194     if (!global->parseScript(startupScript)) {
    195         printf("Failed to parse startup script: %s.\n", FLAGS_infile[0]);
    196         exit(1);
    197     }
    198 
    199     const char* script =
    200             "function onDraw(canvas) {              \n"
    201             "    canvas.fillStyle = '#00FF00';      \n"
    202             "    canvas.fillRect(20, 20, 100, 100); \n"
    203             "    canvas.inval();                    \n"
    204             "}                                      \n";
    205 
    206     SkAutoTUnref<SkData> data;
    207     if (FLAGS_infile.count()) {
    208         data.reset(SkData::NewFromFileName(FLAGS_infile[0]));
    209         script = static_cast<const char*>(data->data());
    210     }
    211     if (NULL == script) {
    212         printf("Could not load file: %s.\n", FLAGS_infile[0]);
    213         exit(1);
    214     }
    215     Path2DBuilder::AddToGlobal(global);
    216     Path2D::AddToGlobal(global);
    217 
    218     if (!global->parseScript(script)) {
    219         printf("Failed to parse file: %s.\n", FLAGS_infile[0]);
    220         exit(1);
    221     }
    222 
    223 
    224     JsContext* jsContext = new JsContext(global);
    225 
    226     if (!jsContext->initialize()) {
    227         printf("Failed to initialize.\n");
    228         exit(1);
    229     }
    230     SkV8ExampleWindow* win = new SkV8ExampleWindow(hwnd, jsContext);
    231     global->setWindow(win);
    232 
    233     return win;
    234 }
    235