OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2011 Skia | |
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 #include "com_skia_SkiaSampleRenderer.h" | |
9 | |
10 #include "SampleApp.h" | |
11 #include "SkApplication.h" | |
12 #include "SkCanvas.h" | |
13 #include "SkDevice.h" | |
14 #include "SkEvent.h" | |
15 #include "SkWindow.h" | |
16 | |
17 #include <jni.h> | |
18 #include "AndroidKeyToSkKey.h" | |
19 | |
20 | |
21 /////////////////////////////////////////// | |
22 ///////////////// Globals ///////////////// | |
23 /////////////////////////////////////////// | |
24 | |
25 struct ActivityGlue { | |
26 JNIEnv* m_env; | |
27 jweak m_obj; | |
28 jmethodID m_setTitle; | |
29 jmethodID m_setSlideList; | |
30 jmethodID m_addToDownloads; | |
31 ActivityGlue() { | |
32 m_env = NULL; | |
33 m_obj = NULL; | |
34 m_setTitle = NULL; | |
35 m_setSlideList = NULL; | |
36 m_addToDownloads = NULL; | |
37 } | |
38 } gActivityGlue; | |
39 | |
40 struct WindowGlue { | |
41 jweak m_obj; | |
42 jmethodID m_inval; | |
43 jmethodID m_queueSkEvent; | |
44 jmethodID m_startTimer; | |
45 jmethodID m_getMSAASampleCount; | |
46 WindowGlue() { | |
47 m_obj = NULL; | |
48 m_inval = NULL; | |
49 m_queueSkEvent = NULL; | |
50 m_startTimer = NULL; | |
51 m_getMSAASampleCount = NULL; | |
52 } | |
53 } gWindowGlue; | |
54 | |
55 SampleWindow* gWindow; | |
56 | |
57 /////////////////////////////////////////// | |
58 ///////////// SkOSWindow impl ///////////// | |
59 /////////////////////////////////////////// | |
60 | |
61 SkOSWindow::SkOSWindow(void*) : fDestroyRequested(false) { | |
62 } | |
63 | |
64 SkOSWindow::~SkOSWindow() { | |
65 } | |
66 | |
67 bool SkOSWindow::attach(SkBackEndTypes /* attachType */, int /*msaaSampleCount*/
, AttachmentInfo* info) | |
68 { | |
69 JNIEnv* env = gActivityGlue.m_env; | |
70 if (!env || !gWindowGlue.m_getMSAASampleCount || !gWindowGlue.m_obj) { | |
71 return false; | |
72 } | |
73 if (env->IsSameObject(gWindowGlue.m_obj, NULL)) { | |
74 SkDebugf("ERROR: The JNI WeakRef to the Window is invalid"); | |
75 return false; | |
76 } | |
77 info->fSampleCount = env->CallIntMethod(gWindowGlue.m_obj, gWindowGlue.m_get
MSAASampleCount); | |
78 | |
79 // This is the value requested in SkiaSampleView.java. | |
80 info->fStencilBits = 8; | |
81 return true; | |
82 } | |
83 | |
84 void SkOSWindow::detach() { | |
85 } | |
86 | |
87 void SkOSWindow::present() { | |
88 } | |
89 | |
90 void SkOSWindow::closeWindow() { | |
91 } | |
92 | |
93 void SkOSWindow::setVsync(bool) { | |
94 } | |
95 | |
96 void SkOSWindow::onSetTitle(const char title[]) | |
97 { | |
98 JNIEnv* env = gActivityGlue.m_env; | |
99 if (!env) { | |
100 return; | |
101 } | |
102 if (env->IsSameObject(gActivityGlue.m_obj, NULL)) { | |
103 SkDebugf("ERROR: The JNI WeakRef to the Activity is invalid"); | |
104 return; | |
105 } | |
106 | |
107 jstring string = env->NewStringUTF(title); | |
108 env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_setTitle, string); | |
109 env->DeleteLocalRef(string); | |
110 } | |
111 | |
112 void SkOSWindow::onHandleInval(const SkIRect& rect) | |
113 { | |
114 JNIEnv* env = gActivityGlue.m_env; | |
115 if (!env || !gWindowGlue.m_inval || !gWindowGlue.m_obj) { | |
116 return; | |
117 } | |
118 if (env->IsSameObject(gWindowGlue.m_obj, NULL)) { | |
119 SkDebugf("ERROR: The JNI WeakRef to the Window is invalid"); | |
120 return; | |
121 } | |
122 env->CallVoidMethod(gWindowGlue.m_obj, gWindowGlue.m_inval); | |
123 } | |
124 | |
125 void SkOSWindow::onPDFSaved(const char title[], const char desc[], | |
126 const char path[]) | |
127 { | |
128 JNIEnv* env = gActivityGlue.m_env; | |
129 if (!env || !gActivityGlue.m_addToDownloads || !gActivityGlue.m_obj) { | |
130 return; | |
131 } | |
132 if (env->IsSameObject(gActivityGlue.m_obj, NULL)) { | |
133 SkDebugf("ERROR: The JNI WeakRef to the Activity is invalid"); | |
134 return; | |
135 } | |
136 | |
137 jstring jtitle = env->NewStringUTF(title); | |
138 jstring jdesc = env->NewStringUTF(desc); | |
139 jstring jpath = env->NewStringUTF(path); | |
140 | |
141 env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_addToDownloads, | |
142 jtitle, jdesc, jpath); | |
143 | |
144 env->DeleteLocalRef(jtitle); | |
145 env->DeleteLocalRef(jdesc); | |
146 env->DeleteLocalRef(jpath); | |
147 } | |
148 | |
149 /////////////////////////////////////////// | |
150 /////////////// SkEvent impl ////////////// | |
151 /////////////////////////////////////////// | |
152 | |
153 void SkEvent::SignalQueueTimer(SkMSec ms) | |
154 { | |
155 JNIEnv* env = gActivityGlue.m_env; | |
156 if (!env || !gWindowGlue.m_startTimer || !gWindowGlue.m_obj || !ms) { | |
157 return; | |
158 } | |
159 if (env->IsSameObject(gWindowGlue.m_obj, NULL)) { | |
160 SkDebugf("ERROR: The JNI WeakRef to the Window is invalid"); | |
161 return; | |
162 } | |
163 env->CallVoidMethod(gWindowGlue.m_obj, | |
164 gWindowGlue.m_startTimer, ms); | |
165 } | |
166 | |
167 void SkEvent::SignalNonEmptyQueue() | |
168 { | |
169 JNIEnv* env = gActivityGlue.m_env; | |
170 if (!env || !gWindowGlue.m_queueSkEvent || !gWindowGlue.m_obj) { | |
171 return; | |
172 } | |
173 if (env->IsSameObject(gWindowGlue.m_obj, NULL)) { | |
174 SkDebugf("ERROR: The JNI WeakRef to the Window is invalid"); | |
175 return; | |
176 } | |
177 env->CallVoidMethod(gWindowGlue.m_obj, gWindowGlue.m_queueSkEvent); | |
178 } | |
179 | |
180 /////////////////////////////////////////// | |
181 ////////////////// JNI //////////////////// | |
182 /////////////////////////////////////////// | |
183 | |
184 static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], | |
185 const char signature[]) | |
186 { | |
187 jmethodID m = env->GetMethodID(clazz, name, signature); | |
188 if (!m) SkDebugf("Could not find Java method %s\n", name); | |
189 return m; | |
190 } | |
191 | |
192 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_init(JNIEnv* env, | |
193 jobject thiz, jobject jsampleActivity, jstring cmdLineFlags, jint msaaSa
mpleCount) | |
194 { | |
195 // setup jni hooks to the java activity | |
196 gActivityGlue.m_env = env; | |
197 jclass clazz = env->FindClass("com/skia/SkiaSampleActivity"); | |
198 gActivityGlue.m_obj = env->NewWeakGlobalRef(jsampleActivity); | |
199 gActivityGlue.m_setTitle = GetJMethod(env, clazz, "setTitle", "(Ljava/lang/C
harSequence;)V"); | |
200 gActivityGlue.m_setSlideList = GetJMethod(env, clazz, "setSlideList", "([Lja
va/lang/String;)V"); | |
201 gActivityGlue.m_addToDownloads = GetJMethod(env, clazz, "addToDownloads", | |
202 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); | |
203 env->DeleteLocalRef(clazz); | |
204 | |
205 // setup jni hooks to the java renderer | |
206 clazz = env->FindClass("com/skia/SkiaSampleRenderer"); | |
207 gWindowGlue.m_obj = env->NewWeakGlobalRef(thiz); | |
208 gWindowGlue.m_inval = GetJMethod(env, clazz, "requestRender", "()V"); | |
209 gWindowGlue.m_queueSkEvent = GetJMethod(env, clazz, "queueSkEvent", "()V"); | |
210 gWindowGlue.m_startTimer = GetJMethod(env, clazz, "startTimer", "(I)V"); | |
211 gWindowGlue.m_getMSAASampleCount = GetJMethod(env, clazz, "getMSAASampleCoun
t", "()I"); | |
212 env->DeleteLocalRef(clazz); | |
213 | |
214 application_init(); | |
215 | |
216 const char* flags = env->GetStringUTFChars(cmdLineFlags, JNI_FALSE); | |
217 SkTArray<SkString> flagEntries; | |
218 SkStrSplit(flags, " ", &flagEntries); | |
219 | |
220 SkTArray<const char*> args; | |
221 args.push_back("SampleApp"); | |
222 for (int i = 0; i < flagEntries.count(); i++) { | |
223 SkDebugf(flagEntries[i].c_str()); | |
224 args.push_back(flagEntries[i].c_str()); | |
225 } | |
226 | |
227 SkString msaaSampleCountString; | |
228 if (msaaSampleCount > 0) { | |
229 args.push_back("--msaa"); | |
230 msaaSampleCountString.appendS32(static_cast<uint32_t>(msaaSampleCount)); | |
231 args.push_back(msaaSampleCountString.c_str()); | |
232 } | |
233 | |
234 if (gWindow) { | |
235 SkDebugf("The sample window already exists."); | |
236 } else { | |
237 gWindow = new SampleWindow(NULL, args.count(), const_cast<char**>(args.b
egin()), NULL); | |
238 } | |
239 | |
240 // cleanup the command line flags | |
241 env->ReleaseStringUTFChars(cmdLineFlags, flags); | |
242 | |
243 // send the list of slides up to the activity | |
244 const int slideCount = gWindow->sampleCount(); | |
245 jobjectArray slideList = env->NewObjectArray(slideCount, env->FindClass("jav
a/lang/String"), env->NewStringUTF("")); | |
246 for (int i = 0; i < slideCount; i++) { | |
247 jstring slideTitle = env->NewStringUTF(gWindow->getSampleTitle(i).c_str(
)); | |
248 env->SetObjectArrayElement(slideList, i, slideTitle); | |
249 env->DeleteLocalRef(slideTitle); | |
250 } | |
251 env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_setSlideList, slide
List); | |
252 env->DeleteLocalRef(slideList); | |
253 } | |
254 | |
255 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_term(JNIEnv* env, | |
256 jobject thiz) | |
257 { | |
258 delete gWindow; | |
259 gWindow = NULL; | |
260 application_term(); | |
261 if (gWindowGlue.m_obj) { | |
262 env->DeleteWeakGlobalRef(gWindowGlue.m_obj); | |
263 gWindowGlue.m_obj = NULL; | |
264 } | |
265 if (gActivityGlue.m_obj) { | |
266 env->DeleteWeakGlobalRef(gActivityGlue.m_obj); | |
267 gActivityGlue.m_obj = NULL; | |
268 } | |
269 } | |
270 | |
271 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_draw( | |
272 JNIEnv* env, jobject thiz) | |
273 { | |
274 if (!gWindow) return; | |
275 gWindow->update(NULL); | |
276 } | |
277 | |
278 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_updateSize(JNIEnv* env, | |
279 jobject thiz, jint w, jint h) | |
280 { | |
281 gWindow->resize(w, h); | |
282 } | |
283 | |
284 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_handleClick(JNIEnv* env, | |
285 jobject thiz, jint owner, jfloat x, jfloat y, jint jstate) | |
286 { | |
287 SkView::Click::State state; | |
288 switch(jstate) { | |
289 case 0: // MotionEvent.ACTION_DOWN | |
290 state = SkView::Click::kDown_State; | |
291 break; | |
292 case 1: // MotionEvent.ACTION_UP | |
293 case 3: // MotionEvent.ACTION_CANCEL | |
294 state = SkView::Click::kUp_State; | |
295 break; | |
296 case 2: // MotionEvent.ACTION_MOVE | |
297 state = SkView::Click::kMoved_State; | |
298 break; | |
299 default: | |
300 SkDebugf("motion event ignored\n"); | |
301 return; | |
302 } | |
303 gWindow->handleClick(x, y, state, reinterpret_cast<void*>(owner)); | |
304 } | |
305 | |
306 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_nextSample( | |
307 JNIEnv* env, jobject thiz) | |
308 { | |
309 gWindow->nextSample(); | |
310 } | |
311 | |
312 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_previousSample( | |
313 JNIEnv* env, jobject thiz) | |
314 { | |
315 gWindow->previousSample(); | |
316 } | |
317 | |
318 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_goToSample( | |
319 JNIEnv* env, jobject thiz, jint position) | |
320 { | |
321 gWindow->goToSample(position); | |
322 } | |
323 | |
324 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_toggleRenderingMode( | |
325 JNIEnv* env, jobject thiz) | |
326 { | |
327 gWindow->toggleRendering(); | |
328 } | |
329 | |
330 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_showOverview( | |
331 JNIEnv* env, jobject thiz) | |
332 { | |
333 gWindow->showOverview(); | |
334 } | |
335 | |
336 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_toggleSlideshow( | |
337 JNIEnv* env, jobject thiz) | |
338 { | |
339 gWindow->toggleSlideshow(); | |
340 } | |
341 | |
342 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_toggleFPS( | |
343 JNIEnv* env, jobject thiz) | |
344 { | |
345 gWindow->toggleFPS(); | |
346 } | |
347 | |
348 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_toggleTiling( | |
349 JNIEnv* env, jobject thiz) | |
350 { | |
351 gWindow->handleChar('t'); | |
352 } | |
353 | |
354 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_toggleBBox( | |
355 JNIEnv* env, jobject thiz) | |
356 { | |
357 gWindow->handleChar('b'); | |
358 } | |
359 | |
360 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_processSkEvent( | |
361 JNIEnv* env, jobject thiz) | |
362 { | |
363 if (SkEvent::ProcessEvent()) { | |
364 SkEvent::SignalNonEmptyQueue(); | |
365 } | |
366 } | |
367 | |
368 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_serviceQueueTimer( | |
369 JNIEnv* env, jobject thiz) | |
370 { | |
371 SkEvent::ServiceQueueTimer(); | |
372 } | |
373 | |
374 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_saveToPDF( | |
375 JNIEnv* env, jobject thiz) | |
376 { | |
377 gWindow->saveToPdf(); | |
378 } | |
379 | |
380 JNIEXPORT void JNICALL Java_com_skia_SkiaSampleRenderer_postInval( | |
381 JNIEnv* env, jobject thiz) | |
382 { | |
383 gWindow->postInvalDelay(); | |
384 } | |
OLD | NEW |