diff options
author | Marco Nelissen <marcone@google.com> | 2009-11-10 08:22:06 -0800 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2009-11-10 10:19:51 -0800 |
commit | 423d39f6a9fd7b6399b92a272eadc49676375f48 (patch) | |
tree | 3994c10ff1692951a5de252db6f5baa93d91382c /src | |
parent | 425c152170cade85a8e53f554c2f835eab78c30b (diff) | |
download | android_packages_wallpapers_MagicSmoke-423d39f6a9fd7b6399b92a272eadc49676375f48.tar.gz android_packages_wallpapers_MagicSmoke-423d39f6a9fd7b6399b92a272eadc49676375f48.tar.bz2 android_packages_wallpapers_MagicSmoke-423d39f6a9fd7b6399b92a272eadc49676375f48.zip |
Don't let the magic smoke out!
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/magicsmoke/MagicSmoke.java | 26 | ||||
-rw-r--r-- | src/com/android/magicsmoke/MagicSmokeRS.java | 363 | ||||
-rw-r--r-- | src/com/android/magicsmoke/MagicSmokeSelector.java | 234 | ||||
-rw-r--r-- | src/com/android/magicsmoke/RenderScriptScene.java | 91 | ||||
-rw-r--r-- | src/com/android/magicsmoke/RenderScriptWallpaper.java | 114 |
5 files changed, 828 insertions, 0 deletions
diff --git a/src/com/android/magicsmoke/MagicSmoke.java b/src/com/android/magicsmoke/MagicSmoke.java new file mode 100644 index 0000000..e0ff258 --- /dev/null +++ b/src/com/android/magicsmoke/MagicSmoke.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 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.android.magicsmoke; + +public class MagicSmoke extends RenderScriptWallpaper<MagicSmokeRS> { + + @Override + protected MagicSmokeRS createScene(int width, int height) { + return new MagicSmokeRS(this, width, height); + } +} + diff --git a/src/com/android/magicsmoke/MagicSmokeRS.java b/src/com/android/magicsmoke/MagicSmokeRS.java new file mode 100644 index 0000000..726d128 --- /dev/null +++ b/src/com/android/magicsmoke/MagicSmokeRS.java @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2009 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.android.magicsmoke; + +import static android.renderscript.ProgramFragment.EnvMode.REPLACE; +import static android.renderscript.Sampler.Value.LINEAR; +import static android.renderscript.Sampler.Value.WRAP; + +import com.android.magicsmoke.R; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.MediaPlayer; +import android.os.Handler; +import android.renderscript.Allocation; +import android.renderscript.Dimension; +import android.renderscript.Element; +import android.renderscript.Primitive; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.Sampler; +import android.renderscript.ScriptC; +import android.renderscript.SimpleMesh; +import android.renderscript.Type; +import android.renderscript.Element.Builder; +import android.renderscript.ProgramStore.BlendDstFunc; +import android.renderscript.ProgramStore.BlendSrcFunc; +import android.util.Log; +import android.view.MotionEvent; + +import java.util.TimeZone; + +class MagicSmokeRS extends RenderScriptScene implements OnSharedPreferenceChangeListener { + + static class WorldState { + public float mXOffset; + public float mTilt; + public int mPreset; + public int mTextureMask; + public int mRotate; + public int mTextureSwap; + public int mProcessTexture; + public int mBackCol; + public int mLowCol; + public int mHighCol; + public float mAlphaMul; + public int mPreMul; + public int mBlendFunc; + } + WorldState mWorldState = new WorldState(); + private Type mStateType; + private Allocation mState; + + private ProgramStore mPfsBackgroundOne; + private ProgramStore mPfsBackgroundSrc; + private ProgramFragment mPfBackground; + private Sampler mSampler; + private Allocation[] mSourceTextures; + private Allocation[] mRealTextures; + + private ProgramVertex mPVBackground; + private ProgramVertex.MatrixAllocation mPVAlloc; + + private static final int RSID_STATE = 0; + //private static final int RSID_PROGRAMVERTEX = 3; + private static final int RSID_NOISESRC1 = 1; + private static final int RSID_NOISESRC2 = 2; + private static final int RSID_NOISESRC3 = 3; + private static final int RSID_NOISESRC4 = 4; + private static final int RSID_NOISESRC5 = 5; + private static final int RSID_NOISEDST1 = 6; + private static final int RSID_NOISEDST2 = 7; + private static final int RSID_NOISEDST3 = 8; + private static final int RSID_NOISEDST4 = 9; + private static final int RSID_NOISEDST5 = 10; + + private Context mContext; + private SharedPreferences mSharedPref; + + static class Preset { + Preset(boolean process, int backcol, int locol, int hicol, float mul, int mask, + boolean rot, int blend, boolean texswap, boolean premul) { + mProcessTexture = process; + mBackColor = backcol; + mLowColor = locol; + mHighColor = hicol; + mAlphaMul = mul; + mTextureMask = mask; + mRotate = rot; + mBlendFunc = blend; + mTextureSwap = texswap; + mPreMul = premul; + } + public boolean mProcessTexture; + public int mBackColor; + public int mLowColor; + public int mHighColor; + public float mAlphaMul; + public int mTextureMask; + public boolean mRotate; + public int mBlendFunc; + public boolean mTextureSwap; + public boolean mPreMul; + } + + public static final int DEFAULT_PRESET = 4; + public static final Preset [] mPreset = new Preset[] { + // proc back low high alph mask rot blend swap premul + new Preset(true, 0x000000, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, false, false), + new Preset(true, 0x0000ff, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, false, false), + new Preset(true, 0x00ff00, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, false, false), + new Preset(true, 0x00ff00, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, false, true), + new Preset(true, 0x00ff00, 0x00ff00, 0xffffff, 2.5f, 0x1f, true, 0, true, true), + new Preset(true, 0x800000, 0xff0000, 0xffffff, 2.5f, 0x1f, true, 0, true, false), + new Preset(false, 0x000000, 0x000000, 0xffffff, 0.0f, 0x1f, true, 0, false, false), + new Preset(true, 0x0000ff, 0x00ff00, 0xffff00, 2.0f, 0x1f, true, 0, true, false), + new Preset(true, 0x008000, 0x00ff00, 0xffffff, 2.5f, 0x1f, true, 0, true, false), + new Preset(true, 0x800000, 0xff0000, 0xffffff, 2.5f, 0x1f, true, 0, true, true), + new Preset(true, 0x808080, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, false, true), + new Preset(true, 0x0000ff, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, false, true), + new Preset(true, 0x0000ff, 0x00ff00, 0xffff00, 1.5f, 0x1f, false, 0, false, true), + new Preset(true, 0x0000ff, 0x00ff00, 0xffff00, 2.0f, 0x1f, true, 0, true, true), + new Preset(true, 0x0000ff, 0x00ff00, 0xffff00, 1.5f, 0x1f, true, 0, true, true), + new Preset(true, 0x808080, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, false, false), + new Preset(true, 0x000000, 0x000000, 0xffffff, 2.0f, 0x0f, true, 0, true, false), + }; + + private float mTouchY; + + MagicSmokeRS(Context context, int width, int height) { + super(width, height); + mWidth = width; + mHeight = height; + mWorldState.mTilt = 0; + mContext = context; + mSharedPref = mContext.getSharedPreferences("magicsmoke", Context.MODE_PRIVATE); + makeNewState(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + + makeNewState(); + mState.data(mWorldState); + } + + void makeNewState() { + int p = mSharedPref.getInt("preset", DEFAULT_PRESET); + if (p >= mPreset.length) { + p = 0; + } + mWorldState.mPreset = p; + mWorldState.mTextureMask = mPreset[p].mTextureMask; + mWorldState.mRotate = mPreset[p].mRotate ? 1 : 0; + mWorldState.mTextureSwap = mPreset[p].mTextureSwap ? 1 : 0; + mWorldState.mProcessTexture = mPreset[p].mProcessTexture ? 1 : 0; + mWorldState.mBackCol = mPreset[p].mBackColor; + mWorldState.mLowCol = mPreset[p].mLowColor; + mWorldState.mHighCol = mPreset[p].mHighColor; + mWorldState.mAlphaMul = mPreset[p].mAlphaMul; + mWorldState.mPreMul = mPreset[p].mPreMul ? 1 : 0; + mWorldState.mBlendFunc = mPreset[p].mBlendFunc; + } + + @Override + public void resize(int width, int height) { + super.resize(width, height); + if (mPVAlloc != null) { + mPVAlloc.setupProjectionNormalized(width, height); + } + } + + @Override + public void onTouchEvent(MotionEvent event) { + switch(event.getAction()) { + case MotionEvent.ACTION_DOWN: + mTouchY = event.getY(); + break; + case MotionEvent.ACTION_MOVE: + float dy = event.getY() - mTouchY; + mTouchY += dy; + dy /= 20; + dy += mWorldState.mTilt; + if (dy > 4) { + dy = 4; + } else if (dy < -4) { + dy = -4; + } + mWorldState.mTilt = dy; + mState.data(mWorldState); + } + } + + @Override + public void setOffset(float xOffset, float yOffset, float xStep, float yStep, + int xPixels, int yPixels) { + // update our state, then push it to the renderscript + mWorldState.mXOffset = xOffset; + mState.data(mWorldState); + } + + @Override + public void stop() { + mSharedPref.unregisterOnSharedPreferenceChangeListener(this); + super.stop(); + } + + @Override + public void start() { + super.start(); + mSharedPref.registerOnSharedPreferenceChangeListener(this); + makeNewState(); + mState.data(mWorldState); + } + + float alphafactor; + Type mTextureType; + + void loadBitmap(int id, int index, String name, float alphamul, int lowcol, int highcol) { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inPreferredConfig = Bitmap.Config.ARGB_8888; + Bitmap in = BitmapFactory.decodeResource(mResources, id, opts); + + int pixels[] = new int[65536]; + in.getPixels(pixels, 0, 256, 0, 0, 256, 256); + mRealTextures[index] = Allocation.createTyped(mRS, mTextureType); + mSourceTextures[index] = Allocation.createTyped(mRS, mTextureType); + mSourceTextures[index].setName(name+"_src"); + mSourceTextures[index].data(pixels); + mRealTextures[index].setName(name); + in.recycle(); + } + + void loadBitmaps() { + alphafactor = 1f; + float alphamul = mPreset[mWorldState.mPreset].mAlphaMul; + int lowcol = mPreset[mWorldState.mPreset].mLowColor; + int highcol = mPreset[mWorldState.mPreset].mHighColor; + //Log.i("@@@@", "preset " + mWorldState.mPreset + ", mul: " + alphamul + + // ", colors: " + Integer.toHexString(lowcol) + "/" + Integer.toHexString(highcol)); + + // TODO: using different high and low colors for each layer offers some cool effects too + loadBitmap(R.drawable.noise1, 0, "Tnoise1", alphamul, lowcol, highcol); + loadBitmap(R.drawable.noise2, 1, "Tnoise2", alphamul, lowcol, highcol); + loadBitmap(R.drawable.noise3, 2, "Tnoise3", alphamul, lowcol, highcol); + loadBitmap(R.drawable.noise4, 3, "Tnoise4", alphamul, lowcol, highcol); + loadBitmap(R.drawable.noise5, 4, "Tnoise5", alphamul, lowcol, highcol); + } + + @Override + protected ScriptC createScript() { + + // Create a renderscript type from a java class. The specified name doesn't + // really matter; the name by which we refer to the object in RenderScript + // will be specified later. + mStateType = Type.createFromClass(mRS, WorldState.class, 1, "WorldState"); + // Create an allocation from the type we just created. + mState = Allocation.createTyped(mRS, mStateType); + mState.data(mWorldState); + + // First set up the coordinate system and such + ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); + mPVBackground = pvb.create(); + mPVBackground.setName("PVBackground"); + mPVAlloc = new ProgramVertex.MatrixAllocation(mRS); + mPVBackground.bindAllocation(mPVAlloc); + mPVAlloc.setupProjectionNormalized(mWidth, mHeight); + + mSourceTextures = new Allocation[5]; + mRealTextures = new Allocation[5]; + + Type.Builder tb = new Type.Builder(mRS, Element.RGBA_8888(mRS)); + tb.add(Dimension.X, 256); + tb.add(Dimension.Y, 256); + mTextureType = tb.create(); + loadBitmaps(); + + Sampler.Builder samplerBuilder = new Sampler.Builder(mRS); + samplerBuilder.setMin(LINEAR); + samplerBuilder.setMag(LINEAR); + samplerBuilder.setWrapS(WRAP); + samplerBuilder.setWrapT(WRAP); + mSampler = samplerBuilder.create(); + + { + ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null); + builder.setTexEnable(true, 0); + builder.setTexEnvMode(ProgramFragment.EnvMode.MODULATE, 0); + mPfBackground = builder.create(); + mPfBackground.setName("PFBackground"); + mPfBackground.bindSampler(mSampler, 0); + } + + { + ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null); + builder.setDepthFunc(ProgramStore.DepthFunc.EQUAL); + builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE_MINUS_SRC_ALPHA); + builder.setDitherEnable(true); // without dithering there is severe banding + builder.setDepthMask(false); + mPfsBackgroundOne = builder.create(); + mPfsBackgroundOne.setName("PFSBackgroundOne"); + builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); + mPfsBackgroundSrc = builder.create(); + mPfsBackgroundSrc.setName("PFSBackgroundSrc"); + } + + // Time to create the script + ScriptC.Builder sb = new ScriptC.Builder(mRS); + // Specify the name by which to refer to the WorldState object in the + // renderscript. + sb.setType(mStateType, "State", RSID_STATE); + sb.setType(mTextureType, "noisesrc1", RSID_NOISESRC1); + sb.setType(mTextureType, "noisedst1", RSID_NOISEDST1); + sb.setType(mTextureType, "noisesrc2", RSID_NOISESRC2); + sb.setType(mTextureType, "noisedst2", RSID_NOISEDST2); + sb.setType(mTextureType, "noisesrc3", RSID_NOISESRC3); + sb.setType(mTextureType, "noisedst3", RSID_NOISEDST3); + sb.setType(mTextureType, "noisesrc4", RSID_NOISESRC4); + sb.setType(mTextureType, "noisedst4", RSID_NOISEDST4); + sb.setType(mTextureType, "noisesrc5", RSID_NOISESRC5); + sb.setType(mTextureType, "noisedst5", RSID_NOISEDST5); + sb.setScript(mResources, R.raw.clouds); + sb.setRoot(true); + + ScriptC script = sb.create(); + script.setClearColor(1.0f, 0.0f, 0.0f, 1.0f); + script.setTimeZone(TimeZone.getDefault().getID()); + + script.bindAllocation(mState, RSID_STATE); + script.bindAllocation(mSourceTextures[0], RSID_NOISESRC1); + script.bindAllocation(mRealTextures[0], RSID_NOISEDST1); + script.bindAllocation(mSourceTextures[1], RSID_NOISESRC2); + script.bindAllocation(mRealTextures[1], RSID_NOISEDST2); + script.bindAllocation(mSourceTextures[2], RSID_NOISESRC3); + script.bindAllocation(mRealTextures[2], RSID_NOISEDST3); + script.bindAllocation(mSourceTextures[3], RSID_NOISESRC4); + script.bindAllocation(mRealTextures[3], RSID_NOISEDST4); + script.bindAllocation(mSourceTextures[4], RSID_NOISESRC5); + script.bindAllocation(mRealTextures[4], RSID_NOISEDST5); + //script.bindAllocation(mPVAlloc.mAlloc, RSID_PROGRAMVERTEX); + + + return script; + } +} diff --git a/src/com/android/magicsmoke/MagicSmokeSelector.java b/src/com/android/magicsmoke/MagicSmokeSelector.java new file mode 100644 index 0000000..fbe335d --- /dev/null +++ b/src/com/android/magicsmoke/MagicSmokeSelector.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2009 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.android.magicsmoke; + +import android.app.Activity; +import android.app.WallpaperManager; +import android.app.WallpaperInfo; +import android.app.Dialog; +import android.service.wallpaper.IWallpaperConnection; +import android.service.wallpaper.IWallpaperService; +import android.service.wallpaper.IWallpaperEngine; +import android.service.wallpaper.WallpaperSettingsActivity; +import android.content.ServiceConnection; +import android.content.Intent; +import android.content.Context; +import android.content.ComponentName; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.os.RemoteException; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; +import android.view.ViewGroup; +import android.view.Window; +import android.view.LayoutInflater; +import android.util.Log; +import android.widget.TextView; + +public class MagicSmokeSelector extends Activity { + + private static final String LOG_TAG = "MagicSmokeSelector"; + + private WallpaperManager mWallpaperManager; + private WallpaperConnection mWallpaperConnection; + + private Intent mWallpaperIntent; + private SharedPreferences mSharedPref; + private int mCurrentPreset; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.selector); + + mWallpaperIntent = new Intent(this, MagicSmoke.class); + + mWallpaperManager = WallpaperManager.getInstance(this); + mWallpaperConnection = new WallpaperConnection(mWallpaperIntent); + + mSharedPref = getSharedPreferences("magicsmoke", Context.MODE_PRIVATE); + mCurrentPreset = mSharedPref.getInt("preset", MagicSmokeRS.DEFAULT_PRESET); + if (mCurrentPreset >= MagicSmokeRS.mPreset.length) { + mCurrentPreset = 0; + updatePrefs(); + } + } + + // button hook + public void setLiveWallpaper(View v) { + finish(); + } + + + @Override + public void onResume() { + super.onResume(); + if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { + try { + mWallpaperConnection.mEngine.setVisibility(true); + } catch (RemoteException e) { + // Ignore + } + } + } + + @Override + public void onPause() { + super.onPause(); + if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) { + try { + mWallpaperConnection.mEngine.setVisibility(false); + } catch (RemoteException e) { + // Ignore + } + } + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + + if (!mWallpaperConnection.connect()) { + mWallpaperConnection = null; + } + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + if (mWallpaperConnection != null) { + mWallpaperConnection.disconnect(); + } + mWallpaperConnection = null; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // TODO: make this conditional on preview mode. Right now we + // don't get touch events in preview mode. + switch(event.getAction()) { + case MotionEvent.ACTION_DOWN: + if (mCurrentPreset == 0) { + mCurrentPreset = MagicSmokeRS.mPreset.length - 1; + } else { + mCurrentPreset--; + } + updatePrefs(); + return true; + } + + return super.onTouchEvent(event); + } + + private void updatePrefs() { + + Editor edit = mSharedPref.edit(); + edit.putInt("preset", mCurrentPreset); + edit.commit(); + + } + + class WallpaperConnection extends IWallpaperConnection.Stub implements ServiceConnection { + final Intent mIntent; + IWallpaperService mService; + IWallpaperEngine mEngine; + boolean mConnected; + + WallpaperConnection(Intent intent) { + mIntent = intent; + } + + public boolean connect() { + synchronized (this) { + if (!bindService(mIntent, this, Context.BIND_AUTO_CREATE)) { + return false; + } + + mConnected = true; + return true; + } + } + + public void disconnect() { + synchronized (this) { + mConnected = false; + if (mEngine != null) { + try { + mEngine.destroy(); + } catch (RemoteException e) { + // Ignore + } + mEngine = null; + } + unbindService(this); + mService = null; + } + } + + public void onServiceConnected(ComponentName name, IBinder service) { + if (mWallpaperConnection == this) { + mService = IWallpaperService.Stub.asInterface(service); + try { + final View view = findViewById(R.id.backgroundview); + final View root = view.getRootView(); + mService.attach(this, view.getWindowToken(), + WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY, + true, root.getWidth(), root.getHeight()); + } catch (RemoteException e) { + Log.w(LOG_TAG, "Failed attaching wallpaper; clearing", e); + } + } + } + + public void onServiceDisconnected(ComponentName name) { + mService = null; + mEngine = null; + if (mWallpaperConnection == this) { + Log.w(LOG_TAG, "Wallpaper service gone: " + name); + } + } + + public void attachEngine(IWallpaperEngine engine) { + synchronized (this) { + if (mConnected) { + mEngine = engine; + try { + engine.setVisibility(true); + } catch (RemoteException e) { + // Ignore + } + } else { + try { + engine.destroy(); + } catch (RemoteException e) { + // Ignore + } + } + } + } + + public ParcelFileDescriptor setWallpaper(String name) { + return null; + } + } +} diff --git a/src/com/android/magicsmoke/RenderScriptScene.java b/src/com/android/magicsmoke/RenderScriptScene.java new file mode 100644 index 0000000..446e01f --- /dev/null +++ b/src/com/android/magicsmoke/RenderScriptScene.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 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.android.magicsmoke; + +import android.content.res.Resources; +import android.renderscript.RenderScript; +import android.renderscript.ScriptC; +import android.view.MotionEvent; + +public abstract class RenderScriptScene { + protected int mWidth; + protected int mHeight; + protected boolean mPreview; + protected Resources mResources; + protected RenderScript mRS; + protected ScriptC mScript; + + public RenderScriptScene(int width, int height) { + mWidth = width; + mHeight = height; + } + + public void init(RenderScript rs, Resources res, boolean isPreview) { + mRS = rs; + mResources = res; + mPreview = isPreview; + mScript = createScript(); + } + + public boolean isPreview() { + return mPreview; + } + + public int getWidth() { + return mWidth; + } + + public int getHeight() { + return mHeight; + } + + public Resources getResources() { + return mResources; + } + + public RenderScript getRS() { + return mRS; + } + + public ScriptC getScript() { + return mScript; + } + + protected abstract ScriptC createScript(); + + public void stop() { + mRS.contextBindRootScript(null); + } + + public void start() { + mRS.contextBindRootScript(mScript); + } + + public void resize(int width, int height) { + mWidth = width; + mHeight = height; + } + + @SuppressWarnings({"UnusedDeclaration"}) + public void setOffset(float xOffset, float yOffset, + float xStep, float yStep, int xPixels, int yPixels) { + } + public void onTouchEvent(MotionEvent event) { + } + +} diff --git a/src/com/android/magicsmoke/RenderScriptWallpaper.java b/src/com/android/magicsmoke/RenderScriptWallpaper.java new file mode 100644 index 0000000..984496d --- /dev/null +++ b/src/com/android/magicsmoke/RenderScriptWallpaper.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2009 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.android.magicsmoke; + +import android.service.wallpaper.WallpaperService; +import android.renderscript.RenderScript; +import android.util.Log; +import android.view.MotionEvent; +import android.view.SurfaceHolder; +import android.view.Surface; + +public abstract class RenderScriptWallpaper<T extends RenderScriptScene> extends WallpaperService { + public Engine onCreateEngine() { + return new RenderScriptEngine(); + } + + protected abstract T createScene(int width, int height); + + private class RenderScriptEngine extends Engine { + private RenderScript mRs; + private T mRenderer; + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + super.onCreate(surfaceHolder); + setTouchEventsEnabled(true); + surfaceHolder.setSizeFromLayout(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + destroyRenderer(); + } + + private void destroyRenderer() { + if (mRenderer != null) { + mRenderer.stop(); + mRenderer = null; + } + if (mRs != null) { + mRs.destroy(); + mRs = null; + } + } + + @Override + public void onVisibilityChanged(boolean visible) { + super.onVisibilityChanged(visible); + if (mRenderer != null) { + if (visible) { + mRenderer.start(); + } else { + mRenderer.stop(); + } + } + } + + @Override + public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { + super.onSurfaceChanged(holder, format, width, height); + if (mRenderer == null) { + mRenderer = createScene(width, height); + mRenderer.init(mRs, getResources(), isPreview()); + mRenderer.start(); + } else { + mRenderer.resize(width, height); + } + } + + @Override + public void onTouchEvent(MotionEvent event) { + mRenderer.onTouchEvent(event); + } + + @Override + public void onOffsetsChanged(float xOffset, float yOffset, + float xStep, float yStep, int xPixels, int yPixels) { + mRenderer.setOffset(xOffset, yOffset, xStep, yStep, xPixels, yPixels); + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + super.onSurfaceCreated(holder); + + Surface surface = null; + while (surface == null) { + surface = holder.getSurface(); + } + mRs = new RenderScript(surface, false, false); + } + + @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + destroyRenderer(); + } + } +} |