Home | History | Annotate | Download | only in src
      1 #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 
     15 static GrContext* make_context() {
     16     SkDebugf("---- before create\n");
     17     GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, 0);
     18 //    GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, 0);
     19     SkDebugf("---- after create %p\n", ctx);
     20     return ctx;
     21 }
     22 
     23 ///////////////////////////////////////////////////////////////////////////////
     24 
     25 void gr_run_unittests() {}
     26 
     27 #include "FlingState.h"
     28 #include "GrTouchGesture.h"
     29 #include "SkView.h"
     30 
     31 typedef SkView* (*SkViewFactory)();
     32 
     33 // these values must match those in Ganesh.java
     34 enum TouchState {
     35     kUnknown_TouchState,
     36     kDown_TouchState,
     37     kMoved_TouchState,
     38     kUp_TouchState
     39 };
     40 
     41 struct 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 
     63 private:
     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 
     86 SkViewRegister* SkViewRegister::gHead;
     87 SkViewRegister::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 
     98 static const char gCharEvtName[] = "SampleCode_Char_Event";
     99 static const char gKeyEvtName[] = "SampleCode_Key_Event";
    100 static const char gTitleEvtName[] = "SampleCode_Title_Event";
    101 static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
    102 static const char gFastTextEvtName[] = "SampleCode_FastText_Event";
    103 
    104 bool 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 
    114 bool 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 
    124 bool SampleCode::TitleQ(const SkEvent& evt) {
    125     return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
    126 }
    127 
    128 void SampleCode::TitleR(SkEvent* evt, const char title[]) {
    129     GrAssert(evt && TitleQ(*evt));
    130     evt->setString(gTitleEvtName, title);
    131 }
    132 
    133 bool SampleCode::PrefSizeQ(const SkEvent& evt) {
    134     return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
    135 }
    136 
    137 void 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 
    145 bool SampleCode::FastTextQ(const SkEvent& evt) {
    146     return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
    147 }
    148 
    149 static SkMSec gAnimTime;
    150 static SkMSec gAnimTimePrev;
    151 
    152 SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
    153 SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
    154 SkScalar SampleCode::GetAnimSecondsDelta() {
    155     return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
    156 }
    157 
    158 SkScalar 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 
    170 static void drawIntoCanvas(State* state, SkCanvas* canvas) {
    171     gAnimTime = SkTime::GetMSecs();
    172     SkView* view = state->getView();
    173     view->draw(canvas);
    174 }
    175 
    176 ///////////////////////////////////////////////////////////////////////////////
    177 
    178 static void resetGpuState();
    179 
    180 State::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 
    194 State::~State() {
    195     SkSafeUnref(fView);
    196 }
    197 
    198 void 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 
    206 const 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 
    217 void 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 
    231 void 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 
    240 static State* get_state() {
    241     static State* gState;
    242     if (NULL == gState) {
    243         gState = new State;
    244     }
    245     return gState;
    246 }
    247 
    248 ///////////////////////////////////////////////////////////////////////////////
    249 
    250 static GrContext* gContext;
    251 static int gWidth;
    252 static int gHeight;
    253 static float gX, gY;
    254 
    255 static 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 
    267 static 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 
    322 extern "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 
    336 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
    337                                                             JNIEnv*, jobject) {
    338     SkDebugf("------ nativeSurfaceCreated\n");
    339     resetGpuState();
    340     SkDebugf("------ end nativeSurfaceCreated\n");
    341 }
    342 
    343 JNIEXPORT 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 
    351 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject) {
    352     doDraw();
    353 }
    354 
    355 union IntPtr {
    356     jint    fInt;
    357     void*   fPtr;
    358 };
    359 static void* int2ptr(jint n) {
    360     IntPtr data;
    361     data.fInt = n;
    362     return data.fPtr;
    363 }
    364 
    365 JNIEXPORT 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 
    372 JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) {
    373     return get_state()->countSlides();
    374 }
    375 
    376 JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv* env, jobject, jint index) {
    377     return env->NewStringUTF(get_state()->getSlideTitle(index));
    378 }
    379 
    380 JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index) {
    381     get_state()->chooseSlide(index);
    382 }
    383 
    384 
    385 
    386 
    387 
    388