15ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller/*
25ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * Copyright (C) 2010 The Android Open Source Project
35ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *
45ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * Licensed under the Apache License, Version 2.0 (the "License");
55ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * you may not use this file except in compliance with the License.
65ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * You may obtain a copy of the License at
75ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *
85ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *      http://www.apache.org/licenses/LICENSE-2.0
95ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *
105ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * Unless required by applicable law or agreed to in writing, software
115ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * distributed under the License is distributed on an "AS IS" BASIS,
125ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * See the License for the specific language governing permissions and
145ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * limitations under the License.
155ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller */
165ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
175ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerpackage com.android.ex.carousel;
185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.content.res.Resources;
205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.graphics.Bitmap;
21e8cab95c5f73ddf6843d82793decc3adb4692860Jim Shumaimport android.graphics.Rect;
225ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.renderscript.*;
23819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchoukimport static android.renderscript.Element.*;
24819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchoukimport android.renderscript.Program.TextureType;
2527b81f375cfa65f4f689c64bd2c48e3a56c1e11bJason Samsimport android.renderscript.RenderScript.RSMessageHandler;
265ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.util.Log;
275ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
287cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller/**
297cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * This is a support class for Carousel renderscript.  It handles most of the low-level interactions
307cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * with Renderscript as well as dispatching events.
317cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller *
327cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller */
335ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerpublic class CarouselRS  {
345ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private static final int DEFAULT_VISIBLE_SLOTS = 1;
35b8c3aee40f704e71fd9a8af41f060ebae2ea445fBryan Mawhinney    private static final int DEFAULT_CARD_COUNT = 0;
360cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney    private static final int DEFAULT_ROW_COUNT = 1;
375ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
385ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    // Client messages *** THIS LIST MUST MATCH THOSE IN carousel.rs ***
395ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static final int CMD_CARD_SELECTED = 100;
408fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma    public static final int CMD_DETAIL_SELECTED = 105;
41594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma    public static final int CMD_CARD_LONGPRESS = 110;
425ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static final int CMD_REQUEST_TEXTURE = 200;
435ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static final int CMD_INVALIDATE_TEXTURE = 210;
445ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static final int CMD_REQUEST_GEOMETRY = 300;
455ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static final int CMD_INVALIDATE_GEOMETRY = 310;
465ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static final int CMD_ANIMATION_STARTED = 400;
475ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static final int CMD_ANIMATION_FINISHED = 500;
487cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    public static final int CMD_REQUEST_DETAIL_TEXTURE = 600;
497cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    public static final int CMD_INVALIDATE_DETAIL_TEXTURE = 610;
507cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    public static final int CMD_PING = 1000; // for debugging
515ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
52be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller    // Drag models *** THIS LIST MUST MATCH THOSE IN carousel.rs ***
53be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller    public static final int DRAG_MODEL_SCREEN_DELTA = 0;
54be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller    public static final int DRAG_MODEL_PLANE = 1;
55be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller    public static final int DRAG_MODEL_CYLINDER_INSIDE = 2;
56be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller    public static final int DRAG_MODEL_CYLINDER_OUTSIDE = 3;
57be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller
5814d2c1ec52bb04b5120c2bfdd1a8811a238573ceJim Shuma    public static final int FILL_DIRECTION_CCW = +1;
5914d2c1ec52bb04b5120c2bfdd1a8811a238573ceJim Shuma    public static final int FILL_DIRECTION_CW = -1;
6014d2c1ec52bb04b5120c2bfdd1a8811a238573ceJim Shuma
615ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private static final String TAG = "CarouselRS";
625ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private static final int DEFAULT_SLOT_COUNT = 10;
630508a5d4e679d52de6e902c07e63d5856225d616Jason Sams    private static final Allocation.MipmapControl MIPMAP =
640508a5d4e679d52de6e902c07e63d5856225d616Jason Sams        Allocation.MipmapControl.MIPMAP_NONE;
657cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    private static final boolean DBG = false;
665ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
675ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private RenderScriptGL mRS;
685ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private Resources mRes;
691126aa8ba186b42baf5b14c66d44b59f43888b70Stephen Hines    private ScriptC_carousel mScript;
705ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private ScriptField_Card mCards;
71420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    private ScriptField_FragmentShaderConstants_s mFSConst;
72f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    private ScriptField_ProgramStore_s mProgramStoresCard;
73420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    private ProgramFragment mSingleTextureFragmentProgram;
743adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma    private ProgramFragment mSingleTextureBlendingFragmentProgram;
75420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    private ProgramFragment mMultiTextureFragmentProgram;
763adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma    private ProgramFragment mMultiTextureBlendingFragmentProgram;
775ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private ProgramVertex mVertexProgram;
785ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private ProgramRaster mRasterProgram;
791eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller    private Allocation[] mAllocationPool;
80f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    private boolean mForceBlendCardsWithZ;
811eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller    private int mVisibleSlots;
820cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney    private int mRowCount;
831eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller    private int mPrefetchCardCount;
845ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private CarouselCallback mCallback;
85a044fbbb1e5498a0112f20a1b0de11a4089ef612Jim Miller    private float[] mEyePoint = new float[] { 2.0f, 0.0f, 0.0f };
86a044fbbb1e5498a0112f20a1b0de11a4089ef612Jim Miller    private float[] mAtPoint = new float[] { 0.0f, 0.0f, 0.0f };
87a044fbbb1e5498a0112f20a1b0de11a4089ef612Jim Miller    private float[] mUp = new float[] { 0.0f, 1.0f, 0.0f };
88a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller
89a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller    private static final String mSingleTextureShader = new String(
909f0c6badc3e8f928c6f2658a3c85ea50319424d4Alex Sakhartchouk            "varying vec2 varTex0;" +
91a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller            "void main() {" +
92a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller            "vec2 t0 = varTex0.xy;" +
93a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller            "vec4 col = texture2D(UNI_Tex0, t0);" +
94a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller            "gl_FragColor = col; " +
95a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller            "}");
96a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller
973adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma    private static final String mSingleTextureBlendingShader = new String(
983adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "varying vec2 varTex0;" +
993adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "void main() {" +
1003adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "vec2 t0 = varTex0.xy;" +
1013adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "vec4 col = texture2D(UNI_Tex0, t0);" +
1023adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "gl_FragColor = col * UNI_overallAlpha; " +
1033adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "}");
1043adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma
105a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller    private static final String mMultiTextureShader = new String(
1069f0c6badc3e8f928c6f2658a3c85ea50319424d4Alex Sakhartchouk            "varying vec2 varTex0;" +
107420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller            "void main() {" +
108420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller            "vec2 t0 = varTex0.xy;" +
109420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller            "vec4 col = texture2D(UNI_Tex0, t0);" +
110420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller            "vec4 col2 = texture2D(UNI_Tex1, t0);" +
111420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller            "gl_FragColor = mix(col, col2, UNI_fadeAmount);}");
1125ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1133adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma    private static final String mMultiTextureBlendingShader = new String(
1143adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "varying vec2 varTex0;" +
1153adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "void main() {" +
1163adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "vec2 t0 = varTex0.xy;" +
1173adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "vec4 col = texture2D(UNI_Tex0, t0);" +
1183adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "vec4 col2 = texture2D(UNI_Tex1, t0);" +
1193adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "gl_FragColor = mix(col, col2, UNI_fadeAmount) * UNI_overallAlpha;" +
1203adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma            "}"
1213adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma    );
1223adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma
1235ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static interface CarouselCallback {
1245ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        /**
1255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * Called when a card is selected
1265ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * @param n the id of the card
1275ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         */
1285ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        void onCardSelected(int n);
1295ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1305ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        /**
1318fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma         * Called when the detail texture for a card is tapped
1328fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma         * @param n the id of the card
1338fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma         * @param x how far the user tapped from the left edge of the card, in pixels
1348fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma         * @param y how far the user tapped from the top edge of the card, in pixels
1358fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma         */
1368fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma        void onDetailSelected(int n, int x, int y);
1378fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma
1388fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma        /**
139594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma         * Called when a card is long-pressed
140594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma         * @param n the id of the card
141e8cab95c5f73ddf6843d82793decc3adb4692860Jim Shuma         * @param touchPosition position of where the user pressed, in screen coordinates
142e8cab95c5f73ddf6843d82793decc3adb4692860Jim Shuma         * @param detailCoordinates position of detail texture, in screen coordinates
143594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma         */
144e8cab95c5f73ddf6843d82793decc3adb4692860Jim Shuma        void onCardLongPress(int n, int touchPosition[], Rect detailCoordinates);
145594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma
146594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma        /**
1475ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * Called when texture is needed for card n.  This happens when the given card becomes
1485ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * visible.
1495ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * @param n the id of the card
1505ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         */
1515ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        void onRequestTexture(int n);
1525ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1535ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        /**
1545ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * Called when a texture is no longer needed for card n.  This happens when the card
1555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * goes out of view.
1565ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * @param n the id of the card
1575ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         */
1585ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        void onInvalidateTexture(int n);
1595ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1605ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        /**
1617cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         * Called when detail texture is needed for card n.  This happens when the given card
1627cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         * becomes visible.
1637cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         * @param n the id of the card
1647cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         */
1657cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        void onRequestDetailTexture(int n);
1667cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
1677cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        /**
1687cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         * Called when a detail texture is no longer needed for card n.  This happens when the card
1697cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         * goes out of view.
1707cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         * @param n the id of the card
1717cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller         */
1727cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        void onInvalidateDetailTexture(int n);
1737cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
1747cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        /**
1755ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * Called when geometry is needed for card n.
1765ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * @param n the id of the card.
1775ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         */
1785ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        void onRequestGeometry(int n);
1795ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1805ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        /**
1819afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller         * Called when geometry is no longer needed for card n. This happens when the card goes
1825ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * out of view.
1835ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * @param n the id of the card
1845ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         */
1855ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        void onInvalidateGeometry(int n);
1865ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1875ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        /**
1885ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * Called when card animation (e.g. a fling) has started.
1895ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         */
1905ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        void onAnimationStarted();
1915ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1925ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        /**
1935ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         * Called when card animation has stopped.
1948fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma         * @param carouselRotationAngle the angle of rotation, in radians, at which the animation
1958fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma         * stopped.
1965ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller         */
197a84feeb7e4dc1a75ec6d0b1f2494893987fc3ca3Jack Palevich        void onAnimationFinished(float carouselRotationAngle);
1985ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    };
1995ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
20027b81f375cfa65f4f689c64bd2c48e3a56c1e11bJason Sams    private RSMessageHandler mRsMessage = new RSMessageHandler() {
2015ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public void run() {
2025ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            if (mCallback == null) return;
2035ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            switch (mID) {
2045ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_CARD_SELECTED:
2055ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    mCallback.onCardSelected(mData[0]);
2065ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    break;
2075ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2088fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma                case CMD_DETAIL_SELECTED:
2098fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma                    mCallback.onDetailSelected(mData[0], mData[1], mData[2]);
2108fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma                    break;
2118fd40311898a9ec759a76f021642f43e617e38c4Jim Shuma
212594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma                case CMD_CARD_LONGPRESS:
213e8cab95c5f73ddf6843d82793decc3adb4692860Jim Shuma                    int touchPosition[] = { mData[1], mData[2] };
214e8cab95c5f73ddf6843d82793decc3adb4692860Jim Shuma                    Rect detailCoordinates = new Rect(mData[3], mData[4], mData[5], mData[6]);
215e8cab95c5f73ddf6843d82793decc3adb4692860Jim Shuma                    mCallback.onCardLongPress(mData[0], touchPosition, detailCoordinates);
216594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma                    break;
217594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma
2185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_REQUEST_TEXTURE:
2195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    mCallback.onRequestTexture(mData[0]);
2205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    break;
2215ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2225ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_INVALIDATE_TEXTURE:
223c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    setTexture(mData[0], null);
2245ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    mCallback.onInvalidateTexture(mData[0]);
2255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    break;
2265ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2277cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller                case CMD_REQUEST_DETAIL_TEXTURE:
2287cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller                    mCallback.onRequestDetailTexture(mData[0]);
2297cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller                    break;
2307cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
2317cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller                case CMD_INVALIDATE_DETAIL_TEXTURE:
232b378af500b36226635b6343b1d5009ee9af44fc1Jim Miller                    setDetailTexture(mData[0], 0.0f, 0.0f, 0.0f, 0.0f, null);
2337cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller                    mCallback.onInvalidateDetailTexture(mData[0]);
2347cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller                    break;
2357cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
2365ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_REQUEST_GEOMETRY:
2375ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    mCallback.onRequestGeometry(mData[0]);
2385ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    break;
2395ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2405ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_INVALIDATE_GEOMETRY:
241c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    setGeometry(mData[0], null);
2425ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    mCallback.onInvalidateGeometry(mData[0]);
2435ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    break;
2445ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2455ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_ANIMATION_STARTED:
2465ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    mCallback.onAnimationStarted();
2475ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    break;
2485ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2495ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_ANIMATION_FINISHED:
250a84feeb7e4dc1a75ec6d0b1f2494893987fc3ca3Jack Palevich                    mCallback.onAnimationFinished(Float.intBitsToFloat(mData[0]));
251198a060d650bc849ef0f25b597888fac9546803bJack Palevich                    break;
252198a060d650bc849ef0f25b597888fac9546803bJack Palevich
2535ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                case CMD_PING:
2547cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller                    if (DBG) Log.v(TAG, "PING...");
2555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    break;
2565ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2575ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                default:
2585ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    Log.e(TAG, "Unknown RSMessage: " + mID);
2595ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            }
2605ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
2615ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    };
2625ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
263a044fbbb1e5498a0112f20a1b0de11a4089ef612Jim Miller    public CarouselRS(RenderScriptGL rs, Resources res, int resId) {
2645ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mRS = rs;
2655ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mRes = res;
2665ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2675ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        // create the script object
26827b81f375cfa65f4f689c64bd2c48e3a56c1e11bJason Sams        mScript = new ScriptC_carousel(mRS, mRes, resId);
26927b81f375cfa65f4f689c64bd2c48e3a56c1e11bJason Sams        mRS.setMessageHandler(mRsMessage);
2705ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        initProgramStore();
2715ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        initFragmentProgram();
2725ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        initRasterProgram();
2735ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        initVertexProgram();
2745ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setSlotCount(DEFAULT_SLOT_COUNT);
2755ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setVisibleSlots(DEFAULT_VISIBLE_SLOTS);
2760cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney        setRowCount(DEFAULT_ROW_COUNT);
2775ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        createCards(DEFAULT_CARD_COUNT);
2785ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setStartAngle(0.0f);
279a84feeb7e4dc1a75ec6d0b1f2494893987fc3ca3Jack Palevich        setCarouselRotationAngle(0.0f);
2805ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setRadius(1.0f);
281a044fbbb1e5498a0112f20a1b0de11a4089ef612Jim Miller        setLookAt(mEyePoint, mAtPoint, mUp);
282a044fbbb1e5498a0112f20a1b0de11a4089ef612Jim Miller        setRadius(20.0f);
283a044fbbb1e5498a0112f20a1b0de11a4089ef612Jim Miller        // Fov: 25
2845ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
2855ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2865ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setLookAt(float[] eye, float[] at, float[] up) {
2875ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        for (int i = 0; i < 3; i++) {
2885ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mEyePoint[i] = eye[i];
2895ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mAtPoint[i] = at[i];
2905ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mUp[i] = up[i];
2915ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
2925ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.invoke_lookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], up[0], up[1], up[2]);
2935ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
2945ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2955ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setRadius(float radius) {
296be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller        mScript.invoke_setRadius(radius);
2975ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
2985ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
299c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setCardRotation(float cardRotation) {
300c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mScript.set_cardRotation(cardRotation);
301c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
302c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
30383d7a5f03e6511372f73e3e4e03a6d403b20125dBryan Mawhinney    public void setCardsFaceTangent(boolean faceTangent) {
30483d7a5f03e6511372f73e3e4e03a6d403b20125dBryan Mawhinney        mScript.set_cardsFaceTangent(faceTangent);
30583d7a5f03e6511372f73e3e4e03a6d403b20125dBryan Mawhinney    }
30683d7a5f03e6511372f73e3e4e03a6d403b20125dBryan Mawhinney
307c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setSwaySensitivity(float swaySensitivity) {
308c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mScript.set_swaySensitivity(swaySensitivity);
309c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
310c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
311c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setFrictionCoefficient(float frictionCoeff) {
312c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mScript.set_frictionCoeff(frictionCoeff);
313c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
314c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
315c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setDragFactor(float dragFactor) {
316c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mScript.set_dragFactor(dragFactor);
317c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
318c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
319be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller    public void setDragModel(int model) {
320be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller        mScript.set_dragModel(model);
321be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller    }
322be5482f170e191aa98a3c2ecefdeaf936b7df412Jim Miller
32314d2c1ec52bb04b5120c2bfdd1a8811a238573ceJim Shuma    public void setFillDirection(int direction) {
32414d2c1ec52bb04b5120c2bfdd1a8811a238573ceJim Shuma        mScript.set_fillDirection(direction);
32514d2c1ec52bb04b5120c2bfdd1a8811a238573ceJim Shuma    }
32614d2c1ec52bb04b5120c2bfdd1a8811a238573ceJim Shuma
327c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma    private Matrix4f matrixFromFloat(float[] matrix) {
32851dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        int dimensions;
32951dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        if (matrix == null || matrix.length == 0) {
33051dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney          dimensions = 0;
33151dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        } else if (matrix.length == 16) {
33251dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney          dimensions = 4;
33351dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        } else if (matrix.length == 9) {
33451dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney          dimensions = 3;
33551dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        } else {
33651dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney          throw new IllegalArgumentException("matrix length not 0,9 or 16");
33751dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        }
33851dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney
33951dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        Matrix4f rsMatrix = new Matrix4f();  // initialized as identity.
34051dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        for (int i = 0; i < dimensions; i++) {
34151dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney            for (int j = 0; j < dimensions; j++) {
34251dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney                rsMatrix.set(i, j, matrix[i*dimensions + j]);
34351dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney            }
34451dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney        }
345c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma
346c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        return rsMatrix;
347c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma    }
348c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma
349c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma    public void setDefaultCardMatrix(float[] matrix) {
350c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        mScript.set_defaultCardMatrix(matrixFromFloat(matrix));
35151dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney    }
35251dd0196e4f3bd4086545f5bf30038ca9ad9ac27Bryan Mawhinney
3535ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private void initVertexProgram() {
354819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
3555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mVertexProgram = pvb.create();
356819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        ProgramVertexFixedFunction.Constants pva = new ProgramVertexFixedFunction.Constants(mRS);
357819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        ((ProgramVertexFixedFunction)mVertexProgram).bindConstants(pva);
358819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        Matrix4f proj = new Matrix4f();
359819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        proj.loadProjectionNormalized(1, 1);
360819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        pva.setProjection(proj);
3615ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_vertexProgram(mVertexProgram);
3625ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
3635ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
3645ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private void initRasterProgram() {
3655ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        ProgramRaster.Builder programRasterBuilder = new ProgramRaster.Builder(mRS);
3665ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mRasterProgram = programRasterBuilder.create();
3675ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        //mRasterProgram.setCullMode(CullMode.NONE);
3685ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_rasterProgram(mRasterProgram);
3695ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
3705ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
3715ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private void initFragmentProgram() {
372a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        //
373a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Single texture program
374a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        //
375819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        ProgramFragment.Builder pfbSingle = new ProgramFragment.Builder(mRS);
376a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Specify the resource that contains the shader string
377a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        pfbSingle.setShader(mSingleTextureShader);
378a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Tell the builder how many textures we have
379819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        pfbSingle.addTexture(Program.TextureType.TEXTURE_2D);
380a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mSingleTextureFragmentProgram = pfbSingle.create();
381a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Bind the source of constant data
382a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mSingleTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
383a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller
384a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        //
3853adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Single texture program, plus blending
386a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        //
387a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mFSConst = new ScriptField_FragmentShaderConstants_s(mRS, 1);
388a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mScript.bind_shaderConstants(mFSConst);
389819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        ProgramFragment.Builder pfbSingleBlend = new ProgramFragment.Builder(mRS);
3903adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Specify the resource that contains the shader string
3913adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        pfbSingleBlend.setShader(mSingleTextureBlendingShader);
3923adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Tell the builder how many textures we have
393819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        pfbSingleBlend.addTexture(Program.TextureType.TEXTURE_2D);
3943adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Define the constant input layout
3953adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        pfbSingleBlend.addConstant(mFSConst.getAllocation().getType());
3963adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mSingleTextureBlendingFragmentProgram = pfbSingleBlend.create();
3973adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Bind the source of constant data
3983adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mSingleTextureBlendingFragmentProgram.bindConstants(mFSConst.getAllocation(), 0);
3993adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mSingleTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
4003adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma
4013adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        //
4023adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Multi texture program
4033adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        //
404819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        ProgramFragment.Builder pfbMulti = new ProgramFragment.Builder(mRS);
405a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Specify the resource that contains the shader string
406a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        pfbMulti.setShader(mMultiTextureShader);
407a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Tell the builder how many textures we have
408819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        pfbMulti.addTexture(Program.TextureType.TEXTURE_2D);
409819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        pfbMulti.addTexture(Program.TextureType.TEXTURE_2D);
410a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Define the constant input layout
411a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        pfbMulti.addConstant(mFSConst.getAllocation().getType());
412a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mMultiTextureFragmentProgram = pfbMulti.create();
413a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        // Bind the source of constant data
414a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mMultiTextureFragmentProgram.bindConstants(mFSConst.getAllocation(), 0);
415a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
416a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mMultiTextureFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 1);
417a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller
4183adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        //
4193adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Multi texture program, plus blending
4203adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        //
421819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        ProgramFragment.Builder pfbMultiBlend = new ProgramFragment.Builder(mRS);
4223adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Specify the resource that contains the shader string
4233adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        pfbMultiBlend.setShader(mMultiTextureBlendingShader);
4243adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Tell the builder how many textures we have
425819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        pfbMultiBlend.addTexture(Program.TextureType.TEXTURE_2D);
426819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk        pfbMultiBlend.addTexture(Program.TextureType.TEXTURE_2D);
4273adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Define the constant input layout
4283adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        pfbMultiBlend.addConstant(mFSConst.getAllocation().getType());
4293adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mMultiTextureBlendingFragmentProgram = pfbMultiBlend.create();
4303adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        // Bind the source of constant data
4313adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mMultiTextureBlendingFragmentProgram.bindConstants(mFSConst.getAllocation(), 0);
4323adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mMultiTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
4333adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mMultiTextureBlendingFragmentProgram.bindSampler(Sampler.CLAMP_LINEAR(mRS), 1);
4343adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma
435a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mScript.set_linearClamp(Sampler.CLAMP_LINEAR(mRS));
436a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mScript.set_singleTextureFragmentProgram(mSingleTextureFragmentProgram);
4373adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mScript.set_singleTextureBlendingFragmentProgram(mSingleTextureBlendingFragmentProgram);
438a9e9c4bef076e718094786edfe0290f798e1db4bJim Miller        mScript.set_multiTextureFragmentProgram(mMultiTextureFragmentProgram);
4393adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mScript.set_multiTextureBlendingFragmentProgram(mMultiTextureBlendingFragmentProgram);
4405ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
4415ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4425ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private void initProgramStore() {
443f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        resizeProgramStoresCard(1);
444f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
445fb179e7afd8f02be63061b478b0283e3085fc25fJim Miller        final boolean dither = true;
446f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        final ProgramStore.DepthFunc depthFunc = mForceBlendCardsWithZ ?
447f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                ProgramStore.DepthFunc.LESS : ProgramStore.DepthFunc.ALWAYS;
448f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
449f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        // Background: Alpha disabled, depth optional
450f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        mScript.set_programStoreBackground(new ProgramStore.Builder(mRS)
451f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ZERO)
452819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk            .setDitherEnabled(dither)
453f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .setDepthFunc(depthFunc)
454819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk            .setDepthMaskEnabled(mForceBlendCardsWithZ)
455f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .create());
456f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
457f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        // Card: Alpha enabled, depth optional
458f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        setProgramStoreCard(0, new ProgramStore.Builder(mRS)
459f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
460f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
461819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk            .setDitherEnabled(dither)
462f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .setDepthFunc(depthFunc)
463819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk            .setDepthMaskEnabled(mForceBlendCardsWithZ)
464f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .create());
465f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
466f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        // Detail: Alpha enabled, depth disabled
467f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        mScript.set_programStoreDetail(new ProgramStore.Builder(mRS)
468f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .setBlendFunc(ProgramStore.BlendSrcFunc.ONE,
469f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA)
470819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk            .setDitherEnabled(dither)
471f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .setDepthFunc(ProgramStore.DepthFunc.ALWAYS)
472819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk            .setDepthMaskEnabled(false)
473f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            .create());
4745ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
4755ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4765ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void createCards(int count)
4775ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
4783df59346f395434454d310b070fff195089fbaf1Jim Miller        // Because RenderScript can't have allocations with 0 dimensions, we always create
4793df59346f395434454d310b070fff195089fbaf1Jim Miller        // an allocation of at least one card. This relies on invoke_createCards() to keep
4803df59346f395434454d310b070fff195089fbaf1Jim Miller        // track of when the allocation is not valid.
481d696cd4dc90b92e7653d5bcb0b14654c588e9d7dJim Shuma        if (mCards != null && count > 0) {
4828b55d7500c1e5a88c415dae8dcead16b152d7929Jack Palevich            // resize the array
4836f2cc8cf611860467315ecc542f71a225625eb1cJason Sams            int oldSize = mCards.getAllocation().getType().getX();
484d696cd4dc90b92e7653d5bcb0b14654c588e9d7dJim Shuma            mCards.resize(count);
4856f2cc8cf611860467315ecc542f71a225625eb1cJason Sams            mScript.invoke_createCards(oldSize, count);
4868b55d7500c1e5a88c415dae8dcead16b152d7929Jack Palevich        } else {
4878b55d7500c1e5a88c415dae8dcead16b152d7929Jack Palevich            // create array from scratch
4888b55d7500c1e5a88c415dae8dcead16b152d7929Jack Palevich            mCards = new ScriptField_Card(mRS, count > 0 ? count : 1);
4898b55d7500c1e5a88c415dae8dcead16b152d7929Jack Palevich            mScript.bind_cards(mCards);
4906f2cc8cf611860467315ecc542f71a225625eb1cJason Sams            mScript.invoke_createCards(0, count);
4918b55d7500c1e5a88c415dae8dcead16b152d7929Jack Palevich        }
4925ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
4935ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4945ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setVisibleSlots(int count)
4955ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
4961eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        mVisibleSlots = count;
4975ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_visibleSlotCount(count);
4985ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
4995ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
5007c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma    public void setVisibleDetails(int count) {
5017c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma        mScript.set_visibleDetailCount(count);
5027c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma    }
5037c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma
5040cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney    public void setRowCount(int count) {
5050cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney        mRowCount = count;
5060cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney        mScript.set_rowCount(count);
5070cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney    }
5080cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney
5090cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney    public void setRowSpacing(float spacing) {
5100cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney        mScript.set_rowSpacing(spacing);
5110cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney    }
5120cec8afdb4f9d78adf88c9b9b41e993aef617beaBryan Mawhinney
5139afded4d212243e554c2695c4a2f90c13628e24bBryan Mawhinney    public void setOverscrollSlots(float slots) {
5149afded4d212243e554c2695c4a2f90c13628e24bBryan Mawhinney        mScript.set_overscrollSlots(slots);
5159afded4d212243e554c2695c4a2f90c13628e24bBryan Mawhinney    }
5169afded4d212243e554c2695c4a2f90c13628e24bBryan Mawhinney
5171a5b4d109397ea175b5cbaa7490ca18e78eb040fSimon Wilson    public void setFirstCardTop(boolean first) {
5181a5b4d109397ea175b5cbaa7490ca18e78eb040fSimon Wilson        mScript.set_firstCardTop(first);
5191a5b4d109397ea175b5cbaa7490ca18e78eb040fSimon Wilson    }
5201a5b4d109397ea175b5cbaa7490ca18e78eb040fSimon Wilson
5214fe6ea729d1fc44c8126de7a92a710c3885fb2ecJim Shuma    public void setPrefetchCardCount(int count) {
5221eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        mPrefetchCardCount = count;
5234fe6ea729d1fc44c8126de7a92a710c3885fb2ecJim Shuma        mScript.set_prefetchCardCount(count);
5244fe6ea729d1fc44c8126de7a92a710c3885fb2ecJim Shuma    }
5254fe6ea729d1fc44c8126de7a92a710c3885fb2ecJim Shuma
5264a8736e22d7b40ab9dfa3fbd8a10de92144912b3Bryan Mawhinney    public void setDetailTextureAlignment(int alignment) {
5274a8736e22d7b40ab9dfa3fbd8a10de92144912b3Bryan Mawhinney        mScript.set_detailTextureAlignment(alignment);
5284fe6ea729d1fc44c8126de7a92a710c3885fb2ecJim Shuma    }
5294fe6ea729d1fc44c8126de7a92a710c3885fb2ecJim Shuma
530f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    private void resizeProgramStoresCard(int count) {
531f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        // enableResize works around a Renderscript bug that keeps resizes from being propagated.
532f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        // TODO(jshuma): Remove enableResize once the Renderscript bug is fixed
533f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        final boolean enableResize = false;
534f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
535f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        if (mProgramStoresCard != null && enableResize) {
536f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            int newSize = count > 0 ? count : 1;
537f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            mProgramStoresCard.resize(newSize);
538f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        } else {
539f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            mProgramStoresCard = new ScriptField_ProgramStore_s(mRS, count > 0 ? count : 1);
540f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            mScript.bind_programStoresCard(mProgramStoresCard);
541f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        }
542f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    }
543f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
544f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    private void setProgramStoreCard(int n, ProgramStore programStore) {
545f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        ScriptField_ProgramStore_s.Item item = mProgramStoresCard.get(n);
546f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        if (item == null) {
547f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            item = new ScriptField_ProgramStore_s.Item();
548f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        }
549f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        item.programStore = programStore;
550f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        mProgramStoresCard.set(item, n, false);
551f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        mScript.invoke_setProgramStoresCard(n, programStore);
552f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    }
553f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
554f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    public void setStoreConfigs(int configs[]) {
555ac1d1fd9b14ce42aa9e04f8c472039790d736786Jim Shuma        if (configs == null) {
556ac1d1fd9b14ce42aa9e04f8c472039790d736786Jim Shuma            initProgramStore();
557ac1d1fd9b14ce42aa9e04f8c472039790d736786Jim Shuma            return;
558ac1d1fd9b14ce42aa9e04f8c472039790d736786Jim Shuma        }
559ac1d1fd9b14ce42aa9e04f8c472039790d736786Jim Shuma
560f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        final int count = configs.length;
561f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
562f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        resizeProgramStoresCard(count);
563f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        for (int i=0; i<count; ++i) {
564f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final int config = configs[i];
565f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
566f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final boolean alpha = (config & CarouselController.STORE_CONFIG_ALPHA) != 0;
567f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final boolean depthReads = (config & CarouselController.STORE_CONFIG_DEPTH_READS) != 0;
568f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final boolean depthWrites =
569f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    (config & CarouselController.STORE_CONFIG_DEPTH_WRITES) != 0;
570f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
571f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final boolean dither = true;
572f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final ProgramStore.BlendDstFunc dstFunc = alpha ?
573f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA :
574f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    ProgramStore.BlendDstFunc.ZERO;
575f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final ProgramStore.DepthFunc depthFunc = depthReads ?
576f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    ProgramStore.DepthFunc.LESS :
577f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    ProgramStore.DepthFunc.ALWAYS;
578f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
579f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            final ProgramStore ps = new ProgramStore.Builder(mRS)
580f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    .setBlendFunc(ProgramStore.BlendSrcFunc.ONE, dstFunc)
581819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk                    .setDitherEnabled(dither)
582f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    .setDepthFunc(depthFunc)
583819c18b25f5316429f34f975178999876c75b1deAlex Sakhartchouk                    .setDepthMaskEnabled(depthWrites)
584f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma                    .create();
585f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
586f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma            setProgramStoreCard(i, ps);
587f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        }
588f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    }
589f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma
590f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma    /**
591f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     * Sets whether the background texture and default card geometry are to be drawn with respect
592f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     * to the depth buffer (both reading from it and writing to it).
593f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     *
594f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     * This method is a specialization of functionality that can be done with greater flexibility
595f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     * by setStoreConfigs. Calling setForceBlendCardsWithZ() after calling setStoreConfigs()
596f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     * results in the values set in setStoreConfigs() being discarded.
597f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     *
598f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     * @param enabled true to read from and write to the depth buffer, false to ignore it
599f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma     */
600fb179e7afd8f02be63061b478b0283e3085fc25fJim Miller    public void setForceBlendCardsWithZ(boolean enabled) {
601f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        mForceBlendCardsWithZ = enabled;
602f664659f79399e92025e1dfe1ffbb682ff05613cJim Shuma        initProgramStore();
603bfc5ce2da9e0d8d0ec2535c465624574d98418d7Jim Shuma    }
604bfc5ce2da9e0d8d0ec2535c465624574d98418d7Jim Shuma
6057c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma    public void setDrawRuler(boolean drawRuler) {
6067c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma        mScript.set_drawRuler(drawRuler);
6077c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma    }
6087c09ccce478100d75e4427d87866ff19d758ae7aJim Shuma
6095ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setDefaultBitmap(Bitmap bitmap)
6105ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
6115ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_defaultTexture(allocationFromBitmap(bitmap, MIPMAP));
6125ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
6135ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
6145ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setLoadingBitmap(Bitmap bitmap)
6155ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
6165ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_loadingTexture(allocationFromBitmap(bitmap, MIPMAP));
6175ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
6185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
6195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setDefaultGeometry(Mesh mesh)
6205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
6215ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_defaultGeometry(mesh);
6225ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
6235ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
6245ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setLoadingGeometry(Mesh mesh)
6255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
6265ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_loadingGeometry(mesh);
6275ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
6285ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
6295ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setStartAngle(float theta)
6305ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
6315ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_startAngle(theta);
6325ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
6335ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
634a84feeb7e4dc1a75ec6d0b1f2494893987fc3ca3Jack Palevich    public void setCarouselRotationAngle(float theta) {
635a84feeb7e4dc1a75ec6d0b1f2494893987fc3ca3Jack Palevich        mScript.invoke_setCarouselRotationAngle(theta);
636a84feeb7e4dc1a75ec6d0b1f2494893987fc3ca3Jack Palevich    }
637a84feeb7e4dc1a75ec6d0b1f2494893987fc3ca3Jack Palevich
6388debeb8a0a785f0ad66bc75200cdb47c137602bcArnaud Berry    public void setCarouselRotationAngle(float endAngle, int milliseconds, int interpolationMode,
6398debeb8a0a785f0ad66bc75200cdb47c137602bcArnaud Berry            float maxAnimatedArc) {
6408debeb8a0a785f0ad66bc75200cdb47c137602bcArnaud Berry        mScript.invoke_setCarouselRotationAngle2(endAngle, milliseconds, interpolationMode,
6418debeb8a0a785f0ad66bc75200cdb47c137602bcArnaud Berry                maxAnimatedArc);
6428debeb8a0a785f0ad66bc75200cdb47c137602bcArnaud Berry    }
6438debeb8a0a785f0ad66bc75200cdb47c137602bcArnaud Berry
6445ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setCallback(CarouselCallback callback)
6455ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
6465ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mCallback = callback;
6475ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
6485ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
6490508a5d4e679d52de6e902c07e63d5856225d616Jason Sams    private Allocation allocationFromBitmap(Bitmap bitmap, Allocation.MipmapControl mipmap)
6505ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
6515ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (bitmap == null) return null;
652e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        Allocation allocation = Allocation.createFromBitmap(mRS, bitmap,
6530508a5d4e679d52de6e902c07e63d5856225d616Jason Sams                mipmap, Allocation.USAGE_GRAPHICS_TEXTURE);
6545ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        return allocation;
6555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
6565ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
6570508a5d4e679d52de6e902c07e63d5856225d616Jason Sams    private Allocation allocationFromPool(int n, Bitmap bitmap, Allocation.MipmapControl mipmap)
6581eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller    {
65946a02894a12775c16c4588a168c3cbc767a6f983Jim Miller        int count = (mVisibleSlots + 2*mPrefetchCardCount) * mRowCount;
6601eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        if (mAllocationPool == null || mAllocationPool.length != count) {
6611eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            Allocation[] tmp = new Allocation[count];
6621eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            int oldsize = mAllocationPool == null ? 0 : mAllocationPool.length;
6631eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            for (int i = 0; i < Math.min(count, oldsize); i++) {
6641eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller                tmp[i] = mAllocationPool[i];
6651eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            }
6661eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            mAllocationPool = tmp;
6671eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        }
6681eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        Allocation allocation = mAllocationPool[n % count];
6691eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        if (allocation == null) {
6701eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            allocation = allocationFromBitmap(bitmap, mipmap);
6711eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            mAllocationPool[n % count]  = allocation;
6721eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        } else if (bitmap != null) {
6731eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            if (bitmap.getWidth() == allocation.getType().getX()
6741eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller                && bitmap.getHeight() == allocation.getType().getY()) {
67527b81f375cfa65f4f689c64bd2c48e3a56c1e11bJason Sams                allocation.copyFrom(bitmap);
6761eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            } else {
6771eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller                Log.v(TAG, "Warning, bitmap has different size. Taking slow path");
6781eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller                allocation = allocationFromBitmap(bitmap, mipmap);
6791eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller                mAllocationPool[n % count]  = allocation;
6801eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller            }
6811eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        }
6821eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller        return allocation;
6831eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller    }
6841eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller
685ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma    private ScriptField_Card.Item getCard(int n) {
686c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        ScriptField_Card.Item item;
687c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        try {
688c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            item = mCards.get(n);
689c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        }
690c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        catch (ArrayIndexOutOfBoundsException e) {
691ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            if (DBG) Log.v(TAG, "getCard(): no item at index " + n);
692c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            item = null;
693c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        }
694ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma        return item;
695ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma    }
696ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma
697ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma    private ScriptField_Card.Item getOrCreateCard(int n) {
698ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma        ScriptField_Card.Item item = getCard(n);
699c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        if (item == null) {
700ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            if (DBG) Log.v(TAG, "getOrCreateCard(): no item at index " + n + "; creating new");
701c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            item = new ScriptField_Card.Item();
702c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        }
703c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        return item;
704c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma    }
705c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma
706ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma    private void setCard(int n, ScriptField_Card.Item item) {
707ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma        try {
708ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            mCards.set(item, n, false); // This is primarily used for reference counting.
709ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma        }
710ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma        catch (ArrayIndexOutOfBoundsException e) {
711ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            // The specified index didn't exist. This can happen when a stale invalidate
712ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            // request outlived an array resize request. Something might be getting dropped,
713ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            // but there's not much we can do about this at this point to recover.
714ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            Log.w(TAG, "setCard(" + n + "): Texture " + n + " doesn't exist");
715ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma        }
716ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma    }
717ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma
7185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setTexture(int n, Bitmap bitmap)
7195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
7203df59346f395434454d310b070fff195089fbaf1Jim Miller        if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
7213df59346f395434454d310b070fff195089fbaf1Jim Miller
722c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller        synchronized(this) {
723c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            ScriptField_Card.Item item = getOrCreateCard(n);
724c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            if (bitmap != null) {
7251eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller                item.texture = allocationFromPool(n, bitmap, MIPMAP);
726c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            } else {
727c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                if (item.texture != null) {
728c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    if (DBG) Log.v(TAG, "unloading texture " + n);
729c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    item.texture = null;
730c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                }
731c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            }
732ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            setCard(n, item);
733c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            mScript.invoke_setTexture(n, item.texture);
7345ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
7355ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
7365ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
737b378af500b36226635b6343b1d5009ee9af44fc1Jim Miller    void setDetailTexture(int n, float offx, float offy, float loffx, float loffy, Bitmap bitmap)
7387cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    {
7393df59346f395434454d310b070fff195089fbaf1Jim Miller        if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
7403df59346f395434454d310b070fff195089fbaf1Jim Miller
741c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller        synchronized(this) {
742c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            ScriptField_Card.Item item = getOrCreateCard(n);
743c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            float width = 0.0f;
744c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            float height = 0.0f;
745c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            if (bitmap != null) {
7461eccd028e704c15e842c1f23254d77a1a0a4cae0Jim Miller                item.detailTexture = allocationFromBitmap(bitmap, MIPMAP);
747c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                width = bitmap.getWidth();
748c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                height = bitmap.getHeight();
749c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            } else {
750c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                if (item.detailTexture != null) {
7518441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                    if (DBG) Log.v(TAG, "unloading detail texture " + n);
752c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    // Don't wait for GC to free native memory.
753c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    // Only works if textures are not shared.
754c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    item.detailTexture.destroy();
755c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    item.detailTexture = null;
756c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                }
7577cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            }
758ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            setCard(n, item);
759b378af500b36226635b6343b1d5009ee9af44fc1Jim Miller            mScript.invoke_setDetailTexture(n, offx, offy, loffx, loffy, item.detailTexture);
7607cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        }
7617cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    }
7627cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
7638441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey    void invalidateTexture(int n, boolean eraseCurrent)
7648441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey    {
7658441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey        if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
7668441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey
7678441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey        synchronized(this) {
768ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            ScriptField_Card.Item item = getCard(n);
7698441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey            if (item == null) {
7708441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                // This card was never created, so there's nothing to invalidate.
7718441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                return;
7728441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey            }
7738441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey            if (eraseCurrent && item.texture != null) {
7748441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                if (DBG) Log.v(TAG, "unloading texture " + n);
7758441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                // Don't wait for GC to free native memory.
7768441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                // Only works if textures are not shared.
7778441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                item.texture.destroy();
7788441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                item.texture = null;
7798441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey            }
780ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            setCard(n, item);
7818441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey            mScript.invoke_invalidateTexture(n, eraseCurrent);
7828441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey        }
7838441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey    }
7848441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey
7856af401bca5f8854524d128e9df5700035fae1160Jim Shuma    void invalidateDetailTexture(int n, boolean eraseCurrent)
7866af401bca5f8854524d128e9df5700035fae1160Jim Shuma    {
7876af401bca5f8854524d128e9df5700035fae1160Jim Shuma        if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
7886af401bca5f8854524d128e9df5700035fae1160Jim Shuma
7896af401bca5f8854524d128e9df5700035fae1160Jim Shuma        synchronized(this) {
790ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            ScriptField_Card.Item item = getCard(n);
7916af401bca5f8854524d128e9df5700035fae1160Jim Shuma            if (item == null) {
7920f529a84c393814bccd851d94c34b77558dcbab0Jim Shuma                // This card was never created, so there's nothing to invalidate.
7930f529a84c393814bccd851d94c34b77558dcbab0Jim Shuma                return;
7946af401bca5f8854524d128e9df5700035fae1160Jim Shuma            }
7956af401bca5f8854524d128e9df5700035fae1160Jim Shuma            if (eraseCurrent && item.detailTexture != null) {
7968441b1025afe64748f9e3483baacee92171bbfa3Jeff Sharkey                if (DBG) Log.v(TAG, "unloading detail texture " + n);
7976af401bca5f8854524d128e9df5700035fae1160Jim Shuma                // Don't wait for GC to free native memory.
7986af401bca5f8854524d128e9df5700035fae1160Jim Shuma                // Only works if textures are not shared.
7996af401bca5f8854524d128e9df5700035fae1160Jim Shuma                item.detailTexture.destroy();
8006af401bca5f8854524d128e9df5700035fae1160Jim Shuma                item.detailTexture = null;
8016af401bca5f8854524d128e9df5700035fae1160Jim Shuma            }
802ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            setCard(n, item);
8036af401bca5f8854524d128e9df5700035fae1160Jim Shuma            mScript.invoke_invalidateDetailTexture(n, eraseCurrent);
8046af401bca5f8854524d128e9df5700035fae1160Jim Shuma        }
8056af401bca5f8854524d128e9df5700035fae1160Jim Shuma    }
8066af401bca5f8854524d128e9df5700035fae1160Jim Shuma
8075ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setGeometry(int n, Mesh geometry)
8085ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
8093df59346f395434454d310b070fff195089fbaf1Jim Miller        if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
8103df59346f395434454d310b070fff195089fbaf1Jim Miller
811c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller        synchronized(this) {
812c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            final boolean mipmap = false;
813c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            ScriptField_Card.Item item = getOrCreateCard(n);
814c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            if (geometry != null) {
815c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                item.geometry = geometry;
816c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            } else {
817c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                if (DBG) Log.v(TAG, "unloading geometry " + n);
818c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                if (item.geometry != null) {
819c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    // item.geometry.destroy();
820c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                    item.geometry = null;
821c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller                }
8225ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            }
823ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            setCard(n, item);
824c4c6f38bf410af40e10c63b152befd5a39df87c8Jim Miller            mScript.invoke_setGeometry(n, item.geometry);
8255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
8265ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
8275ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
828c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma    public void setMatrix(int n, float[] matrix) {
829c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        if (n < 0) throw new IllegalArgumentException("Index cannot be negative");
830c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma
831c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        synchronized(this) {
832c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            final boolean mipmap = false;
833c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            ScriptField_Card.Item item = getOrCreateCard(n);
834c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            if (matrix != null) {
835c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma                item.matrix = matrixFromFloat(matrix);
836c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            } else {
837c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma                if (DBG) Log.v(TAG, "unloading matrix " + n);
838c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma                item.matrix = null;
839c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            }
840ec18350090abbba03c3f0c9f0511cfde4afee66fJim Shuma            setCard(n, item);
841c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma            mScript.invoke_setMatrix(n, item.matrix);
842c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma        }
843c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma    }
844c2baf88a763ae0e3694c8a10c13f203db9aec363Jim Shuma
845b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller    public void setBackgroundColor(Float4 color) {
846b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller        mScript.set_backgroundColor(color);
847b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller    }
848b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller
8499afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller    public void setBackgroundTexture(Bitmap bitmap) {
8509afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        Allocation texture = null;
8519afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        if (bitmap != null) {
852e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            texture = Allocation.createFromBitmap(mRS, bitmap,
8530508a5d4e679d52de6e902c07e63d5856225d616Jason Sams                    MIPMAP, Allocation.USAGE_GRAPHICS_TEXTURE);
8549afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        }
8559afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        mScript.set_backgroundTexture(texture);
8569afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller    }
8579afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller
8587cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    public void setDetailLineTexture(Bitmap bitmap) {
8597cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        Allocation texture = null;
8607cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        if (bitmap != null) {
861e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            texture = Allocation.createFromBitmap(mRS, bitmap,
8620508a5d4e679d52de6e902c07e63d5856225d616Jason Sams                    MIPMAP, Allocation.USAGE_GRAPHICS_TEXTURE);
8637cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        }
8647cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        mScript.set_detailLineTexture(texture);
8657cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    }
8667cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
867420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    public void setDetailLoadingTexture(Bitmap bitmap) {
868420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller        Allocation texture = null;
869420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller        if (bitmap != null) {
870420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller            texture = Allocation.createFromBitmap(mRS, bitmap,
8710508a5d4e679d52de6e902c07e63d5856225d616Jason Sams                    MIPMAP, Allocation.USAGE_GRAPHICS_TEXTURE);
872420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller        }
873420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller        mScript.set_detailLoadingTexture(texture);
874420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    }
875420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller
8765ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void pauseRendering() {
8775ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        // Used to update multiple states at once w/o redrawing for each.
87827b81f375cfa65f4f689c64bd2c48e3a56c1e11bJason Sams        mRS.bindRootScript(null);
8795ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
8805ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
8815ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void resumeRendering() {
88227b81f375cfa65f4f689c64bd2c48e3a56c1e11bJason Sams        mRS.bindRootScript(mScript);
8835ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
8845ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
885594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma    public void doLongPress() {
886594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma        mScript.invoke_doLongPress();
887594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma    }
888594ff62c170509c0d69b30f4c2a5e71d4799a9c8Jim Shuma
8891882cebdc1b7b0551189ca33fb7cb77ef10c988bJim Miller    public void doMotion(float x, float y, long t) {
8901882cebdc1b7b0551189ca33fb7cb77ef10c988bJim Miller        mScript.invoke_doMotion(x, y, t);
8915ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
8925ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
8931882cebdc1b7b0551189ca33fb7cb77ef10c988bJim Miller    public void doStart(float x, float y, long t) {
8941882cebdc1b7b0551189ca33fb7cb77ef10c988bJim Miller        mScript.invoke_doStart(x, y, t);
8955ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
8965ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
8971882cebdc1b7b0551189ca33fb7cb77ef10c988bJim Miller    public void doStop(float x, float y, long t) {
8981882cebdc1b7b0551189ca33fb7cb77ef10c988bJim Miller        mScript.invoke_doStop(x, y, t);
8995ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
9005ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
9015ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setSlotCount(int n) {
9025ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mScript.set_slotCount(n);
9035ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
904198a060d650bc849ef0f25b597888fac9546803bJack Palevich
905420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    public void setRezInCardCount(float alpha) {
906420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller        mScript.set_rezInCardCount(alpha);
907420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    }
908420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller
909420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    public void setFadeInDuration(long t) {
910420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller        mScript.set_fadeInDuration((int)t); // TODO: Remove cast when RS supports exporting longs
911420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller    }
912420b44b8b11ec1c309ea130e69a6876325dbfef9Jim Miller
9133adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma    public void setCardCreationFadeDuration(long t) {
9143adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma        mScript.set_cardCreationFadeDuration((int)t);
9153adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma    }
9163adf712e636f67265da7a6ff425c87e63fc20884Jim Shuma
917e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich    private Element elementForBitmap(Bitmap bitmap, Bitmap.Config defaultConfig) {
918e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        Bitmap.Config config = bitmap.getConfig();
919e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        if (config == null) {
920e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            config = defaultConfig;
921e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        }
922e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        if (config == Bitmap.Config.ALPHA_8) {
923e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            return A_8(mRS);
924e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        } else if (config == Bitmap.Config.RGB_565) {
925e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            return RGB_565(mRS);
926e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        } else if (config == Bitmap.Config.ARGB_4444) {
927e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            return RGBA_4444(mRS);
928e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        } else if (config == Bitmap.Config.ARGB_8888) {
929e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            return RGBA_8888(mRS);
930e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        } else {
931e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich            throw new IllegalArgumentException("Unknown configuration");
932e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich        }
933e0103cfd1a72197454e522834d2e8f600f798073Jack Palevich    }
934358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney
935358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney    public Mesh loadGeometry(int resId) {
936358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        if (resId == 0) {
937358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney          return null;
938358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        }
939358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        FileA3D model = FileA3D.createFromResource(mRS, mRes, resId);
940358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        if (model == null) {
941358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney          return null;
942358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        }
943358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        FileA3D.IndexEntry entry = model.getIndexEntry(0);
94452b26266238d124ec2831835a90988f89304218eAlex Sakhartchouk        if(entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
945358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney            return null;
946358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        }
947358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney        return (Mesh) entry.getObject();
948358868df5043b240c9a241c7bb75128ff94b1f34Bryan Mawhinney    }
9495ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller}
950