aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-09-01 11:01:51 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-01 17:30:57 +0000
commitdbb24efcc5f224a0d9a73ad9b200daf8013df0a1 (patch)
tree755251b59a15a044d40737ccb0b59b80e926e4bc /tools
parent4b277b9b66abffa024732a2e12b5a5b13f3d9168 (diff)
Get viewer running on iOS
Bug: skia: Change-Id: Ic8b25ca2ecf51cfc190ac01bc9282396905a33b3 Reviewed-on: https://skia-review.googlesource.com/40862 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/viewer/sk_app/ios/GLWindowContext_ios.cpp109
-rw-r--r--tools/viewer/sk_app/ios/RasterWindowContext_ios.cpp136
-rw-r--r--tools/viewer/sk_app/ios/WindowContextFactory_ios.h38
-rw-r--r--tools/viewer/sk_app/ios/Window_ios.cpp277
-rw-r--r--tools/viewer/sk_app/ios/Window_ios.h64
-rw-r--r--tools/viewer/sk_app/ios/main_ios.cpp58
6 files changed, 682 insertions, 0 deletions
diff --git a/tools/viewer/sk_app/ios/GLWindowContext_ios.cpp b/tools/viewer/sk_app/ios/GLWindowContext_ios.cpp
new file mode 100644
index 0000000000..30bacf5cea
--- /dev/null
+++ b/tools/viewer/sk_app/ios/GLWindowContext_ios.cpp
@@ -0,0 +1,109 @@
+
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <OpenGLES/ES2/gl.h>
+#include "../GLWindowContext.h"
+#include "SDL.h"
+#include "WindowContextFactory_ios.h"
+#include "gl/GrGLInterface.h"
+
+using sk_app::DisplayParams;
+using sk_app::window_context_factory::IOSWindowInfo;
+using sk_app::GLWindowContext;
+
+namespace {
+
+class GLWindowContext_ios : public GLWindowContext {
+public:
+ GLWindowContext_ios(const IOSWindowInfo&, const DisplayParams&);
+
+ ~GLWindowContext_ios() override;
+
+ void onSwapBuffers() override;
+
+ sk_sp<const GrGLInterface> onInitializeContext() override;
+ void onDestroyContext() override;
+
+private:
+ SDL_Window* fWindow;
+ SDL_GLContext fGLContext;
+
+ typedef GLWindowContext INHERITED;
+};
+
+GLWindowContext_ios::GLWindowContext_ios(const IOSWindowInfo& info, const DisplayParams& params)
+ : INHERITED(params)
+ , fWindow(info.fWindow)
+ , fGLContext(nullptr) {
+
+ // any config code here (particularly for msaa)?
+
+ this->initializeContext();
+}
+
+GLWindowContext_ios::~GLWindowContext_ios() {
+ this->destroyContext();
+}
+
+sk_sp<const GrGLInterface> GLWindowContext_ios::onInitializeContext() {
+ SkASSERT(fWindow);
+
+ fGLContext = SDL_GL_CreateContext(fWindow);
+ if (!fGLContext) {
+ SkDebugf("%s\n", SDL_GetError());
+ return nullptr;
+ }
+
+ if (0 == SDL_GL_MakeCurrent(fWindow, fGLContext)) {
+ glClearStencil(0);
+ glClearColor(0, 0, 0, 0);
+ glStencilMask(0xffffffff);
+ glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+ SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &fStencilBits);
+ SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fSampleCount);
+
+ SDL_GL_GetDrawableSize(fWindow, &fWidth, &fHeight);
+ glViewport(0, 0, fWidth, fHeight);
+ } else {
+ SkDebugf("MakeCurrent failed: %s\n", SDL_GetError());
+ }
+ return sk_sp<const GrGLInterface>(GrGLCreateNativeInterface());
+}
+
+void GLWindowContext_ios::onDestroyContext() {
+ if (!fWindow || !fGLContext) {
+ return;
+ }
+ SDL_GL_DeleteContext(fGLContext);
+ fGLContext = nullptr;
+}
+
+
+void GLWindowContext_ios::onSwapBuffers() {
+ if (fWindow && fGLContext) {
+ SDL_GL_SwapWindow(fWindow);
+ }
+}
+
+} // anonymous namespace
+
+namespace sk_app {
+namespace window_context_factory {
+
+WindowContext* NewGLForIOS(const IOSWindowInfo& info, const DisplayParams& params) {
+ WindowContext* ctx = new GLWindowContext_ios(info, params);
+ if (!ctx->isValid()) {
+ delete ctx;
+ return nullptr;
+ }
+ return ctx;
+}
+
+} // namespace window_context_factory
+} // namespace sk_app
diff --git a/tools/viewer/sk_app/ios/RasterWindowContext_ios.cpp b/tools/viewer/sk_app/ios/RasterWindowContext_ios.cpp
new file mode 100644
index 0000000000..08b6560510
--- /dev/null
+++ b/tools/viewer/sk_app/ios/RasterWindowContext_ios.cpp
@@ -0,0 +1,136 @@
+
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <OpenGLES/ES2/gl.h>
+#include "../GLWindowContext.h"
+#include "SDL.h"
+#include "SkCanvas.h"
+#include "SkColorFilter.h"
+#include "WindowContextFactory_ios.h"
+#include "gl/GrGLInterface.h"
+#include "sk_tool_utils.h"
+
+using sk_app::DisplayParams;
+using sk_app::window_context_factory::IOSWindowInfo;
+using sk_app::GLWindowContext;
+
+namespace {
+
+// We use SDL to support Mac windowing mainly for convenience's sake. However, it
+// does not allow us to support a purely raster backend because we have no hooks into
+// the NSWindow's drawRect: method. Hence we use GL to handle the update. Should we
+// want to avoid this, we will probably need to write our own windowing backend.
+
+class RasterWindowContext_ios : public GLWindowContext {
+public:
+ RasterWindowContext_ios(const IOSWindowInfo&, const DisplayParams&);
+
+ ~RasterWindowContext_ios() override;
+
+ sk_sp<SkSurface> getBackbufferSurface() override;
+
+ void onSwapBuffers() override;
+
+ sk_sp<const GrGLInterface> onInitializeContext() override;
+ void onDestroyContext() override;
+
+private:
+ SDL_Window* fWindow;
+ SDL_GLContext fGLContext;
+ sk_sp<SkSurface> fBackbufferSurface;
+
+ typedef GLWindowContext INHERITED;
+};
+
+RasterWindowContext_ios::RasterWindowContext_ios(const IOSWindowInfo& info,
+ const DisplayParams& params)
+ : INHERITED(params)
+ , fWindow(info.fWindow)
+ , fGLContext(nullptr) {
+
+ // any config code here (particularly for msaa)?
+
+ this->initializeContext();
+}
+
+RasterWindowContext_ios::~RasterWindowContext_ios() {
+ this->destroyContext();
+}
+
+sk_sp<const GrGLInterface> RasterWindowContext_ios::onInitializeContext() {
+ SkASSERT(fWindow);
+
+ fGLContext = SDL_GL_CreateContext(fWindow);
+ if (!fGLContext) {
+ SkDebugf("%s\n", SDL_GetError());
+ return nullptr;
+ }
+
+ if (0 == SDL_GL_MakeCurrent(fWindow, fGLContext)) {
+ glClearStencil(0);
+ glClearColor(0, 0, 0, 0);
+ glStencilMask(0xffffffff);
+ glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+ SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &fStencilBits);
+ SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fSampleCount);
+
+ SDL_GL_GetDrawableSize(fWindow, &fWidth, &fHeight);
+ glViewport(0, 0, fWidth, fHeight);
+ } else {
+ SkDebugf("MakeCurrent failed: %s\n", SDL_GetError());
+ }
+
+ // make the offscreen image
+ SkImageInfo info = SkImageInfo::Make(fWidth, fHeight, fDisplayParams.fColorType,
+ kPremul_SkAlphaType, fDisplayParams.fColorSpace);
+ fBackbufferSurface = SkSurface::MakeRaster(info);
+ return sk_sp<const GrGLInterface>(GrGLCreateNativeInterface());
+}
+
+void RasterWindowContext_ios::onDestroyContext() {
+ if (!fWindow || !fGLContext) {
+ return;
+ }
+ fBackbufferSurface.reset(nullptr);
+ SDL_GL_DeleteContext(fGLContext);
+ fGLContext = nullptr;
+}
+
+sk_sp<SkSurface> RasterWindowContext_ios::getBackbufferSurface() { return fBackbufferSurface; }
+
+void RasterWindowContext_ios::onSwapBuffers() {
+ if (fWindow && fGLContext) {
+ // We made/have an off-screen surface. Get the contents as an SkImage:
+ sk_sp<SkImage> snapshot = fBackbufferSurface->makeImageSnapshot();
+
+ sk_sp<SkSurface> gpuSurface = INHERITED::getBackbufferSurface();
+ SkCanvas* gpuCanvas = gpuSurface->getCanvas();
+ gpuCanvas->drawImage(snapshot, 0, 0);
+ gpuCanvas->flush();
+
+ SDL_GL_SwapWindow(fWindow);
+ }
+}
+
+} // anonymous namespace
+
+namespace sk_app {
+namespace window_context_factory {
+
+WindowContext* NewRasterForIOS(const IOSWindowInfo& info, const DisplayParams& params) {
+ WindowContext* ctx = new RasterWindowContext_ios(info, params);
+ if (!ctx->isValid()) {
+ delete ctx;
+ return nullptr;
+ }
+ return ctx;
+}
+
+} // namespace window_context_factory
+} // namespace sk_app
diff --git a/tools/viewer/sk_app/ios/WindowContextFactory_ios.h b/tools/viewer/sk_app/ios/WindowContextFactory_ios.h
new file mode 100644
index 0000000000..09999c4c83
--- /dev/null
+++ b/tools/viewer/sk_app/ios/WindowContextFactory_ios.h
@@ -0,0 +1,38 @@
+
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef WindowContextFactory_ios_DEFINED
+#define WindowContextFactory_ios_DEFINED
+
+#include "SDL.h"
+
+namespace sk_app {
+
+class WindowContext;
+struct DisplayParams;
+
+namespace window_context_factory {
+
+struct IOSWindowInfo {
+ SDL_Window* fWindow;
+};
+
+inline WindowContext* NewVulkanForIOS(const IOSWindowInfo&, const DisplayParams&) {
+ // No Vulkan support on iOS.
+ return nullptr;
+}
+
+WindowContext* NewGLForIOS(const IOSWindowInfo&, const DisplayParams&);
+
+WindowContext* NewRasterForIOS(const IOSWindowInfo&, const DisplayParams&);
+
+} // namespace window_context_factory
+
+} // namespace sk_app
+
+#endif
diff --git a/tools/viewer/sk_app/ios/Window_ios.cpp b/tools/viewer/sk_app/ios/Window_ios.cpp
new file mode 100644
index 0000000000..d37269703c
--- /dev/null
+++ b/tools/viewer/sk_app/ios/Window_ios.cpp
@@ -0,0 +1,277 @@
+/*
+* Copyright 2017 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "SkUtils.h"
+#include "Timer.h"
+#include "WindowContextFactory_ios.h"
+#include "Window_ios.h"
+
+namespace sk_app {
+
+SkTDynamicHash<Window_ios, Uint32> Window_ios::gWindowMap;
+
+Window* Window::CreateNativeWindow(void*) {
+ Window_ios* window = new Window_ios();
+ if (!window->initWindow()) {
+ delete window;
+ return nullptr;
+ }
+
+ return window;
+}
+
+bool Window_ios::initWindow() {
+ if (fRequestedDisplayParams.fMSAASampleCount != fMSAASampleCount) {
+ this->closeWindow();
+ }
+ // we already have a window
+ if (fWindow) {
+ return true;
+ }
+
+ constexpr int initialWidth = 1280;
+ constexpr int initialHeight = 960;
+
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+
+ SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
+
+ if (fRequestedDisplayParams.fMSAASampleCount > 0) {
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fRequestedDisplayParams.fMSAASampleCount);
+ } else {
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
+ }
+ // TODO: handle other display params
+
+ uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI;
+ fWindow = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+ initialWidth, initialHeight, windowFlags);
+
+ if (!fWindow) {
+ return false;
+ }
+
+ fMSAASampleCount = fRequestedDisplayParams.fMSAASampleCount;
+
+ // add to hashtable of windows
+ fWindowID = SDL_GetWindowID(fWindow);
+ gWindowMap.add(this);
+
+ return true;
+}
+
+void Window_ios::closeWindow() {
+ if (fWindow) {
+ gWindowMap.remove(fWindowID);
+ SDL_DestroyWindow(fWindow);
+ fWindowID = 0;
+ fWindow = nullptr;
+ }
+}
+
+static Window::Key get_key(const SDL_Keysym& keysym) {
+ static const struct {
+ SDL_Keycode fSDLK;
+ Window::Key fKey;
+ } gPair[] = {
+ { SDLK_BACKSPACE, Window::Key::kBack },
+ { SDLK_CLEAR, Window::Key::kBack },
+ { SDLK_RETURN, Window::Key::kOK },
+ { SDLK_UP, Window::Key::kUp },
+ { SDLK_DOWN, Window::Key::kDown },
+ { SDLK_LEFT, Window::Key::kLeft },
+ { SDLK_RIGHT, Window::Key::kRight },
+ { SDLK_TAB, Window::Key::kTab },
+ { SDLK_PAGEUP, Window::Key::kPageUp },
+ { SDLK_PAGEDOWN, Window::Key::kPageDown },
+ { SDLK_HOME, Window::Key::kHome },
+ { SDLK_END, Window::Key::kEnd },
+ { SDLK_DELETE, Window::Key::kDelete },
+ { SDLK_ESCAPE, Window::Key::kEscape },
+ { SDLK_LSHIFT, Window::Key::kShift },
+ { SDLK_RSHIFT, Window::Key::kShift },
+ { SDLK_LCTRL, Window::Key::kCtrl },
+ { SDLK_RCTRL, Window::Key::kCtrl },
+ { SDLK_LALT, Window::Key::kOption },
+ { SDLK_LALT, Window::Key::kOption },
+ { 'A', Window::Key::kA },
+ { 'C', Window::Key::kC },
+ { 'V', Window::Key::kV },
+ { 'X', Window::Key::kX },
+ { 'Y', Window::Key::kY },
+ { 'Z', Window::Key::kZ },
+ };
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
+ if (gPair[i].fSDLK == keysym.sym) {
+ return gPair[i].fKey;
+ }
+ }
+ return Window::Key::kNONE;
+}
+
+static uint32_t get_modifiers(const SDL_Event& event) {
+ static const struct {
+ unsigned fSDLMask;
+ unsigned fSkMask;
+ } gModifiers[] = {
+ { KMOD_SHIFT, Window::kShift_ModifierKey },
+ { KMOD_CTRL, Window::kControl_ModifierKey },
+ { KMOD_ALT, Window::kOption_ModifierKey },
+ };
+
+ auto modifiers = 0;
+
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ // fall through
+ case SDL_KEYUP: {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
+ if (event.key.keysym.mod & gModifiers[i].fSDLMask) {
+ modifiers |= gModifiers[i].fSkMask;
+ }
+ }
+ if (0 == event.key.repeat) {
+ modifiers |= Window::kFirstPress_ModifierKey;
+ }
+ break;
+ }
+
+ default: {
+ SDL_Keymod mod = SDL_GetModState();
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
+ if (mod & gModifiers[i].fSDLMask) {
+ modifiers |= gModifiers[i].fSkMask;
+ }
+ }
+ break;
+ }
+ }
+ return modifiers;
+}
+
+bool Window_ios::HandleWindowEvent(const SDL_Event& event) {
+ Window_ios* win = gWindowMap.find(event.window.windowID);
+ if (win && win->handleEvent(event)) {
+ return true;
+ }
+
+ return false;
+}
+
+bool Window_ios::handleEvent(const SDL_Event& event) {
+ switch (event.type) {
+ case SDL_WINDOWEVENT:
+ if (SDL_WINDOWEVENT_EXPOSED == event.window.event) {
+ this->onPaint();
+ } else if (SDL_WINDOWEVENT_RESIZED == event.window.event) {
+ this->onResize(event.window.data1, event.window.data2);
+ }
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ if (event.button.button == SDL_BUTTON_LEFT) {
+ this->onMouse(event.button.x, event.button.y,
+ Window::kDown_InputState, get_modifiers(event));
+ }
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ if (event.button.button == SDL_BUTTON_LEFT) {
+ this->onMouse(event.button.x, event.button.y,
+ Window::kUp_InputState, get_modifiers(event));
+ }
+ break;
+
+ case SDL_MOUSEMOTION:
+ this->onMouse(event.motion.x, event.motion.y,
+ Window::kMove_InputState, get_modifiers(event));
+ break;
+
+ case SDL_MOUSEWHEEL:
+ this->onMouseWheel(event.wheel.y, get_modifiers(event));
+ break;
+
+ case SDL_KEYDOWN: {
+ Window::Key key = get_key(event.key.keysym);
+ if (key != Window::Key::kNONE) {
+ if (!this->onKey(key, Window::kDown_InputState, get_modifiers(event))) {
+ if (event.key.keysym.sym == SDLK_ESCAPE) {
+ return true;
+ }
+ }
+ }
+ } break;
+
+ case SDL_KEYUP: {
+ Window::Key key = get_key(event.key.keysym);
+ if (key != Window::Key::kNONE) {
+ (void) this->onKey(key, Window::kUp_InputState,
+ get_modifiers(event));
+ }
+ } break;
+
+ case SDL_TEXTINPUT: {
+ const char* textIter = &event.text.text[0];
+ while (SkUnichar c = SkUTF8_NextUnichar(&textIter)) {
+ (void) this->onChar(c, get_modifiers(event));
+ }
+ } break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+void Window_ios::setTitle(const char* title) {
+ SDL_SetWindowTitle(fWindow, title);
+}
+
+void Window_ios::show() {
+ SDL_ShowWindow(fWindow);
+}
+
+bool Window_ios::attach(BackendType attachType) {
+ this->initWindow();
+
+ window_context_factory::IOSWindowInfo info;
+ info.fWindow = fWindow;
+ switch (attachType) {
+ case kRaster_BackendType:
+ fWindowContext = NewRasterForIOS(info, fRequestedDisplayParams);
+ break;
+
+ case kNativeGL_BackendType:
+ default:
+ fWindowContext = NewGLForIOS(info, fRequestedDisplayParams);
+ break;
+ }
+ this->onBackendCreated();
+
+ return (SkToBool(fWindowContext));
+}
+
+void Window_ios::onInval() {
+ SDL_Event sdlevent;
+ sdlevent.type = SDL_WINDOWEVENT;
+ sdlevent.window.windowID = fWindowID;
+ sdlevent.window.event = SDL_WINDOWEVENT_EXPOSED;
+ SDL_PushEvent(&sdlevent);
+}
+
+} // namespace sk_app
diff --git a/tools/viewer/sk_app/ios/Window_ios.h b/tools/viewer/sk_app/ios/Window_ios.h
new file mode 100644
index 0000000000..667fa74e82
--- /dev/null
+++ b/tools/viewer/sk_app/ios/Window_ios.h
@@ -0,0 +1,64 @@
+/*
+* Copyright 2017 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef Window_ios_DEFINED
+#define Window_ios_DEFINED
+
+#include "../Window.h"
+#include "SkChecksum.h"
+#include "SkTDynamicHash.h"
+
+#include "SDL.h"
+
+namespace sk_app {
+
+class Window_ios : public Window {
+public:
+ Window_ios()
+ : INHERITED()
+ , fWindow(nullptr)
+ , fWindowID(0)
+ , fMSAASampleCount(0) {}
+ ~Window_ios() override { this->closeWindow(); }
+
+ bool initWindow();
+
+ void setTitle(const char*) override;
+ void show() override;
+
+ bool attach(BackendType) override;
+
+ void onInval() override;
+
+ static bool HandleWindowEvent(const SDL_Event& event);
+
+ static const Uint32& GetKey(const Window_ios& w) {
+ return w.fWindowID;
+ }
+
+ static uint32_t Hash(const Uint32& winID) {
+ return winID;
+ }
+
+private:
+ bool handleEvent(const SDL_Event& event);
+
+ void closeWindow();
+
+ static SkTDynamicHash<Window_ios, Uint32> gWindowMap;
+
+ SDL_Window* fWindow;
+ Uint32 fWindowID;
+
+ int fMSAASampleCount;
+
+ typedef Window INHERITED;
+};
+
+} // namespace sk_app
+
+#endif
diff --git a/tools/viewer/sk_app/ios/main_ios.cpp b/tools/viewer/sk_app/ios/main_ios.cpp
new file mode 100644
index 0000000000..fe82c46485
--- /dev/null
+++ b/tools/viewer/sk_app/ios/main_ios.cpp
@@ -0,0 +1,58 @@
+/*
+* Copyright 2017 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "SkTypes.h"
+#include "SkTHash.h"
+#include "SDL.h"
+#include "Timer.h"
+#include "Window_ios.h"
+#include "../Application.h"
+
+using sk_app::Application;
+
+int main(int argc, char* argv[]) {
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
+ SkDebugf("Could not initialize SDL!\n");
+ return 1;
+ }
+
+ Application* app = Application::Create(argc, argv, nullptr);
+
+ SDL_Event event;
+ bool done = false;
+ while (!done) {
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ // events handled by the windows
+ case SDL_WINDOWEVENT:
+ case SDL_MOUSEMOTION:
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ case SDL_MOUSEWHEEL:
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ case SDL_TEXTINPUT:
+ done = sk_app::Window_ios::HandleWindowEvent(event);
+ break;
+
+ case SDL_QUIT:
+ done = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ app->onIdle();
+ }
+ delete app;
+
+ SDL_Quit();
+
+ return 0;
+}