1bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck/*
2bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * Copyright (C) 2014 The Android Open Source Project
3bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck *
4bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * Licensed under the Apache License, Version 2.0 (the "License");
5bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * you may not use this file except in compliance with the License.
6bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * You may obtain a copy of the License at
7bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck *
8bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck *      http://www.apache.org/licenses/LICENSE-2.0
9bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck *
10bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * Unless required by applicable law or agreed to in writing, software
11bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * distributed under the License is distributed on an "AS IS" BASIS,
12bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * See the License for the specific language governing permissions and
14bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck * limitations under the License.
15bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck */
16bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
17bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckpackage com.android.test.hwui;
18bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
19bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.app.Activity;
20bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.graphics.Canvas;
21bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.graphics.Paint;
22bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.graphics.PorterDuff;
23bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.os.Bundle;
24bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.view.Gravity;
25bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.view.Surface;
26bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.view.SurfaceHolder;
27bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.view.SurfaceHolder.Callback;
28bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.view.SurfaceView;
29bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckimport android.widget.FrameLayout;
30bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
31bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck@SuppressWarnings({"UnusedDeclaration"})
32bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reckpublic class HardwareCanvasSurfaceViewActivity extends Activity implements Callback {
33bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private SurfaceView mSurfaceView;
34bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private HardwareCanvasSurfaceViewActivity.RenderingThread mThread;
35bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
36bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    @Override
37bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    protected void onCreate(Bundle savedInstanceState) {
38bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        super.onCreate(savedInstanceState);
39bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
40bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        FrameLayout content = new FrameLayout(this);
41bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
42bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        mSurfaceView = new SurfaceView(this);
43bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        mSurfaceView.getHolder().addCallback(this);
44bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
45bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        content.addView(mSurfaceView, new FrameLayout.LayoutParams(
46bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                FrameLayout.LayoutParams.MATCH_PARENT,
47bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                FrameLayout.LayoutParams.MATCH_PARENT,
48bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                Gravity.CENTER));
49bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        setContentView(content);
50bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
51bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
52bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    @Override
53bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    public void surfaceCreated(SurfaceHolder holder) {
54bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        mThread = new RenderingThread(holder.getSurface());
55bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        mThread.start();
56bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
57bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
58bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    @Override
59bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
60bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        mThread.setSize(width, height);
61bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
62bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
63bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    @Override
64bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    public void surfaceDestroyed(SurfaceHolder holder) {
65bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        if (mThread != null) mThread.stopRendering();
66bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
67bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
68bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    private static class RenderingThread extends Thread {
69bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private final Surface mSurface;
70bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private volatile boolean mRunning = true;
71bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        private int mWidth, mHeight;
72bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
73bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        public RenderingThread(Surface surface) {
74bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mSurface = surface;
75bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
76bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
77bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void setSize(int width, int height) {
78bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mWidth = width;
79bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mHeight = height;
80bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
81bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
82bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        @Override
83bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        public void run() {
84bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            float x = 0.0f;
85bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            float y = 0.0f;
86bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            float speedX = 5.0f;
87bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            float speedY = 3.0f;
88bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
89bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            Paint paint = new Paint();
90bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            paint.setColor(0xff00ff00);
91bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
92bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            while (mRunning && !Thread.interrupted()) {
93bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                final Canvas canvas = mSurface.lockHardwareCanvas();
94bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                try {
95bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
96bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    canvas.drawRect(x, y, x + 20.0f, y + 20.0f, paint);
97bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                } finally {
98bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    mSurface.unlockCanvasAndPost(canvas);
99bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                }
100bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
101bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                if (x + 20.0f + speedX >= mWidth || x + speedX <= 0.0f) {
102bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    speedX = -speedX;
103bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                }
104bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                if (y + 20.0f + speedY >= mHeight || y + speedY <= 0.0f) {
105bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    speedY = -speedY;
106bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                }
107bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
108bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                x += speedX;
109bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                y += speedY;
110bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
111bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                try {
112bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    Thread.sleep(15);
113bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                } catch (InterruptedException e) {
114bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                    // Interrupted
115bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck                }
116bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            }
117bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
118bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck
119bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        void stopRendering() {
120bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            interrupt();
121bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck            mRunning = false;
122bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck        }
123bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck    }
124bb2d0cc7e1d487f7021b1f9ec0c6740e41b535f2John Reck}
125