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