summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sergei Vasilinetc <sergeyv@google.com> 2017-01-17 21:27:48 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-01-17 21:27:52 +0000
commit1f6df68a90c6aa02ed21e8ed2753f9d2488880c8 (patch)
treeaaa62b280246e726f89be6be22acc6b215c74806
parent04e7b6c6de620406348142ba9dd65bad094e264b (diff)
parentb3061e82ebfaefdbf33b35f78e5e87de7abd5591 (diff)
Merge "Prohibit rendering hardware bitmaps in software mode."
-rw-r--r--graphics/java/android/graphics/BaseCanvas.java63
-rw-r--r--graphics/java/android/graphics/ComposeShader.java4
2 files changed, 65 insertions, 2 deletions
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index f135484adcc0..2ebd2cc6206b 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -58,6 +58,7 @@ public abstract class BaseCanvas {
throw new RuntimeException("Canvas: trying to use a non-premultiplied bitmap "
+ bitmap);
}
+ throwIfHwBitmapInSwMode(bitmap);
}
protected final static void checkRange(int length, int offset, int count) {
@@ -80,12 +81,14 @@ public abstract class BaseCanvas {
public void drawArc(float left, float top, float right, float bottom, float startAngle,
float sweepAngle, boolean useCenter, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawArc(mNativeCanvasWrapper, left, top, right, bottom, startAngle, sweepAngle,
useCenter, paint.getNativeInstance());
}
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,
@NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
paint);
}
@@ -96,12 +99,14 @@ public abstract class BaseCanvas {
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
throwIfCannotDraw(bitmap);
+ throwIfHasHwBitmapInSwMode(paint);
nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
bitmap.mDensity);
}
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
paint != null ? paint.getNativeInstance() : 0);
}
@@ -112,6 +117,7 @@ public abstract class BaseCanvas {
throw new NullPointerException();
}
throwIfCannotDraw(bitmap);
+ throwIfHasHwBitmapInSwMode(paint);
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
int left, top, right, bottom;
@@ -137,6 +143,7 @@ public abstract class BaseCanvas {
throw new NullPointerException();
}
throwIfCannotDraw(bitmap);
+ throwIfHasHwBitmapInSwMode(paint);
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
float left, top, right, bottom;
@@ -175,6 +182,7 @@ public abstract class BaseCanvas {
|| (lastScanline + width > length)) {
throw new ArrayIndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
// quick escape if there's nothing to draw
if (width == 0 || height == 0) {
return;
@@ -198,6 +206,7 @@ public abstract class BaseCanvas {
if ((meshWidth | meshHeight | vertOffset | colorOffset) < 0) {
throw new ArrayIndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
if (meshWidth == 0 || meshHeight == 0) {
return;
}
@@ -214,6 +223,7 @@ public abstract class BaseCanvas {
}
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
}
@@ -227,19 +237,23 @@ public abstract class BaseCanvas {
public void drawLine(float startX, float startY, float stopX, float stopY,
@NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
}
public void drawLines(@Size(multiple = 4) @NonNull float[] pts, int offset, int count,
@NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawLines(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
}
public void drawLines(@Size(multiple = 4) @NonNull float[] pts, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
drawLines(pts, 0, pts.length, paint);
}
public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
}
@@ -247,6 +261,7 @@ public abstract class BaseCanvas {
if (oval == null) {
throw new NullPointerException();
}
+ throwIfHasHwBitmapInSwMode(paint);
drawOval(oval.left, oval.top, oval.right, oval.bottom, paint);
}
@@ -257,6 +272,7 @@ public abstract class BaseCanvas {
public void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst, @Nullable Paint paint) {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
+ throwIfHasHwBitmapInSwMode(paint);
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
@@ -266,6 +282,7 @@ public abstract class BaseCanvas {
public void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst, @Nullable Paint paint) {
Bitmap bitmap = patch.getBitmap();
throwIfCannotDraw(bitmap);
+ throwIfHasHwBitmapInSwMode(paint);
final long nativePaint = paint == null ? 0 : paint.getNativeInstance();
nDrawNinePatch(mNativeCanvasWrapper, bitmap.getNativeInstance(), patch.mNativeChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint,
@@ -273,6 +290,7 @@ public abstract class BaseCanvas {
}
public void drawPath(@NonNull Path path, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
if (path.isSimplePath && path.rects != null) {
nDrawRegion(mNativeCanvasWrapper, path.rects.mNativeRegion, paint.getNativeInstance());
} else {
@@ -281,15 +299,18 @@ public abstract class BaseCanvas {
}
public void drawPoint(float x, float y, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawPoint(mNativeCanvasWrapper, x, y, paint.getNativeInstance());
}
public void drawPoints(@Size(multiple = 2) float[] pts, int offset, int count,
@NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawPoints(mNativeCanvasWrapper, pts, offset, count, paint.getNativeInstance());
}
public void drawPoints(@Size(multiple = 2) @NonNull float[] pts, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
drawPoints(pts, 0, pts.length, paint);
}
@@ -300,6 +321,7 @@ public abstract class BaseCanvas {
if (index < 0 || index + count > text.length || count * 2 > pos.length) {
throw new IndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
for (int i = 0; i < count; i++) {
drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
}
@@ -308,18 +330,22 @@ public abstract class BaseCanvas {
@Deprecated
public void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos,
@NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
}
public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawRect(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
}
public void drawRect(@NonNull Rect r, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
drawRect(r.left, r.top, r.right, r.bottom, paint);
}
public void drawRect(@NonNull RectF rect, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawRect(mNativeCanvasWrapper,
rect.left, rect.top, rect.right, rect.bottom, paint.getNativeInstance());
}
@@ -330,11 +356,13 @@ public abstract class BaseCanvas {
public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
@NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawRoundRect(mNativeCanvasWrapper, left, top, right, bottom, rx, ry,
paint.getNativeInstance());
}
public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
}
@@ -344,6 +372,7 @@ public abstract class BaseCanvas {
(text.length - index - count)) < 0) {
throw new IndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
nDrawText(mNativeCanvasWrapper, text, index, count, x, y, paint.mBidiFlags,
paint.getNativeInstance(), paint.mNativeTypeface);
}
@@ -353,6 +382,7 @@ public abstract class BaseCanvas {
if ((start | end | (end - start) | (text.length() - end)) < 0) {
throw new IndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
nDrawText(mNativeCanvasWrapper, text.toString(), start, end, x, y,
@@ -370,6 +400,7 @@ public abstract class BaseCanvas {
}
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
paint.getNativeInstance(), paint.mNativeTypeface);
}
@@ -379,6 +410,7 @@ public abstract class BaseCanvas {
if ((start | end | (end - start) | (text.length() - end)) < 0) {
throw new IndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
nDrawText(mNativeCanvasWrapper, text, start, end, x, y, paint.mBidiFlags,
paint.getNativeInstance(), paint.mNativeTypeface);
}
@@ -388,6 +420,7 @@ public abstract class BaseCanvas {
if (index < 0 || index + count > text.length) {
throw new ArrayIndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
nDrawTextOnPath(mNativeCanvasWrapper, text, index, count,
path.readOnlyNI(), hOffset, vOffset,
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
@@ -396,6 +429,7 @@ public abstract class BaseCanvas {
public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,
float vOffset, @NonNull Paint paint) {
if (text.length() > 0) {
+ throwIfHasHwBitmapInSwMode(paint);
nDrawTextOnPath(mNativeCanvasWrapper, text, path.readOnlyNI(), hOffset, vOffset,
paint.mBidiFlags, paint.getNativeInstance(), paint.mNativeTypeface);
}
@@ -416,6 +450,7 @@ public abstract class BaseCanvas {
throw new IndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
nDrawTextRun(mNativeCanvasWrapper, text, index, count, contextIndex, contextCount,
x, y, isRtl, paint.getNativeInstance(), paint.mNativeTypeface);
}
@@ -434,6 +469,7 @@ public abstract class BaseCanvas {
throw new IndexOutOfBoundsException();
}
+ throwIfHasHwBitmapInSwMode(paint);
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
nDrawTextRun(mNativeCanvasWrapper, text.toString(), start, end, contextStart,
@@ -469,11 +505,38 @@ public abstract class BaseCanvas {
if (indices != null) {
checkRange(indices.length, indexOffset, indexCount);
}
+ throwIfHasHwBitmapInSwMode(paint);
nDrawVertices(mNativeCanvasWrapper, mode.nativeInt, vertexCount, verts,
vertOffset, texs, texOffset, colors, colorOffset,
indices, indexOffset, indexCount, paint.getNativeInstance());
}
+ private void throwIfHwBitmapInSwMode(Bitmap bitmap) {
+ if (!isHardwareAccelerated() && bitmap.getConfig() == Bitmap.Config.HARDWARE) {
+ throw new IllegalStateException("Software rendering doesn't support hardware bitmaps");
+ }
+ }
+
+ private void throwIfHasHwBitmapInSwMode(Paint p) {
+ if (isHardwareAccelerated() || p == null) {
+ return;
+ }
+ throwIfHasHwBitmapInSwMode(p.getShader());
+ }
+
+ private void throwIfHasHwBitmapInSwMode(Shader shader) {
+ if (shader == null) {
+ return;
+ }
+ if (shader instanceof BitmapShader) {
+ throwIfHwBitmapInSwMode(((BitmapShader) shader).mBitmap);
+ }
+ if (shader instanceof ComposeShader) {
+ throwIfHasHwBitmapInSwMode(((ComposeShader) shader).mShaderA);
+ throwIfHasHwBitmapInSwMode(((ComposeShader) shader).mShaderB);
+ }
+ }
+
private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 08a68f4a9b9b..36fc5969bad7 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -22,8 +22,8 @@ package android.graphics;
public class ComposeShader extends Shader {
private int mPorterDuffMode;
- private final Shader mShaderA;
- private final Shader mShaderB;
+ final Shader mShaderA;
+ final Shader mShaderB;
/** Create a new compose shader, given shaders A, B, and a combining mode.
When the mode is applied, it will be given the result from shader A as its