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