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