diff --git a/api/current.xml b/api/current.xml index a36f0665498bc..cd827a6f2cb16 100644 --- a/api/current.xml +++ b/api/current.xml @@ -77585,6 +77585,23 @@ visibility="public" > + + + + + + + + + + + + + + + + - + diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index ae06888addc11..e00b9cd889b93 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5748,9 +5748,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } mCamera.save(); mMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY); - mCamera.rotateX(mRotationX); - mCamera.rotateY(mRotationY); - mCamera.rotateZ(-mRotation); + mCamera.rotate(mRotationX, mRotationY, -mRotation); mCamera.getMatrix(matrix3D); matrix3D.preTranslate(-mPivotX, -mPivotY); matrix3D.postTranslate(mPivotX + mTranslationX, mPivotY + mTranslationY); diff --git a/core/jni/android/graphics/Camera.cpp b/core/jni/android/graphics/Camera.cpp index 980003e27efb8..0d715fd92045a 100644 --- a/core/jni/android/graphics/Camera.cpp +++ b/core/jni/android/graphics/Camera.cpp @@ -45,6 +45,18 @@ static void Camera_rotateZ(JNIEnv* env, jobject obj, float degrees) { v->rotateZ(SkFloatToScalar(degrees)); } +static void Camera_rotate(JNIEnv* env, jobject obj, jfloat x, jfloat y, jfloat z) { + Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID); + v->rotateX(SkFloatToScalar(x)); + v->rotateY(SkFloatToScalar(y)); + v->rotateZ(SkFloatToScalar(z)); +} + +static void Camera_setLocation(JNIEnv* env, jobject obj, jfloat x, jfloat y, jfloat z) { + Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID); + v->setCameraLocation(SkFloatToScalar(x), SkFloatToScalar(y), SkFloatToScalar(z)); +} + static void Camera_getMatrix(JNIEnv* env, jobject obj, int native_matrix) { Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID); v->getMatrix((SkMatrix*)native_matrix); @@ -79,6 +91,8 @@ static JNINativeMethod gCameraMethods[] = { { "rotateX", "(F)V", (void*)Camera_rotateX }, { "rotateY", "(F)V", (void*)Camera_rotateY }, { "rotateZ", "(F)V", (void*)Camera_rotateZ }, + { "rotate", "(FFF)V", (void*)Camera_rotate }, + { "setLocation", "(FFF)V", (void*)Camera_setLocation }, { "nativeGetMatrix", "(I)V", (void*)Camera_getMatrix }, { "nativeApplyToCanvas", "(I)V", (void*)Camera_applyToCanvas }, { "dotWithNormal", "(FFF)F", (void*)Camera_dotWithNormal } diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java index 530655f1e4dde..7ef35a925060e 100644 --- a/graphics/java/android/graphics/Camera.java +++ b/graphics/java/android/graphics/Camera.java @@ -16,24 +16,115 @@ package android.graphics; - +/** + * A camera instance can be used to compute 3D transformations and + * generate a matrix that can be applied, for instance, on a + * {@link Canvas}. + */ public class Camera { - + /** + * Creates a new camera, with empty transformations. + */ public Camera() { nativeConstructor(); } + /** + * Saves the camera state. Each save should be balanced + * with a call to {@link #restore()}. + * + * @see #save() + */ public native void save(); + + /** + * Restores the saved state, if any. + * + * @see #restore() + */ public native void restore(); + /** + * Applies a translation transform on all three axis. + * + * @param x The distance to translate by on the X axis + * @param y The distance to translate by on the Y axis + * @param z The distance to translate by on the Z axis + */ public native void translate(float x, float y, float z); + + /** + * Applies a rotation transform around the X axis. + * + * @param deg The angle of rotation around the X axis, in degrees + * + * @see #rotateY(float) + * @see #rotateZ(float) + * @see #rotate(float, float, float) + */ public native void rotateX(float deg); + + /** + * Applies a rotation transform around the Y axis. + * + * @param deg The angle of rotation around the Y axis, in degrees + * + * @see #rotateX(float) + * @see #rotateZ(float) + * @see #rotate(float, float, float) + */ public native void rotateY(float deg); + + /** + * Applies a rotation transform around the Z axis. + * + * @param deg The angle of rotation around the Z axis, in degrees + * + * @see #rotateX(float) + * @see #rotateY(float) + * @see #rotate(float, float, float) + */ public native void rotateZ(float deg); + /** + * Applies a rotation transform around all three axis. + * + * @param x The angle of rotation around the X axis, in degrees + * @param y The angle of rotation around the Y axis, in degrees + * @param z The angle of rotation around the Z axis, in degrees + * + * @see #rotateX(float) + * @see #rotateY(float) + * @see #rotateZ(float) + */ + public native void rotate(float x, float y, float z); + + /** + * Sets the location of the camera. The default location is set at + * 0, 0, -8. + * + * @param x The x location of the camera + * @param y The y location of the camera + * @param z The z location of the camera + */ + public native void setLocation(float x, float y, float z); + + /** + * Computes the matrix corresponding to the current transformation + * and copies it to the supplied matrix object. + * + * @param matrix The matrix to copy the current transforms into + */ public void getMatrix(Matrix matrix) { nativeGetMatrix(matrix.native_instance); } + + /** + * Computes the matrix corresponding to the current transformation + * and applies it to the specified Canvas. + * + * @param canvas The Canvas to set the transform matrix onto + */ public void applyToCanvas(Canvas canvas) { nativeApplyToCanvas(canvas.mNativeCanvas); } @@ -41,7 +132,11 @@ public class Camera { public native float dotWithNormal(float dx, float dy, float dz); protected void finalize() throws Throwable { - nativeDestructor(); + try { + nativeDestructor(); + } finally { + super.finalize(); + } } private native void nativeConstructor(); @@ -51,4 +146,3 @@ public class Camera { int native_instance; } - diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index ae7ec45903cf1..e82f9aa83826f 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -396,6 +396,16 @@ + + + + + + + diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/large_photo.jpg b/tests/HwAccelerationTest/res/drawable-nodpi/large_photo.jpg new file mode 100644 index 0000000000000..e23dbb093f39d Binary files /dev/null and b/tests/HwAccelerationTest/res/drawable-nodpi/large_photo.jpg differ diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/Animated3dActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/Animated3dActivity.java new file mode 100644 index 0000000000000..f632c8372c353 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/Animated3dActivity.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.animation.ObjectAnimator; +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Camera; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.os.Bundle; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageView; + +@SuppressWarnings({"UnusedDeclaration"}) +public class Animated3dActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ImageView view = new ImageView(this); + view.setImageResource(R.drawable.large_photo); + + setContentView(view, new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT + )); + + ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 0.0f, 360.0f); + animator.setDuration(4000); + animator.setRepeatCount(ObjectAnimator.INFINITE); + animator.setRepeatMode(ObjectAnimator.REVERSE); + animator.start(); + } +}