diff options
author | Tom Hudson <tomhudson@google.com> | 2014-12-09 15:03:44 -0500 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2015-01-05 15:25:41 -0800 |
commit | 8dfaa4904205772cdceee63ef3989bcdedf1a914 (patch) | |
tree | baf5ea37427770659698766562bbd3b80f9eddf9 | |
parent | c82be5f27f1dd9da665b0ca52590cc30ede4e78a (diff) | |
download | frameworks_base-8dfaa4904205772cdceee63ef3989bcdedf1a914.zip frameworks_base-8dfaa4904205772cdceee63ef3989bcdedf1a914.tar.gz frameworks_base-8dfaa4904205772cdceee63ef3989bcdedf1a914.tar.bz2 |
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
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 769 | ||||
-rw-r--r-- | core/java/android/view/GLES20RecordingCanvas.java | 2 | ||||
-rw-r--r-- | core/java/android/view/HardwareCanvas.java | 8 | ||||
-rw-r--r-- | core/jni/android/graphics/SkiaCanvas.cpp | 6 | ||||
-rw-r--r-- | core/jni/android_graphics_Canvas.cpp | 14 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 638 | ||||
-rw-r--r-- | graphics/java/android/graphics/Canvas.java | 11 | ||||
-rw-r--r-- | include/private/graphics/Canvas.h | 14 | ||||
-rw-r--r-- | libs/hwui/DisplayListOp.h | 3 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 185 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 217 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.cpp | 22 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/Renderer.h | 34 | ||||
-rw-r--r-- | libs/hwui/tests/main.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/utils/PaintUtils.h | 64 |
16 files changed, 406 insertions, 1586 deletions
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 @@ package android.view; 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 @@ import android.text.TextUtils; * 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 @@ class GLES20Canvas extends HardwareCanvas { private Rect mClipBounds; private RectF mPathBounds; - private DrawFilter mFilter; - /////////////////////////////////////////////////////////////////////////// // JNI /////////////////////////////////////////////////////////////////////////// @@ -77,39 +61,10 @@ class GLES20Canvas extends HardwareCanvas { // 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 @@ class GLES20Canvas extends HardwareCanvas { @Override public boolean isOpaque() { - return mOpaque; + return false; } @Override @@ -153,7 +108,7 @@ class GLES20Canvas extends HardwareCanvas { * Returns the native OpenGLRenderer object. */ long getRenderer() { - return mRenderer; + return mNativeCanvasWrapper; } /////////////////////////////////////////////////////////////////////////// @@ -165,7 +120,7 @@ class GLES20Canvas extends HardwareCanvas { mWidth = width; mHeight = height; - nSetViewport(mRenderer, width, height); + nSetViewport(mNativeCanvasWrapper, width, height); } private static native void nSetViewport(long renderer, @@ -173,19 +128,19 @@ class GLES20Canvas extends HardwareCanvas { @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 @@ class GLES20Canvas extends HardwareCanvas { @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 @@ class GLES20Canvas extends HardwareCanvas { @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 @@ class GLES20Canvas extends HardwareCanvas { @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 @@ class GLES20Canvas extends HardwareCanvas { 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 @@ class GLES20Canvas extends HardwareCanvas { 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 @@ class GLES20Canvas extends HardwareCanvas { 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 @@ class GLES20Canvas extends HardwareCanvas { 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 @@ class GLES20Canvas extends HardwareCanvas { 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 @@ class GLES20RecordingCanvas extends GLES20Canvas { } 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 @@ import android.graphics.Rect; */ 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 @@ public: 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::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshH 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 265300e..4675b49 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -411,9 +411,10 @@ static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jlong bitma 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 @@ public: 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 @@ private: float x; float y; MinikinRect& bounds; + float totalAdvance; }; // Same values used by Skia @@ -494,8 +497,11 @@ void drawText(Canvas* canvas, const uint16_t* text, int start, int count, int co 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 struct { 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_insertReorderBarrier(JNIEnv* env, jobject } 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 @@ static jint android_view_GLES20Canvas_getMaxTextureHeight(JNIEnv* env, jobject c } // ---------------------------------------------------------------------------- -// 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 @@ static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz, 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 @@ static void android_view_GLES20Canvas_drawRoundRectProps(JNIEnv* env, jobject cl 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 @@ static void android_view_GLES20Canvas_drawCircleProps(JNIEnv* env, jobject clazz 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 @@ static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject cla 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_drawRegionAsRects(JNIEnv* env, jobject cla } } -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 @@ const char* const kClassPathName = "android/view/GLES20Canvas"; 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 }, - - { "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 }, - { "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 @@ import javax.microedition.khronos.opengles.GL; */ 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 @@ public class Canvas { 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 @@ public: 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 @@ protected: 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 1eefa89..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 @@ DisplayListData* DisplayListRenderer::finishRecording() { } 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 @@ void DisplayListRenderer::prepareDirty(float left, float top, mState.initializeSaveStack(0, 0, mState.getWidth(), mState.getHeight(), Vector3()); mDeferredBarrierType = kBarrier_InOrder; - mState.setDirtyClip(opaque); + mState.setDirtyClip(false); mRestoreSaveCount = -1; } @@ -94,9 +95,9 @@ void DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) { 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 @@ void DisplayListRenderer::restoreToCount(int saveCount) { } 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 @@ void DisplayListRenderer::setMatrix(const SkMatrix& matrix) { 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 @@ void DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* pain 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 @@ void DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, const SkPaint* 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 @@ void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { 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 @@ void DisplayListRenderer::drawRoundRect( &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::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyP } 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; - - text = refText(text, bytesCount); - path = refPath(path); - paint = refPaint(paint); +void DisplayListRenderer::drawTextOnPath(const uint16_t* glyphs, int count, + const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) { + if (!glyphs || count <= 0) return; - 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 @@ static void simplifyPaint(int color, SkPaint* paint) { 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::addStateOp(StateOp* op) { 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 @@ class StateOp; /** * 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 @@ public: 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; - - // 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; + void setViewport(int width, int height) { mState.setViewport(width, height); } - 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 @@ void OpenGLRenderer::setupDrawBlending(const Layer* layer, bool swapSrcDst) { // 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 @@ void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool sw 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 @@ void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bot 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::drawRoundRect(float left, float top, float right, float bot 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 @@ void OpenGLRenderer::drawOval(float left, float top, float right, float bottom, const SkPaint* p) { if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { + || PaintUtils::paintWillNotDraw(*p)) { return; } @@ -2540,7 +2543,7 @@ void OpenGLRenderer::drawArc(float left, float top, float right, float bottom, 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 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { if (mState.currentlyIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) - || paintWillNotDraw(*p)) { + || PaintUtils::paintWillNotDraw(*p)) { return; } @@ -2657,7 +2660,8 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, 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 @@ public: 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 @@ class ANDROID_API Renderer { 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 @@ public: 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 */ |