blob: 2dad1f902ebc7f5be0af43fd05db298b4e12cbf2 [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
tomhudson@google.com02f90e82012-02-14 15:43:01 +000020#include "gl/GrGLConfig.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000021
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);
reed@google.comac10a2d2010-12-22 21:39:39 +000025 SkDebugf("---- after create %p\n", ctx);
26 return ctx;
27}
28
29///////////////////////////////////////////////////////////////////////////////
30
31void gr_run_unittests() {}
32
33#include "FlingState.h"
Scroggob0921402011-06-17 15:17:07 +000034#include "SkTouchGesture.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000035#include "SkView.h"
36
37typedef SkView* (*SkViewFactory)();
38
39// these values must match those in Ganesh.java
40enum TouchState {
41 kUnknown_TouchState,
42 kDown_TouchState,
43 kMoved_TouchState,
44 kUp_TouchState
45};
46
47struct State {
48 State();
49 ~State();
50
51 int countSlides() const { return fFactory.count(); }
52 const char* getSlideTitle(int index) const;
53 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);
61 int getWidth() const { return fViewport.fX; }
62 int getHeight() const { return fViewport.fY; }
63
64 void handleTouch(void*, TouchState, float x, float y);
65 void applyMatrix(SkCanvas*);
66
67 SkView* getView() const { return fView; }
68
69private:
70 SkView* fView;
71 SkIPoint fViewport;
72
Scroggob0921402011-06-17 15:17:07 +000073 SkTouchGesture fGesture;
reed@google.comac10a2d2010-12-22 21:39:39 +000074
75 SkTDArray<SkViewFactory> fFactory;
76
77 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
92SkViewRegister* SkViewRegister::gHead;
93SkViewRegister::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
104static const char gCharEvtName[] = "SampleCode_Char_Event";
105static const char gKeyEvtName[] = "SampleCode_Key_Event";
106static const char gTitleEvtName[] = "SampleCode_Title_Event";
107static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
108static const char gFastTextEvtName[] = "SampleCode_FastText_Event";
109
110bool 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
120bool 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
130bool SampleCode::TitleQ(const SkEvent& evt) {
131 return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
132}
133
134void SampleCode::TitleR(SkEvent* evt, const char title[]) {
135 GrAssert(evt && TitleQ(*evt));
136 evt->setString(gTitleEvtName, title);
137}
138
139bool SampleCode::PrefSizeQ(const SkEvent& evt) {
140 return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
141}
142
143void 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
151bool SampleCode::FastTextQ(const SkEvent& evt) {
152 return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
153}
154
155static SkMSec gAnimTime;
156static SkMSec gAnimTimePrev;
157
158SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
159SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
160SkScalar SampleCode::GetAnimSecondsDelta() {
161 return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
162}
163
164SkScalar 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
176static void drawIntoCanvas(State* state, SkCanvas* canvas) {
177 gAnimTime = SkTime::GetMSecs();
178 SkView* view = state->getView();
179 view->draw(canvas);
180}
181
182///////////////////////////////////////////////////////////////////////////////
183
184static void resetGpuState();
185
186State::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
200State::~State() {
201 SkSafeUnref(fView);
202}
203
204void 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
212const 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
223void 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
237void 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
246static State* get_state() {
247 static State* gState;
248 if (NULL == gState) {
249 gState = new State;
250 }
251 return gState;
252}
253
254///////////////////////////////////////////////////////////////////////////////
255
256static GrContext* gContext;
257static int gWidth;
258static int gHeight;
259static float gX, gY;
260
261static 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
273static 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
328extern "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
342JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
343 JNIEnv*, jobject) {
344 SkDebugf("------ nativeSurfaceCreated\n");
345 resetGpuState();
346 SkDebugf("------ end nativeSurfaceCreated\n");
347}
348
349JNIEXPORT 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
357JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject) {
358 doDraw();
359}
360
361union IntPtr {
362 jint fInt;
363 void* fPtr;
364};
365static void* int2ptr(jint n) {
366 IntPtr data;
367 data.fInt = n;
368 return data.fPtr;
369}
370
371JNIEXPORT 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
378JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) {
379 return get_state()->countSlides();
380}
381
382JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv* env, jobject, jint index) {
383 return env->NewStringUTF(get_state()->getSlideTitle(index));
384}
385
386JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index) {
387 get_state()->chooseSlide(index);
388}
389
390
391
392
393