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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/embedders/openglui/common/vm_glue.cc
===================================================================
--- runtime/embedders/openglui/common/vm_glue.cc (revision 0)
+++ runtime/embedders/openglui/common/vm_glue.cc (revision 0)
@@ -0,0 +1,344 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "embedders/openglui/common/extension.h"
+#include "embedders/openglui/common/log.h"
+#include "embedders/openglui/common/vm_glue.h"
+#include "include/dart_api.h"
+
+char* VMGlue::extension_script_ = NULL;
+
+// snapshot_buffer points to a snapshot if we link in a snapshot otherwise
+// it is initialized to NULL.
+
+VMGlue::VMGlue(ISized* surface,
+ const char* script_path,
+ const char* extension_script,
+ const char* main_script)
+ : surface_(surface),
+ isolate_(NULL),
+ initialized_vm_(false),
+ initialized_script_(false) {
+ LOGI("Creating VMGlue");
+ if (main_script == NULL) {
+ main_script = "main.dart";
+ }
+ if (extension_script == NULL) {
+ extension_script = "gl.dart";
+ }
+ size_t len = strlen(script_path) + strlen(main_script) + 2;
+ main_script_ = new char[len];
+ snprintf(main_script_, len, "%s/%s", script_path, main_script);
+ len = strlen(script_path) + strlen(extension_script) + 2;
+ extension_script_ = new char[len];
+ snprintf(extension_script_, len, "%s/%s", script_path, extension_script);
+}
+
+int VMGlue::ErrorExit(const char* format, ...) {
+ va_list arguments;
+ va_start(arguments, format);
+ LOGE(format, arguments);
+ va_end(arguments);
+ Dart_ExitScope();
+ Dart_ShutdownIsolate();
+ LOGE("Shutdown isolate");
+ return -1;
+}
+
+Dart_Handle VMGlue::CheckError(Dart_Handle handle) {
+ if (Dart_IsError(handle)) {
+ LOGE("Unexpected Error Handle: %s", Dart_GetError(handle));
+ Dart_PropagateError(handle);
+ }
+ return handle;
+}
+
+#define CHECK_RESULT(result) \
+ if (Dart_IsError(result)) { \
+ *error = strdup(Dart_GetError(result)); \
+ LOGE("%s", *error); \
+ Dart_ExitScope(); \
+ Dart_ShutdownIsolate(); \
+ return false; \
+ }
+
+Dart_Handle VMGlue::LibraryTagHandler(Dart_LibraryTag tag,
+ Dart_Handle library,
+ Dart_Handle urlHandle) {
+ const char* url;
+ Dart_StringToCString(urlHandle, &url);
+ if (tag == kCanonicalizeUrl) {
+ return urlHandle;
+ }
+ // TODO(vsm): Split this up into separate libraries for 3D, 2D,
+ // Touch, Audio, etc. All builtin libraries should be handled here
+ // (or moved into a snapshot).
+ if (strcmp(url, "gl.dart") == 0) {
+ Dart_Handle source =
+ VMGlue::LoadSourceFromFile(extension_script_);
+ Dart_Handle library = CheckError(Dart_LoadLibrary(urlHandle, source));
+ CheckError(Dart_SetNativeResolver(library, ResolveName));
+ return library;
+ }
+ LOGE("UNIMPLEMENTED: load library %s\n", url);
+ return NULL;
+}
+
+// Returns true on success, false on failure.
+bool VMGlue::CreateIsolateAndSetupHelper(const char* script_uri,
+ const char* main,
+ void* data,
+ char** error) {
+ LOGI("Creating isolate %s, %s", script_uri, main);
+ Dart_Isolate isolate =
+ Dart_CreateIsolate(script_uri, main, NULL, data, error);
+ if (isolate == NULL) {
+ LOGE("Couldn't create isolate: %s", *error);
+ return false;
+ }
+
+ LOGI("Entering scope");
+ Dart_EnterScope();
+
+ // Set up the library tag handler for this isolate.
+ LOGI("Setting up library tag handler");
+ Dart_Handle result = CheckError(Dart_SetLibraryTagHandler(LibraryTagHandler));
+ CHECK_RESULT(result);
+
+ Dart_ExitScope();
+ return true;
+}
+
+bool VMGlue::CreateIsolateAndSetup(const char* script_uri,
+ const char* main,
+ void* data, char** error) {
+ return CreateIsolateAndSetupHelper(script_uri,
+ main,
+ data,
+ error);
+}
+
+const char* VM_FLAGS[] = {
+ "--enable_type_checks", // TODO(gram): This should be an option!
+ "--trace_isolates",
+ "--trace_natives",
+};
+
+int VMGlue::InitializeVM() {
+ // We need the next call to get Dart_Initialize not to bail early.
+ LOGI("Setting VM Options");
+ Dart_SetVMFlags(sizeof(VM_FLAGS) / sizeof(VM_FLAGS[0]), VM_FLAGS);
+
+ // Initialize the Dart VM, providing the callbacks to use for
+ // creating and shutting down isolates.
+ LOGI("Initializing Dart");
+ if (!Dart_Initialize(CreateIsolateAndSetup,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL)) {
+ LOGE("VM initialization failed\n");
+ return -1;
+ }
+ initialized_vm_ = true;
+
+ return 0;
+}
+
+Dart_Handle VMGlue::LoadSourceFromFile(const char* url) {
+ FILE* file = fopen(url, "r");
+ if (file == NULL) {
+ LOGE("Main script not found at: %s\n", url);
+ return NULL;
+ }
+
+ struct stat sb;
+ int fd = fileno(file);
+ fstat(fd, &sb);
+ int length = sb.st_size;
+ LOGI("Entry file %s is %d bytes.\n", url, length);
+
+ char* buffer = new char[length+1];
+ if (read(fd, buffer, length) < 0) {
+ LOGE("Could not read script %s.\n", url);
+ return NULL;
+ }
+ buffer[length] = 0;
+ fclose(file);
+
+ Dart_Handle contents = CheckError(Dart_NewStringFromCString(buffer));
+ delete[] buffer;
+ return contents;
+}
+
+int VMGlue::StartMainIsolate() {
+ if (!initialized_vm_) {
+ int rtn = InitializeVM();
+ if (rtn != 0) return rtn;
+ }
+
+ // Create an isolate and loads up the application script.
+ char* error = NULL;
+ if (!CreateIsolateAndSetup(main_script_, "main", NULL, &error)) {
+ LOGE("CreateIsolateAndSetup: %s\n", error);
+ free(error);
+ return -1;
+ }
+ LOGI("Created isolate");
+ isolate_ = Dart_CurrentIsolate();
+ Dart_EnterScope();
+
+ Dart_Handle url = CheckError(Dart_NewStringFromCString(main_script_));
+ Dart_Handle source = LoadSourceFromFile(main_script_);
+ CheckError(Dart_LoadScript(url, source));
+
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+ return 0;
+}
+
+int VMGlue::CallSetup() {
+ if (!initialized_script_) {
+ initialized_script_ = true;
+ LOGI("Invoking setup(0,0,%d,%d)", surface_->width(), surface_->height());
+ Dart_EnterIsolate(isolate_);
+ Dart_EnterScope();
+ Dart_Handle args[2];
+ args[0] = CheckError(Dart_NewInteger(surface_->width()));
+ args[1] = CheckError(Dart_NewInteger(surface_->height()));
+ int rtn = Invoke("setup", 2, args);
+
+ if (rtn == 0) {
+ // Plug in the print handler. It would be nice if we could do this
+ // before calling setup, but the call to GetField blows up if we
+ // haven't run anything yet.
+ Dart_Handle library = CheckError(Dart_LookupLibrary(
+ Dart_NewStringFromCString("gl.dart")));
+ Dart_Handle print = CheckError(
+ Dart_GetField(library, Dart_NewStringFromCString("_printClosure")));
+ Dart_Handle corelib = CheckError(Dart_LookupLibrary(
+ Dart_NewStringFromCString("dart:core")));
+ CheckError(Dart_SetField(corelib,
+ Dart_NewStringFromCString("_printClosure"), print));
+ }
+
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+ LOGI("Done setup");
+ return rtn;
+ }
+ return 0;
+}
+
+int VMGlue::CallUpdate() {
+ if (initialized_script_) {
+ LOGI("Invoking update");
+ Dart_EnterIsolate(isolate_);
+ Dart_EnterScope();
+ int rtn = Invoke("update", 0, 0);
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+ LOGI("Done update");
+ return rtn;
+ }
+ return -1;
+}
+
+int VMGlue::OnMotionEvent(const char* pFunction, int64_t pWhen,
+ float pMoveX, float pMoveY) {
+ if (initialized_script_) {
+ LOGI("Invoking %s", pFunction);
+ Dart_EnterIsolate(isolate_);
+ Dart_EnterScope();
+ Dart_Handle args[3];
+ args[0] = CheckError(Dart_NewInteger(pWhen));
+ args[1] = CheckError(Dart_NewDouble(pMoveX));
+ args[2] = CheckError(Dart_NewDouble(pMoveY));
+ int rtn = Invoke(pFunction, 3, args, false);
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+ LOGI("Done %s", pFunction);
+ return rtn;
+ }
+ return -1;
+}
+
+int VMGlue::OnKeyEvent(const char* function, int64_t when, int32_t flags,
+ int32_t key_code, int32_t meta_state, int32_t repeat) {
+ if (initialized_script_) {
+ LOGI("Invoking %s", function);
+ Dart_EnterIsolate(isolate_);
+ Dart_EnterScope();
+ Dart_Handle args[5];
+ args[0] = CheckError(Dart_NewInteger(when));
+ args[1] = CheckError(Dart_NewInteger(flags));
+ args[2] = CheckError(Dart_NewInteger(key_code));
+ args[3] = CheckError(Dart_NewInteger(meta_state));
+ args[4] = CheckError(Dart_NewInteger(repeat));
+ int rtn = Invoke(function, 5, args, false);
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+ LOGI("Done %s", function);
+ return rtn;
+ }
+ return -1;
+}
+
+int VMGlue::Invoke(const char* function,
+ int argc,
+ Dart_Handle* args,
+ bool failIfNotDefined) {
+ LOGI("in invoke(%s)", function);
+
+ // Lookup the library of the root script.
+ LOGI("looking up the root library");
+ Dart_Handle library = Dart_RootLibrary();
+ if (Dart_IsNull(library)) {
+ return ErrorExit("Unable to find root library\n");
+ }
+
+ Dart_Handle nameHandle = Dart_NewStringFromCString(function);
+
+ LOGI("invoking %s", function);
+ Dart_Handle result = Dart_Invoke(library, nameHandle, argc, args);
+
+ if (Dart_IsError(result)) {
+ if (failIfNotDefined) {
+ return ErrorExit("Invoke %s: %s\n", function, Dart_GetError(result));
+ } else {
+ LOGE("Invoke %s: %s", function, Dart_GetError(result));
+ }
+ }
+
+ // TODO(vsm): I don't think we need this.
+ // Keep handling messages until the last active receive port is closed.
+ LOGI("Entering Dart message loop");
+ result = Dart_RunLoop();
+ if (Dart_IsError(result)) {
+ return ErrorExit("Dart_RunLoop: %s\n", Dart_GetError(result));
+ }
+
+ LOGI("out invoke");
+ return 0;
+}
+
+void VMGlue::FinishMainIsolate() {
+ LOGI("Finish main isolate");
+ Dart_EnterIsolate(isolate_);
+ // Shutdown the isolate.
+ Dart_ShutdownIsolate();
+ isolate_ = NULL;
+ initialized_script_ = false;
+}
+
« 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