Home | History | Annotate | Download | only in nexus
      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