1
2 /*
3 * Copyright 2011 Google Inc.
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 <jni.h>
9 #include <sys/time.h>
10 #include <time.h>
11 #include <android/log.h>
12 #include <stdint.h>
13
14 #include "GrContext.h"
15 #include "SkGpuCanvas.h"
16 #include "SkPaint.h"
17 #include "SkString.h"
18 #include "SkTime.h"
19
20 #include "gl/GrGLConfig.h"
21
make_context()22 static GrContext* make_context() {
23 SkDebugf("---- before create\n");
24 GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, 0);
25 SkDebugf("---- after create %p\n", ctx);
26 return ctx;
27 }
28
29 ///////////////////////////////////////////////////////////////////////////////
30
gr_run_unittests()31 void gr_run_unittests() {}
32
33 #include "FlingState.h"
34 #include "SkTouchGesture.h"
35 #include "SkView.h"
36
37 typedef SkView* (*SkViewFactory)();
38
39 // these values must match those in Ganesh.java
40 enum TouchState {
41 kUnknown_TouchState,
42 kDown_TouchState,
43 kMoved_TouchState,
44 kUp_TouchState
45 };
46
47 struct State {
48 State();
49 ~State();
50
countSlidesState51 int countSlides() const { return fFactory.count(); }
52 const char* getSlideTitle(int index) const;
chooseSlideState53 void chooseSlide(int index) {
54 SkDebugf("----- index %d\n", index);
55 if (index < fFactory.count()) {
56 this->setView(fFactory[index]());
57 }
58 }
59
60 void setViewport(int w, int h);
getWidthState61 int getWidth() const { return fViewport.fX; }
getHeightState62 int getHeight() const { return fViewport.fY; }
63
64 void handleTouch(void*, TouchState, float x, float y);
65 void applyMatrix(SkCanvas*);
66
getViewState67 SkView* getView() const { return fView; }
68
69 private:
70 SkView* fView;
71 SkIPoint fViewport;
72
73 SkTouchGesture fGesture;
74
75 SkTDArray<SkViewFactory> fFactory;
76
setViewState77 void setView(SkView* view) {
78 SkSafeUnref(fView);
79 fView = view;
80
81 view->setVisibleP(true);
82 view->setClipToBounds(false);
83 view->setSize(SkIntToScalar(fViewport.fX),
84 SkIntToScalar(fViewport.fY));
85 }
86 };
87
88 ///////////////////////////////////////////////////////////////////////////////
89
90 #include "SampleCode.h"
91
92 SkViewRegister* SkViewRegister::gHead;
SkViewRegister(SkViewFactory fact)93 SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
94 static bool gOnce;
95 if (!gOnce) {
96 gHead = NULL;
97 gOnce = true;
98 }
99
100 fChain = gHead;
101 gHead = this;
102 }
103
104 static const char gCharEvtName[] = "SampleCode_Char_Event";
105 static const char gKeyEvtName[] = "SampleCode_Key_Event";
106 static const char gTitleEvtName[] = "SampleCode_Title_Event";
107 static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
108 static const char gFastTextEvtName[] = "SampleCode_FastText_Event";
109
CharQ(const SkEvent & evt,SkUnichar * outUni)110 bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
111 if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
112 if (outUni) {
113 *outUni = evt.getFast32();
114 }
115 return true;
116 }
117 return false;
118 }
119
KeyQ(const SkEvent & evt,SkKey * outKey)120 bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
121 if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
122 if (outKey) {
123 *outKey = (SkKey)evt.getFast32();
124 }
125 return true;
126 }
127 return false;
128 }
129
TitleQ(const SkEvent & evt)130 bool SampleCode::TitleQ(const SkEvent& evt) {
131 return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
132 }
133
TitleR(SkEvent * evt,const char title[])134 void SampleCode::TitleR(SkEvent* evt, const char title[]) {
135 GrAssert(evt && TitleQ(*evt));
136 evt->setString(gTitleEvtName, title);
137 }
138
PrefSizeQ(const SkEvent & evt)139 bool SampleCode::PrefSizeQ(const SkEvent& evt) {
140 return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
141 }
142
PrefSizeR(SkEvent * evt,SkScalar width,SkScalar height)143 void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
144 GrAssert(evt && PrefSizeQ(*evt));
145 SkScalar size[2];
146 size[0] = width;
147 size[1] = height;
148 evt->setScalars(gPrefSizeEvtName, 2, size);
149 }
150
FastTextQ(const SkEvent & evt)151 bool SampleCode::FastTextQ(const SkEvent& evt) {
152 return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
153 }
154
155 static SkMSec gAnimTime;
156 static SkMSec gAnimTimePrev;
157
GetAnimTime()158 SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
GetAnimTimeDelta()159 SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
GetAnimSecondsDelta()160 SkScalar SampleCode::GetAnimSecondsDelta() {
161 return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
162 }
163
GetAnimScalar(SkScalar speed,SkScalar period)164 SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
165 // since gAnimTime can be up to 32 bits, we can't convert it to a float
166 // or we'll lose the low bits. Hence we use doubles for the intermediate
167 // calculations
168 double seconds = (double)gAnimTime / 1000.0;
169 double value = SkScalarToDouble(speed) * seconds;
170 if (period) {
171 value = ::fmod(value, SkScalarToDouble(period));
172 }
173 return SkDoubleToScalar(value);
174 }
175
drawIntoCanvas(State * state,SkCanvas * canvas)176 static void drawIntoCanvas(State* state, SkCanvas* canvas) {
177 gAnimTime = SkTime::GetMSecs();
178 SkView* view = state->getView();
179 view->draw(canvas);
180 }
181
182 ///////////////////////////////////////////////////////////////////////////////
183
184 static void resetGpuState();
185
State()186 State::State() {
187 fViewport.set(0, 0);
188
189 const SkViewRegister* reg = SkViewRegister::Head();
190 while (reg) {
191 *fFactory.append() = reg->factory();
192 reg = reg->next();
193 }
194
195 SkDebugf("----- %d slides\n", fFactory.count());
196 fView = NULL;
197 this->chooseSlide(0);
198 }
199
~State()200 State::~State() {
201 SkSafeUnref(fView);
202 }
203
setViewport(int w,int h)204 void State::setViewport(int w, int h) {
205 fViewport.set(w, h);
206 if (fView) {
207 fView->setSize(SkIntToScalar(w), SkIntToScalar(h));
208 }
209 resetGpuState();
210 }
211
getSlideTitle(int index) const212 const char* State::getSlideTitle(int index) const {
213 SkEvent evt(gTitleEvtName);
214 evt.setFast32(index);
215 {
216 SkView* view = fFactory[index]();
217 view->doQuery(&evt);
218 view->unref();
219 }
220 return evt.findString(gTitleEvtName);
221 }
222
handleTouch(void * owner,TouchState state,float x,float y)223 void State::handleTouch(void* owner, TouchState state, float x, float y) {
224 switch (state) {
225 case kDown_TouchState:
226 fGesture.touchBegin(owner, x, y);
227 break;
228 case kMoved_TouchState:
229 fGesture.touchMoved(owner, x, y);
230 break;
231 case kUp_TouchState:
232 fGesture.touchEnd(owner);
233 break;
234 }
235 }
236
applyMatrix(SkCanvas * canvas)237 void State::applyMatrix(SkCanvas* canvas) {
238 const SkMatrix& localM = fGesture.localM();
239 if (localM.getType() & SkMatrix::kScale_Mask) {
240 canvas->setExternalMatrix(&localM);
241 }
242 canvas->concat(localM);
243 canvas->concat(fGesture.globalM());
244 }
245
get_state()246 static State* get_state() {
247 static State* gState;
248 if (NULL == gState) {
249 gState = new State;
250 }
251 return gState;
252 }
253
254 ///////////////////////////////////////////////////////////////////////////////
255
256 static GrContext* gContext;
257 static int gWidth;
258 static int gHeight;
259 static float gX, gY;
260
resetGpuState()261 static void resetGpuState() {
262 if (NULL == gContext) {
263 SkDebugf("creating context for first time\n");
264 gContext = make_context();
265 } else {
266 SkDebugf("------ gContext refcnt=%d\n", gContext->refcnt());
267 gContext->abandonAllTextures();
268 gContext->unref();
269 gContext = make_context();
270 }
271 }
272
doDraw()273 static void doDraw() {
274 if (NULL == gContext) {
275 gContext = make_context();
276 }
277
278 State* state = get_state();
279 SkBitmap viewport;
280 viewport.setConfig(SkBitmap::kARGB_8888_Config,
281 state->getWidth(), state->getHeight());
282
283 SkGpuCanvas canvas(gContext);
284
285 canvas.setBitmapDevice(viewport);
286 state->applyMatrix(&canvas);
287
288 drawIntoCanvas(state, &canvas);
289
290 GrGLCheckErr();
291 GrGLClearErr();
292 // gContext->checkError();
293 // gContext->clearError();
294
295 if (true) {
296 static const int FRAME_COUNT = 32;
297 static SkMSec gDuration;
298
299 static SkMSec gNow;
300 static int gFrameCounter;
301 if (++gFrameCounter == FRAME_COUNT) {
302 gFrameCounter = 0;
303 SkMSec now = SkTime::GetMSecs();
304
305 gDuration = now - gNow;
306 gNow = now;
307 }
308
309 int fps = (FRAME_COUNT * 1000) / gDuration;
310 SkString str;
311 str.printf("FPS=%3d MS=%3d", fps, gDuration / FRAME_COUNT);
312
313 SkGpuCanvas c(gContext);
314 c.setBitmapDevice(viewport);
315
316 SkPaint p;
317 p.setAntiAlias(true);
318 SkRect r = { 0, 0, 110, 16 };
319 p.setColor(SK_ColorWHITE);
320 c.drawRect(r, p);
321 p.setColor(SK_ColorBLACK);
322 c.drawText(str.c_str(), str.size(), 4, 12, p);
323 }
324 }
325
326 ///////////////////////////////////////////////////////////////////////////////
327
328 extern "C" {
329 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
330 JNIEnv*, jobject);
331 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
332 jint w, jint h);
333 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject);
334 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
335 jint id, jint type, jfloat x, jfloat y);
336
337 JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject);
338 JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv*, jobject, jint index);
339 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index);
340 }
341
Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(JNIEnv *,jobject)342 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
343 JNIEnv*, jobject) {
344 SkDebugf("------ nativeSurfaceCreated\n");
345 resetGpuState();
346 SkDebugf("------ end nativeSurfaceCreated\n");
347 }
348
Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv *,jobject,jint w,jint h)349 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
350 jint w, jint h) {
351 State* state = get_state();
352 SkDebugf("---- state.setviewport %p %d %d\n", state, w, h);
353 state->setViewport(w, h);
354 SkDebugf("---- end setviewport\n");
355 }
356
Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv *,jobject)357 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject) {
358 doDraw();
359 }
360
361 union IntPtr {
362 jint fInt;
363 void* fPtr;
364 };
int2ptr(jint n)365 static void* int2ptr(jint n) {
366 IntPtr data;
367 data.fInt = n;
368 return data.fPtr;
369 }
370
Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv *,jobject,jint id,jint type,jfloat x,jfloat y)371 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
372 jint id, jint type, jfloat x, jfloat y) {
373 get_state()->handleTouch(int2ptr(id), (TouchState)type, x, y);
374 }
375
376 ////////////
377
Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv *,jobject)378 JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) {
379 return get_state()->countSlides();
380 }
381
Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv * env,jobject,jint index)382 JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv* env, jobject, jint index) {
383 return env->NewStringUTF(get_state()->getSlideTitle(index));
384 }
385
Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv *,jobject,jint index)386 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index) {
387 get_state()->chooseSlide(index);
388 }
389
390
391
392
393
394