Merge "De-couple RenderNode from View package"
This commit is contained in:
@@ -19,6 +19,7 @@ package android.view;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.graphics.BaseRecordingCanvas;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.CanvasProperty;
|
||||
import android.graphics.Paint;
|
||||
@@ -35,7 +36,7 @@ import dalvik.annotation.optimization.FastNative;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class DisplayListCanvas extends RecordingCanvas {
|
||||
public final class DisplayListCanvas extends BaseRecordingCanvas {
|
||||
// The recording canvas pool should be large enough to handle a deeply nested
|
||||
// view hierarchy because display lists are generated recursively.
|
||||
private static final int POOL_LIMIT = 25;
|
||||
|
||||
29
core/java/android/view/NativeVectorDrawableAnimator.java
Normal file
29
core/java/android/view/NativeVectorDrawableAnimator.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 android.view;
|
||||
|
||||
/**
|
||||
* Exists just to allow for android.graphics & android.view package separation
|
||||
*
|
||||
* TODO: Get off of this coupling more cleanly somehow
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public interface NativeVectorDrawableAnimator {
|
||||
/** @hide */
|
||||
long getAnimatorNativePtr();
|
||||
}
|
||||
@@ -1,657 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 android.view;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.Size;
|
||||
import android.graphics.BaseCanvas;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.NinePatch;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Picture;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.TemporaryBuffer;
|
||||
import android.text.GraphicsOperations;
|
||||
import android.text.MeasuredParagraph;
|
||||
import android.text.PrecomputedText;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannedString;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import dalvik.annotation.optimization.FastNative;
|
||||
|
||||
/**
|
||||
* This class is a base class for canvases that defer drawing operations, so all
|
||||
* the draw operations can be marked @FastNative. It contains a re-implementation of
|
||||
* all the methods in {@link BaseCanvas}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class RecordingCanvas extends Canvas {
|
||||
|
||||
public RecordingCanvas(long nativeCanvas) {
|
||||
super(nativeCanvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawArc(float left, float top, float right, float bottom, float startAngle,
|
||||
float sweepAngle, boolean useCenter, @NonNull Paint paint) {
|
||||
nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
|
||||
useCenter, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle,
|
||||
boolean useCenter, @NonNull Paint paint) {
|
||||
drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
|
||||
paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawARGB(int a, int r, int g, int b) {
|
||||
drawColor(Color.argb(a, r, g, b));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawBitmap(@NonNull Bitmap bitmap, float left, float top,
|
||||
@Nullable Paint paint) {
|
||||
throwIfCannotDraw(bitmap);
|
||||
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
|
||||
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
|
||||
bitmap.mDensity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix,
|
||||
@Nullable Paint paint) {
|
||||
nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
|
||||
paint != null ? paint.getNativeInstance() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst,
|
||||
@Nullable Paint paint) {
|
||||
if (dst == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
throwIfCannotDraw(bitmap);
|
||||
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||
|
||||
int left, top, right, bottom;
|
||||
if (src == null) {
|
||||
left = top = 0;
|
||||
right = bitmap.getWidth();
|
||||
bottom = bitmap.getHeight();
|
||||
} else {
|
||||
left = src.left;
|
||||
right = src.right;
|
||||
top = src.top;
|
||||
bottom = src.bottom;
|
||||
}
|
||||
|
||||
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
|
||||
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
|
||||
bitmap.mDensity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst,
|
||||
@Nullable Paint paint) {
|
||||
if (dst == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
throwIfCannotDraw(bitmap);
|
||||
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||
|
||||
float left, top, right, bottom;
|
||||
if (src == null) {
|
||||
left = top = 0;
|
||||
right = bitmap.getWidth();
|
||||
bottom = bitmap.getHeight();
|
||||
} else {
|
||||
left = src.left;
|
||||
right = src.right;
|
||||
top = src.top;
|
||||
bottom = src.bottom;
|
||||
}
|
||||
|
||||
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
|
||||
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
|
||||
bitmap.mDensity);
|
||||
}
|
||||
|
||||
/** @deprecated checkstyle */
|
||||
@Override
|
||||
@Deprecated
|
||||
public final void drawBitmap(@NonNull int[] colors, int offset, int stride, float x, float y,
|
||||
int width, int height, boolean hasAlpha, @Nullable Paint paint) {
|
||||
// check for valid input
|
||||
if (width < 0) {
|
||||
throw new IllegalArgumentException("width must be >= 0");
|
||||
}
|
||||
if (height < 0) {
|
||||
throw new IllegalArgumentException("height must be >= 0");
|
||||
}
|
||||
if (Math.abs(stride) < width) {
|
||||
throw new IllegalArgumentException("abs(stride) must be >= width");
|
||||
}
|
||||
int lastScanline = offset + (height - 1) * stride;
|
||||
int length = colors.length;
|
||||
if (offset < 0 || (offset + width > length) || lastScanline < 0
|
||||
|| (lastScanline + width > length)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
// quick escape if there's nothing to draw
|
||||
if (width == 0 || height == 0) {
|
||||
return;
|
||||
}
|
||||
// punch down to native for the actual draw
|
||||
nDrawBitmap(mNativeCanvasWrapper, colors, offset, stride, x, y, width, height, hasAlpha,
|
||||
paint != null ? paint.getNativeInstance() : 0);
|
||||
}
|
||||
|
||||
/** @deprecated checkstyle */
|
||||
@Override
|
||||
@Deprecated
|
||||
public final void drawBitmap(@NonNull int[] colors, int offset, int stride, int x, int y,
|
||||
int width, int height, boolean hasAlpha, @Nullable Paint paint) {
|
||||
// call through to the common float version
|
||||
drawBitmap(colors, offset, stride, (float) x, (float) y, width, height,
|
||||
hasAlpha, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawBitmapMesh(@NonNull Bitmap bitmap, int meshWidth, int meshHeight,
|
||||
@NonNull float[] verts, int vertOffset, @Nullable int[] colors, int colorOffset,
|
||||
@Nullable Paint paint) {
|
||||
if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (meshWidth == 0 || meshHeight == 0) {
|
||||
return;
|
||||
}
|
||||
int count = (meshWidth + 1) * (meshHeight + 1);
|
||||
// we mul by 2 since we need two floats per vertex
|
||||
checkRange(verts.length, vertOffset, count * 2);
|
||||
if (colors != null) {
|
||||
// no mul by 2, since we need only 1 color per vertex
|
||||
checkRange(colors.length, colorOffset, count);
|
||||
}
|
||||
nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
|
||||
verts, vertOffset, colors, colorOffset,
|
||||
paint != null ? paint.getNativeInstance() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
|
||||
nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawColor(@ColorInt int color) {
|
||||
nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawColor(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
|
||||
nDrawColor(mNativeCanvasWrapper, color, mode.nativeInt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawLine(float startX, float startY, float stopX, float stopY,
|
||||
@NonNull Paint paint) {
|
||||
nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
|
||||
@NonNull Paint paint) {
|
||||
nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) {
|
||||
drawLines(pts, 0, pts.length, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawOval(float left, float top, float right, float bottom,
|
||||
@NonNull Paint paint) {
|
||||
nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawOval(@NonNull RectF oval, @NonNull Paint paint) {
|
||||
if (oval == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPaint(@NonNull Paint paint) {
|
||||
nDrawPaint(mNativeCanvasWrapper, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst,
|
||||
@Nullable Paint paint) {
|
||||
Bitmap bitmap = patch.getBitmap();
|
||||
throwIfCannotDraw(bitmap);
|
||||
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
|
||||
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
|
||||
mDensity, patch.getDensity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst,
|
||||
@Nullable Paint paint) {
|
||||
Bitmap bitmap = patch.getBitmap();
|
||||
throwIfCannotDraw(bitmap);
|
||||
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
|
||||
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
|
||||
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
|
||||
mDensity, patch.getDensity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPath(@NonNull Path path, @NonNull Paint paint) {
|
||||
if (path.isSimplePath && path.rects != null) {
|
||||
nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
|
||||
} else {
|
||||
nDrawPath(mNativeCanvasWrapper, path.readOnlyNI(), paint.getNativeInstance());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPicture(@NonNull Picture picture) {
|
||||
picture.endRecording();
|
||||
int restoreCount = save();
|
||||
picture.draw(this);
|
||||
restoreToCount(restoreCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPicture(@NonNull Picture picture, @NonNull Rect dst) {
|
||||
save();
|
||||
translate(dst.left, dst.top);
|
||||
if (picture.getWidth() > 0 && picture.getHeight() > 0) {
|
||||
scale((float) dst.width() / picture.getWidth(),
|
||||
(float) dst.height() / picture.getHeight());
|
||||
}
|
||||
drawPicture(picture);
|
||||
restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPicture(@NonNull Picture picture, @NonNull RectF dst) {
|
||||
save();
|
||||
translate(dst.left, dst.top);
|
||||
if (picture.getWidth() > 0 && picture.getHeight() > 0) {
|
||||
scale(dst.width() / picture.getWidth(), dst.height() / picture.getHeight());
|
||||
}
|
||||
drawPicture(picture);
|
||||
restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPoint(float x, float y, @NonNull Paint paint) {
|
||||
nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
|
||||
@NonNull Paint paint) {
|
||||
nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) {
|
||||
drawPoints(pts, 0, pts.length, paint);
|
||||
}
|
||||
|
||||
/** @deprecated checkstyle */
|
||||
@Override
|
||||
@Deprecated
|
||||
public final void drawPosText(@NonNull char[] text, int index, int count,
|
||||
@NonNull @Size(multiple = 2) float[] pos,
|
||||
@NonNull Paint paint) {
|
||||
if (index < 0 || index + count > text.length || count * 2 > pos.length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated checkstyle */
|
||||
@Override
|
||||
@Deprecated
|
||||
public final void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
|
||||
@NonNull Paint paint) {
|
||||
drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawRect(float left, float top, float right, float bottom,
|
||||
@NonNull Paint paint) {
|
||||
nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawRect(@NonNull Rect r, @NonNull Paint paint) {
|
||||
drawRect(r.left, r.top, r.right, r.bottom, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
|
||||
nDrawRect(mNativeCanvasWrapper,
|
||||
rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawRGB(int r, int g, int b) {
|
||||
drawColor(Color.rgb(r, g, b));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawRoundRect(float left, float top, float right, float bottom,
|
||||
float rx, float ry, @NonNull Paint paint) {
|
||||
nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry,
|
||||
paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
|
||||
drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawText(@NonNull char[] text, int index, int count, float x, float y,
|
||||
@NonNull Paint paint) {
|
||||
if ((index | count | (index + count)
|
||||
| (text.length - index - count)) < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
|
||||
paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawText(@NonNull CharSequence text, int start, int end, float x, float y,
|
||||
@NonNull Paint paint) {
|
||||
if ((start | end | (end - start) | (text.length() - end)) < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
if (text instanceof String || text instanceof SpannedString
|
||||
|| text instanceof SpannableString) {
|
||||
nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
|
||||
paint.mBidiFlags, paint.getNativeInstance());
|
||||
} else if (text instanceof GraphicsOperations) {
|
||||
((GraphicsOperations) text).drawText(this, start, end, x, y,
|
||||
paint);
|
||||
} else {
|
||||
char[] buf = TemporaryBuffer.obtain(end - start);
|
||||
TextUtils.getChars(text, start, end, buf, 0);
|
||||
nDrawText(mNativeCanvasWrapper, buf, 0, end - start, x, y,
|
||||
paint.mBidiFlags, paint.getNativeInstance());
|
||||
TemporaryBuffer.recycle(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
|
||||
nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
|
||||
paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawText(@NonNull String text, int start, int end, float x, float y,
|
||||
@NonNull Paint paint) {
|
||||
if ((start | end | (end - start) | (text.length() - end)) < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
|
||||
paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path,
|
||||
float hOffset, float vOffset, @NonNull Paint paint) {
|
||||
if (index < 0 || index + count > text.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
nDrawTextOnPath(mNativeCanvasWrapper, text, index, count,
|
||||
path.readOnlyNI(), hOffset, vOffset,
|
||||
paint.mBidiFlags, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
|
||||
float vOffset, @NonNull Paint paint) {
|
||||
if (text.length() > 0) {
|
||||
nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset,
|
||||
paint.mBidiFlags, paint.getNativeInstance());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex,
|
||||
int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) {
|
||||
|
||||
if (text == null) {
|
||||
throw new NullPointerException("text is null");
|
||||
}
|
||||
if (paint == null) {
|
||||
throw new NullPointerException("paint is null");
|
||||
}
|
||||
if ((index | count | contextIndex | contextCount | index - contextIndex
|
||||
| (contextIndex + contextCount) - (index + count)
|
||||
| text.length - (contextIndex + contextCount)) < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount,
|
||||
x, y, isRtl, paint.getNativeInstance(), 0 /* measured text */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart,
|
||||
int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) {
|
||||
|
||||
if (text == null) {
|
||||
throw new NullPointerException("text is null");
|
||||
}
|
||||
if (paint == null) {
|
||||
throw new NullPointerException("paint is null");
|
||||
}
|
||||
if ((start | end | contextStart | contextEnd | start - contextStart | end - start
|
||||
| contextEnd - end | text.length() - contextEnd) < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
if (text instanceof String || text instanceof SpannedString
|
||||
|| text instanceof SpannableString) {
|
||||
nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart,
|
||||
contextEnd, x, y, isRtl, paint.getNativeInstance());
|
||||
} else if (text instanceof GraphicsOperations) {
|
||||
((GraphicsOperations) text).drawTextRun(this, start, end,
|
||||
contextStart, contextEnd, x, y, isRtl, paint);
|
||||
} else {
|
||||
if (text instanceof PrecomputedText) {
|
||||
final PrecomputedText pt = (PrecomputedText) text;
|
||||
final int paraIndex = pt.findParaIndex(start);
|
||||
if (end <= pt.getParagraphEnd(paraIndex)) {
|
||||
final int paraStart = pt.getParagraphStart(paraIndex);
|
||||
final MeasuredParagraph mp = pt.getMeasuredParagraph(paraIndex);
|
||||
// Only support if the target is in the same paragraph.
|
||||
nDrawTextRun(mNativeCanvasWrapper,
|
||||
mp.getChars(),
|
||||
start - paraStart,
|
||||
end - start,
|
||||
contextStart - paraStart,
|
||||
contextEnd - contextStart,
|
||||
x, y, isRtl, paint.getNativeInstance(),
|
||||
mp.getNativeMeasuredParagraph().getNativePtr());
|
||||
return;
|
||||
}
|
||||
}
|
||||
int contextLen = contextEnd - contextStart;
|
||||
int len = end - start;
|
||||
char[] buf = TemporaryBuffer.obtain(contextLen);
|
||||
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
|
||||
nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
|
||||
0, contextLen, x, y, isRtl, paint.getNativeInstance(),
|
||||
0 /* measured paragraph pointer */);
|
||||
TemporaryBuffer.recycle(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void drawVertices(@NonNull VertexMode mode, int vertexCount,
|
||||
@NonNull float[] verts, int vertOffset, @Nullable float[] texs, int texOffset,
|
||||
@Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset,
|
||||
int indexCount, @NonNull Paint paint) {
|
||||
checkRange(verts.length, vertOffset, vertexCount);
|
||||
if (texs != null) {
|
||||
checkRange(texs.length, texOffset, vertexCount);
|
||||
}
|
||||
if (colors != null) {
|
||||
checkRange(colors.length, colorOffset, vertexCount / 2);
|
||||
}
|
||||
if (indices != null) {
|
||||
checkRange(indices.length, indexOffset, indexCount);
|
||||
}
|
||||
nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
|
||||
vertOffset, texs, texOffset, colors, colorOffset,
|
||||
indices, indexOffset, indexCount, paint.getNativeInstance());
|
||||
}
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
|
||||
long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap,
|
||||
float srcLeft, float srcTop, float srcRight, float srcBottom,
|
||||
float dstLeft, float dstTop, float dstRight, float dstBottom,
|
||||
long nativePaintOrZero, int screenDensity, int bitmapDensity);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
|
||||
float x, float y, int width, int height, boolean hasAlpha, long nativePaintOrZero);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawColor(long nativeCanvas, int color, int mode);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawPaint(long nativeCanvas, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawPoint(long canvasHandle, float x, float y, long paintHandle);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawPoints(long canvasHandle, float[] pts, int offset, int count,
|
||||
long paintHandle);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawLine(long nativeCanvas, float startX, float startY, float stopX,
|
||||
float stopY, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawLines(long canvasHandle, float[] pts, int offset, int count,
|
||||
long paintHandle);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawRect(long nativeCanvas, float left, float top, float right,
|
||||
float bottom, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawOval(long nativeCanvas, float left, float top, float right,
|
||||
float bottom, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawCircle(long nativeCanvas, float cx, float cy, float radius,
|
||||
long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawArc(long nativeCanvas, float left, float top, float right,
|
||||
float bottom, float startAngle, float sweep, boolean useCenter, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right,
|
||||
float bottom, float rx, float ry, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
|
||||
float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero,
|
||||
int screenDensity, int bitmapDensity);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
|
||||
long nativeMatrix, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
|
||||
int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
|
||||
long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawVertices(long nativeCanvas, int mode, int n, float[] verts,
|
||||
int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset,
|
||||
short[] indices, int indexOffset, int indexCount, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawText(long nativeCanvas, char[] text, int index, int count,
|
||||
float x, float y, int flags, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawText(long nativeCanvas, String text, int start, int end,
|
||||
float x, float y, int flags, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawTextRun(long nativeCanvas, String text, int start, int end,
|
||||
int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawTextRun(long nativeCanvas, char[] text, int start, int count,
|
||||
int contextStart, int contextCount, float x, float y, boolean isRtl, long nativePaint,
|
||||
long nativePrecomputedText);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawTextOnPath(long nativeCanvas, char[] text, int index, int count,
|
||||
long nativePath, float hOffset, float vOffset, int bidiFlags, long nativePaint);
|
||||
|
||||
@FastNative
|
||||
private static native void nDrawTextOnPath(long nativeCanvas, String text, long nativePath,
|
||||
float hOffset, float vOffset, int flags, long nativePaint);
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import android.graphics.Matrix;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
|
||||
import dalvik.annotation.optimization.CriticalNative;
|
||||
import dalvik.annotation.optimization.FastNative;
|
||||
@@ -148,12 +147,12 @@ public class RenderNode {
|
||||
* @hide
|
||||
*/
|
||||
final long mNativeRenderNode;
|
||||
private final View mOwningView;
|
||||
private final AnimationHost mAnimationHost;
|
||||
|
||||
private RenderNode(String name, View owningView) {
|
||||
private RenderNode(String name, AnimationHost animationHost) {
|
||||
mNativeRenderNode = nCreate(name);
|
||||
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
|
||||
mOwningView = owningView;
|
||||
mAnimationHost = animationHost;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,7 +161,7 @@ public class RenderNode {
|
||||
private RenderNode(long nativePtr) {
|
||||
mNativeRenderNode = nativePtr;
|
||||
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
|
||||
mOwningView = null;
|
||||
mAnimationHost = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,8 +173,8 @@ public class RenderNode {
|
||||
* @return A new RenderNode.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static RenderNode create(String name, @Nullable View owningView) {
|
||||
return new RenderNode(name, owningView);
|
||||
public static RenderNode create(String name, @Nullable AnimationHost animationHost) {
|
||||
return new RenderNode(name, animationHost);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,11 +187,38 @@ public class RenderNode {
|
||||
return new RenderNode(nativePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for RenderNode position updates for synchronous window movement.
|
||||
*
|
||||
* This is not suitable for generic position listening, it is only designed & intended
|
||||
* for use by things which require external position events like SurfaceView, PopupWindow, etc..
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface PositionUpdateListener {
|
||||
|
||||
/**
|
||||
* Called by native by a Rendering Worker thread to update window position
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
void positionChanged(long frameNumber, int left, int top, int right, int bottom);
|
||||
|
||||
/**
|
||||
* Called by native on RenderThread to notify that the view is no longer in the
|
||||
* draw tree. UI thread is blocked at this point.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
void positionLost(long frameNumber);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable callbacks for position changes.
|
||||
*/
|
||||
public void requestPositionUpdates(SurfaceView view) {
|
||||
nRequestPositionUpdates(mNativeRenderNode, view);
|
||||
public void requestPositionUpdates(PositionUpdateListener listener) {
|
||||
nRequestPositionUpdates(mNativeRenderNode, listener);
|
||||
}
|
||||
|
||||
|
||||
@@ -873,26 +899,42 @@ public class RenderNode {
|
||||
// Animations
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* TODO: Figure out if this can be eliminated/refactored away
|
||||
*
|
||||
* For now this interface exists to de-couple RenderNode from anything View-specific in a
|
||||
* bit of a kludge.
|
||||
*
|
||||
* @hide */
|
||||
interface AnimationHost {
|
||||
void registerAnimatingRenderNode(RenderNode animator);
|
||||
void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator);
|
||||
boolean isAttached();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void addAnimator(RenderNodeAnimator animator) {
|
||||
if (mOwningView == null || mOwningView.mAttachInfo == null) {
|
||||
if (!isAttached()) {
|
||||
throw new IllegalStateException("Cannot start this animator on a detached view!");
|
||||
}
|
||||
nAddAnimator(mNativeRenderNode, animator.getNativeAnimator());
|
||||
mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
|
||||
mAnimationHost.registerAnimatingRenderNode(this);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public boolean isAttached() {
|
||||
return mOwningView != null && mOwningView.mAttachInfo != null;
|
||||
return mAnimationHost != null && mAnimationHost.isAttached();
|
||||
}
|
||||
|
||||
public void registerVectorDrawableAnimator(
|
||||
AnimatedVectorDrawable.VectorDrawableAnimatorRT animatorSet) {
|
||||
if (mOwningView == null || mOwningView.mAttachInfo == null) {
|
||||
/** @hide */
|
||||
public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animatorSet) {
|
||||
if (!isAttached()) {
|
||||
throw new IllegalStateException("Cannot start this animator on a detached view!");
|
||||
}
|
||||
mOwningView.mAttachInfo.mViewRootImpl.registerVectorDrawableAnimator(animatorSet);
|
||||
mAnimationHost.registerVectorDrawableAnimator(animatorSet);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void endAllAnimators() {
|
||||
nEndAllAnimators(mNativeRenderNode);
|
||||
}
|
||||
@@ -906,7 +948,8 @@ public class RenderNode {
|
||||
private static native long nGetNativeFinalizer();
|
||||
private static native void nOutput(long renderNode);
|
||||
private static native int nGetDebugSize(long renderNode);
|
||||
private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback);
|
||||
private static native void nRequestPositionUpdates(long renderNode,
|
||||
PositionUpdateListener callback);
|
||||
|
||||
// Animations
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
|
||||
|
||||
public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mRenderNode.requestPositionUpdates(this);
|
||||
mRenderNode.requestPositionUpdates(mPositionListener);
|
||||
|
||||
setWillNotDraw(true);
|
||||
}
|
||||
@@ -826,81 +826,80 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
|
||||
|
||||
private Rect mRTLastReportedPosition = new Rect();
|
||||
|
||||
/**
|
||||
* Called by native by a Rendering Worker thread to update the window position
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public final void updateSurfacePosition_renderWorker(long frameNumber,
|
||||
int left, int top, int right, int bottom) {
|
||||
if (mSurfaceControl == null) {
|
||||
return;
|
||||
}
|
||||
private RenderNode.PositionUpdateListener mPositionListener =
|
||||
new RenderNode.PositionUpdateListener() {
|
||||
|
||||
// TODO: This is teensy bit racey in that a brand new SurfaceView moving on
|
||||
// its 2nd frame if RenderThread is running slowly could potentially see
|
||||
// this as false, enter the branch, get pre-empted, then this comes along
|
||||
// and reports a new position, then the UI thread resumes and reports
|
||||
// its position. This could therefore be de-sync'd in that interval, but
|
||||
// the synchronization would violate the rule that RT must never block
|
||||
// on the UI thread which would open up potential deadlocks. The risk of
|
||||
// a single-frame desync is therefore preferable for now.
|
||||
mRtHandlingPositionUpdates = true;
|
||||
if (mRTLastReportedPosition.left == left
|
||||
&& mRTLastReportedPosition.top == top
|
||||
&& mRTLastReportedPosition.right == right
|
||||
&& mRTLastReportedPosition.bottom == bottom) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format("%d updateSurfacePosition RenderWorker, frameNr = %d, " +
|
||||
"postion = [%d, %d, %d, %d]", System.identityHashCode(this),
|
||||
frameNumber, left, top, right, bottom));
|
||||
@Override
|
||||
public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
|
||||
if (mSurfaceControl == null) {
|
||||
return;
|
||||
}
|
||||
mRTLastReportedPosition.set(left, top, right, bottom);
|
||||
setParentSpaceRectangle(mRTLastReportedPosition, frameNumber);
|
||||
// Now overwrite mRTLastReportedPosition with our values
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "Exception from repositionChild", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by native on RenderThread to notify that the view is no longer in the
|
||||
* draw tree. UI thread is blocked at this point.
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public final void surfacePositionLost_uiRtSync(long frameNumber) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
|
||||
System.identityHashCode(this), frameNumber));
|
||||
// TODO: This is teensy bit racey in that a brand new SurfaceView moving on
|
||||
// its 2nd frame if RenderThread is running slowly could potentially see
|
||||
// this as false, enter the branch, get pre-empted, then this comes along
|
||||
// and reports a new position, then the UI thread resumes and reports
|
||||
// its position. This could therefore be de-sync'd in that interval, but
|
||||
// the synchronization would violate the rule that RT must never block
|
||||
// on the UI thread which would open up potential deadlocks. The risk of
|
||||
// a single-frame desync is therefore preferable for now.
|
||||
mRtHandlingPositionUpdates = true;
|
||||
if (mRTLastReportedPosition.left == left
|
||||
&& mRTLastReportedPosition.top == top
|
||||
&& mRTLastReportedPosition.right == right
|
||||
&& mRTLastReportedPosition.bottom == bottom) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format(
|
||||
"%d updateSurfacePosition RenderWorker, frameNr = %d, "
|
||||
+ "postion = [%d, %d, %d, %d]",
|
||||
System.identityHashCode(this), frameNumber,
|
||||
left, top, right, bottom));
|
||||
}
|
||||
mRTLastReportedPosition.set(left, top, right, bottom);
|
||||
setParentSpaceRectangle(mRTLastReportedPosition, frameNumber);
|
||||
// Now overwrite mRTLastReportedPosition with our values
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "Exception from repositionChild", ex);
|
||||
}
|
||||
}
|
||||
mRTLastReportedPosition.setEmpty();
|
||||
|
||||
if (mSurfaceControl == null) {
|
||||
return;
|
||||
}
|
||||
if (mRtHandlingPositionUpdates) {
|
||||
mRtHandlingPositionUpdates = false;
|
||||
// This callback will happen while the UI thread is blocked, so we can
|
||||
// safely access other member variables at this time.
|
||||
// So do what the UI thread would have done if RT wasn't handling position
|
||||
// updates.
|
||||
if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) {
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition, " +
|
||||
"postion = [%d, %d, %d, %d]", System.identityHashCode(this),
|
||||
mScreenRect.left, mScreenRect.top,
|
||||
mScreenRect.right, mScreenRect.bottom));
|
||||
setParentSpaceRectangle(mScreenRect, frameNumber);
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "Exception configuring surface", ex);
|
||||
@Override
|
||||
public void positionLost(long frameNumber) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
|
||||
System.identityHashCode(this), frameNumber));
|
||||
}
|
||||
mRTLastReportedPosition.setEmpty();
|
||||
|
||||
if (mSurfaceControl == null) {
|
||||
return;
|
||||
}
|
||||
if (mRtHandlingPositionUpdates) {
|
||||
mRtHandlingPositionUpdates = false;
|
||||
// This callback will happen while the UI thread is blocked, so we can
|
||||
// safely access other member variables at this time.
|
||||
// So do what the UI thread would have done if RT wasn't handling position
|
||||
// updates.
|
||||
if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) {
|
||||
try {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format("%d updateSurfacePosition, "
|
||||
+ "postion = [%d, %d, %d, %d]",
|
||||
System.identityHashCode(this),
|
||||
mScreenRect.left, mScreenRect.top,
|
||||
mScreenRect.right, mScreenRect.bottom));
|
||||
}
|
||||
setParentSpaceRectangle(mScreenRect, frameNumber);
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "Exception configuring surface", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private SurfaceHolder.Callback[] getSurfaceCallbacks() {
|
||||
SurfaceHolder.Callback callbacks[];
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
@@ -914,8 +913,7 @@ public final class ThreadedRenderer {
|
||||
nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
|
||||
}
|
||||
|
||||
void registerVectorDrawableAnimator(
|
||||
AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
|
||||
void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
|
||||
nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
|
||||
animator.getAnimatorNativePtr());
|
||||
}
|
||||
|
||||
@@ -4864,7 +4864,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
|
||||
mUserPaddingStart = UNDEFINED_PADDING;
|
||||
mUserPaddingEnd = UNDEFINED_PADDING;
|
||||
mRenderNode = RenderNode.create(getClass().getName(), this);
|
||||
mRenderNode = RenderNode.create(getClass().getName(), new ViewAnimationHostBridge(this));
|
||||
|
||||
if (!sCompatibilityDone && context != null) {
|
||||
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
|
||||
@@ -5732,7 +5732,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
@UnsupportedAppUsage
|
||||
View() {
|
||||
mResources = null;
|
||||
mRenderNode = RenderNode.create(getClass().getName(), this);
|
||||
mRenderNode = RenderNode.create(getClass().getName(), new ViewAnimationHostBridge(this));
|
||||
}
|
||||
|
||||
final boolean debugDraw() {
|
||||
@@ -20600,7 +20600,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
*/
|
||||
private RenderNode getDrawableRenderNode(Drawable drawable, RenderNode renderNode) {
|
||||
if (renderNode == null) {
|
||||
renderNode = RenderNode.create(drawable.getClass().getName(), this);
|
||||
renderNode = RenderNode.create(drawable.getClass().getName(),
|
||||
new ViewAnimationHostBridge(this));
|
||||
renderNode.setUsageHint(RenderNode.USAGE_BACKGROUND);
|
||||
}
|
||||
|
||||
|
||||
48
core/java/android/view/ViewAnimationHostBridge.java
Normal file
48
core/java/android/view/ViewAnimationHostBridge.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 android.view;
|
||||
|
||||
/**
|
||||
* Maps a View to a RenderNode's AnimationHost
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class ViewAnimationHostBridge implements RenderNode.AnimationHost {
|
||||
private final View mView;
|
||||
|
||||
/**
|
||||
* @param view the View to bridge to an AnimationHost
|
||||
*/
|
||||
public ViewAnimationHostBridge(View view) {
|
||||
mView = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAnimatingRenderNode(RenderNode animator) {
|
||||
mView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(animator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
|
||||
mView.mAttachInfo.mViewRootImpl.registerVectorDrawableAnimator(animator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttached() {
|
||||
return mView.mAttachInfo != null;
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,6 @@ import android.graphics.PointF;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.DisplayManager.DisplayListener;
|
||||
@@ -991,6 +990,9 @@ public final class ViewRootImpl implements ViewParent,
|
||||
ThreadedRenderer.invokeFunctor(functor, waitForCompletion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param animator animator to register with the hardware renderer
|
||||
*/
|
||||
public void registerAnimatingRenderNode(RenderNode animator) {
|
||||
if (mAttachInfo.mThreadedRenderer != null) {
|
||||
mAttachInfo.mThreadedRenderer.registerAnimatingRenderNode(animator);
|
||||
@@ -1002,8 +1004,10 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
public void registerVectorDrawableAnimator(
|
||||
AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
|
||||
/**
|
||||
* @param animator animator to register with the hardware renderer
|
||||
*/
|
||||
public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
|
||||
if (mAttachInfo.mThreadedRenderer != null) {
|
||||
mAttachInfo.mThreadedRenderer.registerVectorDrawableAnimator(animator);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user