Make DisplayListRenderer inherit from Canvas, merge JNI
Incrementally unify the upper layers for Skia and HWUI.
Remove redundant code from GLES20Canvas.java; instead
use inherited mNativeCanvasWrapper and superclass method
definitions.
Moves some unrelated SkPaint utility functions from Renderer
to new utils/PaintUtils.
bug: 15672762
Change-Id: I4ddd4214b8e9eeb95289d054ef423f2542bb5fa5
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index eaea4d4..3cb4666 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -19,19 +19,13 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
-import android.graphics.DrawFilter;
import android.graphics.Matrix;
import android.graphics.NinePatch;
import android.graphics.Paint;
-import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.Picture;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Shader;
-import android.graphics.TemporaryBuffer;
import android.text.GraphicsOperations;
import android.text.SpannableString;
import android.text.SpannedString;
@@ -41,14 +35,6 @@
* An implementation of Canvas on top of OpenGL ES 2.0.
*/
class GLES20Canvas extends HardwareCanvas {
- private final boolean mOpaque;
- protected long mRenderer;
-
- // The native renderer will be destroyed when this object dies.
- // DO NOT overwrite this reference once it is set.
- @SuppressWarnings({"unused", "FieldCanBeLocal"})
- private CanvasFinalizer mFinalizer;
-
private int mWidth;
private int mHeight;
@@ -58,8 +44,6 @@
private Rect mClipBounds;
private RectF mPathBounds;
- private DrawFilter mFilter;
-
///////////////////////////////////////////////////////////////////////////
// JNI
///////////////////////////////////////////////////////////////////////////
@@ -77,39 +61,10 @@
// TODO: Merge with GLES20RecordingCanvas
protected GLES20Canvas() {
- mOpaque = false;
- mRenderer = nCreateDisplayListRenderer();
- setupFinalizer();
- }
-
- private void setupFinalizer() {
- if (mRenderer == 0) {
- throw new IllegalStateException("Could not create GLES20Canvas renderer");
- } else {
- mFinalizer = new CanvasFinalizer(mRenderer);
- }
+ super(nCreateDisplayListRenderer());
}
private static native long nCreateDisplayListRenderer();
- private static native void nResetDisplayListRenderer(long renderer);
- private static native void nDestroyRenderer(long renderer);
-
- private static final class CanvasFinalizer {
- private final long mRenderer;
-
- public CanvasFinalizer(long renderer) {
- mRenderer = renderer;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- nDestroyRenderer(mRenderer);
- } finally {
- super.finalize();
- }
- }
- }
public static void setProperty(String name, String value) {
nSetProperty(name, value);
@@ -123,7 +78,7 @@
@Override
public boolean isOpaque() {
- return mOpaque;
+ return false;
}
@Override
@@ -153,7 +108,7 @@
* Returns the native OpenGLRenderer object.
*/
long getRenderer() {
- return mRenderer;
+ return mNativeCanvasWrapper;
}
///////////////////////////////////////////////////////////////////////////
@@ -165,7 +120,7 @@
mWidth = width;
mHeight = height;
- nSetViewport(mRenderer, width, height);
+ nSetViewport(mNativeCanvasWrapper, width, height);
}
private static native void nSetViewport(long renderer,
@@ -173,19 +128,19 @@
@Override
public void setHighContrastText(boolean highContrastText) {
- nSetHighContrastText(mRenderer, highContrastText);
+ nSetHighContrastText(mNativeCanvasWrapper, highContrastText);
}
private static native void nSetHighContrastText(long renderer, boolean highContrastText);
@Override
public void insertReorderBarrier() {
- nInsertReorderBarrier(mRenderer, true);
+ nInsertReorderBarrier(mNativeCanvasWrapper, true);
}
@Override
public void insertInorderBarrier() {
- nInsertReorderBarrier(mRenderer, false);
+ nInsertReorderBarrier(mNativeCanvasWrapper, false);
}
private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
@@ -193,20 +148,18 @@
@Override
public void onPreDraw(Rect dirty) {
if (dirty != null) {
- nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom,
- mOpaque);
+ nPrepareDirty(mNativeCanvasWrapper, dirty.left, dirty.top, dirty.right, dirty.bottom);
} else {
- nPrepare(mRenderer, mOpaque);
+ nPrepare(mNativeCanvasWrapper);
}
}
- private static native void nPrepare(long renderer, boolean opaque);
- private static native void nPrepareDirty(long renderer, int left, int top, int right, int bottom,
- boolean opaque);
+ private static native void nPrepare(long renderer);
+ private static native void nPrepareDirty(long renderer, int left, int top, int right, int bottom);
@Override
public void onPostDraw() {
- nFinish(mRenderer);
+ nFinish(mNativeCanvasWrapper);
}
private static native void nFinish(long renderer);
@@ -217,7 +170,7 @@
@Override
public void callDrawGLFunction2(long drawGLFunction) {
- nCallDrawGLFunction(mRenderer, drawGLFunction);
+ nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction);
}
private static native void nCallDrawGLFunction(long renderer, long drawGLFunction);
@@ -230,7 +183,7 @@
@Override
public void drawRenderNode(RenderNode renderNode, int flags) {
- nDrawRenderNode(mRenderer, renderNode.getNativeDisplayList(), flags);
+ nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList(), flags);
}
private static native void nDrawRenderNode(long renderer, long renderNode,
@@ -242,326 +195,32 @@
void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
layer.setLayerPaint(paint);
- nDrawLayer(mRenderer, layer.getLayerHandle(), x, y);
+ nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle(), x, y);
}
private static native void nDrawLayer(long renderer, long layer, float x, float y);
///////////////////////////////////////////////////////////////////////////
- // Support
- ///////////////////////////////////////////////////////////////////////////
-
- private Rect getInternalClipBounds() {
- if (mClipBounds == null) mClipBounds = new Rect();
- return mClipBounds;
- }
-
-
- private RectF getPathBounds() {
- if (mPathBounds == null) mPathBounds = new RectF();
- return mPathBounds;
- }
-
- private float[] getPointStorage() {
- if (mPoint == null) mPoint = new float[2];
- return mPoint;
- }
-
- private float[] getLineStorage() {
- if (mLine == null) mLine = new float[4];
- return mLine;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // Clipping
- ///////////////////////////////////////////////////////////////////////////
-
- @Override
- public boolean clipPath(Path path) {
- return nClipPath(mRenderer, path.mNativePath, Region.Op.INTERSECT.nativeInt);
- }
-
- @Override
- public boolean clipPath(Path path, Region.Op op) {
- return nClipPath(mRenderer, path.mNativePath, op.nativeInt);
- }
-
- private static native boolean nClipPath(long renderer, long path, int op);
-
- @Override
- public boolean clipRect(float left, float top, float right, float bottom) {
- return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
- }
-
- private static native boolean nClipRect(long renderer, float left, float top,
- float right, float bottom, int op);
-
- @Override
- public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) {
- return nClipRect(mRenderer, left, top, right, bottom, op.nativeInt);
- }
-
- @Override
- public boolean clipRect(int left, int top, int right, int bottom) {
- return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
- }
-
- private static native boolean nClipRect(long renderer, int left, int top,
- int right, int bottom, int op);
-
- @Override
- public boolean clipRect(Rect rect) {
- return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
- Region.Op.INTERSECT.nativeInt);
- }
-
- @Override
- public boolean clipRect(Rect rect, Region.Op op) {
- return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
- }
-
- @Override
- public boolean clipRect(RectF rect) {
- return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
- Region.Op.INTERSECT.nativeInt);
- }
-
- @Override
- public boolean clipRect(RectF rect, Region.Op op) {
- return nClipRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom, op.nativeInt);
- }
-
- @Override
- public boolean clipRegion(Region region) {
- return nClipRegion(mRenderer, region.mNativeRegion, Region.Op.INTERSECT.nativeInt);
- }
-
- @Override
- public boolean clipRegion(Region region, Region.Op op) {
- return nClipRegion(mRenderer, region.mNativeRegion, op.nativeInt);
- }
-
- private static native boolean nClipRegion(long renderer, long region, int op);
-
- @Override
- public boolean getClipBounds(Rect bounds) {
- return nGetClipBounds(mRenderer, bounds);
- }
-
- private static native boolean nGetClipBounds(long renderer, Rect bounds);
-
- @Override
- public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
- return nQuickReject(mRenderer, left, top, right, bottom);
- }
-
- private static native boolean nQuickReject(long renderer, float left, float top,
- float right, float bottom);
-
- @Override
- public boolean quickReject(Path path, EdgeType type) {
- RectF pathBounds = getPathBounds();
- path.computeBounds(pathBounds, true);
- return nQuickReject(mRenderer, pathBounds.left, pathBounds.top,
- pathBounds.right, pathBounds.bottom);
- }
-
- @Override
- public boolean quickReject(RectF rect, EdgeType type) {
- return nQuickReject(mRenderer, rect.left, rect.top, rect.right, rect.bottom);
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // Transformations
- ///////////////////////////////////////////////////////////////////////////
-
- @Override
- public void translate(float dx, float dy) {
- if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy);
- }
-
- private static native void nTranslate(long renderer, float dx, float dy);
-
- @Override
- public void skew(float sx, float sy) {
- nSkew(mRenderer, sx, sy);
- }
-
- private static native void nSkew(long renderer, float sx, float sy);
-
- @Override
- public void rotate(float degrees) {
- nRotate(mRenderer, degrees);
- }
-
- private static native void nRotate(long renderer, float degrees);
-
- @Override
- public void scale(float sx, float sy) {
- nScale(mRenderer, sx, sy);
- }
-
- private static native void nScale(long renderer, float sx, float sy);
-
- @Override
- public void setMatrix(Matrix matrix) {
- nSetMatrix(mRenderer, matrix == null ? 0 : matrix.native_instance);
- }
-
- private static native void nSetMatrix(long renderer, long matrix);
-
- @SuppressWarnings("deprecation")
- @Override
- public void getMatrix(Matrix matrix) {
- nGetMatrix(mRenderer, matrix.native_instance);
- }
-
- private static native void nGetMatrix(long renderer, long matrix);
-
- @Override
- public void concat(Matrix matrix) {
- if (matrix != null) nConcatMatrix(mRenderer, matrix.native_instance);
- }
-
- private static native void nConcatMatrix(long renderer, long matrix);
-
- ///////////////////////////////////////////////////////////////////////////
- // State management
- ///////////////////////////////////////////////////////////////////////////
-
- @Override
- public int save() {
- return nSave(mRenderer, Canvas.CLIP_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
- }
-
- @Override
- public int save(int saveFlags) {
- return nSave(mRenderer, saveFlags);
- }
-
- private static native int nSave(long renderer, int flags);
-
- @Override
- public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
- if (bounds != null) {
- return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
- }
-
- final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- return nSaveLayer(mRenderer, nativePaint, saveFlags);
- }
-
- private static native int nSaveLayer(long renderer, long paint, int saveFlags);
-
- @Override
- public int saveLayer(float left, float top, float right, float bottom, Paint paint,
- int saveFlags) {
- if (left < right && top < bottom) {
- final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
- }
- return save(saveFlags);
- }
-
- private static native int nSaveLayer(long renderer, float left, float top,
- float right, float bottom, long paint, int saveFlags);
-
- @Override
- public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
- if (bounds != null) {
- return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
- alpha, saveFlags);
- }
- return nSaveLayerAlpha(mRenderer, alpha, saveFlags);
- }
-
- private static native int nSaveLayerAlpha(long renderer, int alpha, int saveFlags);
-
- @Override
- public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
- int saveFlags) {
- if (left < right && top < bottom) {
- return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
- }
- return save(saveFlags);
- }
-
- private static native int nSaveLayerAlpha(long renderer, float left, float top, float right,
- float bottom, int alpha, int saveFlags);
-
- @Override
- public void restore() {
- nRestore(mRenderer);
- }
-
- private static native void nRestore(long renderer);
-
- @Override
- public void restoreToCount(int saveCount) {
- nRestoreToCount(mRenderer, saveCount);
- }
-
- private static native void nRestoreToCount(long renderer, int saveCount);
-
- @Override
- public int getSaveCount() {
- return nGetSaveCount(mRenderer);
- }
-
- private static native int nGetSaveCount(long renderer);
-
- ///////////////////////////////////////////////////////////////////////////
- // Filtering
- ///////////////////////////////////////////////////////////////////////////
-
- @Override
- public void setDrawFilter(DrawFilter filter) {
- mFilter = filter;
- nSetDrawFilter(mRenderer, (filter != null) ? filter.mNativeInt : 0);
- }
-
- private static native void nSetDrawFilter(long renderer, long nativeFilter);
-
- @Override
- public DrawFilter getDrawFilter() {
- return mFilter;
- }
-
- ///////////////////////////////////////////////////////////////////////////
// Drawing
///////////////////////////////////////////////////////////////////////////
- @Override
- public void drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, boolean useCenter, Paint paint) {
- nDrawArc(mRenderer, left, top, right, bottom,
- startAngle, sweepAngle, useCenter, paint.getNativeInstance());
- }
-
- private static native void nDrawArc(long renderer, float left, float top,
- float right, float bottom, float startAngle, float sweepAngle,
- boolean useCenter, long paint);
-
- @Override
- public void drawARGB(int a, int r, int g, int b) {
- drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
- }
-
+ // TODO: move to Canvas.java
@Override
public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
+ nDrawPatch(mNativeCanvasWrapper, bitmap.mNativeBitmap, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
+ // TODO: move to Canvas.java
@Override
public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk,
+ nDrawPatch(mNativeCanvasWrapper, bitmap.mNativeBitmap, patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
}
@@ -569,148 +228,9 @@
float left, float top, float right, float bottom, long paint);
@Override
- public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
- throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint);
- }
-
- private static native void nDrawBitmap(long renderer, long bitmap, float left,
- float top, long paint);
-
- @Override
- public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
- throwIfCannotDraw(bitmap);
- final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, matrix.native_instance, nativePaint);
- }
-
- private static native void nDrawBitmap(long renderer, long bitmap,
- long matrix, long paint);
-
- @Override
- public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
- 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(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
- dst.left, dst.top, dst.right, dst.bottom, nativePaint);
- }
-
- @Override
- public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
- 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(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
- dst.left, dst.top, dst.right, dst.bottom, nativePaint);
- }
-
- private static native void nDrawBitmap(long renderer, long bitmap,
- float srcLeft, float srcTop, float srcRight, float srcBottom,
- float left, float top, float right, float bottom, long paint);
-
- @Override
- public void drawBitmap(int[] colors, int offset, int stride, float x, float y,
- int width, int height, boolean hasAlpha, Paint paint) {
- 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();
- }
-
- final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- nDrawBitmap(mRenderer, colors, offset, stride, x, y,
- width, height, hasAlpha, nativePaint);
- }
-
- private static native void nDrawBitmap(long renderer, int[] colors, int offset, int stride,
- float x, float y, int width, int height, boolean hasAlpha, long nativePaint);
-
- @Override
- public void drawBitmap(int[] colors, int offset, int stride, int x, int y,
- int width, int height, boolean hasAlpha, Paint paint) {
- drawBitmap(colors, offset, stride, (float) x, (float) y, width, height, hasAlpha, paint);
- }
-
- @Override
- public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
- int vertOffset, int[] colors, int colorOffset, Paint paint) {
- throwIfCannotDraw(bitmap);
- if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
- throw new ArrayIndexOutOfBoundsException();
- }
-
- if (meshWidth == 0 || meshHeight == 0) {
- return;
- }
-
- final int count = (meshWidth + 1) * (meshHeight + 1);
- checkRange(verts.length, vertOffset, count * 2);
-
- if (colors != null) {
- checkRange(colors.length, colorOffset, count);
- }
-
- final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
- nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, meshWidth, meshHeight,
- verts, vertOffset, colors, colorOffset, nativePaint);
- }
-
- private static native void nDrawBitmapMesh(long renderer, long bitmap,
- int meshWidth, int meshHeight, float[] verts, int vertOffset,
- int[] colors, int colorOffset, long paint);
-
- @Override
- public void drawCircle(float cx, float cy, float radius, Paint paint) {
- nDrawCircle(mRenderer, cx, cy, radius, paint.getNativeInstance());
- }
-
- private static native void nDrawCircle(long renderer, float cx, float cy,
- float radius, long paint);
-
- @Override
public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
- nDrawCircle(mRenderer, cx.getNativeContainer(), cy.getNativeContainer(),
+ nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
radius.getNativeContainer(), paint.getNativeContainer());
}
@@ -721,7 +241,7 @@
public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
- nDrawRoundRect(mRenderer, left.getNativeContainer(), top.getNativeContainer(),
+ nDrawRoundRect(mNativeCanvasWrapper, left.getNativeContainer(), top.getNativeContainer(),
right.getNativeContainer(), bottom.getNativeContainer(),
rx.getNativeContainer(), ry.getNativeContainer(),
paint.getNativeContainer());
@@ -730,73 +250,18 @@
private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
long propRight, long propBottom, long propRx, long propRy, long propPaint);
- @Override
- public void drawColor(int color) {
- drawColor(color, PorterDuff.Mode.SRC_OVER);
- }
-
- @Override
- public void drawColor(int color, PorterDuff.Mode mode) {
- nDrawColor(mRenderer, color, mode.nativeInt);
- }
-
- private static native void nDrawColor(long renderer, int color, int mode);
-
- @Override
- public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
- float[] line = getLineStorage();
- line[0] = startX;
- line[1] = startY;
- line[2] = stopX;
- line[3] = stopY;
- drawLines(line, 0, 4, paint);
- }
-
- @Override
- public void drawLines(float[] pts, int offset, int count, Paint paint) {
- if (count < 4) return;
-
- if ((offset | count) < 0 || offset + count > pts.length) {
- throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
- }
- nDrawLines(mRenderer, pts, offset, count, paint.getNativeInstance());
- }
-
- private static native void nDrawLines(long renderer, float[] points,
- int offset, int count, long paint);
-
- @Override
- public void drawLines(float[] pts, Paint paint) {
- drawLines(pts, 0, pts.length, paint);
- }
-
- @Override
- public void drawOval(float left, float top, float right, float bottom, Paint paint) {
- nDrawOval(mRenderer, left, top, right, bottom, paint.getNativeInstance());
- }
-
- private static native void nDrawOval(long renderer, float left, float top,
- float right, float bottom, long paint);
-
- @Override
- public void drawPaint(Paint paint) {
- final Rect r = getInternalClipBounds();
- nGetClipBounds(mRenderer, r);
- drawRect(r.left, r.top, r.right, r.bottom, paint);
- }
-
+ // TODO: move this optimization to Canvas.java
@Override
public void drawPath(Path path, Paint paint) {
if (path.isSimplePath) {
if (path.rects != null) {
- nDrawRects(mRenderer, path.rects.mNativeRegion, paint.getNativeInstance());
+ nDrawRects(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
}
} else {
- nDrawPath(mRenderer, path.mNativePath, paint.getNativeInstance());
+ super.drawPath(path, paint);
}
}
- private static native void nDrawPath(long renderer, long path, long paint);
private static native void nDrawRects(long renderer, long region, long paint);
@Override
@@ -804,190 +269,4 @@
picture.endRecording();
// TODO: Implement rendering
}
-
- @Override
- public void drawPoint(float x, float y, Paint paint) {
- float[] point = getPointStorage();
- point[0] = x;
- point[1] = y;
- drawPoints(point, 0, 2, paint);
- }
-
- @Override
- public void drawPoints(float[] pts, Paint paint) {
- drawPoints(pts, 0, pts.length, paint);
- }
-
- @Override
- public void drawPoints(float[] pts, int offset, int count, Paint paint) {
- if (count < 2) return;
-
- nDrawPoints(mRenderer, pts, offset, count, paint.getNativeInstance());
- }
-
- private static native void nDrawPoints(long renderer, float[] points,
- int offset, int count, long paint);
-
- // Note: drawPosText just uses implementation in Canvas
-
- @Override
- public void drawRect(float left, float top, float right, float bottom, Paint paint) {
- if (left == right || top == bottom) return;
- nDrawRect(mRenderer, left, top, right, bottom, paint.getNativeInstance());
- }
-
- private static native void nDrawRect(long renderer, float left, float top,
- float right, float bottom, long paint);
-
- @Override
- public void drawRect(Rect r, Paint paint) {
- drawRect(r.left, r.top, r.right, r.bottom, paint);
- }
-
- @Override
- public void drawRect(RectF r, Paint paint) {
- drawRect(r.left, r.top, r.right, r.bottom, paint);
- }
-
- @Override
- public void drawRGB(int r, int g, int b) {
- drawColor(0xFF000000 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
- }
-
- @Override
- public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
- Paint paint) {
- nDrawRoundRect(mRenderer, left, top, right, bottom, rx, ry, paint.getNativeInstance());
- }
-
- private static native void nDrawRoundRect(long renderer, float left, float top,
- float right, float bottom, float rx, float y, long paint);
-
- @Override
- public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
- if ((index | count | (index + count) | (text.length - index - count)) < 0) {
- throw new IndexOutOfBoundsException();
- }
-
- nDrawText(mRenderer, text, index, count, x, y,
- paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
- }
-
- private static native void nDrawText(long renderer, char[] text, int index, int count,
- float x, float y, int bidiFlags, long paint, long typeface);
-
- @Override
- public void drawText(CharSequence text, int start, int end, float x, float y, 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(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
- paint.getNativeInstance(), paint.mNativeTypeface);
- } 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(mRenderer, buf, 0, end - start, x, y,
- paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
- TemporaryBuffer.recycle(buf);
- }
- }
-
- @Override
- public void drawText(String text, int start, int end, float x, float y, Paint paint) {
- if ((start | end | (end - start) | (text.length() - end)) < 0) {
- throw new IndexOutOfBoundsException();
- }
-
- nDrawText(mRenderer, text, start, end, x, y,
- paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
- }
-
- private static native void nDrawText(long renderer, String text, int start, int end,
- float x, float y, int bidiFlags, long paint, long typeface);
-
- @Override
- public void drawText(String text, float x, float y, Paint paint) {
- nDrawText(mRenderer, text, 0, text.length(), x, y,
- paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
- }
-
- @Override
- public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
- float vOffset, Paint paint) {
- if (index < 0 || index + count > text.length) {
- throw new ArrayIndexOutOfBoundsException();
- }
-
- nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset,
- paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
- }
-
- private static native void nDrawTextOnPath(long renderer, char[] text, int index, int count,
- long path, float hOffset, float vOffset, int bidiFlags, long nativePaint,
- long typeface);
-
- @Override
- public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
- if (text.length() == 0) return;
-
- nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset,
- paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
- }
-
- private static native void nDrawTextOnPath(long renderer, String text, int start, int end,
- long path, float hOffset, float vOffset, int bidiFlags, long nativePaint,
- long typeface);
-
- @Override
- public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
- float x, float y, boolean isRtl, Paint paint) {
- if ((index | count | text.length - index - count) < 0) {
- throw new IndexOutOfBoundsException();
- }
-
- nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, isRtl,
- paint.getNativeInstance(), paint.mNativeTypeface);
- }
-
- private static native void nDrawTextRun(long renderer, char[] text, int index, int count,
- int contextIndex, int contextCount, float x, float y, boolean isRtl, long nativePaint, long nativeTypeface);
-
- @Override
- public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
- float x, float y, boolean isRtl, Paint paint) {
- if ((start | end | end - start | text.length() - end) < 0) {
- throw new IndexOutOfBoundsException();
- }
-
- if (text instanceof String || text instanceof SpannedString ||
- text instanceof SpannableString) {
- nDrawTextRun(mRenderer, text.toString(), start, end, contextStart,
- contextEnd, x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
- } else if (text instanceof GraphicsOperations) {
- ((GraphicsOperations) text).drawTextRun(this, start, end,
- contextStart, contextEnd, x, y, isRtl, paint);
- } else {
- int contextLen = contextEnd - contextStart;
- int len = end - start;
- char[] buf = TemporaryBuffer.obtain(contextLen);
- TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
- nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen,
- x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
- TemporaryBuffer.recycle(buf);
- }
- }
-
- private static native void nDrawTextRun(long renderer, String text, int start, int end,
- int contextStart, int contextEnd, float x, float y, boolean isRtl, long nativePaint, long nativeTypeface);
-
- @Override
- public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
- float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
- int indexOffset, int indexCount, Paint paint) {
- // TODO: Implement
- }
}
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index 5e49d8e..5ca5626 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -56,7 +56,7 @@
}
long finishRecording() {
- return nFinishRecording(mRenderer);
+ return nFinishRecording(mNativeCanvasWrapper);
}
@Override
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index 98e3927..cdb350f 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -29,6 +29,14 @@
*/
public abstract class HardwareCanvas extends Canvas {
+ /**
+ * Pass a reference to the native renderer to our superclass's
+ * constructor.
+ */
+ protected HardwareCanvas(long renderer) {
+ super(renderer);
+ }
+
@Override
public boolean isHardwareAccelerated() {
return true;
diff --git a/core/jni/android/graphics/SkiaCanvas.cpp b/core/jni/android/graphics/SkiaCanvas.cpp
index 7de54c4..31c6514 100644
--- a/core/jni/android/graphics/SkiaCanvas.cpp
+++ b/core/jni/android/graphics/SkiaCanvas.cpp
@@ -126,7 +126,8 @@
virtual void drawText(const uint16_t* text, const float* positions, int count,
const SkPaint& paint, float x, float y,
- float boundsLeft, float boundsTop, float boundsRight, float boundsBottom);
+ float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+ float totalAdvance);
virtual void drawPosText(const uint16_t* text, const float* positions, int count,
int posCount, const SkPaint& paint);
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
@@ -686,7 +687,8 @@
void SkiaCanvas::drawText(const uint16_t* text, const float* positions, int count,
const SkPaint& paint, float x, float y,
- float boundsLeft, float boundsTop, float boundsRight, float boundsBottom) {
+ float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+ float totalAdvance) {
// Set align to left for drawing, as we don't want individual
// glyphs centered or right-aligned; the offset above takes
// care of all alignment.
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 265300ed..4675b49 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -411,9 +411,10 @@
class DrawTextFunctor {
public:
DrawTextFunctor(const Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos,
- const SkPaint& paint, float x, float y, MinikinRect& bounds)
+ const SkPaint& paint, float x, float y, MinikinRect& bounds,
+ float totalAdvance)
: layout(layout), canvas(canvas), glyphs(glyphs), pos(pos), paint(paint),
- x(x), y(y), bounds(bounds) { }
+ x(x), y(y), bounds(bounds), totalAdvance(totalAdvance) { }
void operator()(size_t start, size_t end) {
if (canvas->drawTextAbsolutePos()) {
@@ -432,7 +433,8 @@
size_t glyphCount = end - start;
canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, paint, x, y,
- bounds.mLeft , bounds.mTop , bounds.mRight , bounds.mBottom);
+ bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom,
+ totalAdvance);
}
private:
const Layout& layout;
@@ -443,6 +445,7 @@
float x;
float y;
MinikinRect& bounds;
+ float totalAdvance;
};
// Same values used by Skia
@@ -494,8 +497,11 @@
MinikinRect bounds;
layout.getBounds(&bounds);
+ if (!canvas->drawTextAbsolutePos()) {
+ bounds.offset(x, y);
+ }
- DrawTextFunctor f(layout, canvas, glyphs, pos, paint, x, y, bounds);
+ DrawTextFunctor f(layout, canvas, glyphs, pos, paint, x, y, bounds, layout.getAdvance());
MinikinUtils::forFontRun(layout, &paint, f);
drawTextDecorations(canvas, x, y, layout.getAdvance(), paint);
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 084117c..8249120 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -24,19 +24,10 @@
#include <androidfw/ResourceTypes.h>
-#include <private/hwui/DrawGlInfo.h>
-
#include <cutils/properties.h>
#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkImageInfo.h>
-#include <SkMatrix.h>
-#include <SkPorterDuff.h>
#include <SkRegion.h>
-#include <SkScalerContext.h>
-#include <SkTemplates.h>
-#include <SkXfermode.h>
#include <DisplayListRenderer.h>
#include <Rect.h>
@@ -45,8 +36,6 @@
#include <Paint.h>
#include <renderthread/RenderProxy.h>
-#include "MinikinUtils.h"
-
#include "core_jni_helpers.h"
namespace android {
@@ -64,19 +53,6 @@
static const bool kDebugRenderer = false;
// ----------------------------------------------------------------------------
-// Constructors
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
- jlong rendererPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- if (kDebugRenderer) {
- ALOGD("Destroy DisplayListRenderer");
- }
- delete renderer;
-}
-
-// ----------------------------------------------------------------------------
// Setup
// ----------------------------------------------------------------------------
@@ -99,16 +75,15 @@
}
static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jboolean opaque) {
+ jlong rendererPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->prepare(opaque);
+ renderer->prepare();
}
static void android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jint left, jint top, jint right, jint bottom,
- jboolean opaque) {
+ jlong rendererPtr, jint left, jint top, jint right, jint bottom) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->prepareDirty(left, top, right, bottom, opaque);
+ renderer->prepareDirty(left, top, right, bottom);
}
static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
@@ -160,267 +135,9 @@
}
// ----------------------------------------------------------------------------
-// State
-// ----------------------------------------------------------------------------
-
-static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererPtr,
- jint flags) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- return renderer->save(flags);
-}
-
-static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz,
- jlong rendererPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- return renderer->getSaveCount();
-}
-
-static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz,
- jlong rendererPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->restore();
-}
-
-static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jint saveCount) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->restoreToCount(saveCount);
-}
-
-// ----------------------------------------------------------------------------
-// Layers
-// ----------------------------------------------------------------------------
-
-static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
- jlong paintPtr, jint saveFlags) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
-}
-
-static jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong paintPtr, jint saveFlags) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
- return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
- paint, saveFlags);
-}
-
-static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
- jint alpha, jint saveFlags) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
-}
-
-static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jint alpha, jint saveFlags) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
- return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
- alpha, saveFlags);
-}
-
-// ----------------------------------------------------------------------------
-// Clipping
-// ----------------------------------------------------------------------------
-
-static jboolean android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const bool result = renderer->quickRejectConservative(left, top, right, bottom);
- return result ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
- jint op) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const bool result = renderer->clipRect(left, top, right, bottom,
- static_cast<SkRegion::Op>(op));
- return result ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jint left, jint top, jint right, jint bottom,
- jint op) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const bool result = renderer->clipRect(float(left), float(top), float(right),
- float(bottom),
- static_cast<SkRegion::Op>(op));
- return result ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong pathPtr, jint op) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
- const bool result = renderer->clipPath(path, static_cast<SkRegion::Op>(op));
- return result ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong regionPtr, jint op) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
- const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op));
- return result ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jobject rect) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const android::uirenderer::Rect& bounds(renderer->getLocalClipBounds());
-
- env->CallVoidMethod(rect, gRectClassInfo.set,
- int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
-
- return !bounds.isEmpty() ? JNI_TRUE : JNI_FALSE;
-}
-
-// ----------------------------------------------------------------------------
-// Transforms
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat dx, jfloat dy) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->translate(dx, dy);
-}
-
-static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat degrees) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->rotate(degrees);
-}
-
-static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat sx, jfloat sy) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->scale(sx, sy);
-}
-
-static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat sx, jfloat sy) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- renderer->skew(sx, sy);
-}
-
-static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong matrixPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- renderer->setMatrix(matrix ? *matrix : SkMatrix::I());
-}
-
-static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong matrixPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- renderer->getMatrix(matrix);
-}
-
-static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong matrixPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- renderer->concatMatrix(*matrix);
-}
-
-// ----------------------------------------------------------------------------
// Drawing
// ----------------------------------------------------------------------------
-static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jfloat left, jfloat top, jlong paintPtr) {
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
-
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-
- // apply transform directly to canvas, so it affects shaders correctly
- renderer->save(SkCanvas::kMatrix_SaveFlag);
- renderer->translate(left, top);
- renderer->drawBitmap(bitmap, paint);
- renderer->restore();
-}
-
-static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr,
- float srcLeft, float srcTop, float srcRight, float srcBottom,
- float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) {
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
-
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
- dstLeft, dstTop, dstRight, dstBottom, paint);
-}
-
-static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jlong matrixPtr, jlong paintPtr) {
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
-
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-
- // apply transform directly to canvas, so it affects shaders correctly
- renderer->save(SkCanvas::kMatrix_SaveFlag);
- renderer->concatMatrix(*matrix);
- renderer->drawBitmap(bitmap, paint);
- renderer->restore();
-}
-
-static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jintArray colors, jint offset, jint stride,
- jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) {
- // Note: If hasAlpha is false, kRGB_565_SkColorType will be used, which will
- // correct the alphaType to kOpaque_SkAlphaType.
- const SkImageInfo info = SkImageInfo::Make(width, height,
- hasAlpha ? kN32_SkColorType : kRGB_565_SkColorType,
- kPremul_SkAlphaType);
- SkBitmap* bitmap = new SkBitmap;
- if (!bitmap->tryAllocPixels(info)) {
- delete bitmap;
- return;
- }
-
- if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap)) {
- delete bitmap;
- return;
- }
-
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
-
- // apply transform directly to canvas, so it affects shaders correctly
- renderer->save(SkCanvas::kMatrix_SaveFlag);
- renderer->translate(left, top);
- renderer->drawBitmapData(bitmap, paint);
- renderer->restore();
-
- // Note - bitmap isn't deleted as DisplayListRenderer owns it now
-}
-
-static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong bitmapPtr, jint meshWidth, jint meshHeight,
- jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, jlong paintPtr) {
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
-
- jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
- jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
-
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint);
-
- if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0);
- if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0);
-}
-
static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
jlong rendererPtr, jlong bitmapPtr, jlong patchPtr,
float left, float top, float right, float bottom, jlong paintPtr) {
@@ -432,29 +149,6 @@
renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
}
-static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jint color, jint modeHandle) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle);
- renderer->drawColor(color, SkPorterDuff::ToXfermodeMode(mode));
-}
-
-static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
- jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawRect(left, top, right, bottom, paint);
-}
-
-static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
- jfloat rx, jfloat ry, jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
-}
-
static void android_view_GLES20Canvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
jlong rendererPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
@@ -469,13 +163,6 @@
renderer->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
}
-static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawCircle(x, y, radius, paint);
-}
-
static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz,
jlong rendererPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
@@ -486,22 +173,6 @@
renderer->drawCircle(xProp, yProp, radiusProp, paintProp);
}
-static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
- jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawOval(left, top, right, bottom, paint);
-}
-
-static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
- jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
-}
-
static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz,
jlong rendererPtr, jlong regionPtr, jlong paintPtr) {
DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
@@ -512,7 +183,7 @@
SkRegion::Iterator it(*region);
while (!it.done()) {
const SkIRect& r = it.rect();
- renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
+ renderer->drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, *paint);
it.next();
}
} else {
@@ -532,236 +203,6 @@
}
}
-static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- jfloat* storage = env->GetFloatArrayElements(points, NULL);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawPoints(storage + offset, count, paint);
- env->ReleaseFloatArrayElements(points, storage, 0);
-}
-
-static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong pathPtr, jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawPath(path, paint);
-}
-
-static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- jfloat* storage = env->GetFloatArrayElements(points, NULL);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- renderer->drawLines(storage + offset, count, paint);
- env->ReleaseFloatArrayElements(points, storage, 0);
-}
-
-// ----------------------------------------------------------------------------
-// Draw filters
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20Canvas_setDrawFilter(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jlong filterPtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- SkDrawFilter* filter = reinterpret_cast<SkDrawFilter*>(filterPtr);
- renderer->setDrawFilter(filter);
-}
-
-// ----------------------------------------------------------------------------
-// Text
-// ----------------------------------------------------------------------------
-
-class RenderTextFunctor {
-public:
- RenderTextFunctor(const Layout& layout, DisplayListRenderer* renderer, jfloat x, jfloat y,
- Paint* paint, uint16_t* glyphs, float* pos, float totalAdvance,
- uirenderer::Rect& bounds)
- : layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
- pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
- void operator()(size_t start, size_t end) {
- for (size_t i = start; i < end; i++) {
- glyphs[i] = layout.getGlyphId(i);
- pos[2 * i] = layout.getX(i);
- pos[2 * i + 1] = layout.getY(i);
- }
- size_t glyphsCount = end - start;
- int bytesCount = glyphsCount * sizeof(jchar);
- renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
- x, y, pos + 2 * start, paint, totalAdvance, bounds);
- }
-private:
- const Layout& layout;
- DisplayListRenderer* renderer;
- jfloat x;
- jfloat y;
- Paint* paint;
- uint16_t* glyphs;
- float* pos;
- float totalAdvance;
- uirenderer::Rect& bounds;
-};
-
-static void renderTextLayout(DisplayListRenderer* renderer, Layout* layout,
- jfloat x, jfloat y, Paint* paint) {
- size_t nGlyphs = layout->nGlyphs();
- float* pos = new float[nGlyphs * 2];
- uint16_t* glyphs = new uint16_t[nGlyphs];
- MinikinRect b;
- layout->getBounds(&b);
- android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom);
- bounds.translate(x, y);
- float totalAdvance = layout->getAdvance();
-
- RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
- MinikinUtils::forFontRun(*layout, paint, f);
- delete[] glyphs;
- delete[] pos;
-}
-
-static void renderText(DisplayListRenderer* renderer, const jchar* text, int count,
- jfloat x, jfloat y, int bidiFlags, Paint* paint, TypefaceImpl* typeface) {
- Layout layout;
- MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count);
- x += MinikinUtils::xOffsetForTextAlign(paint, layout);
- renderTextLayout(renderer, &layout, x, y, paint);
-}
-
-class RenderTextOnPathFunctor {
-public:
- RenderTextOnPathFunctor(const Layout& layout, DisplayListRenderer* renderer, float hOffset,
- float vOffset, Paint* paint, SkPath* path)
- : layout(layout), renderer(renderer), hOffset(hOffset), vOffset(vOffset),
- paint(paint), path(path) {
- }
- void operator()(size_t start, size_t end) {
- uint16_t glyphs[1];
- for (size_t i = start; i < end; i++) {
- glyphs[0] = layout.getGlyphId(i);
- float x = hOffset + layout.getX(i);
- float y = vOffset + layout.getY(i);
- renderer->drawTextOnPath((const char*) glyphs, sizeof(glyphs), 1, path, x, y, paint);
- }
- }
-private:
- const Layout& layout;
- DisplayListRenderer* renderer;
- float hOffset;
- float vOffset;
- Paint* paint;
- SkPath* path;
-};
-
-static void renderTextOnPath(DisplayListRenderer* renderer, const jchar* text, int count,
- SkPath* path, jfloat hOffset, jfloat vOffset, int bidiFlags, Paint* paint,
- TypefaceImpl* typeface) {
- Layout layout;
- MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count);
- hOffset += MinikinUtils::hOffsetForTextAlign(paint, layout, *path);
- Paint::Align align = paint->getTextAlign();
- paint->setTextAlign(Paint::kLeft_Align);
-
- RenderTextOnPathFunctor f(layout, renderer, hOffset, vOffset, paint, path);
- MinikinUtils::forFontRun(layout, paint, f);
- paint->setTextAlign(align);
-}
-
-static void renderTextRun(DisplayListRenderer* renderer, const jchar* text,
- jint start, jint count, jint contextCount, jfloat x, jfloat y,
- int bidiFlags, Paint* paint, TypefaceImpl* typeface) {
- Layout layout;
- MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, start, count, contextCount);
- x += MinikinUtils::xOffsetForTextAlign(paint, layout);
- renderTextLayout(renderer, &layout, x, y, paint);
-}
-
-static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jcharArray text, jint index, jint count,
- jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- jchar* textArray = env->GetCharArrayElements(text, NULL);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
-
- renderText(renderer, textArray + index, count, x, y, bidiFlags, paint, typeface);
- env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
-}
-
-static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jstring text, jint start, jint end,
- jfloat x, jfloat y, jint bidiFlags, jlong paintPtr, jlong typefacePtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const jchar* textArray = env->GetStringChars(text, NULL);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
-
- renderText(renderer, textArray + start, end - start, x, y, bidiFlags, paint, typeface);
- env->ReleaseStringChars(text, textArray);
-}
-
-static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jcharArray text, jint index, jint count,
- jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr,
- jlong typefacePtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- jchar* textArray = env->GetCharArrayElements(text, NULL);
- SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
-
- renderTextOnPath(renderer, textArray + index, count, path,
- hOffset, vOffset, bidiFlags, paint, typeface);
- env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
-}
-
-static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jstring text, jint start, jint end,
- jlong pathPtr, jfloat hOffset, jfloat vOffset, jint bidiFlags, jlong paintPtr,
- jlong typefacePtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const jchar* textArray = env->GetStringChars(text, NULL);
- SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
-
- renderTextOnPath(renderer, textArray + start, end - start, path,
- hOffset, vOffset, bidiFlags, paint, typeface);
- env->ReleaseStringChars(text, textArray);
-}
-
-static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jcharArray text, jint index, jint count,
- jint contextIndex, jint contextCount, jfloat x, jfloat y, jboolean isRtl,
- jlong paintPtr, jlong typefacePtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- jchar* textArray = env->GetCharArrayElements(text, NULL);
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
-
- int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
- renderTextRun(renderer, textArray + contextIndex, index - contextIndex,
- count, contextCount, x, y, bidiFlags, paint, typeface);
- env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
- }
-
-static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
- jlong rendererPtr, jstring text, jint start, jint end,
- jint contextStart, int contextEnd, jfloat x, jfloat y, jboolean isRtl,
- jlong paintPtr, jlong typefacePtr) {
- DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
- const jchar* textArray = env->GetStringChars(text, NULL);
- jint count = end - start;
- jint contextCount = contextEnd - contextStart;
- Paint* paint = reinterpret_cast<Paint*>(paintPtr);
- TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
-
- int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
- renderTextRun(renderer, textArray + contextStart, start - contextStart,
- count, contextCount, x, y, bidiFlags, paint, typeface);
- env->ReleaseStringChars(text, textArray);
-}
-
// ----------------------------------------------------------------------------
// Display lists
// ----------------------------------------------------------------------------
@@ -830,88 +271,29 @@
static JNINativeMethod gMethods[] = {
{ "nIsAvailable", "()Z", (void*) android_view_GLES20Canvas_isAvailable },
- { "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer },
{ "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport },
{ "nSetHighContrastText","(JZ)V", (void*) android_view_GLES20Canvas_setHighContrastText },
{ "nInsertReorderBarrier","(JZ)V", (void*) android_view_GLES20Canvas_insertReorderBarrier },
- { "nPrepare", "(JZ)V", (void*) android_view_GLES20Canvas_prepare },
- { "nPrepareDirty", "(JIIIIZ)V", (void*) android_view_GLES20Canvas_prepareDirty },
+ { "nPrepare", "(J)V", (void*) android_view_GLES20Canvas_prepare },
+ { "nPrepareDirty", "(JIIII)V", (void*) android_view_GLES20Canvas_prepareDirty },
{ "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish },
- { "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
+ { "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) android_view_GLES20Canvas_setProperty },
{ "nCallDrawGLFunction", "(JJ)V", (void*) android_view_GLES20Canvas_callDrawGLFunction },
- { "nSave", "(JI)I", (void*) android_view_GLES20Canvas_save },
- { "nRestore", "(J)V", (void*) android_view_GLES20Canvas_restore },
- { "nRestoreToCount", "(JI)V", (void*) android_view_GLES20Canvas_restoreToCount },
- { "nGetSaveCount", "(J)I", (void*) android_view_GLES20Canvas_getSaveCount },
+ { "nDrawPatch", "(JJJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch },
- { "nSaveLayer", "(JFFFFJI)I", (void*) android_view_GLES20Canvas_saveLayer },
- { "nSaveLayer", "(JJI)I", (void*) android_view_GLES20Canvas_saveLayerClip },
- { "nSaveLayerAlpha", "(JFFFFII)I", (void*) android_view_GLES20Canvas_saveLayerAlpha },
- { "nSaveLayerAlpha", "(JII)I", (void*) android_view_GLES20Canvas_saveLayerAlphaClip },
-
- { "nQuickReject", "(JFFFF)Z", (void*) android_view_GLES20Canvas_quickReject },
- { "nClipRect", "(JFFFFI)Z", (void*) android_view_GLES20Canvas_clipRectF },
- { "nClipRect", "(JIIIII)Z", (void*) android_view_GLES20Canvas_clipRect },
- { "nClipPath", "(JJI)Z", (void*) android_view_GLES20Canvas_clipPath },
- { "nClipRegion", "(JJI)Z", (void*) android_view_GLES20Canvas_clipRegion },
-
- { "nTranslate", "(JFF)V", (void*) android_view_GLES20Canvas_translate },
- { "nRotate", "(JF)V", (void*) android_view_GLES20Canvas_rotate },
- { "nScale", "(JFF)V", (void*) android_view_GLES20Canvas_scale },
- { "nSkew", "(JFF)V", (void*) android_view_GLES20Canvas_skew },
-
- { "nSetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_setMatrix },
- { "nGetMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_getMatrix },
- { "nConcatMatrix", "(JJ)V", (void*) android_view_GLES20Canvas_concatMatrix },
-
- { "nDrawBitmap", "(JJFFJ)V", (void*) android_view_GLES20Canvas_drawBitmap },
- { "nDrawBitmap", "(JJFFFFFFFFJ)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
- { "nDrawBitmap", "(JJJJ)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
- { "nDrawBitmap", "(J[IIIFFIIZJ)V", (void*) android_view_GLES20Canvas_drawBitmapData },
-
- { "nDrawBitmapMesh", "(JJII[FI[IIJ)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
-
- { "nDrawPatch", "(JJJFFFFJ)V", (void*) android_view_GLES20Canvas_drawPatch },
-
- { "nDrawColor", "(JII)V", (void*) android_view_GLES20Canvas_drawColor },
- { "nDrawRect", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawRect },
{ "nDrawRects", "(JJJ)V", (void*) android_view_GLES20Canvas_drawRegionAsRects },
- { "nDrawRoundRect", "(JFFFFFFJ)V", (void*) android_view_GLES20Canvas_drawRoundRect },
{ "nDrawRoundRect", "(JJJJJJJJ)V", (void*) android_view_GLES20Canvas_drawRoundRectProps },
- { "nDrawCircle", "(JFFFJ)V", (void*) android_view_GLES20Canvas_drawCircle },
{ "nDrawCircle", "(JJJJJ)V", (void*) android_view_GLES20Canvas_drawCircleProps },
- { "nDrawOval", "(JFFFFJ)V", (void*) android_view_GLES20Canvas_drawOval },
- { "nDrawArc", "(JFFFFFFZJ)V", (void*) android_view_GLES20Canvas_drawArc },
- { "nDrawPoints", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawPoints },
-
- { "nDrawPath", "(JJJ)V", (void*) android_view_GLES20Canvas_drawPath },
- { "nDrawLines", "(J[FIIJ)V", (void*) android_view_GLES20Canvas_drawLines },
-
- { "nSetDrawFilter", "(JJ)V", (void*) android_view_GLES20Canvas_setDrawFilter },
-
- { "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray },
- { "nDrawText", "(JLjava/lang/String;IIFFIJJ)V",
- (void*) android_view_GLES20Canvas_drawText },
-
- { "nDrawTextOnPath", "(J[CIIJFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath },
- { "nDrawTextOnPath", "(JLjava/lang/String;IIJFFIJJ)V",
- (void*) android_view_GLES20Canvas_drawTextOnPath },
-
- { "nDrawTextRun", "(J[CIIIIFFZJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
- { "nDrawTextRun", "(JLjava/lang/String;IIIIFFZJJ)V",
- (void*) android_view_GLES20Canvas_drawTextRun },
-
- { "nGetClipBounds", "(JLandroid/graphics/Rect;)Z", (void*) android_view_GLES20Canvas_getClipBounds },
{ "nFinishRecording", "(J)J", (void*) android_view_GLES20Canvas_finishRecording },
{ "nDrawRenderNode", "(JJI)V", (void*) android_view_GLES20Canvas_drawRenderNode },
{ "nCreateDisplayListRenderer", "()J", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
- { "nDrawLayer", "(JJFF)V", (void*) android_view_GLES20Canvas_drawLayer },
+ { "nDrawLayer", "(JJFF)V", (void*) android_view_GLES20Canvas_drawLayer },
{ "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth },
{ "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight },
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index a0267c8..2a7e177 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -44,8 +44,12 @@
*/
public class Canvas {
- // assigned in constructors or setBitmap, freed in finalizer
- private long mNativeCanvasWrapper;
+ /**
+ * Should only be assigned in constructors (or setBitmap if software canvas),
+ * freed in finalizer.
+ * @hide
+ */
+ protected long mNativeCanvasWrapper;
/** @hide */
public long getNativeCanvasWrapper() {
@@ -1619,6 +1623,9 @@
int colorOffset, @Nullable short[] indices, int indexOffset, int indexCount,
@NonNull Paint paint) {
checkRange(verts.length, vertOffset, vertexCount);
+ if (isHardwareAccelerated()) {
+ return;
+ }
if (texs != null) {
checkRange(texs.length, texOffset, vertexCount);
}
diff --git a/include/private/graphics/Canvas.h b/include/private/graphics/Canvas.h
index 2eda6a4..ae79907 100644
--- a/include/private/graphics/Canvas.h
+++ b/include/private/graphics/Canvas.h
@@ -131,15 +131,23 @@
const float* vertices, const int* colors, const SkPaint* paint) = 0;
// Text
- virtual void drawText(const uint16_t* text, const float* positions, int count,
+ /**
+ * drawText: count is of glyphs
+ * totalAdvance is ignored in software renderering, used by hardware renderer for
+ * text decorations (underlines, strikethroughs).
+ */
+ virtual void drawText(const uint16_t* glyphs, const float* positions, int count,
const SkPaint& paint, float x, float y,
- float boundsLeft, float boundsTop, float boundsRight, float boundsBottom) = 0;
+ float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+ float totalAdvance) = 0;
+ /** drawPosText: count is of UTF16 characters, posCount is floats (2 * glyphs) */
virtual void drawPosText(const uint16_t* text, const float* positions, int count,
int posCount, const SkPaint& paint) = 0;
+ /** drawTextOnPath: count is of glyphs */
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
float hOffset, float vOffset, const SkPaint& paint) = 0;
- /*
+ /**
* Specifies if the positions passed to ::drawText are absolute or relative
* to the (x,y) value provided.
*
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index e42a9e4..499c113 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -34,6 +34,7 @@
#include "RenderState.h"
#include "UvMapper.h"
#include "utils/LinearAllocator.h"
+#include "utils/PaintUtils.h"
// Use OP_LOG for logging with arglist, OP_LOGS if just printing char*
#define OP_LOGS(s) OP_LOG("%s", (s))
@@ -203,7 +204,7 @@
if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) {
return false;
}
- if (Renderer::isBlendedColorFilter(mPaint->getColorFilter())) {
+ if (PaintUtils::isBlendedColorFilter(mPaint->getColorFilter())) {
return false;
}
}
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 1eefa89a..5a13293 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -28,6 +28,7 @@
#include "DisplayListOp.h"
#include "DisplayListRenderer.h"
#include "RenderNode.h"
+#include "utils/PaintUtils.h"
namespace android {
namespace uirenderer {
@@ -63,7 +64,7 @@
}
void DisplayListRenderer::prepareDirty(float left, float top,
- float right, float bottom, bool opaque) {
+ float right, float bottom) {
LOG_ALWAYS_FATAL_IF(mDisplayListData,
"prepareDirty called a second time during a recording!");
@@ -72,7 +73,7 @@
mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3());
mDeferredBarrierType = kBarrier_InOrder;
- mState.setDirtyClip(opaque);
+ mState.setDirtyClip(false);
mRestoreSaveCount = -1;
}
@@ -94,9 +95,9 @@
mDisplayListData->functors.add(functor);
}
-int DisplayListRenderer::save(int flags) {
- addStateOp(new (alloc()) SaveOp(flags));
- return mState.save(flags);
+int DisplayListRenderer::save(SkCanvas::SaveFlags flags) {
+ addStateOp(new (alloc()) SaveOp((int) flags));
+ return mState.save((int) flags);
}
void DisplayListRenderer::restore() {
@@ -117,22 +118,21 @@
}
int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, int flags) {
+ const SkPaint* paint, SkCanvas::SaveFlags flags) {
// force matrix/clip isolation for layer
flags |= SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag;
paint = refPaint(paint);
- addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags));
- return mState.save(flags);
+ addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags));
+ return mState.save((int) flags);
}
-void DisplayListRenderer::translate(float dx, float dy, float dz) {
- // ignore dz, not used at defer time
+void DisplayListRenderer::translate(float dx, float dy) {
mHasDeferredTranslate = true;
mTranslateX += dx;
mTranslateY += dy;
flushRestoreToCount();
- mState.translate(dx, dy, dz);
+ mState.translate(dx, dy, 0.0f);
}
void DisplayListRenderer::rotate(float degrees) {
@@ -155,11 +155,27 @@
mState.setMatrix(matrix);
}
-void DisplayListRenderer::concatMatrix(const SkMatrix& matrix) {
+void DisplayListRenderer::concat(const SkMatrix& matrix) {
addStateOp(new (alloc()) ConcatMatrixOp(matrix));
mState.concatMatrix(matrix);
}
+bool DisplayListRenderer::getClipBounds(SkRect* outRect) const {
+ Rect bounds = mState.getLocalClipBounds();
+ *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ return !(outRect->isEmpty());
+}
+
+bool DisplayListRenderer::quickRejectRect(float left, float top, float right, float bottom) const {
+ return mState.quickRejectConservative(left, top, right, bottom);
+}
+
+bool DisplayListRenderer::quickRejectPath(const SkPath& path) const {
+ SkRect bounds = path.getBounds();
+ return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
+}
+
+
bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
SkRegion::Op op) {
addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
@@ -201,23 +217,50 @@
addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
}
-void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
+void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float left, float top,
+ const SkPaint* paint) {
+ save(SkCanvas::kMatrix_SaveFlag);
+ translate(left, top);
+ drawBitmap(&bitmap, paint);
+ restore();
+}
+
+void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
+ const SkPaint* paint) {
+ if (matrix.isIdentity()) {
+ drawBitmap(&bitmap, paint);
+ } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))) {
+ // SkMatrix::isScaleTranslate() not available in L
+ SkRect src;
+ SkRect dst;
+ bitmap.getBounds(&src);
+ matrix.mapRect(&dst, src);
+ drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
+ dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
+ } else {
+ save(SkCanvas::kMatrix_SaveFlag);
+ concat(matrix);
+ drawBitmap(&bitmap, paint);
+ restore();
+ }
+}
+
+void DisplayListRenderer::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) {
if (srcLeft == 0 && srcTop == 0
- && srcRight == bitmap->width() && srcBottom == bitmap->height()
+ && srcRight == bitmap.width() && srcBottom == bitmap.height()
&& (srcBottom - srcTop == dstBottom - dstTop)
&& (srcRight - srcLeft == dstRight - dstLeft)) {
// transform simple rect to rect drawing case into position bitmap ops, since they merge
save(SkCanvas::kMatrix_SaveFlag);
translate(dstLeft, dstTop);
- drawBitmap(bitmap, paint);
+ drawBitmap(&bitmap, paint);
restore();
} else {
- bitmap = refBitmap(bitmap);
paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
+ addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(&bitmap),
srcLeft, srcTop, srcRight, srcBottom,
dstLeft, dstTop, dstRight, dstBottom, paint));
}
@@ -230,16 +273,15 @@
addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, paint));
}
-void DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+void DisplayListRenderer::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const SkPaint* paint) {
int vertexCount = (meshWidth + 1) * (meshHeight + 1);
- bitmap = refBitmap(bitmap);
vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex
paint = refPaint(paint);
colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex
- addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight,
- vertices, colors, paint));
+ addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(&bitmap), meshWidth, meshHeight,
+ vertices, colors, paint));
}
void DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
@@ -255,16 +297,22 @@
addDrawOp(new (alloc()) DrawColorOp(color, mode));
}
+void DisplayListRenderer::drawPaint(const SkPaint& paint) {
+ SkRect bounds;
+ if (getClipBounds(&bounds)) {
+ drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint);
+ }
+}
+
+
void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
- const SkPaint* paint) {
- paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
+ const SkPaint& paint) {
+ addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint)));
}
void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, const SkPaint* paint) {
- paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
+ float rx, float ry, const SkPaint& paint) {
+ addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint)));
}
void DisplayListRenderer::drawRoundRect(
@@ -283,9 +331,8 @@
&right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
}
-void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
- paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
+void DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint& paint) {
+ addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint)));
}
void DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
@@ -299,65 +346,56 @@
}
void DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
- const SkPaint* paint) {
- paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
+ const SkPaint& paint) {
+ addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint)));
}
void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
+ float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
if (fabs(sweepAngle) >= 360.0f) {
drawOval(left, top, right, bottom, paint);
} else {
- paint = refPaint(paint);
addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
- startAngle, sweepAngle, useCenter, paint));
+ startAngle, sweepAngle, useCenter, refPaint(&paint)));
}
}
-void DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
- path = refPath(path);
- paint = refPaint(paint);
-
- addDrawOp(new (alloc()) DrawPathOp(path, paint));
+void DisplayListRenderer::drawPath(const SkPath& path, const SkPaint& paint) {
+ addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint)));
}
-void DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
+void DisplayListRenderer::drawLines(const float* points, int count, const SkPaint& paint) {
points = refBuffer<float>(points, count);
- paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawLinesOp(points, count, paint));
+ addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint)));
}
-void DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
+void DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint& paint) {
points = refBuffer<float>(points, count);
- paint = refPaint(paint);
- addDrawOp(new (alloc()) DrawPointsOp(points, count, paint));
+ addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint)));
}
-void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
- const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
- if (!text || count <= 0) return;
+void DisplayListRenderer::drawTextOnPath(const uint16_t* glyphs, int count,
+ const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) {
+ if (!glyphs || count <= 0) return;
- text = refText(text, bytesCount);
- path = refPath(path);
- paint = refPaint(paint);
-
- DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
- hOffset, vOffset, paint);
+ int bytesCount = 2 * count;
+ DrawOp* op = new (alloc()) DrawTextOnPathOp(refText((const char*) glyphs, bytesCount),
+ bytesCount, count, refPath(&path),
+ hOffset, vOffset, refPaint(&paint));
addDrawOp(op);
}
-void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
- const float* positions, const SkPaint* paint) {
+void DisplayListRenderer::drawPosText(const uint16_t* text, const float* positions,
+ int count, int posCount, const SkPaint& paint) {
if (!text || count <= 0) return;
- text = refText(text, bytesCount);
+ int bytesCount = 2 * count;
positions = refBuffer<float>(positions, count * 2);
- paint = refPaint(paint);
- DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
+ DrawOp* op = new (alloc()) DrawPosTextOp(refText((const char*) text, bytesCount),
+ bytesCount, count, positions, refPaint(&paint));
addDrawOp(op);
}
@@ -371,40 +409,41 @@
paint->setLooper(NULL);
}
-void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
- float x, float y, const float* positions, const SkPaint* paint,
- float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
+void DisplayListRenderer::drawText(const uint16_t* glyphs, const float* positions,
+ int count, const SkPaint& paint, float x, float y,
+ float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+ float totalAdvance) {
- if (!text || count <= 0 || paintWillNotDrawText(*paint)) return;
+ if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
- text = refText(text, bytesCount);
+ int bytesCount = count * 2;
+ const char* text = refText((const char*) glyphs, bytesCount);
positions = refBuffer<float>(positions, count * 2);
+ Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom);
if (CC_UNLIKELY(mHighContrastText)) {
// high contrast draw path
- int color = paint->getColor();
+ int color = paint.getColor();
int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color);
bool darken = channelSum < (128 * 3);
// outline
- SkPaint* outlinePaint = copyPaint(paint);
+ SkPaint* outlinePaint = copyPaint(&paint);
simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, outlinePaint);
outlinePaint->setStyle(SkPaint::kStrokeAndFill_Style);
addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count,
x, y, positions, outlinePaint, totalAdvance, bounds)); // bounds?
// inner
- SkPaint* innerPaint = copyPaint(paint);
+ SkPaint* innerPaint = copyPaint(&paint);
simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, innerPaint);
innerPaint->setStyle(SkPaint::kFill_Style);
addDrawOp(new (alloc()) DrawTextOp(text, bytesCount, count,
x, y, positions, innerPaint, totalAdvance, bounds));
} else {
// standard draw path
- paint = refPaint(paint);
-
DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count,
- x, y, positions, paint, totalAdvance, bounds);
+ x, y, positions, refPaint(&paint), totalAdvance, bounds);
addDrawOp(op);
}
}
@@ -477,7 +516,7 @@
size_t DisplayListRenderer::addDrawOp(DrawOp* op) {
Rect localBounds;
if (op->getLocalBounds(localBounds)) {
- bool rejected = quickRejectConservative(localBounds.left, localBounds.top,
+ bool rejected = quickRejectRect(localBounds.left, localBounds.top,
localBounds.right, localBounds.bottom);
op->setQuickRejected(rejected);
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 34f9c38..a798329 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -25,6 +25,8 @@
#include <SkTLazy.h>
#include <cutils/compiler.h>
+#include <private/graphics/Canvas.h>
+
#include "CanvasState.h"
#include "DisplayList.h"
#include "DisplayListLogBuffer.h"
@@ -62,7 +64,7 @@
/**
* Records drawing commands in a display list for later playback into an OpenGLRenderer.
*/
-class ANDROID_API DisplayListRenderer: public Renderer, public CanvasStateClient {
+class ANDROID_API DisplayListRenderer: public Canvas, public CanvasStateClient {
public:
DisplayListRenderer();
virtual ~DisplayListRenderer();
@@ -72,126 +74,177 @@
DisplayListData* finishRecording();
// ----------------------------------------------------------------------------
-// Frame state operations
+// HWUI Frame state operations
// ----------------------------------------------------------------------------
- virtual void prepareDirty(float left, float top, float right,
- float bottom, bool opaque) override;
- virtual void prepare(bool opaque) override {
- prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque);
- }
- virtual bool finish() override;
- virtual void interrupt();
- virtual void resume();
+
+ void prepareDirty(float left, float top, float right, float bottom);
+ void prepare() { prepareDirty(0.0f, 0.0f, width(), height()); }
+ bool finish();
+ void interrupt();
+ void resume();
// ----------------------------------------------------------------------------
-// Canvas state operations
+// HWUI Canvas state operations
// ----------------------------------------------------------------------------
- virtual void setViewport(int width, int height) override { mState.setViewport(width, height); }
- // Save (layer)
- virtual int getSaveCount() const override { return mState.getSaveCount(); }
- virtual int save(int flags) override;
- virtual void restore() override;
- virtual void restoreToCount(int saveCount) override;
- virtual int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* paint, int flags) override;
+ void setViewport(int width, int height) { mState.setViewport(width, height); }
- // Matrix
- virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
-
- virtual void translate(float dx, float dy, float dz = 0.0f) override;
- virtual void rotate(float degrees) override;
- virtual void scale(float sx, float sy) override;
- virtual void skew(float sx, float sy) override;
-
- virtual void setMatrix(const SkMatrix& matrix) override;
- virtual void concatMatrix(const SkMatrix& matrix) override;
-
- // Clip
- virtual bool clipRect(float left, float top, float right, float bottom,
- SkRegion::Op op) override;
- virtual bool clipPath(const SkPath* path, SkRegion::Op op) override;
- virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override;
-
- // Misc
- virtual void setDrawFilter(SkDrawFilter* filter) override;
- virtual const Rect& getLocalClipBounds() const override { return mState.getLocalClipBounds(); }
const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
- virtual bool quickRejectConservative(float left, float top,
- float right, float bottom) const override {
- return mState.quickRejectConservative(left, top, right, bottom);
- }
bool isCurrentTransformSimple() {
return mState.currentTransform()->isSimple();
}
// ----------------------------------------------------------------------------
-// Canvas draw operations
+// HWUI Canvas draw operations
// ----------------------------------------------------------------------------
- virtual void drawColor(int color, SkXfermode::Mode mode) override;
// Bitmap-based
- virtual void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) override;
- virtual void drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
- float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint) override;
- virtual void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint) override;
- virtual void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
- const float* vertices, const int* colors, const SkPaint* paint) override;
- virtual void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
- float left, float top, float right, float bottom, const SkPaint* paint) override;
+ void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
+ // TODO: move drawBitmapData() to Canvas.h
+ void drawBitmapData(const SkBitmap* bitmap, const SkPaint* paint);
+ // TODO: move drawPatch() to Canvas.h
+ void drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+ float left, float top, float right, float bottom, const SkPaint* paint);
// Shapes
- virtual void drawRect(float left, float top, float right, float bottom,
- const SkPaint* paint) override;
- virtual void drawRects(const float* rects, int count, const SkPaint* paint) override;
- virtual void drawRoundRect(float left, float top, float right, float bottom,
- float rx, float ry, const SkPaint* paint) override;
- virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+ void drawRects(const float* rects, int count, const SkPaint* paint);
+ void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
CanvasPropertyPaint* paint);
- virtual void drawCircle(float x, float y, float radius, const SkPaint* paint) override;
- virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
+ void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
- virtual void drawOval(float left, float top, float right, float bottom,
- const SkPaint* paint) override;
- virtual void drawArc(float left, float top, float right, float bottom,
- float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) override;
- virtual void drawPath(const SkPath* path, const SkPaint* paint) override;
- virtual void drawLines(const float* points, int count, const SkPaint* paint) override;
- virtual void drawPoints(const float* points, int count, const SkPaint* paint) override;
- // Text
- virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
- const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
- DrawOpMode drawOpMode = kDrawOpMode_Immediate) override;
- virtual void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
- float hOffset, float vOffset, const SkPaint* paint) override;
- virtual void drawPosText(const char* text, int bytesCount, int count,
- const float* positions, const SkPaint* paint) override;
// ----------------------------------------------------------------------------
-// Canvas draw operations - special
+// HWUI Canvas draw operations - special
// ----------------------------------------------------------------------------
- virtual void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
- virtual void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) override;
+ void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
+ void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags);
// TODO: rename for consistency
- virtual void callDrawGLFunction(Functor* functor, Rect& dirty) override;
+ void callDrawGLFunction(Functor* functor, Rect& dirty);
void setHighContrastText(bool highContrastText) {
mHighContrastText = highContrastText;
}
// ----------------------------------------------------------------------------
-// CanvasState callbacks
+// CanvasStateClient interface
// ----------------------------------------------------------------------------
virtual void onViewportInitialized() override { }
virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { }
virtual GLuint onGetTargetFbo() const override { return -1; }
+// ----------------------------------------------------------------------------
+// android/graphics/Canvas interface
+// ----------------------------------------------------------------------------
+ virtual SkCanvas* getSkCanvas() {
+ LOG_ALWAYS_FATAL("DisplayListRenderer has no SkCanvas");
+ return NULL;
+ }
+ virtual void setBitmap(SkBitmap* bitmap, bool copyState) {
+ LOG_ALWAYS_FATAL("DisplayListRenderer is not backed by a bitmap.");
+ }
+
+ virtual bool isOpaque() { return false; }
+ virtual int width() { return mState.getWidth(); }
+ virtual int height() { return mState.getHeight(); }
+
+// ----------------------------------------------------------------------------
+// android/graphics/Canvas state operations
+// ----------------------------------------------------------------------------
+ // Save (layer)
+ virtual int getSaveCount() const { return mState.getSaveCount(); }
+ virtual int save(SkCanvas::SaveFlags flags);
+ virtual void restore();
+ virtual void restoreToCount(int saveCount);
+
+ virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
+ SkCanvas::SaveFlags flags);
+ virtual int saveLayerAlpha(float left, float top, float right, float bottom,
+ int alpha, SkCanvas::SaveFlags flags) {
+ SkPaint paint;
+ paint.setAlpha(alpha);
+ return saveLayer(left, top, right, bottom, &paint, flags);
+ }
+
+ // Matrix
+ virtual void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
+ virtual void setMatrix(const SkMatrix& matrix);
+
+ virtual void concat(const SkMatrix& matrix);
+ virtual void rotate(float degrees);
+ virtual void scale(float sx, float sy);
+ virtual void skew(float sx, float sy);
+ virtual void translate(float dx, float dy);
+
+ // Clip
+ virtual bool getClipBounds(SkRect* outRect) const;
+ virtual bool quickRejectRect(float left, float top, float right, float bottom) const;
+ virtual bool quickRejectPath(const SkPath& path) const;
+
+ virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
+ virtual bool clipPath(const SkPath* path, SkRegion::Op op);
+ virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
+
+ // Misc
+ virtual SkDrawFilter* getDrawFilter() { return mDrawFilter.get(); }
+ virtual void setDrawFilter(SkDrawFilter* filter);
+
+// ----------------------------------------------------------------------------
+// android/graphics/Canvas draw operations
+// ----------------------------------------------------------------------------
+ virtual void drawColor(int color, SkXfermode::Mode mode);
+ virtual void drawPaint(const SkPaint& paint);
+
+ // Geometry
+ virtual void drawPoint(float x, float y, const SkPaint& paint) {
+ float points[2] = { x, y };
+ drawPoints(points, 2, paint);
+ }
+ virtual void drawPoints(const float* points, int count, const SkPaint& paint);
+ virtual void drawLine(float startX, float startY, float stopX, float stopY,
+ const SkPaint& paint) {
+ float points[4] = { startX, startY, stopX, stopY };
+ drawLines(points, 4, paint);
+ }
+ virtual void drawLines(const float* points, int count, const SkPaint& paint);
+ virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint);
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, const SkPaint& paint);
+ virtual void drawCircle(float x, float y, float radius, const SkPaint& paint);
+ virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint);
+ virtual void drawArc(float left, float top, float right, float bottom,
+ float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint);
+ virtual void drawPath(const SkPath& path, const SkPaint& paint);
+ virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
+ const float* verts, const float* tex, const int* colors,
+ const uint16_t* indices, int indexCount, const SkPaint& paint)
+ { LOG_ALWAYS_FATAL("DisplayListRenderer does not support drawVertices()"); }
+
+ // Bitmap-based
+ virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint);
+ virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
+ const SkPaint* paint);
+ virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
+ float srcRight, float srcBottom, float dstLeft, float dstTop,
+ float dstRight, float dstBottom, const SkPaint* paint);
+ virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
+ const float* vertices, const int* colors, const SkPaint* paint);
+
+ // Text
+ virtual void drawText(const uint16_t* glyphs, const float* positions, int count,
+ const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
+ float boundsRight, float boundsBottom, float totalAdvance);
+ virtual void drawPosText(const uint16_t* text, const float* positions, int count,
+ int posCount, const SkPaint& paint);
+ virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
+ float hOffset, float vOffset, const SkPaint& paint);
+ virtual bool drawTextAbsolutePos() const { return false; }
+
+
private:
CanvasState mState;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index fb3d462..3c8fb8b 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -47,6 +47,7 @@
#include "Vector.h"
#include "VertexBuffer.h"
#include "utils/GLUtils.h"
+#include "utils/PaintUtils.h"
#include "utils/TraceUtils.h"
#if DEBUG_DETAILED_EVENTS
@@ -1667,8 +1668,10 @@
// argb=1,0,0,0
accountForClear(mode);
// TODO: check shader blending, once we have shader drawing support for layers.
- bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f ||
- (mColorSet && mColorA < 1.0f) || isBlendedColorFilter(layer->getColorFilter());
+ bool blend = layer->isBlend()
+ || getLayerAlpha(layer) < 1.0f
+ || (mColorSet && mColorA < 1.0f)
+ || PaintUtils::isBlendedColorFilter(layer->getColorFilter());
chooseBlending(blend, mode, mDescription, swapSrcDst);
}
@@ -1679,7 +1682,7 @@
accountForClear(mode);
blend |= (mColorSet && mColorA < 1.0f) ||
(getShader(paint) && !getShader(paint)->isOpaque()) ||
- isBlendedColorFilter(getColorFilter(paint));
+ PaintUtils::isBlendedColorFilter(getColorFilter(paint));
chooseBlending(blend, mode, mDescription, swapSrcDst);
}
@@ -2476,7 +2479,7 @@
float rx, float ry, const SkPaint* p) {
if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
- || paintWillNotDraw(*p)) {
+ || PaintUtils::paintWillNotDraw(*p)) {
return;
}
@@ -2495,7 +2498,7 @@
void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) {
if (mState.currentlyIgnored()
|| quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p)
- || paintWillNotDraw(*p)) {
+ || PaintUtils::paintWillNotDraw(*p)) {
return;
}
if (p->getPathEffect() != nullptr) {
@@ -2517,7 +2520,7 @@
const SkPaint* p) {
if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
- || paintWillNotDraw(*p)) {
+ || PaintUtils::paintWillNotDraw(*p)) {
return;
}
@@ -2540,7 +2543,7 @@
float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) {
if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
- || paintWillNotDraw(*p)) {
+ || PaintUtils::paintWillNotDraw(*p)) {
return;
}
@@ -2575,7 +2578,7 @@
const SkPaint* p) {
if (mState.currentlyIgnored()
|| quickRejectSetupScissor(left, top, right, bottom, p)
- || paintWillNotDraw(*p)) {
+ || PaintUtils::paintWillNotDraw(*p)) {
return;
}
@@ -2657,7 +2660,8 @@
bool OpenGLRenderer::canSkipText(const SkPaint* paint) const {
float alpha = (hasTextShadow(paint) ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha;
- return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode;
+ return MathUtils::isZero(alpha)
+ && PaintUtils::getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode;
}
void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 9de4149..9d9b3d2 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -49,6 +49,7 @@
#include "UvMapper.h"
#include "Vertex.h"
#include "Caches.h"
+#include "utils/PaintUtils.h"
class SkShader;
@@ -274,7 +275,7 @@
static inline SkXfermode::Mode getXfermodeDirect(const SkPaint* paint) {
if (!paint) return SkXfermode::kSrcOver_Mode;
- return getXfermode(paint->getXfermode());
+ return PaintUtils::getXfermode(paint->getXfermode());
}
static inline int getAlphaDirect(const SkPaint* paint) {
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index ee44d7a..3240bbc 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -57,40 +57,6 @@
public:
virtual ~Renderer() {}
- /**
- * Safely retrieves the mode from the specified xfermode. If the specified
- * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
- */
- static inline SkXfermode::Mode getXfermode(SkXfermode* mode) {
- SkXfermode::Mode resultMode;
- if (!SkXfermode::AsMode(mode, &resultMode)) {
- resultMode = SkXfermode::kSrcOver_Mode;
- }
- return resultMode;
- }
-
- // TODO: move to a method on android:Paint
- static inline bool paintWillNotDraw(const SkPaint& paint) {
- return paint.getAlpha() == 0
- && !paint.getColorFilter()
- && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
- }
-
- // TODO: move to a method on android:Paint
- static inline bool paintWillNotDrawText(const SkPaint& paint) {
- return paint.getAlpha() == 0
- && paint.getLooper() == nullptr
- && !paint.getColorFilter()
- && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
- }
-
- static bool isBlendedColorFilter(const SkColorFilter* filter) {
- if (filter == nullptr) {
- return false;
- }
- return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0;
- }
-
// ----------------------------------------------------------------------------
// Frame state operations
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index ee16991..4efef6f 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -41,7 +41,7 @@
static DisplayListRenderer* startRecording(RenderNode* node) {
DisplayListRenderer* renderer = new DisplayListRenderer();
renderer->setViewport(node->getWidth(), node->getHeight());
- renderer->prepare(false);
+ renderer->prepare();
return renderer;
}
diff --git a/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h
new file mode 100644
index 0000000..8a4034f
--- /dev/null
+++ b/libs/hwui/utils/PaintUtils.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+#ifndef PAINT_UTILS_H
+#define PAINT_UTILS_H
+
+namespace android {
+namespace uirenderer {
+
+class PaintUtils {
+public:
+
+ /**
+ * Safely retrieves the mode from the specified xfermode. If the specified
+ * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
+ */
+ static inline SkXfermode::Mode getXfermode(SkXfermode* mode) {
+ SkXfermode::Mode resultMode;
+ if (!SkXfermode::AsMode(mode, &resultMode)) {
+ resultMode = SkXfermode::kSrcOver_Mode;
+ }
+ return resultMode;
+ }
+
+ // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()?
+ static inline bool paintWillNotDraw(const SkPaint& paint) {
+ return paint.getAlpha() == 0
+ && !paint.getColorFilter()
+ && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
+ }
+
+ // TODO: move to a method on android:Paint? replace with SkPaint::nothingToDraw()?
+ static inline bool paintWillNotDrawText(const SkPaint& paint) {
+ return paint.getAlpha() == 0
+ && paint.getLooper() == NULL
+ && !paint.getColorFilter()
+ && getXfermode(paint.getXfermode()) == SkXfermode::kSrcOver_Mode;
+ }
+
+ static bool isBlendedColorFilter(const SkColorFilter* filter) {
+ if (filter == NULL) {
+ return false;
+ }
+ return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0;
+ }
+
+}; // class PaintUtils
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* PAINT_UTILS_H */