• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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