OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include "SkOSWindow_SDL.h" | 7 #include "SkOSWindow_SDL.h" |
8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 | 9 |
10 #if defined(SK_BUILD_FOR_ANDROID) | 10 #if defined(SK_BUILD_FOR_ANDROID) |
11 #include <GLES/gl.h> | 11 #include <GLES/gl.h> |
12 #elif defined(SK_BUILD_FOR_UNIX) | 12 #elif defined(SK_BUILD_FOR_UNIX) |
13 #include <GL/gl.h> | 13 #include <GL/gl.h> |
14 #elif defined(SK_BUILD_FOR_MAC) | 14 #elif defined(SK_BUILD_FOR_MAC) |
15 #include <gl.h> | 15 #include <gl.h> |
16 #endif | 16 #endif |
17 | 17 |
18 const int SCREEN_WIDTH = 640; | 18 const int kInitialWindowWidth = 640; |
19 const int SCREEN_HEIGHT = 480; | 19 const int kInitialWindowHeight = 480; |
| 20 static SkOSWindow* gCurrentWindow; |
20 | 21 |
21 static void handle_error() { | 22 static void report_sdl_error(const char* failure) { |
22 const char* error = SDL_GetError(); | 23 const char* error = SDL_GetError(); |
23 SkDebugf("SDL Error: %s\n", error); | 24 SkASSERT(error); // Called only to check SDL error. |
| 25 SkDebugf("%s SDL Error: %s.\n", failure, error); |
24 SDL_ClearError(); | 26 SDL_ClearError(); |
25 } | 27 } |
| 28 SkOSWindow::SkOSWindow(void*) |
| 29 : fWindow(nullptr) |
| 30 , fGLContext(nullptr) |
| 31 , fWindowMSAASampleCount(0) { |
26 | 32 |
27 SkOSWindow::SkOSWindow(void* screen) : fQuit(false) , fGLContext(nullptr) { | 33 SkASSERT(!gCurrentWindow); |
28 #if defined(SK_BUILD_FOR_ANDROID) | 34 gCurrentWindow = this; |
29 // TODO we should try and get a 3.0 context first | |
30 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); | |
31 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); | |
32 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); | |
33 fWindowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | | |
34 SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN_DESKTOP | | |
35 SDL_WINDOW_ALLOW_HIGHDPI; | |
36 #else | |
37 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); | |
38 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); | |
39 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE
); | |
40 SDL_StartTextInput(); | |
41 | 35 |
42 fWindowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; | 36 this->createWindow(0); |
43 #endif | |
44 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); | |
45 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); | |
46 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); | |
47 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | |
48 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); | |
49 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); | |
50 | |
51 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); | |
52 | |
53 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { | |
54 handle_error(); | |
55 return; | |
56 } | |
57 | |
58 SDL_DisplayMode dm; | |
59 if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { | |
60 handle_error(); | |
61 return; | |
62 } | |
63 | |
64 fWindow = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWP
OS_CENTERED, | |
65 dm.w, dm.h, fWindowFlags); | |
66 | |
67 if (!fWindow) { | |
68 handle_error(); | |
69 return; | |
70 } | |
71 this->resize(dm.w, dm.h); | |
72 } | 37 } |
73 | 38 |
74 SkOSWindow::~SkOSWindow() { | 39 SkOSWindow::~SkOSWindow() { |
75 if (fGLContext) { | 40 this->destroyWindow(); |
76 SDL_GL_DeleteContext(fGLContext); | 41 gCurrentWindow = nullptr; |
| 42 } |
| 43 |
| 44 SkOSWindow* SkOSWindow::GetInstanceForWindowID(Uint32 windowID) { |
| 45 if (gCurrentWindow && |
| 46 gCurrentWindow->fWindow && |
| 47 SDL_GetWindowID(gCurrentWindow->fWindow) == windowID) { |
| 48 return gCurrentWindow; |
77 } | 49 } |
78 | 50 return nullptr; |
79 //Destroy window | |
80 SDL_DestroyWindow(fWindow); | |
81 | |
82 //Quit SDL subsystems | |
83 SDL_Quit(); | |
84 } | 51 } |
85 | 52 |
86 void SkOSWindow::detach() { | 53 void SkOSWindow::detach() { |
87 if (fGLContext) { | 54 if (fGLContext) { |
88 SDL_GL_DeleteContext(fGLContext); | 55 SDL_GL_DeleteContext(fGLContext); |
89 fGLContext = nullptr; | 56 fGLContext = nullptr; |
90 } | 57 } |
91 | |
92 #if defined(SK_BUILD_FOR_ANDROID) | |
93 if (fWindow) { | |
94 // Destroy window | |
95 // Not totally sure why, but we have to do this or swapbuffers will hang | |
96 SDL_DestroyWindow(fWindow); | |
97 fWindow = nullptr; | |
98 } | |
99 #endif | |
100 } | 58 } |
101 | 59 |
102 bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, Attachme
ntInfo* info) { | 60 bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, Attachme
ntInfo* info) { |
| 61 this->createWindow(msaaSampleCount); |
103 if (!fWindow) { | 62 if (!fWindow) { |
104 fWindow = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WIN
DOWPOS_CENTERED, | 63 return false; |
105 SCREEN_WIDTH, SCREEN_HEIGHT, | 64 } |
106 fWindowFlags); | 65 if (!fGLContext) { |
| 66 fGLContext = SDL_GL_CreateContext(fWindow); |
| 67 if (!fGLContext) { |
| 68 report_sdl_error("Failed to create SDL GL context."); |
| 69 return false; |
| 70 } |
| 71 glClearColor(0, 0, 0, 0); |
| 72 glClearStencil(0); |
| 73 glStencilMask(0xffffffff); |
| 74 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
107 } | 75 } |
108 | 76 |
109 if (msaaSampleCount > 0) { | 77 if (SDL_GL_MakeCurrent(fWindow, fGLContext) != 0) { |
110 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); | 78 report_sdl_error("Failed to make SDL GL context current."); |
111 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaaSampleCount); | 79 this->detach(); |
| 80 return false; |
112 } | 81 } |
113 | 82 |
114 info->fSampleCount = msaaSampleCount; | 83 info->fSampleCount = msaaSampleCount; |
115 info->fStencilBits = 8; | 84 info->fStencilBits = 8; |
116 | 85 |
117 fGLContext = SDL_GL_CreateContext(fWindow); | 86 glViewport(0, 0, SkScalarRoundToInt(this->width()), SkScalarRoundToInt(this-
>height())); |
118 if (!fGLContext) { | |
119 handle_error(); | |
120 return false; | |
121 } | |
122 | |
123 int success = SDL_GL_MakeCurrent(fWindow, fGLContext); | |
124 if (success != 0) { | |
125 handle_error(); | |
126 return false; | |
127 } | |
128 | |
129 glViewport(0, 0, SkScalarFloorToInt(this->width()), SkScalarFloorToInt(this-
>height())); | |
130 glClearColor(1, 1, 1, 1); | |
131 glClearStencil(0); | |
132 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |
133 | |
134 return true; | 87 return true; |
135 } | 88 } |
136 | 89 |
137 void SkOSWindow::present() { | 90 void SkOSWindow::present() { |
| 91 if (!fWindow) { |
| 92 return; |
| 93 } |
138 SDL_GL_SwapWindow(fWindow); | 94 SDL_GL_SwapWindow(fWindow); |
139 } | 95 } |
140 | 96 |
141 bool SkOSWindow::makeFullscreen() { | 97 bool SkOSWindow::makeFullscreen() { |
142 SDL_SetWindowFullscreen(fWindow, SDL_WINDOW_FULLSCREEN); | 98 if (!fWindow) { |
| 99 return false; |
| 100 } |
| 101 SDL_SetWindowFullscreen(fWindow, SDL_WINDOW_FULLSCREEN_DESKTOP); |
143 return true; | 102 return true; |
144 } | 103 } |
145 | 104 |
146 void SkOSWindow::setVsync(bool vsync) { | 105 void SkOSWindow::setVsync(bool vsync) { |
| 106 if (!fWindow) { |
| 107 return; |
| 108 } |
147 SDL_GL_SetSwapInterval(vsync ? 1 : 0); | 109 SDL_GL_SetSwapInterval(vsync ? 1 : 0); |
148 } | 110 } |
149 | 111 |
150 void SkOSWindow::closeWindow() { | 112 void SkOSWindow::closeWindow() { |
151 fQuit = true; | 113 this->destroyWindow(); |
| 114 |
| 115 // Currently closing the window causes the app to quit. |
| 116 SDL_Event event; |
| 117 event.type = SDL_QUIT; |
| 118 SDL_PushEvent(&event); |
152 } | 119 } |
153 | 120 |
154 static SkKey convert_sdlkey_to_skkey(SDL_Keycode src) { | 121 static SkKey convert_sdlkey_to_skkey(SDL_Keycode src) { |
155 switch (src) { | 122 switch (src) { |
156 case SDLK_UP: | 123 case SDLK_UP: |
157 return kUp_SkKey; | 124 return kUp_SkKey; |
158 case SDLK_DOWN: | 125 case SDLK_DOWN: |
159 return kDown_SkKey; | 126 return kDown_SkKey; |
160 case SDLK_LEFT: | 127 case SDLK_LEFT: |
161 return kLeft_SkKey; | 128 return kLeft_SkKey; |
(...skipping 25 matching lines...) Expand all Loading... |
187 return k7_SkKey; | 154 return k7_SkKey; |
188 case SDLK_8: | 155 case SDLK_8: |
189 return k8_SkKey; | 156 return k8_SkKey; |
190 case SDLK_9: | 157 case SDLK_9: |
191 return k9_SkKey; | 158 return k9_SkKey; |
192 default: | 159 default: |
193 return kNONE_SkKey; | 160 return kNONE_SkKey; |
194 } | 161 } |
195 } | 162 } |
196 | 163 |
197 void SkOSWindow::handleEvents() { | 164 void SkOSWindow::createWindow(int msaaSampleCount) { |
198 SkEvent::ServiceQueueTimer(); | 165 if (fWindowMSAASampleCount != msaaSampleCount) { |
199 SkEvent::ProcessEvent(); | 166 this->destroyWindow(); |
200 | 167 } |
201 SDL_Event event; | 168 if (fWindow) { |
202 while(SDL_PollEvent(&event)) { | 169 return; |
203 switch (event.type) { | 170 } |
204 case SDL_MOUSEMOTION: | 171 uint32_t windowFlags = |
| 172 #if defined(SK_BUILD_FOR_ANDROID) |
| 173 SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN_DESKTOP | |
| 174 SDL_WINDOW_ALLOW_HIGHDPI | |
| 175 #endif |
| 176 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; |
| 177 |
| 178 // GL settings are part of SDL_WINDOW_OPENGL window creation arguments. |
| 179 #if defined(SK_BUILD_FOR_ANDROID) |
| 180 // TODO we should try and get a 3.0 context first |
| 181 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
| 182 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); |
| 183 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); |
| 184 #else |
| 185 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); |
| 186 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); |
| 187 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE
); |
| 188 #endif |
| 189 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); |
| 190 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); |
| 191 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); |
| 192 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); |
| 193 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
| 194 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); |
| 195 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); |
| 196 #if defined(SK_BUILD_FOR_UNIX) |
| 197 // Apparently MSAA request matches "slow caveat". Make SDL not set anything
for caveat for MSAA |
| 198 // by setting -1 for ACCELERATED_VISUAL. For non-MSAA, set ACCELERATED_VISUA
L to 1 just for |
| 199 // compatiblity with other platforms. |
| 200 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, msaaSampleCount > 0 ? -1 : 1)
; |
| 201 #else |
| 202 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); |
| 203 #endif |
| 204 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, msaaSampleCount > 0 ? 1 : 0); |
| 205 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaaSampleCount); |
| 206 |
| 207 // This is an approximation for sizing purposes. |
| 208 bool isInitialWindow = this->width() == 0 && this->height() == 0; |
| 209 SkScalar windowWidth = isInitialWindow ? kInitialWindowWidth : this->width()
; |
| 210 SkScalar windowHeight = isInitialWindow ? kInitialWindowHeight : this->heigh
t(); |
| 211 |
| 212 fWindow = SDL_CreateWindow(this->getTitle(), SDL_WINDOWPOS_CENTERED, SDL_WIN
DOWPOS_CENTERED, |
| 213 windowWidth, windowHeight, windowFlags); |
| 214 if (!fWindow) { |
| 215 report_sdl_error("Failed to create SDL window."); |
| 216 return; |
| 217 } |
| 218 fWindowMSAASampleCount = msaaSampleCount; |
| 219 } |
| 220 |
| 221 void SkOSWindow::destroyWindow() { |
| 222 this->detach(); |
| 223 if (fWindow) { |
| 224 SDL_DestroyWindow(fWindow); |
| 225 fWindow = nullptr; |
| 226 fWindowMSAASampleCount = 0; |
| 227 } |
| 228 } |
| 229 |
| 230 bool SkOSWindow::HasDirtyWindows() { |
| 231 if (gCurrentWindow && gCurrentWindow->fWindow) { |
| 232 return gCurrentWindow->isDirty(); |
| 233 } |
| 234 return false; |
| 235 } |
| 236 |
| 237 void SkOSWindow::UpdateDirtyWindows() { |
| 238 if (gCurrentWindow && gCurrentWindow->fWindow) { |
| 239 if (gCurrentWindow->isDirty()) { |
| 240 // This will call present. |
| 241 gCurrentWindow->update(nullptr); |
| 242 } |
| 243 } |
| 244 } |
| 245 |
| 246 void SkOSWindow::HandleEvent(const SDL_Event& event) { |
| 247 switch (event.type) { |
| 248 case SDL_MOUSEMOTION: |
| 249 if (SkOSWindow* window = GetInstanceForWindowID(event.motion.windowI
D)) { |
205 if (event.motion.state == SDL_PRESSED) { | 250 if (event.motion.state == SDL_PRESSED) { |
206 this->handleClick(event.motion.x, event.motion.y, | 251 window->handleClick(event.motion.x, event.motion.y, |
207 SkView::Click::kMoved_State, nullptr); | 252 SkView::Click::kMoved_State, nullptr); |
208 } | 253 } |
209 break; | 254 } |
210 case SDL_MOUSEBUTTONDOWN: | 255 break; |
211 case SDL_MOUSEBUTTONUP: | 256 case SDL_MOUSEBUTTONDOWN: |
212 this->handleClick(event.button.x, event.button.y, | 257 case SDL_MOUSEBUTTONUP: |
213 event.button.state == SDL_PRESSED ? | 258 if (SkOSWindow* window = GetInstanceForWindowID(event.button.windowI
D)) { |
214 SkView::Click::kDown_State : | 259 window->handleClick(event.button.x, event.button.y, |
215 SkView::Click::kUp_State, nullptr); | 260 event.button.state == SDL_PRESSED ? |
216 break; | 261 SkView::Click::kDown_State : |
217 case SDL_KEYDOWN: { | 262 SkView::Click::kUp_State, nullptr); |
| 263 } |
| 264 break; |
| 265 case SDL_KEYDOWN: |
| 266 if (SkOSWindow* window = GetInstanceForWindowID(event.key.windowID))
{ |
218 SDL_Keycode key = event.key.keysym.sym; | 267 SDL_Keycode key = event.key.keysym.sym; |
219 SkKey sk = convert_sdlkey_to_skkey(key); | 268 SkKey sk = convert_sdlkey_to_skkey(key); |
220 if (kNONE_SkKey != sk) { | 269 if (kNONE_SkKey != sk) { |
221 if (event.key.state == SDL_PRESSED) { | 270 if (event.key.state == SDL_PRESSED) { |
222 this->handleKey(sk); | 271 window->handleKey(sk); |
223 } else { | 272 } else { |
224 this->handleKeyUp(sk); | 273 window->handleKeyUp(sk); |
225 } | 274 } |
226 } else if (key == SDLK_ESCAPE) { | 275 } else if (key == SDLK_ESCAPE) { |
227 fQuit = true; | 276 window->closeWindow(); |
228 } | 277 } |
229 break; | 278 } |
230 } | 279 break; |
231 case SDL_TEXTINPUT: { | 280 case SDL_TEXTINPUT: |
| 281 if (SkOSWindow* window = GetInstanceForWindowID(event.text.windowID)
) { |
232 size_t len = strlen(event.text.text); | 282 size_t len = strlen(event.text.text); |
233 for (size_t i = 0; i < len; i++) { | 283 for (size_t i = 0; i < len; i++) { |
234 this->handleChar((SkUnichar)event.text.text[i]); | 284 window->handleChar((SkUnichar)event.text.text[i]); |
235 } | 285 } |
236 break; | 286 } |
237 } | 287 break; |
238 case SDL_QUIT: | 288 case SDL_WINDOWEVENT: |
239 fQuit = true; | 289 switch (event.window.event) { |
240 break; | 290 case SDL_WINDOWEVENT_SHOWN: |
241 default: | 291 // For initialization purposes, we resize upon first show. |
242 break; | 292 // Fallthrough. |
| 293 case SDL_WINDOWEVENT_SIZE_CHANGED: |
| 294 if (SkOSWindow* window = GetInstanceForWindowID(event.window
.windowID)) { |
| 295 int w = 0; |
| 296 int h = 0; |
| 297 SDL_GetWindowSize(window->fWindow, &w, &h); |
| 298 window->resize(w, h); |
| 299 } |
| 300 break; |
| 301 case SDL_WINDOWEVENT_FOCUS_GAINED: |
| 302 if (GetInstanceForWindowID(event.text.windowID)) { |
| 303 SDL_StartTextInput(); |
| 304 } |
| 305 break; |
| 306 default: |
| 307 break; |
| 308 } |
| 309 break; |
| 310 default: |
| 311 break; |
| 312 } |
| 313 } |
| 314 |
| 315 SkMSec gTimerDelay; |
| 316 |
| 317 void SkOSWindow::RunEventLoop() { |
| 318 for (;;) { |
| 319 SkEvent::ServiceQueueTimer(); |
| 320 bool hasMoreSkEvents = SkEvent::ProcessEvent(); |
| 321 |
| 322 SDL_Event event; |
| 323 bool hasSDLEvents = SDL_PollEvent(&event) == 1; |
| 324 |
| 325 // Invalidations do not post to event loop, rather we just go through th
e |
| 326 // windows for each event loop iteration. |
| 327 bool hasDirtyWindows = HasDirtyWindows(); |
| 328 |
| 329 if (!hasSDLEvents && !hasMoreSkEvents && !hasDirtyWindows) { |
| 330 // If there is no SDL events, SkOSWindow updates or SkEvents |
| 331 // to be done, wait for the SDL events. |
| 332 if (gTimerDelay > 0) { |
| 333 hasSDLEvents = SDL_WaitEventTimeout(&event, gTimerDelay) == 1; |
| 334 } else { |
| 335 hasSDLEvents = SDL_WaitEvent(&event) == 1; |
| 336 } |
243 } | 337 } |
244 } | 338 while (hasSDLEvents) { |
245 } | 339 if (event.type == SDL_QUIT) { |
246 | 340 return; |
| 341 } |
| 342 HandleEvent(event); |
| 343 hasSDLEvents = SDL_PollEvent(&event); |
| 344 } |
| 345 UpdateDirtyWindows(); |
| 346 } |
| 347 } |
247 | 348 |
248 void SkOSWindow::onSetTitle(const char title[]) { | 349 void SkOSWindow::onSetTitle(const char title[]) { |
249 SDL_SetWindowTitle(fWindow, title); | 350 if (!fWindow) { |
| 351 return; |
| 352 } |
| 353 this->updateWindowTitle(); |
| 354 } |
| 355 |
| 356 void SkOSWindow::updateWindowTitle() { |
| 357 SDL_SetWindowTitle(fWindow, this->getTitle()); |
250 } | 358 } |
251 ////////////////////////////////////////////////////////////////////////////////
/////// | 359 ////////////////////////////////////////////////////////////////////////////////
/////// |
252 | 360 |
253 void SkEvent::SignalNonEmptyQueue() { | 361 void SkEvent::SignalNonEmptyQueue() { |
254 // nothing to do, since we spin on our event-queue | 362 // nothing to do, since we spin on our event-queue |
255 } | 363 } |
256 | 364 |
257 void SkEvent::SignalQueueTimer(SkMSec delay) { | 365 void SkEvent::SignalQueueTimer(SkMSec delay) { |
258 // just need to record the delay time. We handle waking up for it in | 366 gTimerDelay = delay; |
259 } | |
260 | |
261 void SkOSWindow::onHandleInval(const SkIRect& rect) { | |
262 } | |
263 | |
264 void SkOSWindow::onPDFSaved(const char title[], const char desc[], const char pa
th[]) { | |
265 } | 367 } |
266 | 368 |
267 ////////////////////////////////////////////////////////////////////////////////
////////////// | 369 ////////////////////////////////////////////////////////////////////////////////
////////////// |
268 | 370 |
269 #include "SkApplication.h" | 371 #include "SkApplication.h" |
270 #include "SkEvent.h" | 372 #include "SkEvent.h" |
271 #include "SkWindow.h" | 373 #include "SkWindow.h" |
272 | 374 |
273 #if defined(SK_BUILD_FOR_ANDROID) | 375 #if defined(SK_BUILD_FOR_ANDROID) |
274 int SDL_main(int argc, char** argv) { | 376 int SDL_main(int argc, char** argv) { |
275 #else | 377 #else |
276 int main(int argc, char** argv) { | 378 int main(int argc, char** argv) { |
277 #endif | 379 #endif |
| 380 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { |
| 381 report_sdl_error("Failed to init SDL."); |
| 382 return -1; |
| 383 } |
| 384 |
| 385 application_init(); |
| 386 |
278 SkOSWindow* window = create_sk_window(nullptr, argc, argv); | 387 SkOSWindow* window = create_sk_window(nullptr, argc, argv); |
279 | 388 |
280 // drain any events that occurred before |window| was assigned. | 389 // drain any events that occurred before |window| was assigned. |
281 while (SkEvent::ProcessEvent()); | 390 while (SkEvent::ProcessEvent()); |
282 | 391 |
283 // Start normal Skia sequence | 392 SkOSWindow::RunEventLoop(); |
284 application_init(); | |
285 | |
286 window->loop(); | |
287 | 393 |
288 delete window; | 394 delete window; |
289 application_term(); | 395 application_term(); |
| 396 |
| 397 SDL_Quit(); |
| 398 |
290 return 0; | 399 return 0; |
291 } | 400 } |
OLD | NEW |