19eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen/* 29eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * Copyright (C) 2010 The Android Open Source Project 39eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * 49eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * Licensed under the Apache License, Version 2.0 (the "License"); 59eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * you may not use this file except in compliance with the License. 69eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * You may obtain a copy of the License at 79eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * 89eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * http://www.apache.org/licenses/LICENSE-2.0 99eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * 109eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * Unless required by applicable law or agreed to in writing, software 119eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * distributed under the License is distributed on an "AS IS" BASIS, 129eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * See the License for the specific language governing permissions and 149eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen * limitations under the License. 159eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen */ 169eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenpackage com.example.plasma.llvm; 179eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 189eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenimport android.app.Activity; 199eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenimport android.os.Bundle; 209eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenimport android.content.Context; 219eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenimport android.view.View; 2237d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport android.view.Menu; 2337d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport android.view.MenuItem; 2437d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport android.view.MenuInflater; 259eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenimport android.graphics.Bitmap; 269eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenimport android.graphics.Canvas; 2737d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport android.graphics.Paint; 2837d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen 2937d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport java.io.InputStream; 3037d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport java.io.FileInputStream; 3137d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport java.io.FileOutputStream; 3237d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport java.io.BufferedOutputStream; 3337d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport java.io.IOException; 3437d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen 3537d8f3486d348ead6b2508ecd035be8439687f15Joseph Wenimport android.content.res.Resources; 369eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 379eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenpublic class Plasma extends Activity 389eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen{ 399eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen /** Called when the activity is first created. */ 409eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen @Override 419eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen public void onCreate(Bundle savedInstanceState) 429eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen { 439eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen super.onCreate(savedInstanceState); 4437d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen view = new PlasmaView(this); 4537d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen setContentView(view); 469eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen } 479eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 4837d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen @Override 4937d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen public boolean onCreateOptionsMenu(Menu menu) { 5037d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen MenuInflater inflater = getMenuInflater(); 5137d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen inflater.inflate(R.menu.menu, menu); 5237d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen return true; 5337d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen } 54dc9c7edca5025d2c3796c2ef587284c10d321fe4Andrew Hsieh 5537d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen @Override 5637d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen public boolean onOptionsItemSelected(MenuItem item) { 5737d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen switch (item.getItemId()) { 5837d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen case R.id.switch_mode: 5937d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen view.switchMode(); 6037d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen 6137d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen return true; 6237d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen default: 6337d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen return super.onOptionsItemSelected(item); 6437d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen } 6537d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen } 66dc9c7edca5025d2c3796c2ef587284c10d321fe4Andrew Hsieh 6737d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen private PlasmaView view; 6837d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen 699eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen /* load our native library */ 709eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen static { 719eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen System.loadLibrary("plasma"); 729eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen } 739eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen} 749eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 759eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wenclass PlasmaView extends View { 769eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen private Bitmap mBitmap; 779eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen private long mStartTime; 789eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 799eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen /* implementend by libplasma.so */ 802c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh private static native boolean gdk(); 8137d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen private static native int nativeRenderPlasma(Bitmap bitmap, long time_ms, byte[] script, int scriptLength, boolean useLLVM); 8237d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen 8337d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen private byte[] pgm; 8437d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen private int pgmLength; 85dc9c7edca5025d2c3796c2ef587284c10d321fe4Andrew Hsieh 862c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh private boolean llvm_mode = false; 8737d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen private Paint paint = null; 8837d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen 8937d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen public void switchMode() { 902c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh if (gdk()) 912c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh llvm_mode = !llvm_mode; 9237d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen } 939eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 949eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen public PlasmaView(Context context) { 959eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen super(context); 966a5fd5f0c6aa00bfbc4473007a349710e026bb10Andrew Hsieh 972c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh llvm_mode = gdk(); 989eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 999eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen mStartTime = System.currentTimeMillis(); 1002c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh if (llvm_mode) 1012c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh { 1022c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh InputStream is = null; 1032c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh is = getResources().openRawResource(R.raw.libplasma_portable); 10437d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen try { 1052c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh try { 1062c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh pgm = new byte[1024]; 1072c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh pgmLength = 0; 1082c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh while(true) { 1092c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh int bytesLeft = pgm.length - pgmLength; 1102c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh if (bytesLeft == 0) { 1112c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh byte[] buf2 = new byte[pgm.length * 2]; 1122c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh System.arraycopy(pgm, 0, buf2, 0, pgm.length); 1132c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh pgm = buf2; 1142c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh bytesLeft = pgm.length - pgmLength; 1152c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh } 1162c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh int bytesRead = is.read(pgm, pgmLength, bytesLeft); 1172c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh if (bytesRead <= 0) { 1182c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh break; 1192c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh } 1202c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh pgmLength += bytesRead; 12137d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen } 1222c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh } finally { 1232c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh is.close(); 12437d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen } 1252c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh } catch(IOException e) { 1262c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh throw new Resources.NotFoundException(); 12737d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen } 1286a5fd5f0c6aa00bfbc4473007a349710e026bb10Andrew Hsieh } 1296a5fd5f0c6aa00bfbc4473007a349710e026bb10Andrew Hsieh 13037d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen paint = new Paint(); 13137d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen paint.setTextSize(40); 1329eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen } 1339eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen 1349eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen @Override protected void onDraw(Canvas canvas) { 13537d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen if (mBitmap == null || mBitmap.getWidth() != getWidth() || mBitmap.getHeight() != getHeight()) 13637d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.RGB_565); 13737d8f3486d348ead6b2508ecd035be8439687f15Joseph Wen 1382c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh int frameRate = nativeRenderPlasma(mBitmap, System.currentTimeMillis() - mStartTime, pgm, pgmLength, llvm_mode); 1399eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen canvas.drawBitmap(mBitmap, 0, 0, null); 1402c18ea2753707ff9b5e1c6ad18d025ff3cef374cAndrew Hsieh canvas.drawText((llvm_mode ? "LLVM/GDK" : "Native") + " Frame: " + Integer.toString(frameRate), 100, 100, paint); 141dc9c7edca5025d2c3796c2ef587284c10d321fe4Andrew Hsieh 1429eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen // force a redraw, with a different time-based pattern. 1439eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen invalidate(); 1449eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen } 1459eb23e0856e35a4649a3678d13ddaa7b585251e8Joseph Wen} 146