diff options
author | Chet Haase <chet@google.com> | 2012-03-12 15:48:32 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-03-12 15:48:32 -0700 |
commit | 81a0647c302edb4ed74d6d80d8f85c85a6c3fec4 (patch) | |
tree | da6a3f7ce1cebe1c613f110d2f0421ca0d780ee3 /core | |
parent | 035c20f5b4f31a2a4b592ff5004fe67fef0106d2 (diff) | |
parent | a1cff5043d0fbd78fcf9c48e7658e56a5b0c2de3 (diff) | |
download | frameworks_base-81a0647c302edb4ed74d6d80d8f85c85a6c3fec4.zip frameworks_base-81a0647c302edb4ed74d6d80d8f85c85a6c3fec4.tar.gz frameworks_base-81a0647c302edb4ed74d6d80d8f85c85a6c3fec4.tar.bz2 |
Merge "Handle view properties at the native level"
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/DisplayList.java | 200 | ||||
-rw-r--r-- | core/java/android/view/GLES20DisplayList.java | 245 | ||||
-rw-r--r-- | core/java/android/view/HardwareLayer.java | 19 | ||||
-rw-r--r-- | core/java/android/view/View.java | 327 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 16 | ||||
-rw-r--r-- | core/java/android/view/ViewPropertyAnimator.java | 2 | ||||
-rw-r--r-- | core/java/android/widget/TextView.java | 5 | ||||
-rw-r--r-- | core/jni/Android.mk | 1 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android/graphics/Camera.cpp | 18 | ||||
-rw-r--r-- | core/jni/android_view_GLES20DisplayList.cpp | 227 |
11 files changed, 999 insertions, 63 deletions
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index f60c8f0..a50f09f 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -70,4 +70,204 @@ public abstract class DisplayList { * @return The size of this display list in bytes */ public abstract int getSize(); + + /////////////////////////////////////////////////////////////////////////// + // DisplayList Property Setters + /////////////////////////////////////////////////////////////////////////// + + /** + * Set the caching property on the DisplayList, which indicates whether the DisplayList + * holds a layer. Layer DisplayLists should avoid creating an alpha layer, since alpha is + * handled in the drawLayer operation directly (and more efficiently). + * + * @param caching true if the DisplayList represents a hardware layer, false otherwise. + */ + public abstract void setCaching(boolean caching); + + /** + * Set whether the DisplayList should clip itself to its bounds. This property is controlled by + * the view's parent. + * + * @param clipChildren true if the DisplayList should clip to its bounds + */ + public abstract void setClipChildren(boolean clipChildren); + + /** + * Set the application scale on the DisplayList. This scale is incurred by applications that + * are auto-scaled for compatibility reasons. By default, the value is 1 (unscaled). + * + * @param scale The scaling factor + */ + public abstract void setApplicationScale(float scale); + + /** + * Sets the alpha value for the DisplayList + * + * @param alpha The translucency of the DisplayList + * @see View#setAlpha(float) + */ + public abstract void setAlpha(float alpha); + + /** + * Sets the translationX value for the DisplayList + * + * @param translationX The translationX value of the DisplayList + * @see View#setTranslationX(float) + */ + public abstract void setTranslationX(float translationX); + + /** + * Sets the translationY value for the DisplayList + * + * @param translationY The translationY value of the DisplayList + * @see View#setTranslationY(float) + */ + public abstract void setTranslationY(float translationY); + + /** + * Sets the rotation value for the DisplayList + * + * @param rotation The rotation value of the DisplayList + * @see View#setRotation(float) + */ + public abstract void setRotation(float rotation); + + /** + * Sets the rotationX value for the DisplayList + * + * @param rotationX The rotationX value of the DisplayList + * @see View#setRotationX(float) + */ + public abstract void setRotationX(float rotationX); + + /** + * Sets the rotationY value for the DisplayList + * + * @param rotationY The rotationY value of the DisplayList + * @see View#setRotationY(float) + */ + public abstract void setRotationY(float rotationY); + + /** + * Sets the scaleX value for the DisplayList + * + * @param scaleX The scaleX value of the DisplayList + * @see View#setScaleX(float) + */ + public abstract void setScaleX(float scaleX); + + /** + * Sets the scaleY value for the DisplayList + * + * @param scaleY The scaleY value of the DisplayList + * @see View#setScaleY(float) + */ + public abstract void setScaleY(float scaleY); + + /** + * Sets all of the transform-related values of the View onto the DisplayList + * + * @param alpha The alpha value of the DisplayList + * @param translationX The translationX value of the DisplayList + * @param translationY The translationY value of the DisplayList + * @param rotation The rotation value of the DisplayList + * @param rotationX The rotationX value of the DisplayList + * @param rotationY The rotationY value of the DisplayList + * @param scaleX The scaleX value of the DisplayList + * @param scaleY The scaleY value of the DisplayList + */ + public abstract void setTransformationInfo(float alpha, float translationX, float translationY, + float rotation, float rotationX, float rotationY, float scaleX, float scaleY); + + /** + * Sets the pivotX value for the DisplayList + * + * @param pivotX The pivotX value of the DisplayList + * @see View#setPivotX(float) + */ + public abstract void setPivotX(float pivotX); + + /** + * Sets the pivotY value for the DisplayList + * + * @param pivotY The pivotY value of the DisplayList + * @see View#setPivotY(float) + */ + public abstract void setPivotY(float pivotY); + + /** + * Sets the camera distance for the DisplayList + * + * @param distance The distance in z of the camera of the DisplayList + * @see View#setCameraDistance(float) + */ + public abstract void setCameraDistance(float distance); + + /** + * Sets the left value for the DisplayList + * + * @param left The left value of the DisplayList + * @see View#setLeft(int) + */ + public abstract void setLeft(int left); + + /** + * Sets the top value for the DisplayList + * + * @param top The top value of the DisplayList + * @see View#setTop(int) + */ + public abstract void setTop(int top); + + /** + * Sets the right value for the DisplayList + * + * @param right The right value of the DisplayList + * @see View#setRight(int) + */ + public abstract void setRight(int right); + + /** + * Sets the bottom value for the DisplayList + * + * @param bottom The bottom value of the DisplayList + * @see View#setBottom(int) + */ + public abstract void setBottom(int bottom); + + /** + * Sets the left and top values for the DisplayList + * + * @param left The left value of the DisplayList + * @param top The top value of the DisplayList + * @see View#setLeft(int) + * @see View#setTop(int) + */ + public abstract void setLeftTop(int left, int top); + + /** + * Sets the left and top values for the DisplayList + * + * @param left The left value of the DisplayList + * @param top The top value of the DisplayList + * @see View#setLeft(int) + * @see View#setTop(int) + */ + public abstract void setLeftTopRightBottom(int left, int top, int right, int bottom); + + /** + * Offsets the left and right values for the DisplayList + * + * @param offset The amount that the left and right values of the DisplayList are offset + * @see View#offsetLeftAndRight(int) + */ + public abstract void offsetLeftRight(int offset); + + /** + * Offsets the top and bottom values for the DisplayList + * + * @param offset The amount that the top and bottom values of the DisplayList are offset + * @see View#offsetTopAndBottom(int) + */ + public abstract void offsetTopBottom(int offset); } diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java index 969c9ab..9b4cf21 100644 --- a/core/java/android/view/GLES20DisplayList.java +++ b/core/java/android/view/GLES20DisplayList.java @@ -96,6 +96,251 @@ class GLES20DisplayList extends DisplayList { return GLES20Canvas.getDisplayListSize(mFinalizer.mNativeDisplayList); } + /////////////////////////////////////////////////////////////////////////// + // Native View Properties + /////////////////////////////////////////////////////////////////////////// + + @Override + public void setCaching(boolean caching) { + try { + nSetCaching(getNativeDisplayList(), caching); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setClipChildren(boolean clipChildren) { + try { + nSetClipChildren(getNativeDisplayList(), clipChildren); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setApplicationScale(float scale) { + try { + nSetApplicationScale(getNativeDisplayList(), scale); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setAlpha(float alpha) { + try { + nSetAlpha(getNativeDisplayList(), alpha); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setTranslationX(float translationX) { + try { + nSetTranslationX(getNativeDisplayList(), translationX); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setTranslationY(float translationY) { + try { + nSetTranslationY(getNativeDisplayList(), translationY); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setRotation(float rotation) { + try { + nSetRotation(getNativeDisplayList(), rotation); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setRotationX(float rotationX) { + try { + nSetRotationX(getNativeDisplayList(), rotationX); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setRotationY(float rotationY) { + try { + nSetRotationY(getNativeDisplayList(), rotationY); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setScaleX(float scaleX) { + try { + nSetScaleX(getNativeDisplayList(), scaleX); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setScaleY(float scaleY) { + try { + nSetScaleY(getNativeDisplayList(), scaleY); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setTransformationInfo(float alpha, float translationX, float translationY, + float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { + try { + nSetTransformationInfo(getNativeDisplayList(), alpha, translationX, translationY, + rotation, rotationX, rotationY, scaleX, scaleY); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setPivotX(float pivotX) { + try { + nSetPivotX(getNativeDisplayList(), pivotX); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setPivotY(float pivotY) { + try { + nSetPivotY(getNativeDisplayList(), pivotY); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setCameraDistance(float distance) { + try { + nSetCameraDistance(getNativeDisplayList(), distance); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setLeft(int left) { + try { + nSetLeft(getNativeDisplayList(), left); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setTop(int top) { + try { + nSetTop(getNativeDisplayList(), top); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setRight(int right) { + try { + nSetRight(getNativeDisplayList(), right); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setBottom(int bottom) { + try { + nSetBottom(getNativeDisplayList(), bottom); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setLeftTop(int left, int top) { + try { + nSetLeftTop(getNativeDisplayList(), left, top); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void setLeftTopRightBottom(int left, int top, int right, int bottom) { + try { + nSetLeftTopRightBottom(getNativeDisplayList(), left, top, right, bottom); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void offsetLeftRight(int offset) { + try { + nOffsetLeftRight(getNativeDisplayList(), offset); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + @Override + public void offsetTopBottom(int offset) { + try { + nOffsetTopBottom(getNativeDisplayList(), offset); + } catch (IllegalStateException e) { + // invalid DisplayList okay: we'll set current values the next time we render to it + } + } + + private static native void nOffsetTopBottom(int displayList, int offset); + private static native void nOffsetLeftRight(int displayList, int offset); + private static native void nSetLeftTopRightBottom(int displayList, int left, int top, + int right, int bottom); + private static native void nSetLeftTop(int displayList, int left, int top); + private static native void nSetBottom(int displayList, int bottom); + private static native void nSetRight(int displayList, int right); + private static native void nSetTop(int displayList, int top); + private static native void nSetLeft(int displayList, int left); + private static native void nSetCameraDistance(int displayList, float distance); + private static native void nSetPivotY(int displayList, float pivotY); + private static native void nSetPivotX(int displayList, float pivotX); + private static native void nSetCaching(int displayList, boolean caching); + private static native void nSetClipChildren(int displayList, boolean clipChildren); + private static native void nSetApplicationScale(int displayList, float scale); + private static native void nSetAlpha(int displayList, float alpha); + private static native void nSetTranslationX(int displayList, float translationX); + private static native void nSetTranslationY(int displayList, float translationY); + private static native void nSetRotation(int displayList, float rotation); + private static native void nSetRotationX(int displayList, float rotationX); + private static native void nSetRotationY(int displayList, float rotationY); + private static native void nSetScaleX(int displayList, float scaleX); + private static native void nSetScaleY(int displayList, float scaleY); + private static native void nSetTransformationInfo(int displayList, float alpha, + float translationX, float translationY, float rotation, float rotationX, + float rotationY, float scaleX, float scaleY); + + + /////////////////////////////////////////////////////////////////////////// + // Finalization + /////////////////////////////////////////////////////////////////////////// + private static class DisplayListFinalizer { final int mNativeDisplayList; diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index a97167b..e73f7bf 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -36,6 +36,7 @@ abstract class HardwareLayer { int mWidth; int mHeight; + DisplayList mDisplayList; boolean mOpaque; @@ -79,6 +80,24 @@ abstract class HardwareLayer { } /** + * Returns the DisplayList for the layer. + * + * @return The DisplayList of the hardware layer + */ + DisplayList getDisplayList() { + return mDisplayList; + } + + /** + * Sets the DisplayList for the layer. + * + * @param displayList The new DisplayList for this layer + */ + void setDisplayList(DisplayList displayList) { + mDisplayList = displayList; + } + + /** * Returns whether or not this layer is opaque. * * @return True if the layer is opaque, false otherwise diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 679a65a..bf48ff2 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1498,6 +1498,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal static final ThreadLocal<Rect> sThreadLocal = new ThreadLocal<Rect>(); /** + * Temporary flag, used to enable processing of View properties in the native DisplayList + * object instead of during draw(). Soon to be enabled by default for hardware-accelerated + * apps. + * @hide + */ + protected static final boolean USE_DISPLAY_LIST_PROPERTIES = false; + + /** * Map used to store views' tags. */ private SparseArray<Object> mKeyedTags; @@ -7284,6 +7292,24 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } /** + * Gets the distance along the Z axis from the camera to this view. + * + * @see #setCameraDistance(float) + * + * @return The distance along the Z axis. + */ + public float getCameraDistance() { + ensureTransformationInfo(); + final float dpi = mResources.getDisplayMetrics().densityDpi; + final TransformationInfo info = mTransformationInfo; + if (info.mCamera == null) { + info.mCamera = new Camera(); + info.matrix3D = new Matrix(); + } + return -(info.mCamera.getLocationZ() * dpi); + } + + /** * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which * views are drawn) from the camera to this view. The camera's distance * affects 3D transformations, for instance rotations around the X and Y @@ -7338,6 +7364,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setCameraDistance(distance); + } } /** @@ -7379,6 +7408,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setRotation(rotation); + } } } @@ -7426,6 +7458,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setRotationY(rotationY); + } } } @@ -7473,6 +7508,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setRotationX(rotationX); + } } } @@ -7512,6 +7550,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setScaleX(scaleX); + } } } @@ -7551,6 +7592,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setScaleY(scaleY); + } } } @@ -7596,6 +7640,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setPivotX(pivotX); + } } } @@ -7640,6 +7687,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setPivotY(pivotY); + } } } @@ -7686,6 +7736,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } else { mPrivateFlags &= ~ALPHA_SET; invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setAlpha(alpha); + } } } } @@ -7710,6 +7763,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return true; } else { mPrivateFlags &= ~ALPHA_SET; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setAlpha(alpha); + } } } return false; @@ -7759,6 +7815,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal int oldHeight = mBottom - mTop; mTop = top; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setTop(mTop); + } onSizeChanged(width, mBottom - mTop, width, oldHeight); @@ -7825,6 +7884,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal int oldHeight = mBottom - mTop; mBottom = bottom; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setBottom(mBottom); + } onSizeChanged(width, mBottom - mTop, width, oldHeight); @@ -7885,6 +7947,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal int height = mBottom - mTop; mLeft = left; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setLeft(left); + } onSizeChanged(mRight - mLeft, height, oldWidth, height); @@ -7898,6 +7963,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } mBackgroundSizeChanged = true; invalidateParentIfNeeded(); + if (USE_DISPLAY_LIST_PROPERTIES) { + + } } } @@ -7942,6 +8010,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal int height = mBottom - mTop; mRight = right; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setRight(mRight); + } onSizeChanged(mRight - mLeft, height, oldWidth, height); @@ -8038,6 +8109,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setTranslationX(translationX); + } } } @@ -8075,6 +8149,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal info.mMatrixDirty = true; mPrivateFlags |= DRAWN; // force another invalidation with the new orientation invalidate(false); + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setTranslationY(translationY); + } } } @@ -8207,6 +8284,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal mTop += offset; mBottom += offset; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.offsetTopBottom(offset); + } if (!matrixIsIdentity) { mPrivateFlags |= DRAWN; // force another invalidation with the new orientation @@ -8248,6 +8328,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal mLeft += offset; mRight += offset; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.offsetLeftRight(offset); + } if (!matrixIsIdentity) { mPrivateFlags |= DRAWN; // force another invalidation with the new orientation @@ -10384,7 +10467,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return null; } - mHardwareLayer.redraw(getDisplayList(), mLocalDirtyRect); + mHardwareLayer.redraw(getHardwareLayerDisplayList(mHardwareLayer), mLocalDirtyRect); mLocalDirtyRect.setEmpty(); } @@ -10536,78 +10619,138 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } /** - * <p>Returns a display list that can be used to draw this view again - * without executing its draw method.</p> + * Returns a DisplayList. If the incoming displayList is null, one will be created. + * Otherwise, the same display list will be returned (after having been rendered into + * along the way, depending on the invalidation state of the view). * - * @return A DisplayList ready to replay, or null if caching is not enabled. - * - * @hide + * @param displayList The previous version of this displayList, could be null. + * @param isLayer Whether the requester of the display list is a layer. If so, + * the view will avoid creating a layer inside the resulting display list. + * @return A new or reused DisplayList object. */ - public DisplayList getDisplayList() { + private DisplayList getDisplayList(DisplayList displayList, boolean isLayer) { if (!canHaveDisplayList()) { return null; } if (((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || - mDisplayList == null || !mDisplayList.isValid() || - mRecreateDisplayList)) { + displayList == null || !displayList.isValid() || + (!isLayer && mRecreateDisplayList))) { // Don't need to recreate the display list, just need to tell our // children to restore/recreate theirs - if (mDisplayList != null && mDisplayList.isValid() && - !mRecreateDisplayList) { + if (displayList != null && displayList.isValid() && + !isLayer && !mRecreateDisplayList) { mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; mPrivateFlags &= ~DIRTY_MASK; dispatchGetDisplayList(); - return mDisplayList; + return displayList; } - // If we got here, we're recreating it. Mark it as such to ensure that - // we copy in child display lists into ours in drawChild() - mRecreateDisplayList = true; - if (mDisplayList == null) { + if (!isLayer) { + // If we got here, we're recreating it. Mark it as such to ensure that + // we copy in child display lists into ours in drawChild() + mRecreateDisplayList = true; + } + if (displayList == null) { final String name = getClass().getSimpleName(); - mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList(name); + displayList = mAttachInfo.mHardwareRenderer.createDisplayList(name); // If we're creating a new display list, make sure our parent gets invalidated // since they will need to recreate their display list to account for this // new child display list. invalidateParentCaches(); } - final HardwareCanvas canvas = mDisplayList.start(); + boolean caching = false; + final HardwareCanvas canvas = displayList.start(); int restoreCount = 0; - try { - int width = mRight - mLeft; - int height = mBottom - mTop; + int width = mRight - mLeft; + int height = mBottom - mTop; + try { canvas.setViewport(width, height); // The dirty rect should always be null for a display list canvas.onPreDraw(null); + int layerType = ( + !(mParent instanceof ViewGroup) || ((ViewGroup)mParent).mDrawLayers) ? + getLayerType() : LAYER_TYPE_NONE; + if (!isLayer && layerType == LAYER_TYPE_HARDWARE && USE_DISPLAY_LIST_PROPERTIES) { + final HardwareLayer layer = getHardwareLayer(); + if (layer != null && layer.isValid()) { + canvas.drawHardwareLayer(layer, 0, 0, mLayerPaint); + } else { + canvas.saveLayer(0, 0, + mRight - mLeft, mBottom - mTop, mLayerPaint, + Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); + } + caching = true; + } else { - computeScroll(); + computeScroll(); - restoreCount = canvas.save(); - canvas.translate(-mScrollX, -mScrollY); - mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; - mPrivateFlags &= ~DIRTY_MASK; + if (!USE_DISPLAY_LIST_PROPERTIES) { + restoreCount = canvas.save(); + } + canvas.translate(-mScrollX, -mScrollY); + if (!isLayer) { + mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; + mPrivateFlags &= ~DIRTY_MASK; + } - // Fast path for layouts with no backgrounds - if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { - dispatchDraw(canvas); - } else { - draw(canvas); + // Fast path for layouts with no backgrounds + if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { + dispatchDraw(canvas); + } else { + draw(canvas); + } } } finally { - canvas.restoreToCount(restoreCount); + if (USE_DISPLAY_LIST_PROPERTIES) { + canvas.restoreToCount(restoreCount); + } canvas.onPostDraw(); - mDisplayList.end(); + displayList.end(); + if (USE_DISPLAY_LIST_PROPERTIES) { + displayList.setCaching(caching); + } + if (isLayer && USE_DISPLAY_LIST_PROPERTIES) { + displayList.setLeftTopRightBottom(0, 0, width, height); + } else { + setDisplayListProperties(displayList); + } } - } else { + } else if (!isLayer) { mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID; mPrivateFlags &= ~DIRTY_MASK; } + return displayList; + } + + /** + * Get the DisplayList for the HardwareLayer + * + * @param layer The HardwareLayer whose DisplayList we want + * @return A DisplayList fopr the specified HardwareLayer + */ + private DisplayList getHardwareLayerDisplayList(HardwareLayer layer) { + DisplayList displayList = getDisplayList(layer.getDisplayList(), true); + layer.setDisplayList(displayList); + return displayList; + } + + + /** + * <p>Returns a display list that can be used to draw this view again + * without executing its draw method.</p> + * + * @return A DisplayList ready to replay, or null if caching is not enabled. + * + * @hide + */ + public DisplayList getDisplayList() { + mDisplayList = getDisplayList(mDisplayList, false); return mDisplayList; } @@ -11152,19 +11295,57 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return more; } + void setDisplayListProperties() { + setDisplayListProperties(mDisplayList); + } + + /** + * This method is called by getDisplayList() when a display list is created or re-rendered. + * It sets or resets the current value of all properties on that display list (resetting is + * necessary when a display list is being re-created, because we need to make sure that + * previously-set transform values + */ + void setDisplayListProperties(DisplayList displayList) { + if (USE_DISPLAY_LIST_PROPERTIES && displayList != null) { + displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); + if (mParent instanceof ViewGroup) { + displayList.setClipChildren( + (((ViewGroup)mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0); + } + if (mAttachInfo != null && mAttachInfo.mScalingRequired && + mAttachInfo.mApplicationScale != 1.0f) { + displayList.setApplicationScale(1f / mAttachInfo.mApplicationScale); + } + if (mTransformationInfo != null) { + displayList.setTransformationInfo(mTransformationInfo.mAlpha, + mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY, + mTransformationInfo.mRotation, mTransformationInfo.mRotationX, + mTransformationInfo.mRotationY, mTransformationInfo.mScaleX, + mTransformationInfo.mScaleY); + displayList.setCameraDistance(getCameraDistance()); + if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == PIVOT_EXPLICITLY_SET) { + displayList.setPivotX(getPivotX()); + displayList.setPivotY(getPivotY()); + } + } + } + } + /** * This method is called by ViewGroup.drawChild() to have each child view draw itself. * This draw() method is an implementation detail and is not intended to be overridden or * to be called from anywhere else other than ViewGroup.drawChild(). */ boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) { + boolean useDisplayListProperties = USE_DISPLAY_LIST_PROPERTIES && mAttachInfo != null && + mAttachInfo.mHardwareAccelerated; boolean more = false; final boolean childHasIdentityMatrix = hasIdentityMatrix(); final int flags = parent.mGroupFlags; - if ((flags & parent.FLAG_CLEAR_TRANSFORMATION) == parent.FLAG_CLEAR_TRANSFORMATION) { + if ((flags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) == ViewGroup.FLAG_CLEAR_TRANSFORMATION) { parent.mChildTransformation.clear(); - parent.mGroupFlags &= ~parent.FLAG_CLEAR_TRANSFORMATION; + parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION; } Transformation transformToApply = null; @@ -11175,8 +11356,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal int layerType = parent.mDrawLayers ? getLayerType() : LAYER_TYPE_NONE; final boolean hardwareAccelerated = canvas.isHardwareAccelerated(); - if ((flags & parent.FLAG_CHILDREN_DRAWN_WITH_CACHE) == parent.FLAG_CHILDREN_DRAWN_WITH_CACHE || - (flags & parent.FLAG_ALWAYS_DRAWN_WITH_CACHE) == parent.FLAG_ALWAYS_DRAWN_WITH_CACHE) { + if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 || + (flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) { caching = true; if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired; } else { @@ -11188,8 +11369,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal more = drawAnimation(parent, drawingTime, a, scalingRequired); concatMatrix = a.willChangeTransformationMatrix(); transformToApply = parent.mChildTransformation; - } else if ((flags & parent.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) == - parent.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) { + } else if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) { final boolean hasTransform = parent.getChildStaticTransformation(this, parent.mChildTransformation); if (hasTransform) { @@ -11239,6 +11419,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal buildDrawingCache(true); cache = getDrawingCache(true); break; + case LAYER_TYPE_HARDWARE: + if (useDisplayListProperties) { + hasDisplayList = canHaveDisplayList(); + } + break; case LAYER_TYPE_NONE: // Delay getting the display list until animation-driven alpha values are // set up and possibly passed on to the view @@ -11247,24 +11432,33 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } } } + useDisplayListProperties &= hasDisplayList; final boolean hasNoCache = cache == null || hasDisplayList; final boolean offsetForScroll = cache == null && !hasDisplayList && layerType != LAYER_TYPE_HARDWARE; - final int restoreTo = canvas.save(); + int restoreTo = -1; + if (!useDisplayListProperties) { + restoreTo = canvas.save(); + } if (offsetForScroll) { canvas.translate(mLeft - sx, mTop - sy); } else { - canvas.translate(mLeft, mTop); + if (!useDisplayListProperties) { + canvas.translate(mLeft, mTop); + } if (scalingRequired) { + if (useDisplayListProperties) { + restoreTo = canvas.save(); + } // mAttachInfo cannot be null, otherwise scalingRequired == false final float scale = 1.0f / mAttachInfo.mApplicationScale; canvas.scale(scale, scale); } } - float alpha = getAlpha(); + float alpha = useDisplayListProperties ? 1 : getAlpha(); if (transformToApply != null || alpha < 1.0f || !hasIdentityMatrix()) { if (transformToApply != null || !childHasIdentityMatrix) { int transX = 0; @@ -11279,20 +11473,22 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal if (concatMatrix) { // Undo the scroll translation, apply the transformation matrix, // then redo the scroll translate to get the correct result. - canvas.translate(-transX, -transY); - canvas.concat(transformToApply.getMatrix()); - canvas.translate(transX, transY); - parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION; + if (!hasDisplayList) { + canvas.translate(-transX, -transY); + canvas.concat(transformToApply.getMatrix()); + canvas.translate(transX, transY); + } + parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION; } float transformAlpha = transformToApply.getAlpha(); if (transformAlpha < 1.0f) { alpha *= transformToApply.getAlpha(); - parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION; + parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION; } } - if (!childHasIdentityMatrix) { + if (!childHasIdentityMatrix && !useDisplayListProperties) { canvas.translate(-transX, -transY); canvas.concat(getMatrix()); canvas.translate(transX, transY); @@ -11300,20 +11496,22 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } if (alpha < 1.0f) { - parent.mGroupFlags |= parent.FLAG_CLEAR_TRANSFORMATION; + parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION; if (hasNoCache) { final int multipliedAlpha = (int) (255 * alpha); if (!onSetAlpha(multipliedAlpha)) { int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG; - if ((flags & parent.FLAG_CLIP_CHILDREN) == parent.FLAG_CLIP_CHILDREN || + if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) != 0 || layerType != LAYER_TYPE_NONE) { layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG; } if (layerType == LAYER_TYPE_NONE) { - final int scrollX = hasDisplayList ? 0 : sx; - final int scrollY = hasDisplayList ? 0 : sy; - canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft, - scrollY + mBottom - mTop, multipliedAlpha, layerFlags); + if (!useDisplayListProperties) { + final int scrollX = hasDisplayList ? 0 : sx; + final int scrollY = hasDisplayList ? 0 : sy; + canvas.saveLayerAlpha(scrollX, scrollY, scrollX + mRight - mLeft, + scrollY + mBottom - mTop, multipliedAlpha, layerFlags); + } } } else { // Alpha is handled by the child directly, clobber the layer's alpha @@ -11326,7 +11524,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal mPrivateFlags &= ~ALPHA_SET; } - if ((flags & parent.FLAG_CLIP_CHILDREN) == parent.FLAG_CLIP_CHILDREN) { + if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN && + !useDisplayListProperties) { if (offsetForScroll) { canvas.clipRect(sx, sy, sx + (mRight - mLeft), sy + (mBottom - mTop)); } else { @@ -11351,7 +11550,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal if (hasNoCache) { boolean layerRendered = false; - if (layerType == LAYER_TYPE_HARDWARE) { + if (layerType == LAYER_TYPE_HARDWARE && !useDisplayListProperties) { final HardwareLayer layer = getHardwareLayer(); if (layer != null && layer.isValid()) { mLayerPaint.setAlpha((int) (alpha * 255)); @@ -11397,11 +11596,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } if (alpha < 1.0f) { cachePaint.setAlpha((int) (alpha * 255)); - parent.mGroupFlags |= parent.FLAG_ALPHA_LOWER_THAN_ONE; - } else if ((flags & parent.FLAG_ALPHA_LOWER_THAN_ONE) == - parent.FLAG_ALPHA_LOWER_THAN_ONE) { + parent.mGroupFlags |= ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE; + } else if ((flags & ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE) != 0) { cachePaint.setAlpha(255); - parent.mGroupFlags &= ~parent.FLAG_ALPHA_LOWER_THAN_ONE; + parent.mGroupFlags &= ~ViewGroup.FLAG_ALPHA_LOWER_THAN_ONE; } } else { cachePaint = mLayerPaint; @@ -11410,7 +11608,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint); } - canvas.restoreToCount(restoreTo); + if (restoreTo >= 0) { + canvas.restoreToCount(restoreTo); + } if (a != null && !more) { if (!hardwareAccelerated && !a.getFillAfter()) { @@ -11868,6 +12068,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal mTop = top; mRight = right; mBottom = bottom; + if (USE_DISPLAY_LIST_PROPERTIES && mDisplayList != null) { + mDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); + } mPrivateFlags |= HAS_BOUNDS; diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index c9e0242..1993ce6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2736,7 +2736,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @attr ref android.R.styleable#ViewGroup_clipChildren */ public void setClipChildren(boolean clipChildren) { - setBooleanFlag(FLAG_CLIP_CHILDREN, clipChildren); + boolean previousValue = (mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN; + if (clipChildren != previousValue) { + setBooleanFlag(FLAG_CLIP_CHILDREN, clipChildren); + if (USE_DISPLAY_LIST_PROPERTIES) { + for (int i = 0; i < mChildrenCount; ++i) { + View child = getChildAt(i); + if (child.mDisplayList != null) { + child.mDisplayList.setClipChildren(clipChildren); + } + } + } + } } /** @@ -3973,6 +3984,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final View v = children[i]; v.mTop += offset; v.mBottom += offset; + if (USE_DISPLAY_LIST_PROPERTIES && v.mDisplayList != null) { + v.mDisplayList.offsetTopBottom(offset); + } } } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index 0fdcd0f..fe0e659 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -866,6 +866,8 @@ public class ViewPropertyAnimator { info.mAlpha = value; break; } + // TODO: optimize to set only the properties that have changed + mView.setDisplayListProperties(); } /** diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b8db848..e535170 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -11703,8 +11703,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener firstLine, lastLine); if (mTextDisplayList == null || !mTextDisplayList.isValid()) { + boolean displayListCreated = false; if (mTextDisplayList == null) { mTextDisplayList = getHardwareRenderer().createDisplayList("Text"); + displayListCreated = true; } final HardwareCanvas hardwareCanvas = mTextDisplayList.start(); @@ -11719,6 +11721,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } finally { hardwareCanvas.onPostDraw(); mTextDisplayList.end(); + if (displayListCreated && USE_DISPLAY_LIST_PROPERTIES) { + mTextDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); + } } } canvas.translate(mScrollX, mScrollY); diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 543e32d..92b07b3 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -53,6 +53,7 @@ LOCAL_SRC_FILES:= \ android_view_KeyEvent.cpp \ android_view_KeyCharacterMap.cpp \ android_view_HardwareRenderer.cpp \ + android_view_GLES20DisplayList.cpp \ android_view_GLES20Canvas.cpp \ android_view_MotionEvent.cpp \ android_view_PointerIcon.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index a512679..92ff8da 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -117,6 +117,7 @@ extern int register_android_graphics_Xfermode(JNIEnv* env); extern int register_android_graphics_PixelFormat(JNIEnv* env); extern int register_android_view_Display(JNIEnv* env); extern int register_android_view_DisplayEventReceiver(JNIEnv* env); +extern int register_android_view_GLES20DisplayList(JNIEnv* env); extern int register_android_view_GLES20Canvas(JNIEnv* env); extern int register_android_view_HardwareRenderer(JNIEnv* env); extern int register_android_view_Surface(JNIEnv* env); @@ -1102,6 +1103,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_nio_utils), REG_JNI(register_android_graphics_PixelFormat), REG_JNI(register_android_graphics_Graphics), + REG_JNI(register_android_view_GLES20DisplayList), REG_JNI(register_android_view_GLES20Canvas), REG_JNI(register_android_view_HardwareRenderer), REG_JNI(register_android_view_Surface), diff --git a/core/jni/android/graphics/Camera.cpp b/core/jni/android/graphics/Camera.cpp index 76d415a..5176d9a 100644 --- a/core/jni/android/graphics/Camera.cpp +++ b/core/jni/android/graphics/Camera.cpp @@ -57,6 +57,21 @@ static void Camera_setLocation(JNIEnv* env, jobject obj, jfloat x, jfloat y, jfl v->setCameraLocation(SkFloatToScalar(x), SkFloatToScalar(y), SkFloatToScalar(z)); } +static jfloat Camera_getLocationX(JNIEnv* env, jobject obj) { + Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID); + return SkScalarToFloat(v->getCameraLocationX()); +} + +static jfloat Camera_getLocationY(JNIEnv* env, jobject obj) { + Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID); + return SkScalarToFloat(v->getCameraLocationY()); +} + +static jfloat Camera_getLocationZ(JNIEnv* env, jobject obj) { + Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID); + return SkScalarToFloat(v->getCameraLocationZ()); +} + static void Camera_getMatrix(JNIEnv* env, jobject obj, int native_matrix) { Sk3DView* v = (Sk3DView*)env->GetIntField(obj, gNativeInstanceFieldID); v->getMatrix((SkMatrix*)native_matrix); @@ -93,6 +108,9 @@ static JNINativeMethod gCameraMethods[] = { { "rotateZ", "(F)V", (void*)Camera_rotateZ }, { "rotate", "(FFF)V", (void*)Camera_rotate }, { "setLocation", "(FFF)V", (void*)Camera_setLocation }, + { "getLocationX", "()F", (void*)Camera_getLocationX }, + { "getLocationY", "()F", (void*)Camera_getLocationY }, + { "getLocationZ", "()F", (void*)Camera_getLocationZ }, { "nativeGetMatrix", "(I)V", (void*)Camera_getMatrix }, { "nativeApplyToCanvas", "(I)V", (void*)Camera_applyToCanvas }, { "dotWithNormal", "(FFF)F", (void*)Camera_dotWithNormal } diff --git a/core/jni/android_view_GLES20DisplayList.cpp b/core/jni/android_view_GLES20DisplayList.cpp new file mode 100644 index 0000000..407c196 --- /dev/null +++ b/core/jni/android_view_GLES20DisplayList.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2012 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. + */ + +#define LOG_TAG "OpenGLRenderer" + +#include <EGL/egl.h> + +#include "jni.h" +#include "GraphicsJNI.h" +#include <nativehelper/JNIHelp.h> +#include <android_runtime/AndroidRuntime.h> + +#include <DisplayListRenderer.h> + +namespace android { + +using namespace uirenderer; + +/** + * Note: OpenGLRenderer JNI layer is generated and compiled only on supported + * devices. This means all the logic must be compiled only when the + * preprocessor variable USE_OPENGL_RENDERER is defined. + */ +#ifdef USE_OPENGL_RENDERER + +// ---------------------------------------------------------------------------- +// DisplayList view properties +// ---------------------------------------------------------------------------- + +static void android_view_GLES20DisplayList_setCaching(JNIEnv* env, + jobject clazz, DisplayList* displayList, jboolean caching) { + displayList->setCaching(caching); +} + +static void android_view_GLES20DisplayList_setApplicationScale(JNIEnv* env, + jobject clazz, DisplayList* displayList, float scale) { + displayList->setApplicationScale(scale); +} + +static void android_view_GLES20DisplayList_setClipChildren(JNIEnv* env, + jobject clazz, DisplayList* displayList, jboolean clipChildren) { + displayList->setClipChildren(clipChildren); +} + +static void android_view_GLES20DisplayList_setAlpha(JNIEnv* env, + jobject clazz, DisplayList* displayList, float alpha) { + displayList->setAlpha(alpha); +} + +static void android_view_GLES20DisplayList_setTranslationX(JNIEnv* env, + jobject clazz, DisplayList* displayList, float tx) { + displayList->setTranslationX(tx); +} + +static void android_view_GLES20DisplayList_setTranslationY(JNIEnv* env, + jobject clazz, DisplayList* displayList, float ty) { + displayList->setTranslationY(ty); +} + +static void android_view_GLES20DisplayList_setRotation(JNIEnv* env, + jobject clazz, DisplayList* displayList, float rotation) { + displayList->setRotation(rotation); +} + +static void android_view_GLES20DisplayList_setRotationX(JNIEnv* env, + jobject clazz, DisplayList* displayList, float rx) { + displayList->setRotationX(rx); +} + +static void android_view_GLES20DisplayList_setRotationY(JNIEnv* env, + jobject clazz, DisplayList* displayList, float ry) { + displayList->setRotationY(ry); +} + +static void android_view_GLES20DisplayList_setScaleX(JNIEnv* env, + jobject clazz, DisplayList* displayList, float sx) { + displayList->setScaleX(sx); +} + +static void android_view_GLES20DisplayList_setScaleY(JNIEnv* env, + jobject clazz, DisplayList* displayList, float sy) { + displayList->setScaleY(sy); +} + +static void android_view_GLES20DisplayList_setTransformationInfo(JNIEnv* env, + jobject clazz, DisplayList* displayList, float alpha, + float translationX, float translationY, float rotation, float rotationX, float rotationY, + float scaleX, float scaleY) { + displayList->setAlpha(alpha); + displayList->setTranslationX(translationX); + displayList->setTranslationY(translationY); + displayList->setRotation(rotation); + displayList->setRotationX(rotationX); + displayList->setRotationY(rotationY); + displayList->setScaleX(scaleX); + displayList->setScaleY(scaleY); +} + +static void android_view_GLES20DisplayList_setPivotX(JNIEnv* env, + jobject clazz, DisplayList* displayList, float px) { + displayList->setPivotX(px); +} + +static void android_view_GLES20DisplayList_setPivotY(JNIEnv* env, + jobject clazz, DisplayList* displayList, float py) { + displayList->setPivotY(py); +} + +static void android_view_GLES20DisplayList_setCameraDistance(JNIEnv* env, + jobject clazz, DisplayList* displayList, float distance) { + displayList->setCameraDistance(distance); +} + +static void android_view_GLES20DisplayList_setLeft(JNIEnv* env, + jobject clazz, DisplayList* displayList, int left) { + displayList->setLeft(left); +} + +static void android_view_GLES20DisplayList_setTop(JNIEnv* env, + jobject clazz, DisplayList* displayList, int top) { + displayList->setTop(top); +} + +static void android_view_GLES20DisplayList_setRight(JNIEnv* env, + jobject clazz, DisplayList* displayList, int right) { + displayList->setRight(right); +} + +static void android_view_GLES20DisplayList_setBottom(JNIEnv* env, + jobject clazz, DisplayList* displayList, int bottom) { + displayList->setBottom(bottom); +} + +static void android_view_GLES20DisplayList_setLeftTop(JNIEnv* env, + jobject clazz, DisplayList* displayList, int left, int top) { + displayList->setLeftTop(left, top); +} + +static void android_view_GLES20DisplayList_setLeftTopRightBottom(JNIEnv* env, + jobject clazz, DisplayList* displayList, int left, int top, + int right, int bottom) { + displayList->setLeftTopRightBottom(left, top, right, bottom); +} + +static void android_view_GLES20DisplayList_offsetLeftRight(JNIEnv* env, + jobject clazz, DisplayList* displayList, int offset) { + displayList->offsetLeftRight(offset); +} + +static void android_view_GLES20DisplayList_offsetTopBottom(JNIEnv* env, + jobject clazz, DisplayList* displayList, int offset) { + displayList->offsetTopBottom(offset); +} + +#endif // USE_OPENGL_RENDERER + +// ---------------------------------------------------------------------------- +// JNI Glue +// ---------------------------------------------------------------------------- + +const char* const kClassPathName = "android/view/GLES20DisplayList"; + +static JNINativeMethod gMethods[] = { +#ifdef USE_OPENGL_RENDERER + { "nSetCaching", "(IZ)V", (void*) android_view_GLES20DisplayList_setCaching }, + { "nSetApplicationScale", "(IF)V", + (void*) android_view_GLES20DisplayList_setApplicationScale }, + { "nSetClipChildren", "(IZ)V", (void*) android_view_GLES20DisplayList_setClipChildren }, + { "nSetAlpha", "(IF)V", (void*) android_view_GLES20DisplayList_setAlpha }, + { "nSetTranslationX", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationX }, + { "nSetTranslationY", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationY }, + { "nSetRotation", "(IF)V", (void*) android_view_GLES20DisplayList_setRotation }, + { "nSetRotationX", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationX }, + { "nSetRotationY", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationY }, + { "nSetScaleX", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleX }, + { "nSetScaleY", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleY }, + { "nSetTransformationInfo", "(IFFFFFFFF)V", + (void*) android_view_GLES20DisplayList_setTransformationInfo }, + { "nSetPivotX", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotX }, + { "nSetPivotY", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotY }, + { "nSetCameraDistance", "(IF)V", + (void*) android_view_GLES20DisplayList_setCameraDistance }, + { "nSetLeft", "(II)V", (void*) android_view_GLES20DisplayList_setLeft }, + { "nSetTop", "(II)V", (void*) android_view_GLES20DisplayList_setTop }, + { "nSetRight", "(II)V", (void*) android_view_GLES20DisplayList_setRight }, + { "nSetBottom", "(II)V", (void*) android_view_GLES20DisplayList_setBottom }, + { "nSetLeftTop", "(III)V", (void*) android_view_GLES20DisplayList_setLeftTop }, + { "nSetLeftTopRightBottom", "(IIIII)V", + (void*) android_view_GLES20DisplayList_setLeftTopRightBottom }, + { "nOffsetLeftRight", "(II)V", (void*) android_view_GLES20DisplayList_offsetLeftRight }, + { "nOffsetTopBottom", "(II)V", (void*) android_view_GLES20DisplayList_offsetTopBottom }, + +#endif +}; + +#ifdef USE_OPENGL_RENDERER + #define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(! var, "Unable to find class " className); + + #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find method " methodName); +#else + #define FIND_CLASS(var, className) + #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) +#endif + +int register_android_view_GLES20DisplayList(JNIEnv* env) { + return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); +} + +}; + |