diff options
Diffstat (limited to 'src/gpu/app-android.cpp')
-rw-r--r-- | src/gpu/app-android.cpp | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/src/gpu/app-android.cpp b/src/gpu/app-android.cpp new file mode 100644 index 0000000000..39cca6ce1a --- /dev/null +++ b/src/gpu/app-android.cpp @@ -0,0 +1,394 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include <jni.h> +#include <sys/time.h> +#include <time.h> +#include <android/log.h> +#include <stdint.h> + +#include "GrContext.h" +#include "SkGpuCanvas.h" +#include "SkPaint.h" +#include "SkString.h" +#include "SkTime.h" + +#include "GrGLConfig.h" + +static GrContext* make_context() { + SkDebugf("---- before create\n"); + GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, 0); +// GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, 0); + SkDebugf("---- after create %p\n", ctx); + return ctx; +} + +/////////////////////////////////////////////////////////////////////////////// + +void gr_run_unittests() {} + +#include "FlingState.h" +#include "SkTouchGesture.h" +#include "SkView.h" + +typedef SkView* (*SkViewFactory)(); + +// these values must match those in Ganesh.java +enum TouchState { + kUnknown_TouchState, + kDown_TouchState, + kMoved_TouchState, + kUp_TouchState +}; + +struct State { + State(); + ~State(); + + int countSlides() const { return fFactory.count(); } + const char* getSlideTitle(int index) const; + void chooseSlide(int index) { + SkDebugf("----- index %d\n", index); + if (index < fFactory.count()) { + this->setView(fFactory[index]()); + } + } + + void setViewport(int w, int h); + int getWidth() const { return fViewport.fX; } + int getHeight() const { return fViewport.fY; } + + void handleTouch(void*, TouchState, float x, float y); + void applyMatrix(SkCanvas*); + + SkView* getView() const { return fView; } + +private: + SkView* fView; + SkIPoint fViewport; + + SkTouchGesture fGesture; + + SkTDArray<SkViewFactory> fFactory; + + void setView(SkView* view) { + SkSafeUnref(fView); + fView = view; + + view->setVisibleP(true); + view->setClipToBounds(false); + view->setSize(SkIntToScalar(fViewport.fX), + SkIntToScalar(fViewport.fY)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// + +#include "SampleCode.h" + +SkViewRegister* SkViewRegister::gHead; +SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) { + static bool gOnce; + if (!gOnce) { + gHead = NULL; + gOnce = true; + } + + fChain = gHead; + gHead = this; +} + +static const char gCharEvtName[] = "SampleCode_Char_Event"; +static const char gKeyEvtName[] = "SampleCode_Key_Event"; +static const char gTitleEvtName[] = "SampleCode_Title_Event"; +static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event"; +static const char gFastTextEvtName[] = "SampleCode_FastText_Event"; + +bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) { + if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) { + if (outUni) { + *outUni = evt.getFast32(); + } + return true; + } + return false; +} + +bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) { + if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) { + if (outKey) { + *outKey = (SkKey)evt.getFast32(); + } + return true; + } + return false; +} + +bool SampleCode::TitleQ(const SkEvent& evt) { + return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1); +} + +void SampleCode::TitleR(SkEvent* evt, const char title[]) { + GrAssert(evt && TitleQ(*evt)); + evt->setString(gTitleEvtName, title); +} + +bool SampleCode::PrefSizeQ(const SkEvent& evt) { + return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1); +} + +void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) { + GrAssert(evt && PrefSizeQ(*evt)); + SkScalar size[2]; + size[0] = width; + size[1] = height; + evt->setScalars(gPrefSizeEvtName, 2, size); +} + +bool SampleCode::FastTextQ(const SkEvent& evt) { + return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1); +} + +static SkMSec gAnimTime; +static SkMSec gAnimTimePrev; + +SkMSec SampleCode::GetAnimTime() { return gAnimTime; } +SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; } +SkScalar SampleCode::GetAnimSecondsDelta() { + return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0); +} + +SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) { + // since gAnimTime can be up to 32 bits, we can't convert it to a float + // or we'll lose the low bits. Hence we use doubles for the intermediate + // calculations + double seconds = (double)gAnimTime / 1000.0; + double value = SkScalarToDouble(speed) * seconds; + if (period) { + value = ::fmod(value, SkScalarToDouble(period)); + } + return SkDoubleToScalar(value); +} + +static void drawIntoCanvas(State* state, SkCanvas* canvas) { + gAnimTime = SkTime::GetMSecs(); + SkView* view = state->getView(); + view->draw(canvas); +} + +/////////////////////////////////////////////////////////////////////////////// + +static void resetGpuState(); + +State::State() { + fViewport.set(0, 0); + + const SkViewRegister* reg = SkViewRegister::Head(); + while (reg) { + *fFactory.append() = reg->factory(); + reg = reg->next(); + } + + SkDebugf("----- %d slides\n", fFactory.count()); + fView = NULL; + this->chooseSlide(0); +} + +State::~State() { + SkSafeUnref(fView); +} + +void State::setViewport(int w, int h) { + fViewport.set(w, h); + if (fView) { + fView->setSize(SkIntToScalar(w), SkIntToScalar(h)); + } + resetGpuState(); +} + +const char* State::getSlideTitle(int index) const { + SkEvent evt(gTitleEvtName); + evt.setFast32(index); + { + SkView* view = fFactory[index](); + view->doQuery(&evt); + view->unref(); + } + return evt.findString(gTitleEvtName); +} + +void State::handleTouch(void* owner, TouchState state, float x, float y) { + switch (state) { + case kDown_TouchState: + fGesture.touchBegin(owner, x, y); + break; + case kMoved_TouchState: + fGesture.touchMoved(owner, x, y); + break; + case kUp_TouchState: + fGesture.touchEnd(owner); + break; + } +} + +void State::applyMatrix(SkCanvas* canvas) { + const SkMatrix& localM = fGesture.localM(); + if (localM.getType() & SkMatrix::kScale_Mask) { + canvas->setExternalMatrix(&localM); + } + canvas->concat(localM); + canvas->concat(fGesture.globalM()); +} + +static State* get_state() { + static State* gState; + if (NULL == gState) { + gState = new State; + } + return gState; +} + +/////////////////////////////////////////////////////////////////////////////// + +static GrContext* gContext; +static int gWidth; +static int gHeight; +static float gX, gY; + +static void resetGpuState() { + if (NULL == gContext) { + SkDebugf("creating context for first time\n"); + gContext = make_context(); + } else { + SkDebugf("------ gContext refcnt=%d\n", gContext->refcnt()); + gContext->abandonAllTextures(); + gContext->unref(); + gContext = make_context(); + } +} + +static void doDraw() { + if (NULL == gContext) { + gContext = make_context(); + } + + State* state = get_state(); + SkBitmap viewport; + viewport.setConfig(SkBitmap::kARGB_8888_Config, + state->getWidth(), state->getHeight()); + + SkGpuCanvas canvas(gContext); + + canvas.setBitmapDevice(viewport); + state->applyMatrix(&canvas); + + drawIntoCanvas(state, &canvas); + + GrGLCheckErr(); + GrGLClearErr(); +// gContext->checkError(); +// gContext->clearError(); + + if (true) { + static const int FRAME_COUNT = 32; + static SkMSec gDuration; + + static SkMSec gNow; + static int gFrameCounter; + if (++gFrameCounter == FRAME_COUNT) { + gFrameCounter = 0; + SkMSec now = SkTime::GetMSecs(); + + gDuration = now - gNow; + gNow = now; + } + + int fps = (FRAME_COUNT * 1000) / gDuration; + SkString str; + str.printf("FPS=%3d MS=%3d", fps, gDuration / FRAME_COUNT); + + SkGpuCanvas c(gContext); + c.setBitmapDevice(viewport); + + SkPaint p; + p.setAntiAlias(true); + SkRect r = { 0, 0, 110, 16 }; + p.setColor(SK_ColorWHITE); + c.drawRect(r, p); + p.setColor(SK_ColorBLACK); + c.drawText(str.c_str(), str.size(), 4, 12, p); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" { + JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated( + JNIEnv*, jobject); + JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject, + jint w, jint h); + JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject); + JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject, + jint id, jint type, jfloat x, jfloat y); + + JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject); + JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv*, jobject, jint index); + JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index); +} + +JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated( + JNIEnv*, jobject) { + SkDebugf("------ nativeSurfaceCreated\n"); + resetGpuState(); + SkDebugf("------ end nativeSurfaceCreated\n"); +} + +JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject, + jint w, jint h) { + State* state = get_state(); + SkDebugf("---- state.setviewport %p %d %d\n", state, w, h); + state->setViewport(w, h); + SkDebugf("---- end setviewport\n"); +} + +JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject) { + doDraw(); +} + +union IntPtr { + jint fInt; + void* fPtr; +}; +static void* int2ptr(jint n) { + IntPtr data; + data.fInt = n; + return data.fPtr; +} + +JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject, + jint id, jint type, jfloat x, jfloat y) { + get_state()->handleTouch(int2ptr(id), (TouchState)type, x, y); +} + +//////////// + +JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) { + return get_state()->countSlides(); +} + +JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv* env, jobject, jint index) { + return env->NewStringUTF(get_state()->getSlideTitle(index)); +} + +JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index) { + get_state()->chooseSlide(index); +} + + + + + |