1a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk/* 2a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project 3a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * 4a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License"); 5a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * you may not use this file except in compliance with the License. 6a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * You may obtain a copy of the License at 7a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * 8a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * http://www.apache.org/licenses/LICENSE-2.0 9a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * 10a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software 11a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS, 12a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * See the License for the specific language governing permissions and 14a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk * limitations under the License. 15a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk */ 16a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 17d4cb9c587c23e3c24d928b0ac1a4de5679846f93Alex Sakhartchoukpackage com.android.testapp; 18a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 19a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.io.Writer; 20a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.ArrayList; 21a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport java.util.concurrent.Semaphore; 22a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 23a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.RSSurfaceView; 24a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.RenderScript; 25a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.renderscript.RenderScriptGL; 26a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 27a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.content.Context; 28a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.content.res.Resources; 29a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.graphics.Bitmap; 30a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.graphics.drawable.BitmapDrawable; 31a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.graphics.drawable.Drawable; 32a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.os.Handler; 33a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.os.Message; 34a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.util.AttributeSet; 35a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.util.Log; 36a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.view.Surface; 37a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.view.SurfaceHolder; 38a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.view.SurfaceView; 39a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.view.KeyEvent; 40a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.view.MotionEvent; 41a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchoukimport android.view.ScaleGestureDetector; 42a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 433fc86ec3d03bb4a0ae61e41d0cfba43595ecc23dAlex Sakhartchoukpublic class TestAppView extends RSSurfaceView { 44a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 453fc86ec3d03bb4a0ae61e41d0cfba43595ecc23dAlex Sakhartchouk public TestAppView(Context context) { 46a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk super(context); 47a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 48a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 49a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 50a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private RenderScriptGL mRS; 513fc86ec3d03bb4a0ae61e41d0cfba43595ecc23dAlex Sakhartchouk TestAppRS mRender; 52a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 53a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private ScaleGestureDetector mScaleDetector; 54a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private static final int INVALID_POINTER_ID = -1; 55a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private int mActivePointerId = INVALID_POINTER_ID; 56a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 57a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 58a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk super.surfaceChanged(holder, format, w, h); 59a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (mRS == null) { 60a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); 61a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk sc.setDepth(16, 24); 62b23b58ad343ccbf8835c7067698a60fc6bc1a870Alex Sakhartchouk sc.setSamples(1, 2, 1); 63a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRS = createRenderScriptGL(sc); 64a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRS.setSurface(holder, w, h); 653fc86ec3d03bb4a0ae61e41d0cfba43595ecc23dAlex Sakhartchouk mRender = new TestAppRS(); 66a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRender.init(mRS, getResources(), w, h); 67a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 68a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 69a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 70a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk @Override 71a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk protected void onDetachedFromWindow() { 72a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (mRS != null) { 73a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRender = null; 74a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRS = null; 75a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk destroyRenderScriptGL(); 76a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 77a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 78a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 79a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk @Override 80a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk public boolean onKeyDown(int keyCode, KeyEvent event) 81a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk { 82a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk // break point at here 83a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk // this method doesn't work when 'extends View' include 'extends ScrollView'. 84a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk return super.onKeyDown(keyCode, event); 85a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 86a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 87a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 88a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk @Override 89a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk public boolean onTouchEvent(MotionEvent ev) { 90a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mScaleDetector.onTouchEvent(ev); 91a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 92a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk boolean ret = false; 93a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk float x = ev.getX(); 94a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk float y = ev.getY(); 95a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 96a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk final int action = ev.getAction(); 97a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 98a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk switch (action & MotionEvent.ACTION_MASK) { 99a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk case MotionEvent.ACTION_DOWN: { 100a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRender.onActionDown(x, y); 101a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mActivePointerId = ev.getPointerId(0); 102a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk ret = true; 103a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk break; 104a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 105a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk case MotionEvent.ACTION_MOVE: { 106a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (!mScaleDetector.isInProgress()) { 107a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRender.onActionMove(x, y); 108a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 109a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRender.onActionDown(x, y); 110a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk ret = true; 111a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk break; 112a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 113a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 114a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk case MotionEvent.ACTION_UP: { 115a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mActivePointerId = INVALID_POINTER_ID; 116a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk break; 117a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 118a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 119a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk case MotionEvent.ACTION_CANCEL: { 120a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mActivePointerId = INVALID_POINTER_ID; 121a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk break; 122a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 123a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 124a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk case MotionEvent.ACTION_POINTER_UP: { 125a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 126a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 127a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk final int pointerId = ev.getPointerId(pointerIndex); 128a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk if (pointerId == mActivePointerId) { 129a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk // This was our active pointer going up. Choose a new 130a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk // active pointer and adjust accordingly. 131a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 132a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk x = ev.getX(newPointerIndex); 133a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk y = ev.getY(newPointerIndex); 134a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRender.onActionDown(x, y); 135a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mActivePointerId = ev.getPointerId(newPointerIndex); 136a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 137a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk break; 138a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 139a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 140a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 141a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk return ret; 142a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 143a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 144a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 145a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk @Override 146a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk public boolean onScale(ScaleGestureDetector detector) { 147a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk mRender.onActionScale(detector.getScaleFactor()); 148a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk return true; 149a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 150a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk } 151a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk} 152a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 153a7a211b8a68a7d3f5ff4409aa286db07f96c0550Alex Sakhartchouk 154