Port the SampleApp (raster) to Android.

git-svn-id: http://skia.googlecode.com/svn/trunk@1452 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Scroggo 2011-05-31 17:10:21 +00:00
Родитель bbb203c075
Коммит f33d153732
10 изменённых файлов: 576 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,70 @@
######################################
# 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
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 \
$(LOCAL_PATH)/skia_extra/include/views \
$(LOCAL_PATH)/skia_extra/samplecode \
$(LOCAL_PATH)/skia_extra/include/xml \
external/skia/include/gpu \
external/skia/src/core \
external/skia/gpu/include \
frameworks/base/core/jni/android/graphics \
frameworks/base/native/include/android \
$(LOCAL_PATH)/jni
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libskia \
libandroid_runtime \
libGLESv2
LOCAL_STATIC_LIBRARIES := \
libskiagpu
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libskia-sample
LOCAL_SRC_FILES := \
skia_extra/src/ports/SkXMLParser_empty.cpp \
jni/sample-jni.cpp
include $(LOCAL_PATH)/skia_extra/src/views/views_files.mk
LOCAL_SRC_FILES += $(addprefix skia_extra/src/views/, $(SOURCE))
include $(LOCAL_PATH)/skia_extra/src/xml/xml_files.mk
LOCAL_SRC_FILES += $(addprefix skia_extra/src/xml/, $(SOURCE))
include $(LOCAL_PATH)/skia_extra/samplecode/samplecode_files.mk
LOCAL_SRC_FILES += $(addprefix skia_extra/samplecode/, $(SOURCE))
include $(BUILD_SHARED_LIBRARY)

Просмотреть файл

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Skia
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.skia.sampleapp"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="3" />
<application android:label="@string/app_name"
android:debuggable="true">
<activity android:name=".SampleApp"
android:theme="@android:style/Theme.Holo.NoActionBar"
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>

Просмотреть файл

@ -0,0 +1,25 @@
Building the sample app for Android using an Android tree:
Copy this folder into an Android tree in packages/apps. In addition to jni,
res, and src, there needs to be a fourth folder named "skia_extra". This
will include the skia files which are not part of an Android checkout. It
should have three folders: include, samplecode, and src.
skia/trunk/include/views -> skia_extra/include/views
skia/trunk/include/xml -> skia_extra/include/xml
skia/trunk/samplecode -> skia_extra/samplecode
skia/trunk/src/views -> skia_extra/src/views
skia/trunk/src/ports/SkXMLParser_empty.cpp -> skia_extra/src/ports/
skia/trunk/src/xml -> skia_extra/src/xml
skia/trunk/include/utils/android/AndroidKeyToSkKey.h -> jni/
From packages/apps/SampleApp, type "mm" to build, and install the
resulting apk.
(It may be necessary to remove samples that do not build from
skia_extra/samplecode/samplecode_files.mk)
TODO: Instructions for building from SDK/NDK

Просмотреть файл

