Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: runtime/embedders/openglui/common/vm_glue.cc

Issue 11883013: Refactored OpenGL embedder that works on Android, Mac or Linux. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include <math.h>
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/stat.h>
11 #include <unistd.h>
12
13 #include "embedders/openglui/common/extension.h"
14 #include "embedders/openglui/common/log.h"
15 #include "embedders/openglui/common/vm_glue.h"
16 #include "include/dart_api.h"
17
18 char* VMGlue::extension_script_ = NULL;
19
20 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise
21 // it is initialized to NULL.
22
23 VMGlue::VMGlue(ISized* surface,
24 const char* script_path,
25 const char* extension_script,
26 const char* main_script)
27 : surface_(surface),
28 isolate_(NULL),
29 initialized_vm_(false),
30 initialized_script_(false) {
31 LOGI("Creating VMGlue");
32 if (main_script == NULL) {
33 main_script = "main.dart";
34 }
35 if (extension_script == NULL) {
36 extension_script = "gl.dart";
37 }
38 size_t len = strlen(script_path) + strlen(main_script) + 2;
39 main_script_ = new char[len];
40 snprintf(main_script_, len, "%s/%s", script_path, main_script);
41 len = strlen(script_path) + strlen(extension_script) + 2;
42 extension_script_ = new char[len];
43 snprintf(extension_script_, len, "%s/%s", script_path, extension_script);
44 }
45
46 int VMGlue::ErrorExit(const char* format, ...) {
47 va_list arguments;
48 va_start(arguments, format);
49 LOGE(format, arguments);
50 va_end(arguments);
51 Dart_ExitScope();
52 Dart_ShutdownIsolate();
53 LOGE("Shutdown isolate");
54 return -1;
55 }
56
57 Dart_Handle VMGlue::CheckError(Dart_Handle handle) {
58 if (Dart_IsError(handle)) {
59 LOGE("Unexpected Error Handle: %s", Dart_GetError(handle));
60 Dart_PropagateError(handle);
61 }
62 return handle;
63 }
64
65 #define CHECK_RESULT(result) \
66 if (Dart_IsError(result)) { \
67 *error = strdup(Dart_GetError(result)); \
68 LOGE("%s", *error); \
69 Dart_ExitScope(); \
70 Dart_ShutdownIsolate(); \
71 return false; \
72 }
73
74 Dart_Handle VMGlue::LibraryTagHandler(Dart_LibraryTag tag,
75 Dart_Handle library,
76 Dart_Handle urlHandle) {
77 const char* url;
78 Dart_StringToCString(urlHandle, &url);
79 if (tag == kCanonicalizeUrl) {
80 return urlHandle;
81 }
82 // TODO(vsm): Split this up into separate libraries for 3D, 2D,
83 // Touch, Audio, etc. All builtin libraries should be handled here
84 // (or moved into a snapshot).
85 if (strcmp(url, "gl.dart") == 0) {
86 Dart_Handle source =
87 VMGlue::LoadSourceFromFile(extension_script_);
88 Dart_Handle library = CheckError(Dart_LoadLibrary(urlHandle, source));
89 CheckError(Dart_SetNativeResolver(library, ResolveName));
90 return library;
91 }
92 LOGE("UNIMPLEMENTED: load library %s\n", url);
93 return NULL;
94 }
95
96 // Returns true on success, false on failure.
97 bool VMGlue::CreateIsolateAndSetupHelper(const char* script_uri,
98 const char* main,
99 void* data,
100 char** error) {
101 LOGI("Creating isolate %s, %s", script_uri, main);
102 Dart_Isolate isolate =
103 Dart_CreateIsolate(script_uri, main, NULL, data, error);
104 if (isolate == NULL) {
105 LOGE("Couldn't create isolate: %s", *error);
106 return false;
107 }
108
109 LOGI("Entering scope");
110 Dart_EnterScope();
111
112 // Set up the library tag handler for this isolate.
113 LOGI("Setting up library tag handler");
114 Dart_Handle result = CheckError(Dart_SetLibraryTagHandler(LibraryTagHandler));
115 CHECK_RESULT(result);
116
117 Dart_ExitScope();
118 return true;
119 }
120
121 bool VMGlue::CreateIsolateAndSetup(const char* script_uri,
122 const char* main,
123 void* data, char** error) {
124 return CreateIsolateAndSetupHelper(script_uri,
125 main,
126 data,
127 error);
128 }
129
130 const char* VM_FLAGS[] = {
131 "--enable_type_checks", // TODO(gram): This should be an option!
132 "--trace_isolates",
133 "--trace_natives",
134 };
135
136 int VMGlue::InitializeVM() {
137 // We need the next call to get Dart_Initialize not to bail early.
138 LOGI("Setting VM Options");
139 Dart_SetVMFlags(sizeof(VM_FLAGS) / sizeof(VM_FLAGS[0]), VM_FLAGS);
140
141 // Initialize the Dart VM, providing the callbacks to use for
142 // creating and shutting down isolates.
143 LOGI("Initializing Dart");
144 if (!Dart_Initialize(CreateIsolateAndSetup,
145 NULL,
146 NULL,
147 NULL,
148 NULL,
149 NULL,
150 NULL)) {
151 LOGE("VM initialization failed\n");
152 return -1;
153 }
154 initialized_vm_ = true;
155
156 return 0;
157 }
158
159 Dart_Handle VMGlue::LoadSourceFromFile(const char* url) {
160 FILE* file = fopen(url, "r");
161 if (file == NULL) {
162 LOGE("Main script not found at: %s\n", url);
163 return NULL;
164 }
165
166 struct stat sb;
167 int fd = fileno(file);
168 fstat(fd, &sb);
169 int length = sb.st_size;
170 LOGI("Entry file %s is %d bytes.\n", url, length);
171
172 char* buffer = new char[length+1];
173 if (read(fd, buffer, length) < 0) {
174 LOGE("Could not read script %s.\n", url);
175 return NULL;
176 }
177 buffer[length] = 0;
178 fclose(file);
179
180 Dart_Handle contents = CheckError(Dart_NewStringFromCString(buffer));
181 delete[] buffer;
182 return contents;
183 }
184
185 int VMGlue::StartMainIsolate() {
186 if (!initialized_vm_) {
187 int rtn = InitializeVM();
188 if (rtn != 0) return rtn;
189 }
190
191 // Create an isolate and loads up the application script.
192 char* error = NULL;
193 if (!CreateIsolateAndSetup(main_script_, "main", NULL, &error)) {
194 LOGE("CreateIsolateAndSetup: %s\n", error);
195 free(error);
196 return -1;
197 }
198 LOGI("Created isolate");
199 isolate_ = Dart_CurrentIsolate();
200 Dart_EnterScope();
201
202 Dart_Handle url = CheckError(Dart_NewStringFromCString(main_script_));
203 Dart_Handle source = LoadSourceFromFile(main_script_);
204 CheckError(Dart_LoadScript(url, source));
205
206 Dart_ExitScope();
207 Dart_ExitIsolate();
208 return 0;
209 }
210
211 int VMGlue::CallSetup() {
212 if (!initialized_script_) {
213 initialized_script_ = true;
214 LOGI("Invoking setup(0,0,%d,%d)", surface_->width(), surface_->height());
215 Dart_EnterIsolate(isolate_);
216 Dart_EnterScope();
217 Dart_Handle args[2];
218 args[0] = CheckError(Dart_NewInteger(surface_->width()));
219 args[1] = CheckError(Dart_NewInteger(surface_->height()));
220 int rtn = Invoke("setup", 2, args);
221
222 if (rtn == 0) {
223 // Plug in the print handler. It would be nice if we could do this
224 // before calling setup, but the call to GetField blows up if we
225 // haven't run anything yet.
226 Dart_Handle library = CheckError(Dart_LookupLibrary(
227 Dart_NewStringFromCString("gl.dart")));
228 Dart_Handle print = CheckError(
229 Dart_GetField(library, Dart_NewStringFromCString("_printClosure")));
230 Dart_Handle corelib = CheckError(Dart_LookupLibrary(
231 Dart_NewStringFromCString("dart:core")));
232 CheckError(Dart_SetField(corelib,
233 Dart_NewStringFromCString("_printClosure"), print));
234 }
235
236 Dart_ExitScope();
237 Dart_ExitIsolate();
238 LOGI("Done setup");
239 return rtn;
240 }
241 return 0;
242 }
243
244 int VMGlue::CallUpdate() {
245 if (initialized_script_) {
246 LOGI("Invoking update");
247 Dart_EnterIsolate(isolate_);
248 Dart_EnterScope();
249 int rtn = Invoke("update", 0, 0);
250 Dart_ExitScope();
251 Dart_ExitIsolate();
252 LOGI("Done update");
253 return rtn;
254 }
255 return -1;
256 }
257
258 int VMGlue::OnMotionEvent(const char* pFunction, int64_t pWhen,
259 float pMoveX, float pMoveY) {
260 if (initialized_script_) {
261 LOGI("Invoking %s", pFunction);
262 Dart_EnterIsolate(isolate_);
263 Dart_EnterScope();
264 Dart_Handle args[3];
265 args[0] = CheckError(Dart_NewInteger(pWhen));
266 args[1] = CheckError(Dart_NewDouble(pMoveX));
267 args[2] = CheckError(Dart_NewDouble(pMoveY));
268 int rtn = Invoke(pFunction, 3, args, false);
269 Dart_ExitScope();
270 Dart_ExitIsolate();
271 LOGI("Done %s", pFunction);
272 return rtn;
273 }
274 return -1;
275 }
276
277 int VMGlue::OnKeyEvent(const char* function, int64_t when, int32_t flags,
278 int32_t key_code, int32_t meta_state, int32_t repeat) {
279 if (initialized_script_) {
280 LOGI("Invoking %s", function);
281 Dart_EnterIsolate(isolate_);
282 Dart_EnterScope();
283 Dart_Handle args[5];
284 args[0] = CheckError(Dart_NewInteger(when));
285 args[1] = CheckError(Dart_NewInteger(flags));
286 args[2] = CheckError(Dart_NewInteger(key_code));
287 args[3] = CheckError(Dart_NewInteger(meta_state));
288 args[4] = CheckError(Dart_NewInteger(repeat));
289 int rtn = Invoke(function, 5, args, false);
290 Dart_ExitScope();
291 Dart_ExitIsolate();
292 LOGI("Done %s", function);
293 return rtn;
294 }
295 return -1;
296 }
297
298 int VMGlue::Invoke(const char* function,
299 int argc,
300 Dart_Handle* args,
301 bool failIfNotDefined) {
302 LOGI("in invoke(%s)", function);
303
304 // Lookup the library of the root script.
305 LOGI("looking up the root library");
306 Dart_Handle library = Dart_RootLibrary();
307 if (Dart_IsNull(library)) {
308 return ErrorExit("Unable to find root library\n");
309 }
310
311 Dart_Handle nameHandle = Dart_NewStringFromCString(function);
312
313 LOGI("invoking %s", function);
314 Dart_Handle result = Dart_Invoke(library, nameHandle, argc, args);
315
316 if (Dart_IsError(result)) {
317 if (failIfNotDefined) {
318 return ErrorExit("Invoke %s: %s\n", function, Dart_GetError(result));
319 } else {
320 LOGE("Invoke %s: %s", function, Dart_GetError(result));
321 }
322 }
323
324 // TODO(vsm): I don't think we need this.
325 // Keep handling messages until the last active receive port is closed.
326 LOGI("Entering Dart message loop");
327 result = Dart_RunLoop();
328 if (Dart_IsError(result)) {
329 return ErrorExit("Dart_RunLoop: %s\n", Dart_GetError(result));
330 }
331
332 LOGI("out invoke");
333 return 0;
334 }
335
336 void VMGlue::FinishMainIsolate() {
337 LOGI("Finish main isolate");
338 Dart_EnterIsolate(isolate_);
339 // Shutdown the isolate.
340 Dart_ShutdownIsolate();
341 isolate_ = NULL;
342 initialized_script_ = false;
343 }
344
OLDNEW
« no previous file with comments | « runtime/embedders/openglui/common/vm_glue.h ('k') | runtime/embedders/openglui/emulator/emulator_embedder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698