Home | History | Annotate | Download | only in testapp
      1 /*
      2  * Copyright (C) 2011 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 
     18 package com.android.testapp;
     19 
     20 import java.util.ArrayList;
     21 
     22 import com.android.scenegraph.*;
     23 
     24 import android.content.res.Resources;
     25 import android.graphics.Bitmap;
     26 import android.graphics.BitmapFactory;
     27 import android.os.AsyncTask;
     28 import android.renderscript.*;
     29 import android.renderscript.Allocation.MipmapControl;
     30 import android.renderscript.Element.Builder;
     31 import android.renderscript.Font.Style;
     32 import android.renderscript.Program.TextureType;
     33 import android.renderscript.ProgramStore.DepthFunc;
     34 import android.util.Log;
     35 
     36 class FullscreenBlur {
     37 
     38     static TextureRenderTarget sRenderTargetBlur0Color;
     39     static TextureRenderTarget sRenderTargetBlur0Depth;
     40     static TextureRenderTarget sRenderTargetBlur1Color;
     41     static TextureRenderTarget sRenderTargetBlur1Depth;
     42     static TextureRenderTarget sRenderTargetBlur2Color;
     43     static TextureRenderTarget sRenderTargetBlur2Depth;
     44 
     45     static FragmentShader mPF_BlurH;
     46     static FragmentShader mPF_BlurV;
     47     static FragmentShader mPF_SelectColor;
     48     static FragmentShader mPF_Texture;
     49     static VertexShader mPV_Paint;
     50     static VertexShader mPV_Blur;
     51 
     52     static int targetWidth;
     53     static int targetHeight;
     54 
     55     // This is only used when full screen blur is enabled
     56     // Basically, it's the offscreen render targets
     57     static void createRenderTargets(RenderScriptGL rs, int w, int h) {
     58         targetWidth = w/8;
     59         targetHeight = h/8;
     60         Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs));
     61         Type renderType = b.setX(targetWidth).setY(targetHeight).create();
     62         int usage = Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET;
     63         sRenderTargetBlur0Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
     64         sRenderTargetBlur1Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
     65         sRenderTargetBlur2Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
     66 
     67         b = new Type.Builder(rs, Element.createPixel(rs, Element.DataType.UNSIGNED_16,
     68                                                      Element.DataKind.PIXEL_DEPTH));
     69         renderType = b.setX(targetWidth).setY(targetHeight).create();
     70         usage = Allocation.USAGE_GRAPHICS_RENDER_TARGET;
     71         sRenderTargetBlur0Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
     72         sRenderTargetBlur1Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
     73         sRenderTargetBlur2Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
     74     }
     75 
     76     static void addOffsets(Renderable quad, float advance) {
     77         quad.appendSourceParams(new Float4Param("blurOffset0", - advance * 2.5f));
     78         quad.appendSourceParams(new Float4Param("blurOffset1", - advance * 0.5f));
     79         quad.appendSourceParams(new Float4Param("blurOffset2", advance * 1.5f));
     80         quad.appendSourceParams(new Float4Param("blurOffset3", advance * 3.5f));
     81     }
     82 
     83     static RenderPass addPass(Scene scene, Camera cam, TextureRenderTarget color, TextureRenderTarget depth) {
     84         RenderPass pass = new RenderPass();
     85         pass.setColorTarget(color);
     86         pass.setDepthTarget(depth);
     87         pass.setShouldClearColor(false);
     88         pass.setShouldClearDepth(false);
     89         pass.setCamera(cam);
     90         scene.appendRenderPass(pass);
     91         return pass;
     92     }
     93 
     94     static void addBlurPasses(Scene scene, RenderScriptGL rs, Camera cam) {
     95         SceneManager sceneManager = SceneManager.getInstance();
     96         ArrayList<RenderableBase> allDraw = scene.getRenderables();
     97         int numDraw = allDraw.size();
     98 
     99         ProgramRaster cullNone = ProgramRaster.CULL_NONE(rs);
    100         ProgramStore blendAdd = SceneManager.BLEND_ADD_DEPTH_NONE(rs);
    101         ProgramStore blendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(rs);
    102 
    103         RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture, blendAdd, cullNone);
    104         RenderState selectCol = new RenderState(mPV_Blur, mPF_SelectColor, blendNone, cullNone);
    105         RenderState hBlur = new RenderState(mPV_Blur, mPF_BlurH, blendNone, cullNone);
    106         RenderState vBlur = new RenderState(mPV_Blur, mPF_BlurV, blendNone, cullNone);
    107 
    108         // Renders the scene off screen
    109         RenderPass blurSourcePass = addPass(scene, cam,
    110                                             sRenderTargetBlur0Color,
    111                                             sRenderTargetBlur0Depth);
    112         blurSourcePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
    113         blurSourcePass.setShouldClearColor(true);
    114         blurSourcePass.setClearDepth(1.0f);
    115         blurSourcePass.setShouldClearDepth(true);
    116         for (int i = 0; i < numDraw; i ++) {
    117             blurSourcePass.appendRenderable((Renderable)allDraw.get(i));
    118         }
    119 
    120         // Pass for selecting bright colors
    121         RenderPass selectColorPass = addPass(scene, cam,
    122                                              sRenderTargetBlur2Color,
    123                                              sRenderTargetBlur2Depth);
    124         Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadS", selectCol);
    125         quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur0Color));
    126         selectColorPass.appendRenderable(quad);
    127 
    128         // Horizontal blur
    129         RenderPass horizontalBlurPass = addPass(scene, cam,
    130                                                 sRenderTargetBlur1Color,
    131                                                 sRenderTargetBlur1Depth);
    132         quad = sceneManager.getRenderableQuad("ScreenAlignedQuadH", hBlur);
    133         quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur2Color));
    134         addOffsets(quad, 1.0f / (float)targetWidth);
    135         horizontalBlurPass.appendRenderable(quad);
    136 
    137         // Vertical Blur
    138         RenderPass verticalBlurPass = addPass(scene, cam,
    139                                               sRenderTargetBlur2Color,
    140                                               sRenderTargetBlur2Depth);
    141         quad = sceneManager.getRenderableQuad("ScreenAlignedQuadV", vBlur);
    142         quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur1Color));
    143         addOffsets(quad, 1.0f / (float)targetHeight);
    144         verticalBlurPass.appendRenderable(quad);
    145     }
    146 
    147     // Additively renders the blurred colors on top of the scene
    148     static void addCompositePass(Scene scene, RenderScriptGL rs, Camera cam) {
    149         SceneManager sceneManager = SceneManager.getInstance();
    150         RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
    151                                               SceneManager.BLEND_ADD_DEPTH_NONE(rs),
    152                                               ProgramRaster.CULL_NONE(rs));
    153 
    154         RenderPass compositePass = addPass(scene, cam, null, null);
    155         Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadComposite", drawTex);
    156         quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur2Color));
    157         compositePass.appendRenderable(quad);
    158     }
    159 
    160     static private FragmentShader getShader(Resources res, RenderScriptGL rs,
    161                                             int resID, Type constants) {
    162         FragmentShader.Builder fb = new FragmentShader.Builder(rs);
    163         fb.setShader(res, resID);
    164         fb.addTexture(TextureType.TEXTURE_2D, "color");
    165         if (constants != null) {
    166             fb.setObjectConst(constants);
    167         }
    168         FragmentShader prog = fb.create();
    169         prog.getProgram().bindSampler(Sampler.CLAMP_LINEAR(rs), 0);
    170         return prog;
    171     }
    172 
    173     static void initShaders(Resources res, RenderScriptGL rs) {
    174         ScriptField_BlurOffsets blurConst = new ScriptField_BlurOffsets(rs, 1);
    175         VertexShader.Builder vb = new VertexShader.Builder(rs);
    176         vb.addInput(ScriptField_VertexShaderInputs.createElement(rs));
    177         vb.setShader(res, R.raw.blur_vertex);
    178         mPV_Blur = vb.create();
    179 
    180         mPF_Texture = getShader(res, rs, R.raw.texture, null);
    181         mPF_Texture.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(rs), 0);
    182         mPF_BlurH = getShader(res, rs, R.raw.blur_h, blurConst.getAllocation().getType());
    183         mPF_BlurV = getShader(res, rs, R.raw.blur_v, blurConst.getAllocation().getType());
    184         mPF_SelectColor = getShader(res, rs, R.raw.select_color, null);
    185     }
    186 
    187 }
    188 
    189 
    190 
    191 
    192 
    193