@ -0,0 +1,208 @@
/*
* Copyright (C) 2011 Skia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <jni.h>
#include "SkCanvas.h"
#include "GraphicsJNI.h"
#include "SkEvent.h"
#include "SkWindow.h"
#include "SkApplication.h"
#include "AndroidKeyToSkKey.h"
///////////////////////////////////////////
///////////////// Globals /////////////////
///////////////////////////////////////////
struct ActivityGlue {
JNIEnv* m_env;
jweak m_obj;
jmethodID m_setTitle;
ActivityGlue() {
m_env = NULL;
m_obj = NULL;
m_setTitle = NULL;
}
} gActivityGlue;
struct WindowGlue {
jweak m_obj;
jmethodID m_inval;
WindowGlue() {
m_obj = NULL;
m_inval = NULL;
}
} gWindowGlue;
SkOSWindow* 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,
rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
}
///////////////////////////////////////////
/////////////// SkEvent impl //////////////
///////////////////////////////////////////
void SkEvent::SignalQueueTimer(SkMSec) {}
void SkEvent::SignalNonEmptyQueue() {}
///////////////////////////////////////////
////////////////// 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_drawToCanvas(
JNIEnv* env, jobject thiz, jobject jcanvas);
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 x, jint y, jint state);
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_createOSWindow(
JNIEnv* env, jobject thiz, jobject jsampleView);
};
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 x, jint 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);
}
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 = create_sk_window(NULL);
// Only using a method on View.
jclass clazz = gActivityGlue.m_env->FindClass("android/view/View");
gWindowGlue.m_obj = gActivityGlue.m_env->NewWeakGlobalRef(jsampleView);
gWindowGlue.m_inval = GetJMethod(gActivityGlue.m_env, clazz, "invalidate",
"(IIII)V");
gActivityGlue.m_env->DeleteLocalRef(clazz);
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_init(JNIEnv* env,
jobject thiz)
{
gActivityGlue.m_env = env;
// Only using a method on Activity.
jclass clazz = env->FindClass("android/app/Activity");
gActivityGlue.m_obj = env->NewWeakGlobalRef(thiz);
gActivityGlue.m_setTitle = GetJMethod(env, clazz, "setTitle",
"(Ljava/lang/CharSequence;)V");
env->DeleteLocalRef(clazz);
application_init();
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_term(JNIEnv* env,
jobject thiz)
{
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;
}
delete gWindow;
gWindow = NULL;
}
JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_drawToCanvas(
JNIEnv* env, jobject thiz, jobject jcanvas)
{
if (!gWindow) return;
gWindow->update(NULL);
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
canvas->drawBitmap(gWindow->getBitmap(), 0, 0);
}

Просмотреть файл

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Skia
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<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>

Просмотреть файл

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Skia
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">SampleApp</string>
</resources>

Просмотреть файл

@ -0,0 +1,114 @@
/*
* Copyright (C) 2011 Skia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.skia.sampleapp;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
public class SampleApp extends Activity
{
private TextView mTitle;
public class SampleView extends View {
public SampleView(Context context) {
super(context);
createOSWindow(this);
}
@Override
protected void onDraw(Canvas canvas) {
drawToCanvas(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
updateSize(w, h);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final int action = event.getAction();
handleClick(x, y, action);
return true;
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
init();
setContentView(R.layout.layout);
mTitle = (TextView) findViewById(R.id.title_view);
LinearLayout holder = (LinearLayout) findViewById(R.id.holder);
View view = new SampleView(this);
holder.addView(view, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
@Override
public void onDestroy()
{
term();
super.onDestroy();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
int uni = event.getUnicodeChar(event.getMetaState());
return handleKeyDown(event.getKeyCode(), uni);
case KeyEvent.ACTION_UP:
return handleKeyUp(event.getKeyCode());
default:
return false;
}
}
@Override
public void setTitle(CharSequence title) {
mTitle.setText(title);
}
private native void drawToCanvas(Canvas canvas);
private native void init();
private native void term();
// Currently depends on init having already been called.
private native void createOSWindow(SampleView view);
private native void updateSize(int w, int h);
private native void handleClick(int x, int y, int state);
private native boolean handleKeyDown(int key, int uni);
private native boolean handleKeyUp(int key);
static {
System.loadLibrary("skia-sample");
}
}

Просмотреть файл

@ -0,0 +1,40 @@
/*
* Copyright (C) 2011 Skia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ANDROID_TO_SKIA_KEYCODES_H
#define _ANDROID_TO_SKIA_KEYCODES_H
#include "keycodes.h"
#include "SkKey.h"
// Convert an Android keycode to an SkKey. This is an incomplete list, only
// including keys used by the sample app.
SkKey AndroidKeycodeToSkKey(int keycode) {
switch (keycode) {
case AKEYCODE_DPAD_LEFT:
return kLeft_SkKey;
case AKEYCODE_DPAD_RIGHT:
return kRight_SkKey;
case AKEYCODE_DPAD_UP:
return kUp_SkKey;
case AKEYCODE_DPAD_DOWN:
return kDown_SkKey;
default:
return kNONE_SkKey;
}
}
#endif

Просмотреть файл

@ -0,0 +1,41 @@
/*
* Copyright (C) 2011 Skia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SkOSWindow_Android_DEFINED
#define SkOSWindow_Android_DEFINED
#include "SkWindow.h"
#include "SkEvent.h"
class SkOSWindow : public SkWindow {
public:
SkOSWindow(void*) {}
~SkOSWindow() {}
bool attachGL() { return false; }
void detachGL() {}
void presentGL() {}
protected:
// overrides from SkWindow
virtual void onHandleInval(const SkIRect&);
virtual void onSetTitle(const char title[]);
private:
typedef SkWindow INHERITED;
};
#endif

Просмотреть файл

@ -111,6 +111,8 @@ private:
#include "SkOSWindow_Mac.h"
#elif defined(SK_BUILD_FOR_WIN)
#include "SkOSWindow_Win.h"
#elif defined(ANDROID)
#include "SkOSWindow_Android.h"
#elif defined(SK_BUILD_FOR_UNIX)
#include "SkOSWindow_Unix.h"
#elif defined(SK_BUILD_FOR_SDL)