Loading Android.mk +3 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ LOCAL_SRC_FILES += \ core/java/android/webkit/EventLogTags.logtags \ telephony/java/com/android/internal/telephony/EventLogTags.logtags \ # RenderScript files for internal widgets LOCAL_SRC_FILES += $(call all-renderscript-files-under, core/java/com/android/internal/widget) # The following filters out code we are temporarily not including at all. # TODO: Move AWT and beans (and associated harmony code) back into libcore. # TODO: Maybe remove javax.microedition entirely? Loading core/java/com/android/internal/widget/CarouselRS.java 0 → 100644 +372 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 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.internal.widget; import android.content.res.Resources; import android.graphics.Bitmap; import android.renderscript.*; import android.renderscript.RenderScript.RSMessage; import android.renderscript.Sampler.Value; import android.renderscript.ProgramRaster.CullMode; import android.util.Log; import com.android.internal.R; import static android.renderscript.Element.*; import static android.renderscript.Sampler.Value.LINEAR; import static android.renderscript.Sampler.Value.WRAP; import static android.renderscript.Sampler.Value.CLAMP; public class CarouselRS { private static final int DEFAULT_VISIBLE_SLOTS = 1; private static final int DEFAULT_CARD_COUNT = 1; // Client messages *** THIS LIST MUST MATCH THOSE IN carousel.rs *** public static final int CMD_CARD_SELECTED = 100; public static final int CMD_REQUEST_TEXTURE = 200; public static final int CMD_INVALIDATE_TEXTURE = 210; public static final int CMD_REQUEST_GEOMETRY = 300; public static final int CMD_INVALIDATE_GEOMETRY = 310; public static final int CMD_ANIMATION_STARTED = 400; public static final int CMD_ANIMATION_FINISHED = 500; public static final int CMD_PING = 600; // for debugging private static final String TAG = "CarouselRS"; private static final int DEFAULT_SLOT_COUNT = 10; private static final boolean MIPMAP = false; private RenderScriptGL mRS; private Resources mRes; private ScriptC_Carousel mScript; private ScriptField_Card mCards; private Sampler mSampler; private ProgramRaster mProgramRaster; private ProgramStore mProgramStore; private ProgramFragment mFragmentProgram; private ProgramVertex mVertexProgram; private ProgramRaster mRasterProgram; private CarouselCallback mCallback; private float[] mEyePoint = new float[3]; private float[] mAtPoint = new float[3]; private float[] mUp = new float[3]; public static interface CarouselCallback { /** * Called when a card is selected * @param n the id of the card */ void onCardSelected(int n); /** * Called when texture is needed for card n. This happens when the given card becomes * visible. * @param n the id of the card */ void onRequestTexture(int n); /** * Called when a texture is no longer needed for card n. This happens when the card * goes out of view. * @param n the id of the card */ void onInvalidateTexture(int n); /** * Called when geometry is needed for card n. * @param n the id of the card. */ void onRequestGeometry(int n); /** * Called when geometry is no longer needed for card n. This happens when the card goes * out of view. * @param n the id of the card */ void onInvalidateGeometry(int n); /** * Called when card animation (e.g. a fling) has started. */ void onAnimationStarted(); /** * Called when card animation has stopped. */ void onAnimationFinished(); }; private RSMessage mRsMessage = new RSMessage() { public void run() { if (mCallback == null) return; switch (mID) { case CMD_CARD_SELECTED: mCallback.onCardSelected(mData[0]); break; case CMD_REQUEST_TEXTURE: mCallback.onRequestTexture(mData[0]); break; case CMD_INVALIDATE_TEXTURE: mCallback.onInvalidateTexture(mData[0]); break; case CMD_REQUEST_GEOMETRY: mCallback.onRequestGeometry(mData[0]); break; case CMD_INVALIDATE_GEOMETRY: mCallback.onInvalidateGeometry(mData[0]); break; case CMD_ANIMATION_STARTED: mCallback.onAnimationStarted(); break; case CMD_ANIMATION_FINISHED: mCallback.onAnimationFinished(); break; case CMD_PING: Log.v(TAG, "PING..."); break; default: Log.e(TAG, "Unknown RSMessage: " + mID); } } }; public void init(RenderScriptGL rs, Resources res) { mRS = rs; mRes = res; // create the script object mScript = new ScriptC_Carousel(mRS, mRes, R.raw.carousel, true); mRS.mMessageCallback = mRsMessage; initProgramStore(); initFragmentProgram(); initRasterProgram(); initVertexProgram(); setSlotCount(DEFAULT_SLOT_COUNT); setVisibleSlots(DEFAULT_VISIBLE_SLOTS); createCards(DEFAULT_CARD_COUNT); setStartAngle(0.0f); setRadius(1.0f); // update the camera boolean pcam = true; if (pcam) { float eye[] = { 20.6829f, 2.77081f, 16.7314f }; float at[] = { 14.7255f, -3.40001f, -1.30184f }; float up[] = { 0.0f, 1.0f, 0.0f }; setLookAt(eye, at, up); setRadius(20.0f); // Fov: 25 } else { mScript.invoke_lookAt(2.5f, 2.0f, 2.5f, 0.0f, -0.75f, 0.0f, 0.0f, 1.0f, 0.0f); mScript.set_cardRotation(0.0f); setRadius(1.5f); } resumeRendering(); } public void setLookAt(float[] eye, float[] at, float[] up) { for (int i = 0; i < 3; i++) { mEyePoint[i] = eye[i]; mAtPoint[i] = at[i]; mUp[i] = up[i]; } mScript.invoke_lookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], up[0], up[1], up[2]); } public void setRadius(float radius) { mScript.set_radius(radius); } private void initVertexProgram() { ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); mVertexProgram = pvb.create(); ProgramVertex.MatrixAllocation pva = new ProgramVertex.MatrixAllocation(mRS); mVertexProgram.bindAllocation(pva); pva.setupProjectionNormalized(1, 1); mScript.set_vertexProgram(mVertexProgram); } private void initRasterProgram() { ProgramRaster.Builder programRasterBuilder = new ProgramRaster.Builder(mRS); mRasterProgram = programRasterBuilder.create(); //mRasterProgram.setCullMode(CullMode.NONE); mScript.set_rasterProgram(mRasterProgram); } private void initFragmentProgram() { Sampler.Builder sampleBuilder = new Sampler.Builder(mRS); sampleBuilder.setMin(Value.LINEAR_MIP_LINEAR); sampleBuilder.setMag(LINEAR); sampleBuilder.setWrapS(CLAMP); sampleBuilder.setWrapT(CLAMP); mSampler = sampleBuilder.create(); ProgramFragment.Builder fragmentBuilder = new ProgramFragment.Builder(mRS); fragmentBuilder.setTexture(ProgramFragment.Builder.EnvMode.DECAL, ProgramFragment.Builder.Format.RGBA, 0); mFragmentProgram = fragmentBuilder.create(); mFragmentProgram.bindSampler(mSampler, 0); mScript.set_fragmentProgram(mFragmentProgram); } private void initProgramStore() { ProgramStore.Builder programStoreBuilder = new ProgramStore.Builder(mRS, null, null); programStoreBuilder.setDepthFunc(ProgramStore.DepthFunc.LESS); programStoreBuilder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA, ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); programStoreBuilder.setDitherEnable(false); programStoreBuilder.setDepthMask(true); mProgramStore = programStoreBuilder.create(); mScript.set_programStore(mProgramStore); } public void createCards(int count) { mCards = count > 0 ? new ScriptField_Card(mRS, count) : null; mScript.bind_cards(mCards); mScript.invoke_createCards(count); } public void setVisibleSlots(int count) { mScript.set_visibleSlotCount(count); } public void setDefaultBitmap(Bitmap bitmap) { mScript.set_defaultTexture(allocationFromBitmap(bitmap, MIPMAP)); } public void setLoadingBitmap(Bitmap bitmap) { mScript.set_loadingTexture(allocationFromBitmap(bitmap, MIPMAP)); } public void setDefaultGeometry(Mesh mesh) { mScript.set_defaultGeometry(mesh); } public void setLoadingGeometry(Mesh mesh) { mScript.set_loadingGeometry(mesh); } public void setStartAngle(float theta) { mScript.set_startAngle(theta); } public void setCallback(CarouselCallback callback) { mCallback = callback; } private Allocation allocationFromBitmap(Bitmap bitmap, boolean mipmap) { if (bitmap == null) return null; Allocation allocation = Allocation.createFromBitmap(mRS, bitmap, RGB_565(mRS), mipmap); allocation.uploadToTexture(0); return allocation; } public void setTexture(int n, Bitmap bitmap) { ScriptField_Card.Item item = mCards.get(n); if (item == null) { Log.v(TAG, "setTexture(): no item at index " + n); item = new ScriptField_Card.Item(); } if (bitmap != null) { Log.v(TAG, "creating new bitmap"); item.texture = Allocation.createFromBitmap(mRS, bitmap, RGB_565(mRS), MIPMAP); Log.v(TAG, "uploadToTexture(" + n + ")"); item.texture.uploadToTexture(0); Log.v(TAG, "done..."); } else { if (item.texture != null) { Log.v(TAG, "unloading texture " + n); // Don't wait for GC to free native memory. // Only works if textures are not shared. item.texture.destroy(); item.texture = null; } } mCards.set(item, n, false); // This is primarily used for reference counting. mScript.invoke_setTexture(n, item.texture); } public void setGeometry(int n, Mesh geometry) { final boolean mipmap = false; ScriptField_Card.Item item = mCards.get(n); if (item == null) { Log.v(TAG, "setGeometry(): no item at index " + n); item = new ScriptField_Card.Item(); } if (geometry != null) { item.geometry = geometry; } else { Log.v(TAG, "unloading geometry " + n); if (item.geometry != null) { // item.geometry.destroy(); item.geometry = null; } } mCards.set(item, n, false); mScript.invoke_setGeometry(n, item.geometry); } public void pauseRendering() { // Used to update multiple states at once w/o redrawing for each. mRS.contextBindRootScript(null); } public void resumeRendering() { mRS.contextBindRootScript(mScript); } public void doMotion(float x, float y) { mScript.invoke_doMotion(x,y); } public void doSelection(float x, float y) { mScript.invoke_doSelection(x, y); } public void doStart(float x, float y) { mScript.invoke_doStart(x, y); } public void doStop(float x, float y) { mScript.invoke_doStop(x, y); } public void setSlotCount(int n) { mScript.set_slotCount(n); } } core/java/com/android/internal/widget/CarouselView.java 0 → 100644 +244 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 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.internal.widget; import com.android.internal.widget.CarouselRS.CarouselCallback; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.renderscript.FileA3D; import android.renderscript.Mesh; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScriptGL; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; public class CarouselView extends RSSurfaceView { private final int DEFAULT_SLOT_COUNT = 10; private final Bitmap DEFAULT_BITMAP = Bitmap.createBitmap(1, 1, Config.RGB_565); private static final String TAG = "CarouselView"; private CarouselRS mRenderScript; private RenderScriptGL mRS; private Context mContext; private boolean mTracking; private Bitmap mDefaultBitmap; private Bitmap mLoadingBitmap; private Mesh mDefaultGeometry; private Mesh mLoadingGeometry; private int mCardCount = 0; private int mVisibleSlots = 0; private float mStartAngle; private int mSlotCount = DEFAULT_SLOT_COUNT; public CarouselView(Context context) { super(context); mContext = context; boolean useDepthBuffer = true; mRS = createRenderScript(useDepthBuffer); mRenderScript = new CarouselRS(); mRenderScript.init(mRS, getResources()); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); mRS.contextSetSurface(w, h, holder.getSurface()); mRenderScript.init(mRS, getResources()); setSlotCount(mSlotCount); createCards(mCardCount); setVisibleSlots(mVisibleSlots); setCallback(mCarouselCallback); setDefaultBitmap(mDefaultBitmap); setLoadingBitmap(mLoadingBitmap); setDefaultGeometry(mDefaultGeometry); setLoadingGeometry(mLoadingGeometry); setStartAngle(mStartAngle); } /** * Loads geometry from a resource id. * * @param resId * @return the loaded mesh or null if it cannot be loaded */ public Mesh loadGeometry(int resId) { Resources res = mContext.getResources(); FileA3D model = FileA3D.createFromResource(mRS, res, resId); FileA3D.IndexEntry entry = model.getIndexEntry(0); if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) { return null; } return (Mesh) entry.getObject(); } /** * Load A3D file from resource. If resId == 0, will clear geometry for this item. * @param n * @param resId */ public void setGeometryForItem(int n, Mesh mesh) { mRenderScript.setGeometry(n, mesh); } public void setSlotCount(int n) { mSlotCount = n; if (mRenderScript != null) { mRenderScript.setSlotCount(n); } } public void setVisibleSlots(int n) { mVisibleSlots = n; if (mRenderScript != null) { mRenderScript.setVisibleSlots(n); } } public void createCards(int n) { mCardCount = n; if (mRenderScript != null) { mRenderScript.createCards(n); } } public void setTextureForItem(int n, Bitmap bitmap) { if (mRenderScript != null) { Log.v(TAG, "setTextureForItem(" + n + ")"); mRenderScript.setTexture(n, bitmap); Log.v(TAG, "done"); } } public void setDefaultBitmap(Bitmap bitmap) { mDefaultBitmap = bitmap; if (mRenderScript != null) { mRenderScript.setDefaultBitmap(bitmap); } } public void setLoadingBitmap(Bitmap bitmap) { mLoadingBitmap = bitmap; if (mRenderScript != null) { mRenderScript.setLoadingBitmap(bitmap); } } public void setDefaultGeometry(Mesh mesh) { mDefaultGeometry = mesh; if (mRenderScript != null) { mRenderScript.setDefaultGeometry(mesh); } } public void setLoadingGeometry(Mesh mesh) { mLoadingGeometry = mesh; if (mRenderScript != null) { mRenderScript.setLoadingGeometry(mesh); } } public void setCallback(CarouselCallback callback) { mCarouselCallback = callback; if (mRenderScript != null) { mRenderScript.setCallback(callback); } } public void setStartAngle(float angle) { mStartAngle = angle; if (mRenderScript != null) { mRenderScript.setStartAngle(angle); } } @Override protected void onDetachedFromWindow() { if(mRS != null) { mRS = null; destroyRenderScript(); } } @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getAction(); final float x = event.getX(); final float y = event.getY(); if (mRenderScript == null) { return true; } switch (action) { case MotionEvent.ACTION_DOWN: mTracking = true; mRenderScript.doStart(x, y); break; case MotionEvent.ACTION_MOVE: if (mTracking) { mRenderScript.doMotion(x, y); } break; case MotionEvent.ACTION_UP: mRenderScript.doStop(x, y); mTracking = false; break; } return true; } private final CarouselCallback DEBUG_CALLBACK = new CarouselCallback() { public void onAnimationStarted() { Log.v(TAG, "onAnimationStarted()"); } public void onAnimationFinished() { Log.v(TAG, "onAnimationFinished()"); } public void onCardSelected(int n) { Log.v(TAG, "onCardSelected(" + n + ")"); } public void onRequestGeometry(int n) { Log.v(TAG, "onRequestGeometry(" + n + ")"); } public void onInvalidateGeometry(int n) { Log.v(TAG, "onInvalidateGeometry(" + n + ")"); } public void onRequestTexture(final int n) { Log.v(TAG, "onRequestTexture(" + n + ")"); } public void onInvalidateTexture(int n) { Log.v(TAG, "onInvalidateTexture(" + n + ")"); } }; private CarouselCallback mCarouselCallback = DEBUG_CALLBACK; } Loading
Android.mk +3 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ LOCAL_SRC_FILES += \ core/java/android/webkit/EventLogTags.logtags \ telephony/java/com/android/internal/telephony/EventLogTags.logtags \ # RenderScript files for internal widgets LOCAL_SRC_FILES += $(call all-renderscript-files-under, core/java/com/android/internal/widget) # The following filters out code we are temporarily not including at all. # TODO: Move AWT and beans (and associated harmony code) back into libcore. # TODO: Maybe remove javax.microedition entirely? Loading
core/java/com/android/internal/widget/CarouselRS.java 0 → 100644 +372 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 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.internal.widget; import android.content.res.Resources; import android.graphics.Bitmap; import android.renderscript.*; import android.renderscript.RenderScript.RSMessage; import android.renderscript.Sampler.Value; import android.renderscript.ProgramRaster.CullMode; import android.util.Log; import com.android.internal.R; import static android.renderscript.Element.*; import static android.renderscript.Sampler.Value.LINEAR; import static android.renderscript.Sampler.Value.WRAP; import static android.renderscript.Sampler.Value.CLAMP; public class CarouselRS { private static final int DEFAULT_VISIBLE_SLOTS = 1; private static final int DEFAULT_CARD_COUNT = 1; // Client messages *** THIS LIST MUST MATCH THOSE IN carousel.rs *** public static final int CMD_CARD_SELECTED = 100; public static final int CMD_REQUEST_TEXTURE = 200; public static final int CMD_INVALIDATE_TEXTURE = 210; public static final int CMD_REQUEST_GEOMETRY = 300; public static final int CMD_INVALIDATE_GEOMETRY = 310; public static final int CMD_ANIMATION_STARTED = 400; public static final int CMD_ANIMATION_FINISHED = 500; public static final int CMD_PING = 600; // for debugging private static final String TAG = "CarouselRS"; private static final int DEFAULT_SLOT_COUNT = 10; private static final boolean MIPMAP = false; private RenderScriptGL mRS; private Resources mRes; private ScriptC_Carousel mScript; private ScriptField_Card mCards; private Sampler mSampler; private ProgramRaster mProgramRaster; private ProgramStore mProgramStore; private ProgramFragment mFragmentProgram; private ProgramVertex mVertexProgram; private ProgramRaster mRasterProgram; private CarouselCallback mCallback; private float[] mEyePoint = new float[3]; private float[] mAtPoint = new float[3]; private float[] mUp = new float[3]; public static interface CarouselCallback { /** * Called when a card is selected * @param n the id of the card */ void onCardSelected(int n); /** * Called when texture is needed for card n. This happens when the given card becomes * visible. * @param n the id of the card */ void onRequestTexture(int n); /** * Called when a texture is no longer needed for card n. This happens when the card * goes out of view. * @param n the id of the card */ void onInvalidateTexture(int n); /** * Called when geometry is needed for card n. * @param n the id of the card. */ void onRequestGeometry(int n); /** * Called when geometry is no longer needed for card n. This happens when the card goes * out of view. * @param n the id of the card */ void onInvalidateGeometry(int n); /** * Called when card animation (e.g. a fling) has started. */ void onAnimationStarted(); /** * Called when card animation has stopped. */ void onAnimationFinished(); }; private RSMessage mRsMessage = new RSMessage() { public void run() { if (mCallback == null) return; switch (mID) { case CMD_CARD_SELECTED: mCallback.onCardSelected(mData[0]); break; case CMD_REQUEST_TEXTURE: mCallback.onRequestTexture(mData[0]); break; case CMD_INVALIDATE_TEXTURE: mCallback.onInvalidateTexture(mData[0]); break; case CMD_REQUEST_GEOMETRY: mCallback.onRequestGeometry(mData[0]); break; case CMD_INVALIDATE_GEOMETRY: mCallback.onInvalidateGeometry(mData[0]); break; case CMD_ANIMATION_STARTED: mCallback.onAnimationStarted(); break; case CMD_ANIMATION_FINISHED: mCallback.onAnimationFinished(); break; case CMD_PING: Log.v(TAG, "PING..."); break; default: Log.e(TAG, "Unknown RSMessage: " + mID); } } }; public void init(RenderScriptGL rs, Resources res) { mRS = rs; mRes = res; // create the script object mScript = new ScriptC_Carousel(mRS, mRes, R.raw.carousel, true); mRS.mMessageCallback = mRsMessage; initProgramStore(); initFragmentProgram(); initRasterProgram(); initVertexProgram(); setSlotCount(DEFAULT_SLOT_COUNT); setVisibleSlots(DEFAULT_VISIBLE_SLOTS); createCards(DEFAULT_CARD_COUNT); setStartAngle(0.0f); setRadius(1.0f); // update the camera boolean pcam = true; if (pcam) { float eye[] = { 20.6829f, 2.77081f, 16.7314f }; float at[] = { 14.7255f, -3.40001f, -1.30184f }; float up[] = { 0.0f, 1.0f, 0.0f }; setLookAt(eye, at, up); setRadius(20.0f); // Fov: 25 } else { mScript.invoke_lookAt(2.5f, 2.0f, 2.5f, 0.0f, -0.75f, 0.0f, 0.0f, 1.0f, 0.0f); mScript.set_cardRotation(0.0f); setRadius(1.5f); } resumeRendering(); } public void setLookAt(float[] eye, float[] at, float[] up) { for (int i = 0; i < 3; i++) { mEyePoint[i] = eye[i]; mAtPoint[i] = at[i]; mUp[i] = up[i]; } mScript.invoke_lookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], up[0], up[1], up[2]); } public void setRadius(float radius) { mScript.set_radius(radius); } private void initVertexProgram() { ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); mVertexProgram = pvb.create(); ProgramVertex.MatrixAllocation pva = new ProgramVertex.MatrixAllocation(mRS); mVertexProgram.bindAllocation(pva); pva.setupProjectionNormalized(1, 1); mScript.set_vertexProgram(mVertexProgram); } private void initRasterProgram() { ProgramRaster.Builder programRasterBuilder = new ProgramRaster.Builder(mRS); mRasterProgram = programRasterBuilder.create(); //mRasterProgram.setCullMode(CullMode.NONE); mScript.set_rasterProgram(mRasterProgram); } private void initFragmentProgram() { Sampler.Builder sampleBuilder = new Sampler.Builder(mRS); sampleBuilder.setMin(Value.LINEAR_MIP_LINEAR); sampleBuilder.setMag(LINEAR); sampleBuilder.setWrapS(CLAMP); sampleBuilder.setWrapT(CLAMP); mSampler = sampleBuilder.create(); ProgramFragment.Builder fragmentBuilder = new ProgramFragment.Builder(mRS); fragmentBuilder.setTexture(ProgramFragment.Builder.EnvMode.DECAL, ProgramFragment.Builder.Format.RGBA, 0); mFragmentProgram = fragmentBuilder.create(); mFragmentProgram.bindSampler(mSampler, 0); mScript.set_fragmentProgram(mFragmentProgram); } private void initProgramStore() { ProgramStore.Builder programStoreBuilder = new ProgramStore.Builder(mRS, null, null); programStoreBuilder.setDepthFunc(ProgramStore.DepthFunc.LESS); programStoreBuilder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA, ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); programStoreBuilder.setDitherEnable(false); programStoreBuilder.setDepthMask(true); mProgramStore = programStoreBuilder.create(); mScript.set_programStore(mProgramStore); } public void createCards(int count) { mCards = count > 0 ? new ScriptField_Card(mRS, count) : null; mScript.bind_cards(mCards); mScript.invoke_createCards(count); } public void setVisibleSlots(int count) { mScript.set_visibleSlotCount(count); } public void setDefaultBitmap(Bitmap bitmap) { mScript.set_defaultTexture(allocationFromBitmap(bitmap, MIPMAP)); } public void setLoadingBitmap(Bitmap bitmap) { mScript.set_loadingTexture(allocationFromBitmap(bitmap, MIPMAP)); } public void setDefaultGeometry(Mesh mesh) { mScript.set_defaultGeometry(mesh); } public void setLoadingGeometry(Mesh mesh) { mScript.set_loadingGeometry(mesh); } public void setStartAngle(float theta) { mScript.set_startAngle(theta); } public void setCallback(CarouselCallback callback) { mCallback = callback; } private Allocation allocationFromBitmap(Bitmap bitmap, boolean mipmap) { if (bitmap == null) return null; Allocation allocation = Allocation.createFromBitmap(mRS, bitmap, RGB_565(mRS), mipmap); allocation.uploadToTexture(0); return allocation; } public void setTexture(int n, Bitmap bitmap) { ScriptField_Card.Item item = mCards.get(n); if (item == null) { Log.v(TAG, "setTexture(): no item at index " + n); item = new ScriptField_Card.Item(); } if (bitmap != null) { Log.v(TAG, "creating new bitmap"); item.texture = Allocation.createFromBitmap(mRS, bitmap, RGB_565(mRS), MIPMAP); Log.v(TAG, "uploadToTexture(" + n + ")"); item.texture.uploadToTexture(0); Log.v(TAG, "done..."); } else { if (item.texture != null) { Log.v(TAG, "unloading texture " + n); // Don't wait for GC to free native memory. // Only works if textures are not shared. item.texture.destroy(); item.texture = null; } } mCards.set(item, n, false); // This is primarily used for reference counting. mScript.invoke_setTexture(n, item.texture); } public void setGeometry(int n, Mesh geometry) { final boolean mipmap = false; ScriptField_Card.Item item = mCards.get(n); if (item == null) { Log.v(TAG, "setGeometry(): no item at index " + n); item = new ScriptField_Card.Item(); } if (geometry != null) { item.geometry = geometry; } else { Log.v(TAG, "unloading geometry " + n); if (item.geometry != null) { // item.geometry.destroy(); item.geometry = null; } } mCards.set(item, n, false); mScript.invoke_setGeometry(n, item.geometry); } public void pauseRendering() { // Used to update multiple states at once w/o redrawing for each. mRS.contextBindRootScript(null); } public void resumeRendering() { mRS.contextBindRootScript(mScript); } public void doMotion(float x, float y) { mScript.invoke_doMotion(x,y); } public void doSelection(float x, float y) { mScript.invoke_doSelection(x, y); } public void doStart(float x, float y) { mScript.invoke_doStart(x, y); } public void doStop(float x, float y) { mScript.invoke_doStop(x, y); } public void setSlotCount(int n) { mScript.set_slotCount(n); } }
core/java/com/android/internal/widget/CarouselView.java 0 → 100644 +244 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 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.internal.widget; import com.android.internal.widget.CarouselRS.CarouselCallback; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.renderscript.FileA3D; import android.renderscript.Mesh; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScriptGL; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; public class CarouselView extends RSSurfaceView { private final int DEFAULT_SLOT_COUNT = 10; private final Bitmap DEFAULT_BITMAP = Bitmap.createBitmap(1, 1, Config.RGB_565); private static final String TAG = "CarouselView"; private CarouselRS mRenderScript; private RenderScriptGL mRS; private Context mContext; private boolean mTracking; private Bitmap mDefaultBitmap; private Bitmap mLoadingBitmap; private Mesh mDefaultGeometry; private Mesh mLoadingGeometry; private int mCardCount = 0; private int mVisibleSlots = 0; private float mStartAngle; private int mSlotCount = DEFAULT_SLOT_COUNT; public CarouselView(Context context) { super(context); mContext = context; boolean useDepthBuffer = true; mRS = createRenderScript(useDepthBuffer); mRenderScript = new CarouselRS(); mRenderScript.init(mRS, getResources()); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); mRS.contextSetSurface(w, h, holder.getSurface()); mRenderScript.init(mRS, getResources()); setSlotCount(mSlotCount); createCards(mCardCount); setVisibleSlots(mVisibleSlots); setCallback(mCarouselCallback); setDefaultBitmap(mDefaultBitmap); setLoadingBitmap(mLoadingBitmap); setDefaultGeometry(mDefaultGeometry); setLoadingGeometry(mLoadingGeometry); setStartAngle(mStartAngle); } /** * Loads geometry from a resource id. * * @param resId * @return the loaded mesh or null if it cannot be loaded */ public Mesh loadGeometry(int resId) { Resources res = mContext.getResources(); FileA3D model = FileA3D.createFromResource(mRS, res, resId); FileA3D.IndexEntry entry = model.getIndexEntry(0); if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) { return null; } return (Mesh) entry.getObject(); } /** * Load A3D file from resource. If resId == 0, will clear geometry for this item. * @param n * @param resId */ public void setGeometryForItem(int n, Mesh mesh) { mRenderScript.setGeometry(n, mesh); } public void setSlotCount(int n) { mSlotCount = n; if (mRenderScript != null) { mRenderScript.setSlotCount(n); } } public void setVisibleSlots(int n) { mVisibleSlots = n; if (mRenderScript != null) { mRenderScript.setVisibleSlots(n); } } public void createCards(int n) { mCardCount = n; if (mRenderScript != null) { mRenderScript.createCards(n); } } public void setTextureForItem(int n, Bitmap bitmap) { if (mRenderScript != null) { Log.v(TAG, "setTextureForItem(" + n + ")"); mRenderScript.setTexture(n, bitmap); Log.v(TAG, "done"); } } public void setDefaultBitmap(Bitmap bitmap) { mDefaultBitmap = bitmap; if (mRenderScript != null) { mRenderScript.setDefaultBitmap(bitmap); } } public void setLoadingBitmap(Bitmap bitmap) { mLoadingBitmap = bitmap; if (mRenderScript != null) { mRenderScript.setLoadingBitmap(bitmap); } } public void setDefaultGeometry(Mesh mesh) { mDefaultGeometry = mesh; if (mRenderScript != null) { mRenderScript.setDefaultGeometry(mesh); } } public void setLoadingGeometry(Mesh mesh) { mLoadingGeometry = mesh; if (mRenderScript != null) { mRenderScript.setLoadingGeometry(mesh); } } public void setCallback(CarouselCallback callback) { mCarouselCallback = callback; if (mRenderScript != null) { mRenderScript.setCallback(callback); } } public void setStartAngle(float angle) { mStartAngle = angle; if (mRenderScript != null) { mRenderScript.setStartAngle(angle); } } @Override protected void onDetachedFromWindow() { if(mRS != null) { mRS = null; destroyRenderScript(); } } @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getAction(); final float x = event.getX(); final float y = event.getY(); if (mRenderScript == null) { return true; } switch (action) { case MotionEvent.ACTION_DOWN: mTracking = true; mRenderScript.doStart(x, y); break; case MotionEvent.ACTION_MOVE: if (mTracking) { mRenderScript.doMotion(x, y); } break; case MotionEvent.ACTION_UP: mRenderScript.doStop(x, y); mTracking = false; break; } return true; } private final CarouselCallback DEBUG_CALLBACK = new CarouselCallback() { public void onAnimationStarted() { Log.v(TAG, "onAnimationStarted()"); } public void onAnimationFinished() { Log.v(TAG, "onAnimationFinished()"); } public void onCardSelected(int n) { Log.v(TAG, "onCardSelected(" + n + ")"); } public void onRequestGeometry(int n) { Log.v(TAG, "onRequestGeometry(" + n + ")"); } public void onInvalidateGeometry(int n) { Log.v(TAG, "onInvalidateGeometry(" + n + ")"); } public void onRequestTexture(final int n) { Log.v(TAG, "onRequestTexture(" + n + ")"); } public void onInvalidateTexture(int n) { Log.v(TAG, "onInvalidateTexture(" + n + ")"); } }; private CarouselCallback mCarouselCallback = DEBUG_CALLBACK; }