Move the Android sample app into the android repo.

Review URL: http://codereview.appspot.com/5332054

git-svn-id: http://skia.googlecode.com/svn/trunk@2602 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
djsollen@google.com 2011-11-04 13:00:18 +00:00
parent 6850eab42b
commit fad4510d43
12 changed files with 13 additions and 1462 deletions

View File

@ -1,87 +0,0 @@
######################################
# Build the app.
######################################
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
$(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := SampleApp
LOCAL_JNI_SHARED_LIBRARIES := libskia-sample
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
######################################
# Build the shared library.
######################################
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES += \
external/skia/include/core \
external/skia/include/config \
external/skia/include/effects \
external/skia/include/images \
external/skia/include/utils \
external/skia/include/utils/android \
external/skia/include/views \
external/skia/samplecode \
external/skia/include/xml \
external/skia/include/gpu \
external/skia/src/core \
external/skia/gpu/include \
frameworks/base/opengl/include/GLES2 \
external/skia/include/pdf \
$(LOCAL_PATH)/jni
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libskia \
libandroid_runtime \
libGLESv2
LOCAL_STATIC_LIBRARIES := \
libskiagpu
LOCAL_CFLAGS += -DDEFAULT_TO_GPU
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libskia-sample
LOCAL_SRC_FILES := \
../../src/ports/SkXMLParser_empty.cpp \
../../src/pdf/SkPDFCatalog.cpp \
../../src/pdf/SkPDFDevice.cpp \
../../src/pdf/SkPDFDocument.cpp \
../../src/pdf/SkPDFFont.cpp \
../../src/pdf/SkPDFFormXObject.cpp \
../../src/pdf/SkPDFGraphicState.cpp \
../../src/pdf/SkPDFImage.cpp \
../../src/pdf/SkPDFPage.cpp \
../../src/pdf/SkPDFShader.cpp \
../../src/pdf/SkPDFStream.cpp \
../../src/pdf/SkPDFTypes.cpp \
../../src/pdf/SkPDFUtils.cpp \
jni/sample-jni.cpp
include external/skia/src/views/views_files.mk
LOCAL_SRC_FILES += $(addprefix ../../src/views/, $(SOURCE))
include external/skia/src/xml/xml_files.mk
LOCAL_SRC_FILES += $(addprefix ../../src/xml/, $(SOURCE))
include external/skia/samplecode/samplecode_files.mk
LOCAL_SRC_FILES += $(addprefix ../../samplecode/, $(SOURCE))
include $(BUILD_SHARED_LIBRARY)

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2011 Google Inc.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.skia.sampleapp"
android:versionCode="1"
android:versionName="1.0">
<!-- Needed to save a file to the file system. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Needed to add to the download manager. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="3" />
<application android:label="@string/app_name"
android:debuggable="true">
<activity android:name=".SampleApp"
android:theme="@android:style/Theme.Holo.Light"
android:configChanges="orientation|screenSize"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -1,6 +0,0 @@
Building the sample app for Android using an Android tree:
cd into external/skia/android_sample/SampleApp.
Type "mm" to build, and install the resulting apk.
TODO: Instructions for building from SDK/NDK

View File

@ -1,375 +0,0 @@
/*
* Copyright 2011 Skia
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrContext.h"
#include "GrGLInterface.h"
#include "SampleApp.h"
#include "SkApplication.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkEvent.h"
#include "SkGpuCanvas.h"
#include "SkWindow.h"
#include <jni.h>
#include "utils/android/AndroidKeyToSkKey.h"
///////////////////////////////////////////
///////////////// Globals /////////////////
///////////////////////////////////////////
struct ActivityGlue {
JNIEnv* m_env;
jweak m_obj;
jmethodID m_setTitle;
jmethodID m_startTimer;
jmethodID m_addToDownloads;
ActivityGlue() {
m_env = NULL;
m_obj = NULL;
m_setTitle = NULL;
m_startTimer = NULL;
m_addToDownloads = NULL;
}
} gActivityGlue;
struct WindowGlue {
jweak m_obj;
jmethodID m_inval;
jmethodID m_queueSkEvent;
WindowGlue() {
m_obj = NULL;
m_inval = NULL;
m_queueSkEvent = NULL;
}
} gWindowGlue;
SampleWindow* gWindow;
///////////////////////////////////////////
///////////// SkOSWindow impl /////////////
///////////////////////////////////////////
void SkOSWindow::onSetTitle(const char title[])
{
if (gActivityGlue.m_env) {
JNIEnv* env = gActivityGlue.m_env;
jstring string = env->NewStringUTF(title);
env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_setTitle,
string);
env->DeleteLocalRef(string);
}
}
void SkOSWindow::onHandleInval(const SkIRect& rect)
{
if (!gActivityGlue.m_env || !gWindowGlue.m_inval || !gWindowGlue.m_obj) {
return;
}
gActivityGlue.m_env->CallVoidMethod(gWindowGlue.m_obj, gWindowGlue.m_inval);
}
void SkOSWindow::onPDFSaved(const char title[], const char desc[],
const char path[])
{
if (gActivityGlue.m_env) {
JNIEnv* env = gActivityGlue.m_env;
jstring jtitle = env->NewStringUTF(title);
jstring jdesc = env->NewStringUTF(desc);
jstring jpath = env->NewStringUTF(path);
env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_addToDownloads,
jtitle, jdesc, jpath);
env->DeleteLocalRef(jtitle);
env->DeleteLocalRef(jdesc);
env->DeleteLocalRef(jpath);
}
}
///////////////////////////////////////////
/////////////// SkEvent impl //////////////
///////////////////////////////////////////
void SkEvent::SignalQueueTimer(SkMSec ms)
{
if (!gActivityGlue.m_env || !gActivityGlue.m_startTimer
|| !gActivityGlue.m_obj || !ms) {
return;
}
gActivityGlue.m_env->CallVoidMethod(gActivityGlue.m_obj,
gActivityGlue.m_startTimer, ms);
}
void SkEvent::SignalNonEmptyQueue()
{
if (!gActivityGlue.m_env || !gWindowGlue.m_queueSkEvent
|| !gWindowGlue.m_obj) {
return;
}
gActivityGlue.m_env->CallVoidMethod(gWindowGlue.m_obj,
gWindowGlue.m_queueSkEvent);
}
///////////////////////////////////////////
////////////////// JNI ////////////////////
///////////////////////////////////////////
static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[],
const char signature[])
{
jmethodID m = env->GetMethodID(clazz, name, signature);
if (!m) SkDebugf("Could not find Java method %s\n", name);
return m;
}
extern "C" {
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_draw(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_term(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(
JNIEnv* env, jobject thiz, jint w, jint h);
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyDown(
JNIEnv* env, jobject thiz, jint keyCode, jint uni);
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyUp(
JNIEnv* env, jobject thiz, jint keyCode);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_handleClick(
JNIEnv* env, jobject thiz, jint owner, jfloat x, jfloat y, jint state);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
JNIEnv* env, jobject thiz, jobject jsampleView);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_setZoomCenter(
JNIEnv* env, jobject thiz, jfloat x, jfloat y);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_zoom(
JNIEnv* env, jobject thiz, jfloat factor);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_nextSample(
JNIEnv* env, jobject thiz, jboolean fprevious);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleRendering(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleSlideshow(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleFps(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_processSkEvent(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_serviceQueueTimer(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_saveToPdf(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_postInval(
JNIEnv* env, jobject thiz);
};
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyDown(
JNIEnv* env, jobject thiz, jint keyCode, jint uni)
{
bool handled = gWindow->handleKey(AndroidKeycodeToSkKey(keyCode));
handled |= gWindow->handleChar((SkUnichar) uni);
return handled;
}
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyUp(JNIEnv* env,
jobject thiz, jint keyCode)
{
return gWindow->handleKeyUp(AndroidKeycodeToSkKey(keyCode));
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_handleClick(JNIEnv* env,
jobject thiz, jint owner, jfloat x, jfloat y, jint jstate)
{
SkView::Click::State state;
switch(jstate) {
case 0: // MotionEvent.ACTION_DOWN
state = SkView::Click::kDown_State;
break;
case 1: // MotionEvent.ACTION_UP
case 3: // MotionEvent.ACTION_CANCEL
state = SkView::Click::kUp_State;
break;
case 2: // MotionEvent.ACTION_MOVE
state = SkView::Click::kMoved_State;
break;
default:
SkDebugf("motion event ignored\n");
return;
}
gWindow->handleClick(x, y, state, (void*) owner);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(JNIEnv* env,
jobject thiz, jint w, jint h)
{
gWindow->resize(w, h);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
JNIEnv* env, jobject thiz, jobject jsampleView)
{
gWindow = new SampleWindow(NULL);
jclass clazz = gActivityGlue.m_env->FindClass(
"com/skia/sampleapp/SampleView");
gWindowGlue.m_obj = gActivityGlue.m_env->NewWeakGlobalRef(jsampleView);
gWindowGlue.m_inval = GetJMethod(gActivityGlue.m_env, clazz,
"requestRender", "()V");
gWindowGlue.m_queueSkEvent = GetJMethod(gActivityGlue.m_env, clazz,
"queueSkEvent", "()V");
gActivityGlue.m_env->DeleteLocalRef(clazz);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(JNIEnv* env,
jobject thiz)
{
gActivityGlue.m_env = env;
jclass clazz = env->FindClass("com/skia/sampleapp/SampleApp");
gActivityGlue.m_obj = env->NewWeakGlobalRef(thiz);
gActivityGlue.m_setTitle = GetJMethod(env, clazz, "setTitle",
"(Ljava/lang/CharSequence;)V");
gActivityGlue.m_addToDownloads = GetJMethod(env, clazz, "addToDownloads",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
gActivityGlue.m_startTimer = GetJMethod(gActivityGlue.m_env, clazz,
"startTimer", "(I)V");
env->DeleteLocalRef(clazz);
application_init();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_term(JNIEnv* env,
jobject thiz)
{
delete gWindow;
gWindow = NULL;
application_term();
if (gWindowGlue.m_obj) {
env->DeleteWeakGlobalRef(gWindowGlue.m_obj);
gWindowGlue.m_obj = NULL;
}
if (gActivityGlue.m_obj) {
env->DeleteWeakGlobalRef(gActivityGlue.m_obj);
gActivityGlue.m_obj = NULL;
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_draw(
JNIEnv* env, jobject thiz)
{
if (!gWindow) return;
gWindow->update(NULL);
// Copy the bitmap to the screen in raster mode
if (!gWindow->drawsToHardware()) {
SkBitmap bitmap = gWindow->getBitmap();
GrContext* context = gWindow->getGrContext();
if (!context) {
context = GrContext::Create(kOpenGL_Shaders_GrEngine, NULL);
if (!context || !gWindow->setGrContext(context)) {
return;
}
context->unref();
}
GrRenderTarget* renderTarget;
GrPlatformSurfaceDesc desc;
desc.reset();
desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
desc.fWidth = bitmap.width();
desc.fHeight = bitmap.height();
desc.fConfig = kRGBA_8888_GrPixelConfig;
desc.fStencilBits = 8;
GrGLint buffer;
GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer);
desc.fPlatformRenderTarget = buffer;
renderTarget = static_cast<GrRenderTarget*>(
context->createPlatformSurface(desc));
SkGpuCanvas* gpuCanvas = new SkGpuCanvas(context, renderTarget);
SkDevice* device = gpuCanvas->createDevice(SkBitmap::kARGB_8888_Config,
bitmap.width(), bitmap.height(),
false, false);
gpuCanvas->setDevice(device)->unref();
gpuCanvas->drawBitmap(bitmap, 0, 0);
SkSafeUnref(renderTarget);
SkSafeUnref(gpuCanvas);
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_setZoomCenter(
JNIEnv* env, jobject thiz, jfloat x, jfloat y)
{
gWindow->setZoomCenter(x, y);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_zoom(
JNIEnv* env, jobject thiz, jfloat factor)
{
gWindow->changeZoomLevel(factor);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_nextSample(
JNIEnv* env, jobject thiz, jboolean fprevious)
{
if (fprevious) {
gWindow->previousSample();
} else {
gWindow->nextSample();
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleRendering(
JNIEnv* env, jobject thiz)
{
gWindow->toggleRendering();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleSlideshow(
JNIEnv* env, jobject thiz)
{
gWindow->toggleSlideshow();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleFps(
JNIEnv* env, jobject thiz)
{
gWindow->toggleFPS();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_processSkEvent(
JNIEnv* env, jobject thiz)
{
if (SkEvent::ProcessEvent()) {
SkEvent::SignalNonEmptyQueue();
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_serviceQueueTimer(
JNIEnv* env, jobject thiz)
{
SkEvent::ServiceQueueTimer();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_saveToPdf(
JNIEnv* env, jobject thiz)
{
gWindow->saveToPdf();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_postInval(
JNIEnv* env, jobject thiz)
{
gWindow->postInvalDelay();
}

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2011 Google Inc.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/holder"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/title_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>

View File

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2011 Google Inc.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/fps"
android:title="@string/fps"
android:showAsAction="always"
/>
<item
android:id="@+id/toggle_rendering"
android:title="@string/toggle_rendering"
android:showAsAction="always"
/>
<item
android:id="@+id/prev"
android:showAsAction="always"
android:icon="@*android:drawable/ic_btn_find_prev"
/>
<item
android:id="@+id/next"
android:showAsAction="always"
android:icon="@*android:drawable/ic_btn_find_next"
/>
<item
android:id="@+id/overview"
android:title="@string/overview"
/>
<item
android:id="@+id/slideshow"
android:title="@string/slideshow"
/>
<item
android:id="@+id/save_to_pdf"
android:title="@string/save_to_pdf"
/>
</menu>

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2011 Google Inc.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">SampleApp</string>
<string name="overview">Overview</string>
<string name="toggle_rendering">Toggle rendering</string>
<string name="slideshow">Slideshow</string>
<string name="fps">FPS</string>
<string name="file_saved"><xliff:g id="title">%s1</xliff:g> saved!</string>
<string name="failed">PDF creation failed</string>
<string name="save_to_pdf">Save as PDF</string>
</resources>

View File

@ -1,269 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package com.skia.sampleapp;
import android.app.Activity;
import android.app.DownloadManager;
import android.content.Context;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.io.File;
public class SampleApp extends Activity
{
private TextView mTitle;
private SampleView mView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
mTitle = (TextView) findViewById(R.id.title_view);
LinearLayout holder = (LinearLayout) findViewById(R.id.holder);
mView = new SampleView(this);
holder.addView(mView, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
mTitle.setVisibility(View.GONE);
getActionBar().setDisplayShowHomeEnabled(false);
}
@Override
protected void onResume () {
super.onResume();
int width = mView.getWidth();
int height = mView.getHeight();
if (width > 0 && height > 0) {
mView.postInval();
}
}
@Override
public void onDestroy() {
mView.queueEvent(new Runnable() {
@Override
public void run() {
term();
}
});
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sample, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.overview:
mView.queueEvent(new Runnable() {
@Override
public void run() {
handleKeyDown(KeyEvent.KEYCODE_BACK, 0);
}
});
return true;
case R.id.prev:
mView.queueEvent(new Runnable() {
@Override
public void run() {
nextSample(true);
}
});
return true;
case R.id.next:
mView.queueEvent(new Runnable() {
@Override
public void run() {
nextSample(false);
}
});
return true;
case R.id.toggle_rendering:
mView.queueEvent(new Runnable() {
@Override
public void run() {
toggleRendering();
}
});
return true;
case R.id.slideshow:
mView.queueEvent(new Runnable() {
@Override
public void run() {
toggleSlideshow();
}
});
return true;
case R.id.fps:
mView.queueEvent(new Runnable() {
@Override
public void run() {
toggleFps();
}
});
return true;
case R.id.save_to_pdf:
mView.queueEvent(new Runnable() {
@Override
public void run() {
saveToPdf();
}
});
return true;
default:
return false;
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
final int keycode = event.getKeyCode();
if (keycode == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_UP) {
finish();
}
return true;
}
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
final int uni = event.getUnicodeChar(event.getMetaState());
mView.queueEvent(new Runnable() {
@Override
public void run() {
handleKeyDown(keycode, uni);
}
});
return true;
case KeyEvent.ACTION_UP:
mView.queueEvent(new Runnable() {
@Override
public void run() {
handleKeyUp(keycode);
}
});
return true;
default:
return false;
}
}
private static final int SET_TITLE = 1;
private static final int TOAST_DOWNLOAD = 2;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SET_TITLE:
mTitle.setText((String) msg.obj);
SampleApp.this.getActionBar().setSubtitle((String) msg.obj);
break;
case TOAST_DOWNLOAD:
Toast.makeText(SampleApp.this, (String) msg.obj,
Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
@Override
public void setTitle(CharSequence title) {
mHandler.obtainMessage(SET_TITLE, title).sendToTarget();
}
// Called by JNI
@SuppressWarnings("unused")
private void addToDownloads(final String title, final String desc,
final String path) {
File file = new File(path);
final long length = file.exists() ? file.length() : 0;
if (length == 0) {
String failed = getString(R.string.failed);
mHandler.obtainMessage(TOAST_DOWNLOAD, failed).sendToTarget();
return;
}
String toast = getString(R.string.file_saved).replace("%s", title);
mHandler.obtainMessage(TOAST_DOWNLOAD, toast).sendToTarget();
final DownloadManager manager = (DownloadManager) getSystemService(
Context.DOWNLOAD_SERVICE);
new Thread("Add pdf to downloads") {
@Override
public void run() {
manager.addCompletedDownload(title, desc, true,
"application/pdf", path, length, true);
}
}.start();
}
// Called by JNI
@SuppressWarnings("unused")
private void startTimer(int ms) {
// After the delay, queue an event to the Renderer's thread
// to handle the event on the timer queue
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mView.queueEvent(new Runnable() {
@Override
public void run() {
serviceQueueTimer();
}
});
}
}, ms);
}
native void draw();
native void init();
native void term();
// Currently depends on init having already been called.
native void createOSWindow(SampleView view);
native void updateSize(int w, int h);
native void handleClick(int owner, float x, float y, int state);
native boolean handleKeyDown(int key, int uni);
native boolean handleKeyUp(int key);
native void nextSample(boolean previous);
native void toggleRendering();
native void toggleSlideshow();
native void toggleFps();
native void processSkEvent();
native void serviceQueueTimer();
native void saveToPdf();
native void postInval();
static {
System.loadLibrary("skia-sample");
}
}

View File

@ -1,101 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
package com.skia.sampleapp;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.MotionEvent;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class SampleView extends GLSurfaceView {
private final SampleApp mApp;
public SampleView(SampleApp app) {
super(app);
mApp = app;
setEGLContextClientVersion(2);
setEGLConfigChooser(8,8,8,8,0,8);
setRenderer(new SampleView.Renderer());
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
public void postInval() {
queueEvent(new Runnable() {
@Override
public void run() {
mApp.postInval();
}
});
}
// Called by JNI
@SuppressWarnings("unused")
private void queueSkEvent() {
queueEvent(new Runnable() {
@Override
public void run() {
mApp.processSkEvent();
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int count = event.getPointerCount();
for (int i = 0; i < count; i++) {
final float x = event.getX(i);
final float y = event.getY(i);
final int owner = event.getPointerId(i);
int action = event.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_POINTER_UP:
action = MotionEvent.ACTION_UP;
break;
case MotionEvent.ACTION_POINTER_DOWN:
action = MotionEvent.ACTION_DOWN;
break;
default:
break;
}
final int finalAction = action;
queueEvent(new Runnable() {
@Override
public void run() {
mApp.handleClick(owner, x, y, finalAction);
}
});
}
return true;
}
private class Renderer implements GLSurfaceView.Renderer {
public void onDrawFrame(GL10 gl) {
mApp.draw();
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
mApp.updateSize(width, height);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearStencil(0);
gl.glClear(gl.GL_STENCIL_BUFFER_BIT);
mApp.init();
mApp.createOSWindow(SampleView.this);
}
}
}

View File

@ -248,8 +248,6 @@
],
}],
[ 'skia_os == "android"', {
# TODO: This doesn't build properly yet, but it's getting there.
'type': 'shared_library',
'sources!': [
'../samplecode/SampleAnimator.cpp',
'../samplecode/SampleUnitMapper.cpp',
@ -258,9 +256,8 @@
'animator.gyp:animator',
'experimental.gyp:experimental',
],
'sources': [
# TODO add support for the android sample app
# '../samplecode/SampleApp_android.cpp',
'dependencies': [
'android_system.gyp:sampleApp',
],
}],
],

View File

@ -2,151 +2,20 @@
# platform. The OS doesn't provide many stable libraries as part of the
# distribution so we have to build a few of them ourselves.
#
# NOTE: We tried adding the gyp file to the android/ directory at the root of
# We tried adding this gyp file to the android directory at the root of
# the Skia repo, but that resulted in the generated makefiles being created
# outside of the out directory. We may be able to move the bulk of this gyp
# to the /android directory and put a simple shim here, but that has yet to be
# tested.
# outside of the intended output directory. So to avoid this we created a simple
# shim here that includes the android_system.gypi file. The actual dependencies
# are defined and maintained in that gypi file.
#
# Also this assumes that the android directory is a sibling to the directory
# that contains your primary Skia checkout. If it is not then you must manually
# edit the includes below to specify the actual location of the android.gypi.
# This is due to the fact that we cannot use variables in an includes as the
# variable expansion step for gyp happens after the includes are processed.
{
# Define the location of the required Android sources, allowing for override
# in GYP_DEFINES.
#
# These sources are necessary because they must be built using the Android
# toolchain and they are not expected to be present on the host OS.
#
'variables': {
'android_repo%': '../../android',
},
'android_repo%': '<(android_repo)',
'includes': [
'common.gypi',
'../../android/gyp/android.gypi',
],
'targets': [
{
'target_name': 'ft2',
'type': 'static_library',
'sources': [
'<(android_repo)/third_party/externals/freetype/src/base/ftbbox.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftbitmap.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftglyph.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftlcdfil.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftstroke.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftxf86.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftbase.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftsystem.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftinit.c',
'<(android_repo)/third_party/externals/freetype/src/base/ftgasp.c',
# '<(android_repo)/third_party/externals/freetype/src/base/ftfstype.c',
'<(android_repo)/third_party/externals/freetype/src/raster/raster.c',
'<(android_repo)/third_party/externals/freetype/src/sfnt/sfnt.c',
'<(android_repo)/third_party/externals/freetype/src/smooth/smooth.c',
'<(android_repo)/third_party/externals/freetype/src/autofit/autofit.c',
'<(android_repo)/third_party/externals/freetype/src/truetype/truetype.c',
'<(android_repo)/third_party/externals/freetype/src/cff/cff.c',
'<(android_repo)/third_party/externals/freetype/src/psnames/psnames.c',
'<(android_repo)/third_party/externals/freetype/src/pshinter/pshinter.c',
],
'include_dirs': [
'<(android_repo)/third_party/externals/freetype/builds',
'<(android_repo)/third_party/externals/freetype/include',
],
'cflags': [
'-W',
'-Wall',
'-fPIC',
'-DPIC',
'-DDARWIN_NO_CARBON',
'-DFT2_BUILD_LIBRARY',
'-O2',
],
'direct_dependent_settings': {
'include_dirs': [
'<(android_repo)/third_party/externals/freetype/include', # For ft2build.h
],
}
},
{
'target_name': 'expat',
'type': 'static_library',
'sources': [
'<(android_repo)/third_party/externals/expat/lib/xmlparse.c',
'<(android_repo)/third_party/externals/expat/lib/xmlrole.c',
'<(android_repo)/third_party/externals/expat/lib/xmltok.c',
],
'include_dirs': [
'<(android_repo)/third_party/externals/expat',
'<(android_repo)/third_party/externals/expat/lib',
],
'cflags': [
'-Wall',
'-Wmissing-prototypes',
'-Wstrict-prototypes',
'-fexceptions',
'-DHAVE_EXPAT_CONFIG_H',
],
'direct_dependent_settings': {
'include_dirs': [
'<(android_repo)/third_party/externals/expat/lib', # For expat.h
],
}
},
{
'target_name': 'gif',
'type': 'static_library',
'sources': [
'<(android_repo)/third_party/externals/gif/dgif_lib.c',
'<(android_repo)/third_party/externals/gif/gifalloc.c',
'<(android_repo)/third_party/externals/gif/gif_err.c',
],
'include_dirs': [
'<(android_repo)/third_party/externals/gif',
],
'cflags': [
'-Wno-format',
'-DHAVE_CONFIG_H',
],
'direct_dependent_settings': {
'include_dirs': [
'<(android_repo)/third_party/externals/gif',
],
}
},
{
'target_name': 'png',
'type': 'static_library',
'sources': [
'<(android_repo)/third_party/externals/png/png.c',
'<(android_repo)/third_party/externals/png/pngerror.c',
'<(android_repo)/third_party/externals/png/pnggccrd.c',
'<(android_repo)/third_party/externals/png/pngget.c',
'<(android_repo)/third_party/externals/png/pngmem.c',
'<(android_repo)/third_party/externals/png/pngpread.c',
'<(android_repo)/third_party/externals/png/pngread.c',
'<(android_repo)/third_party/externals/png/pngrio.c',
'<(android_repo)/third_party/externals/png/pngrtran.c',
'<(android_repo)/third_party/externals/png/pngrutil.c',
'<(android_repo)/third_party/externals/png/pngset.c',
'<(android_repo)/third_party/externals/png/pngtrans.c',
'<(android_repo)/third_party/externals/png/pngvcrd.c',
'<(android_repo)/third_party/externals/png/pngwio.c',
'<(android_repo)/third_party/externals/png/pngwrite.c',
'<(android_repo)/third_party/externals/png/pngwtran.c',
'<(android_repo)/third_party/externals/png/pngwutil.c',
],
'include_dirs': [
'<(android_repo)/third_party/externals/png',
],
'cflags': [
'-fvisibility=hidden',
],
'direct_dependent_settings': {
'include_dirs': [
'<(android_repo)/third_party/externals/png',
],
}
},
]
}

View File

@ -1,375 +0,0 @@
/*
* Copyright 2011 Skia
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "GrContext.h"
#include "GrGLInterface.h"
#include "SampleApp.h"
#include "SkApplication.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkEvent.h"
#include "SkGpuCanvas.h"
#include "SkWindow.h"
#include <jni.h>
#include "android/AndroidKeyToSkKey.h"
///////////////////////////////////////////
///////////////// Globals /////////////////
///////////////////////////////////////////
struct ActivityGlue {
JNIEnv* m_env;
jweak m_obj;
jmethodID m_setTitle;
jmethodID m_startTimer;
jmethodID m_addToDownloads;
ActivityGlue() {
m_env = NULL;
m_obj = NULL;
m_setTitle = NULL;
m_startTimer = NULL;
m_addToDownloads = NULL;
}
} gActivityGlue;
struct WindowGlue {
jweak m_obj;
jmethodID m_inval;
jmethodID m_queueSkEvent;
WindowGlue() {
m_obj = NULL;
m_inval = NULL;
m_queueSkEvent = NULL;
}
} gWindowGlue;
SampleWindow* gWindow;
///////////////////////////////////////////
///////////// SkOSWindow impl /////////////
///////////////////////////////////////////
void SkOSWindow::onSetTitle(const char title[])
{
if (gActivityGlue.m_env) {
JNIEnv* env = gActivityGlue.m_env;
jstring string = env->NewStringUTF(title);
env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_setTitle,
string);
env->DeleteLocalRef(string);
}
}
void SkOSWindow::onHandleInval(const SkIRect& rect)
{
if (!gActivityGlue.m_env || !gWindowGlue.m_inval || !gWindowGlue.m_obj) {
return;
}
gActivityGlue.m_env->CallVoidMethod(gWindowGlue.m_obj, gWindowGlue.m_inval);
}
void SkOSWindow::onPDFSaved(const char title[], const char desc[],
const char path[])
{
if (gActivityGlue.m_env) {
JNIEnv* env = gActivityGlue.m_env;
jstring jtitle = env->NewStringUTF(title);
jstring jdesc = env->NewStringUTF(desc);
jstring jpath = env->NewStringUTF(path);
env->CallVoidMethod(gActivityGlue.m_obj, gActivityGlue.m_addToDownloads,
jtitle, jdesc, jpath);
env->DeleteLocalRef(jtitle);
env->DeleteLocalRef(jdesc);
env->DeleteLocalRef(jpath);
}
}
///////////////////////////////////////////
/////////////// SkEvent impl //////////////
///////////////////////////////////////////
void SkEvent::SignalQueueTimer(SkMSec ms)
{
if (!gActivityGlue.m_env || !gActivityGlue.m_startTimer
|| !gActivityGlue.m_obj || !ms) {
return;
}
gActivityGlue.m_env->CallVoidMethod(gActivityGlue.m_obj,
gActivityGlue.m_startTimer, ms);
}
void SkEvent::SignalNonEmptyQueue()
{
if (!gActivityGlue.m_env || !gWindowGlue.m_queueSkEvent
|| !gWindowGlue.m_obj) {
return;
}
gActivityGlue.m_env->CallVoidMethod(gWindowGlue.m_obj,
gWindowGlue.m_queueSkEvent);
}
///////////////////////////////////////////
////////////////// JNI ////////////////////
///////////////////////////////////////////
static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[],
const char signature[])
{
jmethodID m = env->GetMethodID(clazz, name, signature);
if (!m) SkDebugf("Could not find Java method %s\n", name);
return m;
}
extern "C" {
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_draw(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_term(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(
JNIEnv* env, jobject thiz, jint w, jint h);
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyDown(
JNIEnv* env, jobject thiz, jint keyCode, jint uni);
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyUp(
JNIEnv* env, jobject thiz, jint keyCode);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_handleClick(
JNIEnv* env, jobject thiz, jint owner, jfloat x, jfloat y, jint state);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
JNIEnv* env, jobject thiz, jobject jsampleView);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_setZoomCenter(
JNIEnv* env, jobject thiz, jfloat x, jfloat y);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_zoom(
JNIEnv* env, jobject thiz, jfloat factor);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_nextSample(
JNIEnv* env, jobject thiz, jboolean fprevious);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleRendering(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleSlideshow(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleFps(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_processSkEvent(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_serviceQueueTimer(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_saveToPdf(
JNIEnv* env, jobject thiz);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_postInval(
JNIEnv* env, jobject thiz);
};
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyDown(
JNIEnv* env, jobject thiz, jint keyCode, jint uni)
{
bool handled = gWindow->handleKey(AndroidKeycodeToSkKey(keyCode));
handled |= gWindow->handleChar((SkUnichar) uni);
return handled;
}
JNIEXPORT bool JNICALL Java_com_skia_sampleapp_SampleApp_handleKeyUp(JNIEnv* env,
jobject thiz, jint keyCode)
{
return gWindow->handleKeyUp(AndroidKeycodeToSkKey(keyCode));
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_handleClick(JNIEnv* env,
jobject thiz, jint owner, jfloat x, jfloat y, jint jstate)
{
SkView::Click::State state;
switch(jstate) {
case 0: // MotionEvent.ACTION_DOWN
state = SkView::Click::kDown_State;
break;
case 1: // MotionEvent.ACTION_UP
case 3: // MotionEvent.ACTION_CANCEL
state = SkView::Click::kUp_State;
break;
case 2: // MotionEvent.ACTION_MOVE
state = SkView::Click::kMoved_State;
break;
default:
SkDebugf("motion event ignored\n");
return;
}
gWindow->handleClick(x, y, state, (void*) owner);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(JNIEnv* env,
jobject thiz, jint w, jint h)
{
gWindow->resize(w, h);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
JNIEnv* env, jobject thiz, jobject jsampleView)
{
gWindow = new SampleWindow(NULL);
jclass clazz = gActivityGlue.m_env->FindClass(
"com/skia/sampleapp/SampleView");
gWindowGlue.m_obj = gActivityGlue.m_env->NewWeakGlobalRef(jsampleView);
gWindowGlue.m_inval = GetJMethod(gActivityGlue.m_env, clazz,
"requestRender", "()V");
gWindowGlue.m_queueSkEvent = GetJMethod(gActivityGlue.m_env, clazz,
"queueSkEvent", "()V");
gActivityGlue.m_env->DeleteLocalRef(clazz);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(JNIEnv* env,
jobject thiz)
{
gActivityGlue.m_env = env;
jclass clazz = env->FindClass("com/skia/sampleapp/SampleApp");
gActivityGlue.m_obj = env->NewWeakGlobalRef(thiz);
gActivityGlue.m_setTitle = GetJMethod(env, clazz, "setTitle",
"(Ljava/lang/CharSequence;)V");
gActivityGlue.m_addToDownloads = GetJMethod(env, clazz, "addToDownloads",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
gActivityGlue.m_startTimer = GetJMethod(gActivityGlue.m_env, clazz,
"startTimer", "(I)V");
env->DeleteLocalRef(clazz);
application_init();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_term(JNIEnv* env,
jobject thiz)
{
delete gWindow;
gWindow = NULL;
application_term();
if (gWindowGlue.m_obj) {
env->DeleteWeakGlobalRef(gWindowGlue.m_obj);
gWindowGlue.m_obj = NULL;
}
if (gActivityGlue.m_obj) {
env->DeleteWeakGlobalRef(gActivityGlue.m_obj);
gActivityGlue.m_obj = NULL;
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_draw(
JNIEnv* env, jobject thiz)
{
if (!gWindow) return;
gWindow->update(NULL);
// Copy the bitmap to the screen in raster mode
if (!gWindow->drawsToHardware()) {
SkBitmap bitmap = gWindow->getBitmap();
GrContext* context = gWindow->getGrContext();
if (!context) {
context = GrContext::Create(kOpenGL_Shaders_GrEngine, NULL);
if (!context || !gWindow->setGrContext(context)) {
return;
}
context->unref();
}
GrRenderTarget* renderTarget;
GrPlatformSurfaceDesc desc;
desc.reset();
desc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
desc.fWidth = bitmap.width();
desc.fHeight = bitmap.height();
desc.fConfig = kRGBA_8888_GrPixelConfig;
desc.fStencilBits = 8;
GrGLint buffer;
GR_GL_GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer);
desc.fPlatformRenderTarget = buffer;
renderTarget = static_cast<GrRenderTarget*>(
context->createPlatformSurface(desc));
SkGpuCanvas* gpuCanvas = new SkGpuCanvas(context, renderTarget);
SkDevice* device = gpuCanvas->createDevice(SkBitmap::kARGB_8888_Config,
bitmap.width(), bitmap.height(),
false, false);
gpuCanvas->setDevice(device)->unref();
gpuCanvas->drawBitmap(bitmap, 0, 0);
SkSafeUnref(renderTarget);
SkSafeUnref(gpuCanvas);
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_setZoomCenter(
JNIEnv* env, jobject thiz, jfloat x, jfloat y)
{
gWindow->setZoomCenter(x, y);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_zoom(
JNIEnv* env, jobject thiz, jfloat factor)
{
gWindow->changeZoomLevel(factor);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_nextSample(
JNIEnv* env, jobject thiz, jboolean fprevious)
{
if (fprevious) {
gWindow->previousSample();
} else {
gWindow->nextSample();
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleRendering(
JNIEnv* env, jobject thiz)
{
gWindow->toggleRendering();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleSlideshow(
JNIEnv* env, jobject thiz)
{
gWindow->toggleSlideshow();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_toggleFps(
JNIEnv* env, jobject thiz)
{
gWindow->toggleFPS();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_processSkEvent(
JNIEnv* env, jobject thiz)
{
if (SkEvent::ProcessEvent()) {
SkEvent::SignalNonEmptyQueue();
}
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_serviceQueueTimer(
JNIEnv* env, jobject thiz)
{
SkEvent::ServiceQueueTimer();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_saveToPdf(
JNIEnv* env, jobject thiz)
{
gWindow->saveToPdf();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_postInval(
JNIEnv* env, jobject thiz)
{
gWindow->postInvalDelay();
}