From cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fc Mon Sep 17 00:00:00 2001 From: John Reck Date: Tue, 5 Nov 2013 13:27:50 -0800 Subject: RenderThread work Hacky prototype needs a private API to enable Change-Id: I21e0ddf3cdbd38a4036354b5d6012449e1a34849 --- tests/RenderThreadTest/Android.mk | 18 +++ tests/RenderThreadTest/AndroidManifest.xml | 29 ++++ .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 9397 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 5237 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 14383 bytes .../res/drawable-xhdpi/starry_night_bg.jpg | Bin 0 -> 561519 bytes .../RenderThreadTest/res/layout/activity_main.xml | 12 ++ tests/RenderThreadTest/res/layout/activity_sub.xml | 39 +++++ tests/RenderThreadTest/res/layout/item_layout.xml | 12 ++ tests/RenderThreadTest/res/values/strings.xml | 8 ++ tests/RenderThreadTest/res/values/styles.xml | 11 ++ .../src/com/example/renderthread/MainActivity.java | 158 +++++++++++++++++++++ .../src/com/example/renderthread/SubActivity.java | 60 ++++++++ 13 files changed, 347 insertions(+) create mode 100644 tests/RenderThreadTest/Android.mk create mode 100644 tests/RenderThreadTest/AndroidManifest.xml create mode 100644 tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png create mode 100644 tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png create mode 100644 tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png create mode 100644 tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg create mode 100644 tests/RenderThreadTest/res/layout/activity_main.xml create mode 100644 tests/RenderThreadTest/res/layout/activity_sub.xml create mode 100644 tests/RenderThreadTest/res/layout/item_layout.xml create mode 100644 tests/RenderThreadTest/res/values/strings.xml create mode 100644 tests/RenderThreadTest/res/values/styles.xml create mode 100644 tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java create mode 100644 tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java (limited to 'tests/RenderThreadTest') diff --git a/tests/RenderThreadTest/Android.mk b/tests/RenderThreadTest/Android.mk new file mode 100644 index 0000000..bdcba2e --- /dev/null +++ b/tests/RenderThreadTest/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +# Only compile source java files in this apk. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := RenderThreadTest + +LOCAL_STATIC_JAVA_LIBRARIES += android-common + +LOCAL_PROGUARD_ENABLED := disabled + +include $(BUILD_PACKAGE) + +# Use the following include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/RenderThreadTest/AndroidManifest.xml b/tests/RenderThreadTest/AndroidManifest.xml new file mode 100644 index 0000000..c76cfce --- /dev/null +++ b/tests/RenderThreadTest/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png differ diff --git a/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png differ diff --git a/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png differ diff --git a/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg new file mode 100644 index 0000000..755232d Binary files /dev/null and b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg differ diff --git a/tests/RenderThreadTest/res/layout/activity_main.xml b/tests/RenderThreadTest/res/layout/activity_main.xml new file mode 100644 index 0000000..1fd5459 --- /dev/null +++ b/tests/RenderThreadTest/res/layout/activity_main.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/tests/RenderThreadTest/res/layout/activity_sub.xml b/tests/RenderThreadTest/res/layout/activity_sub.xml new file mode 100644 index 0000000..713cee4 --- /dev/null +++ b/tests/RenderThreadTest/res/layout/activity_sub.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/RenderThreadTest/res/layout/item_layout.xml b/tests/RenderThreadTest/res/layout/item_layout.xml new file mode 100644 index 0000000..5bdb1ac --- /dev/null +++ b/tests/RenderThreadTest/res/layout/item_layout.xml @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/tests/RenderThreadTest/res/values/strings.xml b/tests/RenderThreadTest/res/values/strings.xml new file mode 100644 index 0000000..f782e98 --- /dev/null +++ b/tests/RenderThreadTest/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + Render Thread + Settings + Hello world! + + diff --git a/tests/RenderThreadTest/res/values/styles.xml b/tests/RenderThreadTest/res/values/styles.xml new file mode 100644 index 0000000..f6b5d6a --- /dev/null +++ b/tests/RenderThreadTest/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java new file mode 100644 index 0000000..a39aba8 --- /dev/null +++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java @@ -0,0 +1,158 @@ + +package com.example.renderthread; + +import android.animation.TimeInterpolator; +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.SystemClock; +import android.view.DisplayList; +import android.view.HardwareRenderer; +import android.view.ThreadedRenderer; +import android.view.View; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ListView; +import android.widget.SimpleAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class MainActivity extends Activity implements OnItemClickListener { + + static final int DURATION = 400; + + static final String KEY_NAME = "name"; + static final String KEY_CLASS = "clazz"; + + static Map make(String name) { + Map ret = new HashMap(); + ret.put(KEY_NAME, name); + return ret; + } + + @SuppressWarnings("serial") + static final ArrayList> SAMPLES = new ArrayList>() {{ + for (int i = 1; i < 25; i++) { + add(make("List Item: " + i)); + } + }}; + + Handler mHandler = new Handler(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + HardwareRenderer.sUseRenderThread = true; + setContentView(R.layout.activity_main); + ListView lv = (ListView) findViewById(android.R.id.list); + lv.setDrawSelectorOnTop(true); + lv.setAdapter(new SimpleAdapter(this, SAMPLES, + R.layout.item_layout, new String[] { KEY_NAME }, + new int[] { android.R.id.text1 })); + lv.setOnItemClickListener(this); + getActionBar().setTitle("MainActivity"); + } + + @Override + protected void onResume() { + super.onResume(); + ListView lv = (ListView) findViewById(android.R.id.list); + for (int i = 0; i < lv.getChildCount(); i++) { + lv.getChildAt(i).animate().translationY(0).setDuration(DURATION); + } + } + + private static class DisplayListAnimator { + private static final TimeInterpolator sDefaultInterpolator = + new AccelerateDecelerateInterpolator(); + + DisplayList mDisplayList; + float mFromValue; + float mDelta; + long mDuration = DURATION * 2; + long mStartTime; + + DisplayListAnimator(View view, float translateXBy) { + mDelta = translateXBy; + mFromValue = view.getTranslationY(); + mDisplayList = view.getDisplayList(); + } + + boolean animate(long currentTime) { + if (mStartTime == 0) mStartTime = currentTime; + + float fraction = (float)(currentTime - mStartTime) / mDuration; + if (fraction > 1) { + return false; + } + fraction = sDefaultInterpolator.getInterpolation(fraction); + float translation = mFromValue + (mDelta * fraction); + mDisplayList.setTranslationY(translation); + return fraction < 1f; + } + } + + private static class AnimationExecutor implements Runnable { + DisplayListAnimator[] mAnimations; + ThreadedRenderer mRenderer; + + AnimationExecutor(ThreadedRenderer renderer, DisplayListAnimator[] animations) { + mRenderer = renderer; + mAnimations = animations; + ThreadedRenderer.postToRenderThread(this); + } + + @Override + public void run() { + boolean hasMore = false; + long now = SystemClock.uptimeMillis(); + for (DisplayListAnimator animator : mAnimations) { + hasMore |= animator.animate(now); + } + mRenderer.repeatLastDraw(); + if (hasMore) { + ThreadedRenderer.postToRenderThread(this); + } + } + + } + + @Override + public void onItemClick(final AdapterView adapterView, View clickedView, + int clickedPosition, long clickedId) { + int topPosition = adapterView.getFirstVisiblePosition(); + int dy = adapterView.getHeight(); + final DisplayListAnimator[] animators = new DisplayListAnimator[adapterView.getChildCount()]; + for (int i = 0; i < adapterView.getChildCount(); i++) { + int pos = topPosition + i; + View child = adapterView.getChildAt(i); + float delta = (pos - clickedPosition) * 1.1f; + if (delta == 0) delta = -1; + animators[i] = new DisplayListAnimator(child, dy * delta); + } + adapterView.invalidate(); + adapterView.post(new Runnable() { + + @Override + public void run() { + new AnimationExecutor((ThreadedRenderer) adapterView.getHardwareRenderer(), animators); + } + }); + //mHandler.postDelayed(mLaunchActivity, (long) (DURATION * .4)); + mLaunchActivity.run(); + } + + private Runnable mLaunchActivity = new Runnable() { + + @Override + public void run() { + startActivity(new Intent(MainActivity.this, SubActivity.class)); + overridePendingTransition(0, 0); + } + }; + +} diff --git a/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java new file mode 100644 index 0000000..892cbae --- /dev/null +++ b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * 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.example.renderthread; + +import android.app.Activity; +import android.os.Bundle; +import android.os.Process; +import android.os.SystemClock; +import android.view.View; +import android.view.ViewGroup; + +public class SubActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + long before = SystemClock.currentThreadTimeMillis(); + setContentView(R.layout.activity_sub); + getActionBar().setTitle("SubActivity"); + // Simulate being a real app! + while (SystemClock.currentThreadTimeMillis() - before < 100) { + View v = new View(this, null); + } + } + + @Override + protected void onResume() { + super.onResume(); + ViewGroup container = (ViewGroup) findViewById(R.id.my_container); + int dx = getWindowManager().getDefaultDisplay().getWidth(); + for (int i = 0; i < container.getChildCount(); i++) { + View child = container.getChildAt(i); + int dir = child.getId() == R.id.from_left ? 1 : -1; + child.setTranslationX(dx * dir); + child.animate().translationX(0).setDuration(MainActivity.DURATION); + } + View bg = findViewById(R.id.bg_container); + bg.setAlpha(0f); + bg.animate().alpha(1f).setDuration(MainActivity.DURATION); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(0, 0); + } +} -- cgit v1.1