Home | History | Annotate | Download | only in gpu
      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 
     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 
     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 
     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 
     69 private:
     70     SkView*     fView;
     71     SkIPoint    fViewport;
     72 
     73     SkTouchGesture fGesture;
     74 
     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 
     92 SkViewRegister* SkViewRegister::gHead;
     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 
    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 
    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 
    130 bool SampleCode::TitleQ(const SkEvent& evt) {
    131     return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
    132 }
    133 
    134 void SampleCode::TitleR(SkEvent* evt, const char title[]) {
    135     GrAssert(evt && TitleQ(*evt));
    136     evt->setString(gTitleEvtName, title);
    137 }
    138 
    139 bool SampleCode::PrefSizeQ(const SkEvent& evt) {
    140     return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
    141 }
    142 
    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 
    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 
    158 SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
    159 SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
    160 SkScalar SampleCode::GetAnimSecondsDelta() {
    161     return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
    162 }
    163 
    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 
    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 
    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 
    200 State::~State() {
    201     SkSafeUnref(fView);
    202 }
    203 
    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 
    212 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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 };
    365 static void* int2ptr(jint n) {
    366     IntPtr data;
    367     data.fInt = n;
    368     return data.fPtr;
    369 }
    370 
    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 
    378 JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) {
    379     return get_state()->countSlides();
    380 }
    381 
    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 
    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