1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wallpaper.nexus; 18 19 import static android.renderscript.Element.RGBA_8888; 20 import static android.renderscript.Element.RGB_565; 21 import static android.renderscript.ProgramStore.DepthFunc.ALWAYS; 22 import static android.renderscript.Sampler.Value.LINEAR; 23 import static android.renderscript.Sampler.Value.CLAMP; 24 import static android.renderscript.Sampler.Value.WRAP; 25 26 import com.android.wallpaper.R; 27 import com.android.wallpaper.RenderScriptScene; 28 29 import android.app.WallpaperManager; 30 import android.content.res.Resources; 31 import android.graphics.Bitmap; 32 import android.graphics.BitmapFactory; 33 import android.graphics.Rect; 34 import android.os.Bundle; 35 import android.renderscript.*; 36 import android.renderscript.ProgramStore.BlendDstFunc; 37 import android.renderscript.ProgramStore.BlendSrcFunc; 38 import android.view.SurfaceHolder; 39 40 import java.util.TimeZone; 41 42 class NexusRS extends RenderScriptScene { 43 private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); 44 45 private ProgramVertexFixedFunction.Constants mPvOrthoAlloc; 46 47 private float mXOffset; 48 private ScriptC_nexus mScript; 49 50 public NexusRS(int width, int height) { 51 super(width, height); 52 53 mOptionsARGB.inScaled = false; 54 mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; 55 } 56 57 @Override 58 public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) { 59 mXOffset = xOffset; 60 mScript.set_gXOffset(xOffset); 61 } 62 63 @Override 64 public void start() { 65 super.start(); 66 } 67 68 @Override 69 public void resize(int width, int height) { 70 super.resize(width, height); // updates mWidth, mHeight 71 72 // android.util.Log.d("NexusRS", String.format("resize(%d, %d)", width, height)); 73 } 74 75 @Override 76 protected ScriptC createScript() { 77 mScript = new ScriptC_nexus(mRS, mResources, R.raw.nexus); 78 79 createProgramFragmentStore(); 80 createProgramFragment(); 81 createProgramVertex(); 82 createState(); 83 84 mScript.set_gTBackground(loadTexture(R.drawable.pyramid_background)); 85 mScript.set_gTPulse(loadTextureARGB(R.drawable.pulse)); 86 mScript.set_gTGlow(loadTextureARGB(R.drawable.glow)); 87 mScript.setTimeZone(TimeZone.getDefault().getID()); 88 mScript.invoke_initPulses(); 89 return mScript; 90 } 91 92 private void createState() { 93 int mode; 94 try { 95 mode = mResources.getInteger(R.integer.nexus_mode); 96 } catch (Resources.NotFoundException exc) { 97 mode = 0; // standard nexus mode 98 } 99 100 mScript.set_gIsPreview(isPreview() ? 1 : 0); 101 mScript.set_gMode(mode); 102 mScript.set_gXOffset(0.f); 103 } 104 105 private Allocation loadTexture(int id) { 106 return Allocation.createFromBitmapResource(mRS, mResources, id); 107 } 108 109 private Allocation loadTextureARGB(int id) { 110 Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB); 111 return Allocation.createFromBitmap(mRS, b); 112 } 113 114 115 private void createProgramFragment() { 116 // sampler and program fragment for pulses 117 ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS); 118 builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, 119 ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); 120 ProgramFragment pft = builder.create(); 121 pft.bindSampler(Sampler.WRAP_LINEAR(mRS), 0); 122 mScript.set_gPFTexture(pft); 123 124 // sampler and program fragment for background image 125 builder = new ProgramFragmentFixedFunction.Builder(mRS); 126 builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, 127 ProgramFragmentFixedFunction.Builder.Format.RGB, 0); 128 ProgramFragment pft565 = builder.create(); 129 pft565.bindSampler(Sampler.CLAMP_NEAREST(mRS), 0); 130 mScript.set_gPFTexture565(pft565); 131 } 132 133 private void createProgramFragmentStore() { 134 ProgramStore.Builder builder = new ProgramStore.Builder(mRS); 135 builder.setDepthFunc(ALWAYS); 136 builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE); 137 builder.setDitherEnabled(false); 138 ProgramStore solid = builder.create(); 139 mRS.bindProgramStore(solid); 140 141 builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); 142 mScript.set_gPSBlend(builder.create()); 143 } 144 145 private void createProgramVertex() { 146 mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS); 147 Matrix4f proj = new Matrix4f(); 148 proj.loadOrthoWindow(mWidth, mHeight); 149 mPvOrthoAlloc.setProjection(proj); 150 151 ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); 152 pvb.setTextureMatrixEnable(true); 153 ProgramVertex pv = pvb.create(); 154 ((ProgramVertexFixedFunction)pv).bindConstants(mPvOrthoAlloc); 155 mRS.bindProgramVertex(pv); 156 } 157 158 @Override 159 public Bundle onCommand(String action, int x, int y, int z, Bundle extras, 160 boolean resultRequested) { 161 162 if (mWidth < mHeight) { 163 // nexus.rs ignores the xOffset when rotated; we shall endeavor to do so as well 164 x = (int) (x + mXOffset * mWidth); 165 } 166 167 // android.util.Log.d("NexusRS", String.format( 168 // "dw=%d, bw=%d, xOffset=%g, x=%d", 169 // dw, bw, mWorldState.xOffset, x)); 170 171 if (WallpaperManager.COMMAND_TAP.equals(action) 172 || WallpaperManager.COMMAND_SECONDARY_TAP.equals(action) 173 || WallpaperManager.COMMAND_DROP.equals(action)) { 174 mScript.invoke_addTap(x, y); 175 } 176 return null; 177 } 178 } 179