1185268942b946028b65f5cff9b335af97f9aeab8Romain Guy/*
2185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * Copyright (C) 2011 The Android Open Source Project
3185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *
4185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * you may not use this file except in compliance with the License.
6185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * You may obtain a copy of the License at
7185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *
8185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9185268942b946028b65f5cff9b335af97f9aeab8Romain Guy *
10185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * Unless required by applicable law or agreed to in writing, software
11185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * See the License for the specific language governing permissions and
14185268942b946028b65f5cff9b335af97f9aeab8Romain Guy * limitations under the License.
15185268942b946028b65f5cff9b335af97f9aeab8Romain Guy */
16185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
17185268942b946028b65f5cff9b335af97f9aeab8Romain Guypackage com.android.shaderstest;
18185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
19185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.content.Context;
20185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.RSSurfaceView;
21185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.renderscript.RenderScriptGL;
22185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.view.MotionEvent;
23185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.view.ScaleGestureDetector;
24185268942b946028b65f5cff9b335af97f9aeab8Romain Guyimport android.view.SurfaceHolder;
25185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
26185268942b946028b65f5cff9b335af97f9aeab8Romain Guypublic class ShadersTestView extends RSSurfaceView {
27185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
28185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private RenderScriptGL mRS;
29185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ShadersTestRS mRender;
30185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
31185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private ScaleGestureDetector mScaleDetector;
32185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
33185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private static final int INVALID_POINTER_ID = -1;
34185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private int mActivePointerId = INVALID_POINTER_ID;
35185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
36185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public ShadersTestView(Context context) {
37185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        super(context);
38185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        ensureRenderScript();
39185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
40185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
41185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
42185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private void ensureRenderScript() {
43185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        if (mRS == null) {
44185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
45185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            sc.setDepth(16, 24);
46185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mRS = createRenderScriptGL(sc);
47185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mRender = new ShadersTestRS();
48185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mRender.init(mRS, getResources());
49185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
50185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
51185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
52185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    @Override
53185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    protected void onAttachedToWindow() {
54185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        super.onAttachedToWindow();
55185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        ensureRenderScript();
56185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
57185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
58185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    @Override
59185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
60185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        super.surfaceChanged(holder, format, w, h);
61185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mRender.surfaceChanged();
62185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
63185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
64185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    @Override
65185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    protected void onDetachedFromWindow() {
66185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mRender = null;
67185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        if (mRS != null) {
68185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mRS = null;
69185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            destroyRenderScriptGL();
70185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
71185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
72185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
73185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    @Override
74185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    public boolean onTouchEvent(MotionEvent ev) {
75185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        mScaleDetector.onTouchEvent(ev);
76185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
77185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        boolean ret = false;
78185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        float x = ev.getX();
79185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        float y = ev.getY();
80185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
81185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        final int action = ev.getAction();
82185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
83185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        switch (action & MotionEvent.ACTION_MASK) {
84185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        case MotionEvent.ACTION_DOWN: {
85185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mRender.onActionDown(x, y);
86185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mActivePointerId = ev.getPointerId(0);
87185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            ret = true;
88185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            break;
89185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
90185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        case MotionEvent.ACTION_MOVE: {
91185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            if (!mScaleDetector.isInProgress()) {
92185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                mRender.onActionMove(x, y);
93185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            }
94185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mRender.onActionDown(x, y);
95185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            ret = true;
96185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            break;
97185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
98185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
99185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        case MotionEvent.ACTION_UP: {
100185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mActivePointerId = INVALID_POINTER_ID;
101185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            break;
102185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
103185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
104185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        case MotionEvent.ACTION_CANCEL: {
105185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mActivePointerId = INVALID_POINTER_ID;
106185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            break;
107185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
108185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
109185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        case MotionEvent.ACTION_POINTER_UP: {
110185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
111185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
112185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            final int pointerId = ev.getPointerId(pointerIndex);
113185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            if (pointerId == mActivePointerId) {
114185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                // This was our active pointer going up. Choose a new
115185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                // active pointer and adjust accordingly.
116185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
117185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                x = ev.getX(newPointerIndex);
118185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                y = ev.getY(newPointerIndex);
119185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                mRender.onActionDown(x, y);
120185268942b946028b65f5cff9b335af97f9aeab8Romain Guy                mActivePointerId = ev.getPointerId(newPointerIndex);
121185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            }
122185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            break;
123185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
124185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
125185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
126185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        return ret;
127185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
128185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
129185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
130185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        @Override
131185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        public boolean onScale(ScaleGestureDetector detector) {
132185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            mRender.onActionScale(detector.getScaleFactor());
133185268942b946028b65f5cff9b335af97f9aeab8Romain Guy            return true;
134185268942b946028b65f5cff9b335af97f9aeab8Romain Guy        }
135185268942b946028b65f5cff9b335af97f9aeab8Romain Guy    }
136185268942b946028b65f5cff9b335af97f9aeab8Romain Guy}
137185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
138185268942b946028b65f5cff9b335af97f9aeab8Romain Guy
139