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