• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 int mInitialWidth;
48     private int mInitialHeight;
49     private float mWorldScaleX;
50     private float mWorldScaleY;
51     private float mXOffset;
52     private ScriptC_nexus mScript;
53 
NexusRS(int width, int height)54     public NexusRS(int width, int height) {
55         super(width, height);
56 
57         mInitialWidth = width;
58         mInitialHeight = height;
59         mWorldScaleX = 1.0f;
60         mWorldScaleY = 1.0f;
61 
62         mOptionsARGB.inScaled = false;
63         mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
64     }
65 
66     @Override
setOffset(float xOffset, float yOffset, int xPixels, int yPixels)67     public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
68         mXOffset = xOffset;
69         mScript.set_gXOffset(xOffset);
70     }
71 
72     @Override
start()73     public void start() {
74         super.start();
75     }
76 
77     @Override
resize(int width, int height)78     public void resize(int width, int height) {
79         super.resize(width, height); // updates mWidth, mHeight
80 
81         // android.util.Log.d("NexusRS", String.format("resize(%d, %d)", width, height));
82 
83         mWorldScaleX = (float)mInitialWidth / width;
84         mWorldScaleY = (float)mInitialHeight / height;
85         mScript.set_gWorldScaleX(mWorldScaleX);
86         mScript.set_gWorldScaleY(mWorldScaleY);
87     }
88 
89     @Override
createScript()90     protected ScriptC createScript() {
91         mScript = new ScriptC_nexus(mRS, mResources, R.raw.nexus);
92 
93         createProgramFragmentStore();
94         createProgramFragment();
95         createProgramVertex();
96         createState();
97 
98         mScript.set_gTBackground(loadTexture(R.drawable.pyramid_background));
99         mScript.set_gTPulse(loadTextureARGB(R.drawable.pulse));
100         mScript.set_gTGlow(loadTextureARGB(R.drawable.glow));
101         mScript.setTimeZone(TimeZone.getDefault().getID());
102         mScript.invoke_initPulses();
103         return mScript;
104     }
105 
createState()106     private void createState() {
107         int mode;
108         try {
109             mode = mResources.getInteger(R.integer.nexus_mode);
110         } catch (Resources.NotFoundException exc) {
111             mode = 0; // standard nexus mode
112         }
113 
114         mScript.set_gIsPreview(isPreview() ? 1 : 0);
115         mScript.set_gMode(mode);
116         mScript.set_gXOffset(0.f);
117         mScript.set_gWorldScaleX(mWorldScaleX);
118         mScript.set_gWorldScaleY(mWorldScaleY);
119     }
120 
loadTexture(int id)121     private Allocation loadTexture(int id) {
122         return Allocation.createFromBitmapResource(mRS, mResources, id,
123                                            Allocation.MipmapControl.MIPMAP_NONE,
124                                            Allocation.USAGE_GRAPHICS_TEXTURE);
125     }
126 
loadTextureARGB(int id)127     private Allocation loadTextureARGB(int id) {
128         Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB);
129         return Allocation.createFromBitmap(mRS, b,
130                                            Allocation.MipmapControl.MIPMAP_NONE,
131                                            Allocation.USAGE_GRAPHICS_TEXTURE);
132     }
133 
134 
createProgramFragment()135     private void createProgramFragment() {
136         // sampler and program fragment for pulses
137         ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
138         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
139                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
140         ProgramFragment pft = builder.create();
141         pft.bindSampler(Sampler.WRAP_LINEAR(mRS), 0);
142         mScript.set_gPFTexture(pft);
143 
144         // sampler and program fragment for background image
145         builder = new ProgramFragmentFixedFunction.Builder(mRS);
146         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
147                            ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
148         ProgramFragment pft565 = builder.create();
149         pft565.bindSampler(Sampler.CLAMP_NEAREST(mRS), 0);
150         mScript.set_gPFTexture565(pft565);
151     }
152 
createProgramFragmentStore()153     private void createProgramFragmentStore() {
154         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
155         builder.setDepthFunc(ALWAYS);
156         builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
157         builder.setDitherEnabled(false);
158         ProgramStore solid = builder.create();
159         mRS.bindProgramStore(solid);
160 
161         builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
162         mScript.set_gPSBlend(builder.create());
163     }
164 
createProgramVertex()165     private void createProgramVertex() {
166         mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS);
167         Matrix4f proj = new Matrix4f();
168         proj.loadOrthoWindow(mWidth, mHeight);
169         mPvOrthoAlloc.setProjection(proj);
170 
171         ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
172         pvb.setTextureMatrixEnable(true);
173         ProgramVertex pv = pvb.create();
174         ((ProgramVertexFixedFunction)pv).bindConstants(mPvOrthoAlloc);
175         mRS.bindProgramVertex(pv);
176     }
177 
178     @Override
onCommand(String action, int x, int y, int z, Bundle extras, boolean resultRequested)179     public Bundle onCommand(String action, int x, int y, int z, Bundle extras,
180             boolean resultRequested) {
181 
182         if (mWidth < mHeight) {
183             // nexus.rs ignores the xOffset when rotated; we shall endeavor to do so as well
184             x = (int) (x + mXOffset * mWidth / mWorldScaleX);
185         }
186 
187         // android.util.Log.d("NexusRS", String.format(
188         //     "dw=%d, bw=%d, xOffset=%g, x=%d",
189         //     dw, bw, mWorldState.xOffset, x));
190 
191         if (WallpaperManager.COMMAND_TAP.equals(action)
192                 || WallpaperManager.COMMAND_SECONDARY_TAP.equals(action)
193                 || WallpaperManager.COMMAND_DROP.equals(action)) {
194             mScript.invoke_addTap(x, y);
195         }
196         return null;
197     }
198 }
199