/*
* Copyright (C) 2011 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.ex.carousel;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.renderscript.*;
import static android.renderscript.Element.*;
import android.renderscript.RenderScript.RSMessageHandler;
import android.util.Log;
/**
* This is a support class for Carousel renderscript. It handles most of the low-level interactions
* with Renderscript as well as dispatching events.
*
*/
public class CarouselRS {
private static final int DEFAULT_VISIBLE_SLOTS = 1;
private static final int DEFAULT_CARD_COUNT = 0;
private static final int DEFAULT_ROW_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_DETAIL_SELECTED = 105;
public static final int CMD_CARD_LONGPRESS = 110;
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_REQUEST_DETAIL_TEXTURE = 600;
public static final int CMD_INVALIDATE_DETAIL_TEXTURE = 610;
public static final int CMD_PING = 1000; // for debugging
// Drag models *** THIS LIST MUST MATCH THOSE IN carousel.rs ***
public static final int DRAG_MODEL_SCREEN_DELTA = 0;
public static final int DRAG_MODEL_PLANE = 1;
public static final int DRAG_MODEL_CYLINDER_INSIDE = 2;
public static final int DRAG_MODEL_CYLINDER_OUTSIDE = 3;
public static final int FILL_DIRECTION_CCW = +1;
public static final int FILL_DIRECTION_CW = -1;
private static final String TAG = "CarouselRS";
private static final int DEFAULT_SLOT_COUNT = 10;
private static final Allocation.MipmapControl MIPMAP =
Allocation.MipmapControl.MIPMAP_NONE;
private static final boolean DBG = false;
private RenderScriptGL mRS;
private Resources mRes;
private ScriptC_carousel mScript;
private ScriptField_Card mCards;
private ScriptField_FragmentShaderConstants_s mFSConst;
private ScriptField_ProgramStore_s mProgramStoresCard;
private ProgramFragment mSingleTextureFragmentProgram;
private ProgramFragment mSingleTextureBlendingFragmentProgram;
private ProgramFragment mMultiTextureFragmentProgram;
private ProgramFragment mMultiTextureBlendingFragmentProgram;
private ProgramVertex mVertexProgram;
private ProgramRaster mRasterProgram;
private Allocation[] mAllocationPool;
private boolean mForceBlendCardsWithZ;
private int mVisibleSlots;
private int mRowCount;
private int mPrefetchCardCount;
private CarouselCallback mCallback;
private float[] mEyePoint = new float[] { 2.0f, 0.0f, 0.0f };
private float[] mAtPoint = new float[] { 0.0f, 0.0f, 0.0f };
private float[] mUp = new float[] { 0.0f, 1.0f, 0.0f };
private static final String mSingleTextureShader = new String(
"varying vec2 varTex0;" +
"void main() {" +
"vec2 t0 = varTex0.xy;" +
"vec4 col = texture2D(UNI_Tex0, t0);" +
"gl_FragColor = col; " +
"}");
private static final String mSingleTextureBlendingShader = new String(
"varying vec2 varTex0;" +
"void main() {" +
"vec2 t0 = varTex0.xy;" +
"vec4 col = texture2D(UNI_Tex0, t0);" +
"gl_FragColor = col * UNI_overallAlpha; " +
"}");
private static final String mMultiTextureShader = new String(
"varying vec2 varTex0;" +
"void main() {" +
"vec2 t0 = varTex0.xy;" +
"vec4 col = texture2D(UNI_Tex0, t0);" +
"vec4 col2 = texture2D(UNI_Tex1, t0);" +
"gl_FragColor = mix(col, col2, UNI_fadeAmount);}");
private static final String mMultiTextureBlendingShader = new String(
"varying vec2 varTex0;" +
"void main() {" +
"vec2 t0 = varTex0.xy;" +
"vec4 col = texture2D(UNI_Tex0, t0);" +
"vec4 col2 = texture2D(UNI_Tex1, t0);" +
"gl_FragColor = mix(col, col2, UNI_fadeAmount) * UNI_overallAlpha;" +
"}"
);
public static interface CarouselCallback {
/**
* Called when a card is selected
* @param n the id of the card
*/
void onCardSelected(int n);
/**
* Called when the detail texture for a card is tapped
* @param n the id of the card
* @param x how far the user tapped from the left edge of the card, in pixels
* @param y how far the user tapped from the top edge of the card, in pixels
*/
void onDetailSelected(int n, int x, int y);
/**
* Called when a card is long-pressed
* @param n the id of the card
* @param touchPosition position of where the user pressed, in screen coordinates
* @param detailCoordinates position of detail texture, in screen coordinates
*/
void onCardLongPress(int n, int touchPosition[], Rect detailCoordinates);
/**
* 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 detail texture is needed for card n. This happens when the given card
* becomes visible.
* @param n the id of the card
*/
void onRequestDetailTexture(int n);
/**
* Called when a detail 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 onInvalidateDetailTexture(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.
* @param carouselRotationAngle the angle of rotation, in radians, at which the animation
* stopped.
*/
void onAnimationFinished(float carouselRotationAngle);
};
private RSMessageHandler mRsMessage = new RSMessageHandler() {
public void run() {
if (mCallback == null) return;
switch (mID) {
case CMD_CARD_SELECTED:
mCallback.onCardSelected(mData[0]);
break;
case CMD_DETAIL_SELECTED:
mCallback.onDetailSelected(mData[0