1 /*
2  * Copyright (C) 2012 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.rs.levels;
18 
19 import android.app.Activity;
20 import android.graphics.Bitmap;
21 import android.graphics.BitmapFactory;
22 import android.graphics.Canvas;
23 import android.os.Bundle;
24 import android.graphics.SurfaceTexture;
25 import android.view.Surface;
26 import android.renderscript.Allocation;
27 import android.renderscript.Matrix3f;
28 import android.renderscript.RenderScript;
29 import android.util.Log;
30 import android.view.TextureView;
31 import android.view.View;
32 import android.widget.ImageView;
33 import android.widget.SeekBar;
34 import android.widget.TextView;
35 
36 public class LevelsRSActivity extends Activity
37                               implements SeekBar.OnSeekBarChangeListener,
38                                          TextureView.SurfaceTextureListener
39 {
40     private final String TAG = "Img";
41     private Bitmap mBitmapIn;
42     private float mInBlack = 0.0f;
43     private SeekBar mInBlackSeekBar;
44     private float mOutBlack = 0.0f;
45     private SeekBar mOutBlackSeekBar;
46     private float mInWhite = 255.0f;
47     private SeekBar mInWhiteSeekBar;
48     private float mOutWhite = 255.0f;
49     private SeekBar mOutWhiteSeekBar;
50     private float mGamma = 1.0f;
51     private SeekBar mGammaSeekBar;
52     private float mSaturation = 1.0f;
53     private SeekBar mSaturationSeekBar;
54     private TextView mBenchmarkResult;
55     private TextureView mDisplayView;
56 
57     Matrix3f satMatrix = new Matrix3f();
58     float mInWMinInB;
59     float mOutWMinOutB;
60     float mOverInWMinInB;
61 
62     private RenderScript mRS;
63     private Allocation mInPixelsAllocation;
64     private Allocation mOutPixelsAllocation;
65     private ScriptC_levels mScript;
66 
setLevels()67     private void setLevels() {
68         mInWMinInB = mInWhite - mInBlack;
69         mOutWMinOutB = mOutWhite - mOutBlack;
70         mOverInWMinInB = 1.f / mInWMinInB;
71 
72         mScript.set_inBlack(mInBlack);
73         mScript.set_outBlack(mOutBlack);
74         mScript.set_inWMinInB(mInWMinInB);
75         mScript.set_outWMinOutB(mOutWMinOutB);
76         mScript.set_overInWMinInB(mOverInWMinInB);
77     }
78 
setSaturation()79     private void setSaturation() {
80         float rWeight = 0.299f;
81         float gWeight = 0.587f;
82         float bWeight = 0.114f;
83         float oneMinusS = 1.0f - mSaturation;
84 
85         satMatrix.set(0, 0, oneMinusS * rWeight + mSaturation);
86         satMatrix.set(0, 1, oneMinusS * rWeight);
87         satMatrix.set(0, 2, oneMinusS * rWeight);
88         satMatrix.set(1, 0, oneMinusS * gWeight);
89         satMatrix.set(1, 1, oneMinusS * gWeight + mSaturation);
90         satMatrix.set(1, 2, oneMinusS * gWeight);
91         satMatrix.set(2, 0, oneMinusS * bWeight);
92         satMatrix.set(2, 1, oneMinusS * bWeight);
93         satMatrix.set(2, 2, oneMinusS * bWeight + mSaturation);
94         mScript.set_colorMat(satMatrix);
95     }
96 
onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)97     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
98         if (fromUser) {
99             if (seekBar == mInBlackSeekBar) {
100                 mInBlack = (float)progress;
101                 setLevels();
102             } else if (seekBar == mOutBlackSeekBar) {
103                 mOutBlack = (float)progress;
104                 setLevels();
105             } else if (seekBar == mInWhiteSeekBar) {
106                 mInWhite = (float)progress + 127.0f;
107                 setLevels();
108             } else if (seekBar == mOutWhiteSeekBar) {
109                 mOutWhite = (float)progress + 127.0f;
110                 setLevels();
111             } else if (seekBar == mGammaSeekBar) {
112                 mGamma = (float)progress/100.0f;
113                 mGamma = Math.max(mGamma, 0.1f);
114                 mGamma = 1.0f / mGamma;
115                 mScript.set_gamma(mGamma);
116             } else if (seekBar == mSaturationSeekBar) {
117                 mSaturation = (float)progress / 50.0f;
118                 setSaturation();
119             }
120 
121             filter();
122             mDisplayView.invalidate();
123         }
124     }
125 
onStartTrackingTouch(SeekBar seekBar)126     public void onStartTrackingTouch(SeekBar seekBar) {
127     }
128 
onStopTrackingTouch(SeekBar seekBar)129     public void onStopTrackingTouch(SeekBar seekBar) {
130     }
131 
132     @Override
onCreate(Bundle savedInstanceState)133     protected void onCreate(Bundle savedInstanceState) {
134         super.onCreate(savedInstanceState);
135         setContentView(R.layout.rs);
136 
137         mBitmapIn = loadBitmap(R.drawable.city);
138         mDisplayView = (TextureView) findViewById(R.id.display);
139 
140         mInBlackSeekBar = (SeekBar)findViewById(R.id.inBlack);
141         mInBlackSeekBar.setOnSeekBarChangeListener(this);
142         mInBlackSeekBar.setMax(128);
143         mInBlackSeekBar.setProgress(0);
144         mOutBlackSeekBar = (SeekBar)findViewById(R.id.outBlack);
145         mOutBlackSeekBar.setOnSeekBarChangeListener(this);
146         mOutBlackSeekBar.setMax(128);
147         mOutBlackSeekBar.setProgress(0);
148 
149         mInWhiteSeekBar = (SeekBar)findViewById(R.id.inWhite);
150         mInWhiteSeekBar.setOnSeekBarChangeListener(this);
151         mInWhiteSeekBar.setMax(128);
152         mInWhiteSeekBar.setProgress(128);
153         mOutWhiteSeekBar = (SeekBar)findViewById(R.id.outWhite);
154         mOutWhiteSeekBar.setOnSeekBarChangeListener(this);
155         mOutWhiteSeekBar.setMax(128);
156         mOutWhiteSeekBar.setProgress(128);
157 
158         mGammaSeekBar = (SeekBar)findViewById(R.id.inGamma);
159         mGammaSeekBar.setOnSeekBarChangeListener(this);
160         mGammaSeekBar.setMax(150);
161         mGammaSeekBar.setProgress(100);
162 
163         mSaturationSeekBar = (SeekBar)findViewById(R.id.inSaturation);
164         mSaturationSeekBar.setOnSeekBarChangeListener(this);
165         mSaturationSeekBar.setProgress(50);
166 
167         mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
168         mBenchmarkResult.setText("Result: not run");
169 
170         mRS = RenderScript.create(this);
171         mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
172                                                           Allocation.MipmapControl.MIPMAP_NONE,
173                                                           Allocation.USAGE_SCRIPT);
174         mOutPixelsAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(),
175                                                       Allocation.USAGE_SCRIPT |
176                                                       Allocation.USAGE_IO_OUTPUT);
177         mDisplayView.setSurfaceTextureListener(this);
178 
179         mScript = new ScriptC_levels(mRS);
180         mScript.set_gamma(mGamma);
181 
182         setSaturation();
183         setLevels();
184     }
185 
loadBitmap(int resource)186     private Bitmap loadBitmap(int resource) {
187         final BitmapFactory.Options options = new BitmapFactory.Options();
188         options.inPreferredConfig = Bitmap.Config.ARGB_8888;
189         Bitmap b = BitmapFactory.decodeResource(getResources(), resource, options);
190         Bitmap b2 = Bitmap.createBitmap(b.getWidth(), b.getHeight(), b.getConfig());
191         Canvas c = new Canvas(b2);
192         c.drawBitmap(b, 0, 0, null);
193         b.recycle();
194         return b2;
195     }
196 
filter()197     private void filter() {
198         mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
199         mOutPixelsAllocation.ioSend();
200         mRS.finish();
201     }
202 
benchmark(View v)203     public void benchmark(View v) {
204         filter();
205         long t = java.lang.System.currentTimeMillis();
206         filter();
207         t = java.lang.System.currentTimeMillis() - t;
208         mDisplayView.invalidate();
209         mBenchmarkResult.setText("Result: " + t + " ms");
210     }
211 
212 
213     @Override
onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)214     public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
215         if (surface != null) {
216             mOutPixelsAllocation.setSurface(new Surface(surface));
217         }
218         filter();
219     }
220 
221     @Override
onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)222     public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
223         if (surface != null) {
224             mOutPixelsAllocation.setSurface(new Surface(surface));
225         }
226     }
227 
228     @Override
onSurfaceTextureDestroyed(SurfaceTexture surface)229     public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
230         mOutPixelsAllocation.setSurface(null);
231         return true;
232     }
233 
234     @Override
onSurfaceTextureUpdated(SurfaceTexture surface)235     public void onSurfaceTextureUpdated(SurfaceTexture surface) {
236     }
237 }
238