blob: 20b7dd30a4147756b6fd6127cb5ade166fa01206 [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wallpaper.nexus;
import static android.renderscript.Element.RGBA_8888;
import static android.renderscript.Element.RGB_565;
import static android.renderscript.ProgramStore.DepthFunc.ALWAYS;
import static android.renderscript.Sampler.Value.LINEAR;
import static android.renderscript.Sampler.Value.CLAMP;
import static android.renderscript.Sampler.Value.WRAP;
import com.android.wallpaper.R;
import com.android.wallpaper.RenderScriptScene;
import android.app.WallpaperManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.os.Bundle;
import android.renderscript.*;
import android.renderscript.ProgramStore.BlendDstFunc;
import android.renderscript.ProgramStore.BlendSrcFunc;
import android.view.SurfaceHolder;
import java.util.TimeZone;
class NexusRS extends RenderScriptScene {
private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
private ProgramVertexFixedFunction.Constants mPvOrthoAlloc;
private float mXOffset;
private ScriptC_nexus mScript;
public NexusRS(int width, int height) {
super(width, height);
mOptionsARGB.inScaled = false;
mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
}
@Override
public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
mXOffset = xOffset;
mScript.set_gXOffset(xOffset);
}
@Override
public void start() {
super.start();
}
@Override
public void resize(int width, int height) {
super.resize(width, height); // updates mWidth, mHeight
// android.util.Log.d("NexusRS", String.format("resize(%d, %d)", width, height));
}
@Override
protected ScriptC createScript() {
mScript = new ScriptC_nexus(mRS, mResources, R.raw.nexus);
createProgramFragmentStore();
createProgramFragment();
createProgramVertex();
createState();
mScript.set_gTBackground(loadTexture(R.drawable.pyramid_background));
mScript.set_gTPulse(loadTextureARGB(R.drawable.pulse));
mScript.set_gTGlow(loadTextureARGB(R.drawable.glow));
mScript.setTimeZone(TimeZone.getDefault().getID());
mScript.invoke_initPulses();
return mScript;
}
private void createState() {
int mode;
try {
mode = mResources.getInteger(R.integer.nexus_mode);
} catch (Resources.NotFoundException exc) {
mode = 0; // standard nexus mode
}
mScript.set_gIsPreview(isPreview() ? 1 : 0);
mScript.set_gMode(mode);
mScript.set_gXOffset(0.f);
}
private Allocation loadTexture(int id) {
return Allocation.createFromBitmapResource(mRS, mResources, id);
}
private Allocation loadTextureARGB(int id) {
Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
return Allocation.createFromBitmap(mRS, b);
}
private void createProgramFragment() {
// sampler and program fragment for pulses
ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
ProgramFragment pft = builder.create();
pft.bindSampler(Sampler.WRAP_LINEAR(mRS), 0);
mScript.set_gPFTexture(pft);
// sampler and program fragment for background image
builder = new ProgramFragmentFixedFunction.Builder(mRS);
builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
ProgramFragment pft565 = builder.create();
pft565.bindSampler(Sampler.CLAMP_NEAREST(mRS), 0);
mScript.set_gPFTexture565(pft565);
}
private void createProgramFragmentStore() {
ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
builder.setDepthFunc(ALWAYS);
builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
builder.setDitherEnabled(false);
ProgramStore solid = builder.create();
mRS.bindProgramStore(solid);
builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
mScript.set_gPSBlend(builder.create());
}
private void createProgramVertex() {
mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS);
Matrix4f proj = new Matrix4f();
proj.loadOrthoWindow(mWidth, mHeight);
mPvOrthoAlloc.setProjection(proj);
ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
pvb.setTextureMatrixEnable(true);
ProgramVertex pv = pvb.create();
((ProgramVertexFixedFunction)pv).bindConstants(mPvOrthoAlloc);
mRS.bindProgramVertex(pv);
}
@Override
public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
boolean resultRequested) {
if (mWidth < mHeight) {
// nexus.rs ignores the xOffset when rotated; we shall endeavor to do so as well
x = (int) (x + mXOffset * mWidth);
}
// android.util.Log.d("NexusRS", String.format(
// "dw=%d, bw=%d, xOffset=%g, x=%d",
// dw, bw, mWorldState.xOffset, x));
if (WallpaperManager.COMMAND_TAP.equals(action)
|| WallpaperManager.COMMAND_SECONDARY_TAP.equals(action)
|| WallpaperManager.COMMAND_DROP.equals(action)) {
mScript.invoke_addTap(x, y);
}
return null;
}
}