summaryrefslogtreecommitdiff
path: root/graphics/java
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/java')
-rw-r--r--graphics/java/android/graphics/Bitmap.java126
-rw-r--r--graphics/java/android/graphics/BitmapRegionDecoder.java153
-rw-r--r--graphics/java/android/graphics/BitmapShader.java14
-rw-r--r--graphics/java/android/graphics/Camera.java7
-rw-r--r--graphics/java/android/graphics/Canvas.java81
-rw-r--r--graphics/java/android/graphics/Color.java24
-rw-r--r--graphics/java/android/graphics/ColorMatrix.java288
-rw-r--r--graphics/java/android/graphics/ColorSpace.java856
-rw-r--r--graphics/java/android/graphics/Compatibility.java51
-rw-r--r--graphics/java/android/graphics/ComposeShader.java3
-rw-r--r--graphics/java/android/graphics/GraphicBuffer.java15
-rw-r--r--graphics/java/android/graphics/GraphicsProtos.java48
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java135
-rw-r--r--graphics/java/android/graphics/ImageDecoder.java45
-rw-r--r--graphics/java/android/graphics/LargeBitmap.java118
-rw-r--r--graphics/java/android/graphics/LinearGradient.java3
-rw-r--r--graphics/java/android/graphics/Matrix.java35
-rw-r--r--graphics/java/android/graphics/NinePatch.java19
-rw-r--r--graphics/java/android/graphics/Path.java6
-rw-r--r--graphics/java/android/graphics/PathMeasure.java2
-rw-r--r--graphics/java/android/graphics/Point.java44
-rw-r--r--graphics/java/android/graphics/RadialGradient.java3
-rw-r--r--graphics/java/android/graphics/RecordingCanvas.java32
-rw-r--r--graphics/java/android/graphics/RenderNode.java10
-rw-r--r--graphics/java/android/graphics/RuntimeShader.java3
-rw-r--r--graphics/java/android/graphics/Shader.java36
-rw-r--r--graphics/java/android/graphics/SweepGradient.java3
-rw-r--r--graphics/java/android/graphics/TextureLayer.java153
-rw-r--r--graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedImageDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java11
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java18
-rw-r--r--graphics/java/android/graphics/drawable/ColorDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java4
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java1
-rw-r--r--graphics/java/android/graphics/drawable/DrawableWrapper.java1
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/Icon.java2
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java3
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/StateListDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java1
-rw-r--r--graphics/java/android/graphics/pdf/PdfEditor.java4
-rw-r--r--graphics/java/android/graphics/pdf/PdfRenderer.java4
46 files changed, 699 insertions, 1672 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index f7877590869a..f41049058a62 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -23,7 +23,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.WorkerThread;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.res.ResourcesImpl;
import android.hardware.HardwareBuffer;
import android.os.Build;
import android.os.Parcel;
@@ -40,6 +39,7 @@ import dalvik.annotation.optimization.CriticalNative;
import libcore.util.NativeAllocationRegistry;
import java.io.OutputStream;
+import java.lang.ref.WeakReference;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
@@ -86,21 +86,15 @@ public final class Bitmap implements Parcelable {
private int mWidth;
@UnsupportedAppUsage
private int mHeight;
+ private WeakReference<HardwareBuffer> mHardwareBuffer;
private boolean mRecycled;
private ColorSpace mColorSpace;
- /** @hide */
- public int mDensity = getDefaultDensity();
+ /*package*/ int mDensity = getDefaultDensity();
private static volatile int sDefaultDensity = -1;
- /** @hide Used only when ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD is true. */
- public static volatile int sPreloadTracingNumInstantiatedBitmaps;
-
- /** @hide Used only when ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD is true. */
- public static volatile long sPreloadTracingTotalBitmapsSize;
-
/**
* For backwards compatibility, allows the app layer to change the default
* density when running old apps.
@@ -164,17 +158,14 @@ public final class Bitmap implements Parcelable {
Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), allocationByteCount);
}
registry.registerNativeAllocation(this, nativeBitmap);
-
- if (ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD) {
- sPreloadTracingNumInstantiatedBitmaps++;
- long nativeSize = NATIVE_ALLOCATION_SIZE + allocationByteCount;
- sPreloadTracingTotalBitmapsSize += nativeSize;
- }
}
/**
* Return the pointer to the native object.
+ *
* @hide
+ * Must be public for access from android.graphics.pdf,
+ * but must not be called from outside the UI module.
*/
public long getNativeInstance() {
return mNativePtr;
@@ -353,11 +344,9 @@ public final class Bitmap implements Parcelable {
* Sets the nine patch chunk.
*
* @param chunk The definition of the nine patch
- *
- * @hide
*/
@UnsupportedAppUsage
- public void setNinePatchChunk(byte[] chunk) {
+ private void setNinePatchChunk(byte[] chunk) {
mNinePatchChunk = chunk;
}
@@ -377,6 +366,7 @@ public final class Bitmap implements Parcelable {
nativeRecycle(mNativePtr);
mNinePatchChunk = null;
mRecycled = true;
+ mHardwareBuffer = null;
}
}
@@ -694,14 +684,16 @@ public final class Bitmap implements Parcelable {
return b;
}
+ // FIXME: The maxTargetSdk should be R, once R is no longer set to
+ // CUR_DEVELOPMENT.
/**
* Creates a new immutable bitmap backed by ashmem which can efficiently
- * be passed between processes. The bitmap is assumed to be in the sRGB
- * color space.
+ * be passed between processes.
*
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
+ publicAlternatives = "Use {@link #asShared()} instead")
public Bitmap createAshmemBitmap() {
checkRecycled("Can't copy a recycled bitmap");
noteHardwareBitmapSlowCall();
@@ -714,22 +706,21 @@ public final class Bitmap implements Parcelable {
}
/**
- * Creates a new immutable bitmap backed by ashmem which can efficiently
- * be passed between processes. The bitmap is assumed to be in the sRGB
- * color space.
+ * Return an immutable bitmap backed by shared memory which can be
+ * efficiently passed between processes via Parcelable.
*
- * @hide
+ * <p>If this bitmap already meets these criteria it will return itself.
*/
- @UnsupportedAppUsage
- public Bitmap createAshmemBitmap(Config config) {
- checkRecycled("Can't copy a recycled bitmap");
- noteHardwareBitmapSlowCall();
- Bitmap b = nativeCopyAshmemConfig(mNativePtr, config.nativeInt);
- if (b != null) {
- b.setPremultiplied(mRequestPremultiplied);
- b.mDensity = mDensity;
+ @NonNull
+ public Bitmap asShared() {
+ if (nativeIsBackedByAshmem(mNativePtr) && nativeIsImmutable(mNativePtr)) {
+ return this;
}
- return b;
+ Bitmap shared = createAshmemBitmap();
+ if (shared == null) {
+ throw new RuntimeException("Failed to create shared Bitmap!");
+ }
+ return shared;
}
/**
@@ -759,19 +750,12 @@ public final class Bitmap implements Parcelable {
if (colorSpace == null) {
colorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
}
- return nativeWrapHardwareBufferBitmap(hardwareBuffer, colorSpace.getNativeInstance());
- }
-
- /**
- * Utility method to create a hardware backed bitmap using the graphics buffer.
- * @hide
- */
- @Nullable
- public static Bitmap wrapHardwareBuffer(@NonNull GraphicBuffer graphicBuffer,
- @Nullable ColorSpace colorSpace) {
- try (HardwareBuffer hb = HardwareBuffer.createFromGraphicBuffer(graphicBuffer)) {
- return wrapHardwareBuffer(hb, colorSpace);
+ Bitmap bitmap = nativeWrapHardwareBufferBitmap(hardwareBuffer,
+ colorSpace.getNativeInstance());
+ if (bitmap != null) {
+ bitmap.mHardwareBuffer = new WeakReference<HardwareBuffer>(hardwareBuffer);
}
+ return bitmap;
}
/**
@@ -1340,7 +1324,10 @@ public final class Bitmap implements Parcelable {
* Populates a rectangle with the bitmap's optical insets.
*
* @param outInsets Rect to populate with optical insets
+ *
* @hide
+ * Must be public for access from android.graphics.drawable,
+ * but must not be called from outside the UI module.
*/
public void getOpticalInsets(@NonNull Rect outInsets) {
if (mNinePatchInsets == null) {
@@ -1350,7 +1337,11 @@ public final class Bitmap implements Parcelable {
}
}
- /** @hide */
+ /**
+ * @hide
+ * Must be public for access from android.graphics.drawable,
+ * but must not be called from outside the UI module.
+ */
public NinePatch.InsetStruct getNinePatchInsets() {
return mNinePatchInsets;
}
@@ -1456,10 +1447,8 @@ public final class Bitmap implements Parcelable {
* to {@link #reconfigure(int, int, Config)}, {@link #setPixel(int, int, int)},
* {@link #setPixels(int[], int, int, int, int, int, int)} and {@link #eraseColor(int)} will
* fail and throw an IllegalStateException.
- *
- * @hide
*/
- public void setImmutable() {
+ private void setImmutable() {
if (isMutable()) {
nativeSetImmutable(mNativePtr);
}
@@ -1603,6 +1592,8 @@ public final class Bitmap implements Parcelable {
/**
* @hide
+ * Must be public for access from android.graphics.drawable,
+ * but must not be called from outside the UI module.
*/
@UnsupportedAppUsage
static public int scaleFromDensity(int size, int sdensity, int tdensity) {
@@ -2230,30 +2221,26 @@ public final class Bitmap implements Parcelable {
}
/**
- * @return {@link GraphicBuffer} which is internally used by hardware bitmap
- *
- * Note: the GraphicBuffer does *not* have an associated {@link ColorSpace}.
- * To render this object the same as its rendered with this Bitmap, you
- * should also call {@link getColorSpace}.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public GraphicBuffer createGraphicBufferHandle() {
- return GraphicBuffer.createFromHardwareBuffer(getHardwareBuffer());
- }
-
- /**
* @return {@link HardwareBuffer} which is internally used by hardware bitmap
*
* Note: the HardwareBuffer does *not* have an associated {@link ColorSpace}.
* To render this object the same as its rendered with this Bitmap, you
- * should also call {@link getColorSpace}.
+ * should also call {@link #getColorSpace()}.</p>
*
- * @hide
+ * Must not be modified while a wrapped Bitmap is accessing it. Doing so will
+ * result in undefined behavior.</p>
+ *
+ * @throws IllegalStateException if the bitmap's config is not {@link Config#HARDWARE}
+ * or if the bitmap has been recycled.
*/
- public HardwareBuffer getHardwareBuffer() {
- return nativeGetHardwareBuffer(mNativePtr);
+ public @NonNull HardwareBuffer getHardwareBuffer() {
+ checkRecycled("Can't getHardwareBuffer from a recycled bitmap");
+ HardwareBuffer hardwareBuffer = mHardwareBuffer == null ? null : mHardwareBuffer.get();
+ if (hardwareBuffer == null || hardwareBuffer.isClosed()) {
+ hardwareBuffer = nativeGetHardwareBuffer(mNativePtr);
+ mHardwareBuffer = new WeakReference<HardwareBuffer>(hardwareBuffer);
+ }
+ return hardwareBuffer;
}
//////////// native methods
@@ -2332,4 +2319,7 @@ public final class Bitmap implements Parcelable {
@CriticalNative
private static native boolean nativeIsImmutable(long nativePtr);
+
+ @CriticalNative
+ private static native boolean nativeIsBackedByAshmem(long nativePtr);
}
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java
index 34eba97819aa..29112af9516b 100644
--- a/graphics/java/android/graphics/BitmapRegionDecoder.java
+++ b/graphics/java/android/graphics/BitmapRegionDecoder.java
@@ -15,9 +15,12 @@
package android.graphics;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.os.Build;
+import android.os.ParcelFileDescriptor;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -43,113 +46,158 @@ public final class BitmapRegionDecoder {
/**
* Create a BitmapRegionDecoder from the specified byte array.
- * Currently only the JPEG and PNG formats are supported.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
*
* @param data byte array of compressed image data.
* @param offset offset into data for where the decoder should begin
* parsing.
* @param length the number of bytes, beginning at offset, to parse
- * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
- * shallow reference to the input. If this is false,
- * then the BitmapRegionDecoder will explicitly make a copy of the
- * input data, and keep that. Even if sharing is allowed,
- * the implementation may still decide to make a deep
- * copy of the input data. If an image is progressively encoded,
- * allowing sharing may degrade the decoding speed.
- * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @param isShareable This field has been ignored since
+ * {@link Build.VERSION_CODES#GINGERBREAD}.
* @throws IOException if the image format is not supported or can not be decoded.
+ * @deprecated In favor of {@link #newInstance(byte[], int, int)}
*/
- public static BitmapRegionDecoder newInstance(byte[] data,
+ @Deprecated
+ @NonNull
+ public static BitmapRegionDecoder newInstance(@NonNull byte[] data,
int offset, int length, boolean isShareable) throws IOException {
+ return newInstance(data, offset, length);
+ }
+
+ /**
+ * Create a BitmapRegionDecoder from the specified byte array.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
+ *
+ * @param data byte array of compressed image data.
+ * @param offset offset into data for where the decoder should begin
+ * parsing.
+ * @param length the number of bytes, beginning at offset, to parse
+ * @throws IOException if the image format is not supported or can not be decoded.
+ */
+ @NonNull
+ public static BitmapRegionDecoder newInstance(@NonNull byte[] data,
+ int offset, int length) throws IOException {
if ((offset | length) < 0 || data.length < offset + length) {
throw new ArrayIndexOutOfBoundsException();
}
- return nativeNewInstance(data, offset, length, isShareable);
+ return nativeNewInstance(data, offset, length);
}
/**
* Create a BitmapRegionDecoder from the file descriptor.
* The position within the descriptor will not be changed when
* this returns, so the descriptor can be used again as is.
- * Currently only the JPEG and PNG formats are supported.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
*
* @param fd The file descriptor containing the data to decode
- * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
- * shallow reference to the input. If this is false,
- * then the BitmapRegionDecoder will explicitly make a copy of the
- * input data, and keep that. Even if sharing is allowed,
- * the implementation may still decide to make a deep
- * copy of the input data. If an image is progressively encoded,
- * allowing sharing may degrade the decoding speed.
- * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @param isShareable This field has been ignored since
+ * {@link Build.VERSION_CODES#KITKAT}.
+ * @throws IOException if the image format is not supported or can not be decoded.
+ * @deprecated In favor of {@link #newInstance(ParcelFileDescriptor)}
+ */
+ @Deprecated
+ @NonNull
+ public static BitmapRegionDecoder newInstance(
+ @NonNull FileDescriptor fd, boolean isShareable) throws IOException {
+ return nativeNewInstance(fd);
+ }
+
+ /**
+ * Create a BitmapRegionDecoder from the file descriptor.
+ * The position within the descriptor will not be changed when
+ * this returns, so the descriptor can be used again as is.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
+ *
+ * @param pfd The parcel file descriptor containing the data to decode
* @throws IOException if the image format is not supported or can not be decoded.
*/
+ @NonNull
public static BitmapRegionDecoder newInstance(
- FileDescriptor fd, boolean isShareable) throws IOException {
- return nativeNewInstance(fd, isShareable);
+ @NonNull ParcelFileDescriptor pfd) throws IOException {
+ return nativeNewInstance(pfd.getFileDescriptor());
}
/**
* Create a BitmapRegionDecoder from an input stream.
* The stream's position will be where ever it was after the encoded data
* was read.
- * Currently only the JPEG and PNG formats are supported.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
*
* @param is The input stream that holds the raw data to be decoded into a
* BitmapRegionDecoder.
- * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
- * shallow reference to the input. If this is false,
- * then the BitmapRegionDecoder will explicitly make a copy of the
- * input data, and keep that. Even if sharing is allowed,
- * the implementation may still decide to make a deep
- * copy of the input data. If an image is progressively encoded,
- * allowing sharing may degrade the decoding speed.
- * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @param isShareable This field has always been ignored.
+ * @return A new BitmapRegionDecoder, or {@code null} if {@code is} is {@code null}.
* @throws IOException if the image format is not supported or can not be decoded.
+ * @deprecated In favor of {@link #newInstance(InputStream)}
*
- * <p class="note">Prior to {@link android.os.Build.VERSION_CODES#KITKAT},
+ * <p class="note">Prior to {@link Build.VERSION_CODES#KITKAT},
* if {@link InputStream#markSupported is.markSupported()} returns true,
* <code>is.mark(1024)</code> would be called. As of
- * {@link android.os.Build.VERSION_CODES#KITKAT}, this is no longer the case.</p>
+ * {@link Build.VERSION_CODES#KITKAT}, this is no longer the case.</p>
*/
- public static BitmapRegionDecoder newInstance(InputStream is,
+ @Deprecated
+ @Nullable
+ public static BitmapRegionDecoder newInstance(@NonNull InputStream is,
boolean isShareable) throws IOException {
+ return newInstance(is);
+ }
+
+ /**
+ * Create a BitmapRegionDecoder from an input stream.
+ * The stream's position will be where ever it was after the encoded data
+ * was read.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
+ *
+ * @param is The input stream that holds the raw data to be decoded into a
+ * BitmapRegionDecoder.
+ * @return A new BitmapRegionDecoder, or {@code null} if {@code is} is {@code null}.
+ * @throws IOException if the image format is not supported or can not be decoded.
+ */
+ @Nullable
+ public static BitmapRegionDecoder newInstance(@NonNull InputStream is) throws IOException {
if (is instanceof AssetManager.AssetInputStream) {
return nativeNewInstance(
- ((AssetManager.AssetInputStream) is).getNativeAsset(),
- isShareable);
+ ((AssetManager.AssetInputStream) is).getNativeAsset());
} else {
// pass some temp storage down to the native code. 1024 is made up,
// but should be large enough to avoid too many small calls back
// into is.read(...).
byte [] tempStorage = new byte[16 * 1024];
- return nativeNewInstance(is, tempStorage, isShareable);
+ return nativeNewInstance(is, tempStorage);
}
}
/**
* Create a BitmapRegionDecoder from a file path.
- * Currently only the JPEG and PNG formats are supported.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
*
* @param pathName complete path name for the file to be decoded.
- * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
- * shallow reference to the input. If this is false,
- * then the BitmapRegionDecoder will explicitly make a copy of the
- * input data, and keep that. Even if sharing is allowed,
- * the implementation may still decide to make a deep
- * copy of the input data. If an image is progressively encoded,
- * allowing sharing may degrade the decoding speed.
- * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @param isShareable This field has always been ignored.
* @throws IOException if the image format is not supported or can not be decoded.
+ * @deprecated In favor of {@link #newInstance(String)}
*/
- public static BitmapRegionDecoder newInstance(String pathName,
+ @Deprecated
+ @NonNull
+ public static BitmapRegionDecoder newInstance(@NonNull String pathName,
boolean isShareable) throws IOException {
+ return newInstance(pathName);
+ }
+
+ /**
+ * Create a BitmapRegionDecoder from a file path.
+ * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
+ *
+ * @param pathName complete path name for the file to be decoded.
+ * @throws IOException if the image format is not supported or can not be decoded.
+ */
+ @NonNull
+ public static BitmapRegionDecoder newInstance(@NonNull String pathName) throws IOException {
BitmapRegionDecoder decoder = null;
InputStream stream = null;
try {
stream = new FileInputStream(pathName);
- decoder = newInstance(stream, isShareable);
+ decoder = newInstance(stream);
} finally {
if (stream != null) {
try {
@@ -273,13 +321,12 @@ public final class BitmapRegionDecoder {
private static native int nativeGetHeight(long lbm);
private static native void nativeClean(long lbm);
- @UnsupportedAppUsage
private static native BitmapRegionDecoder nativeNewInstance(
- byte[] data, int offset, int length, boolean isShareable);
+ byte[] data, int offset, int length);
private static native BitmapRegionDecoder nativeNewInstance(
- FileDescriptor fd, boolean isShareable);
+ FileDescriptor fd);
private static native BitmapRegionDecoder nativeNewInstance(
- InputStream is, byte[] storage, boolean isShareable);
+ InputStream is, byte[] storage);
private static native BitmapRegionDecoder nativeNewInstance(
- long asset, boolean isShareable);
+ long asset);
}
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index edf53c491311..1cb5912e7a54 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -17,7 +17,6 @@
package android.graphics;
import android.annotation.NonNull;
-import android.compat.annotation.UnsupportedAppUsage;
/**
* Shader used to draw a bitmap as a texture. The bitmap can be repeated or
@@ -26,15 +25,10 @@ import android.compat.annotation.UnsupportedAppUsage;
public class BitmapShader extends Shader {
/**
* Prevent garbage collection.
- * @hide
*/
- @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
- @UnsupportedAppUsage
- public Bitmap mBitmap;
+ /*package*/ Bitmap mBitmap;
- @UnsupportedAppUsage
private int mTileX;
- @UnsupportedAppUsage
private int mTileY;
/**
@@ -52,16 +46,14 @@ public class BitmapShader extends Shader {
if (bitmap == null) {
throw new IllegalArgumentException("Bitmap must be non-null");
}
- if (bitmap == mBitmap && tileX == mTileX && tileY == mTileY) {
- return;
- }
mBitmap = bitmap;
mTileX = tileX;
mTileY = tileY;
}
+ /** @hide */
@Override
- long createNativeInstance(long nativeMatrix) {
+ protected long createNativeInstance(long nativeMatrix) {
return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY);
}
diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java
index 80a3740d2f4e..46640d7222ca 100644
--- a/graphics/java/android/graphics/Camera.java
+++ b/graphics/java/android/graphics/Camera.java
@@ -16,8 +16,6 @@
package android.graphics;
-import android.compat.annotation.UnsupportedAppUsage;
-
/**
* A camera instance can be used to compute 3D transformations and
* generate a matrix that can be applied, for instance, on a
@@ -139,7 +137,7 @@ public class Camera {
* @param matrix The matrix to copy the current transforms into
*/
public void getMatrix(Matrix matrix) {
- nativeGetMatrix(matrix.native_instance);
+ nativeGetMatrix(matrix.ni());
}
/**
@@ -168,6 +166,5 @@ public class Camera {
private native void nativeGetMatrix(long native_matrix);
private native void nativeApplyToCanvas(long native_canvas);
- @UnsupportedAppUsage
- long native_instance;
+ private long native_instance;
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index d949444d44d6..559571cb0271 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -34,8 +34,6 @@ import libcore.util.NativeAllocationRegistry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import javax.microedition.khronos.opengles.GL;
-
/**
* The Canvas class holds the "draw" calls. To draw something, you need
* 4 basic components: A Bitmap to hold the pixels, a Canvas to host
@@ -51,10 +49,8 @@ import javax.microedition.khronos.opengles.GL;
*/
public class Canvas extends BaseCanvas {
private static int sCompatiblityVersion = 0;
- /** @hide */
- public static boolean sCompatibilityRestore = false;
- /** @hide */
- public static boolean sCompatibilitySetBitmap = false;
+ private static boolean sCompatibilityRestore = false;
+ private static boolean sCompatibilitySetBitmap = false;
/** @hide */
@UnsupportedAppUsage
@@ -62,9 +58,6 @@ public class Canvas extends BaseCanvas {
return mNativeCanvasWrapper;
}
- /** @hide */
- public boolean isRecordingFor(Object o) { return false; }
-
// may be null
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 117521088)
private Bitmap mBitmap;
@@ -124,8 +117,10 @@ public class Canvas extends BaseCanvas {
mDensity = bitmap.mDensity;
}
- /** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ /**
+ * @hide Needed by android.graphics.pdf.PdfDocument, but should not be called from
+ * outside the UI rendering module.
+ */
public Canvas(long nativeCanvas) {
if (nativeCanvas == 0) {
throw new IllegalStateException();
@@ -137,19 +132,6 @@ public class Canvas extends BaseCanvas {
}
/**
- * Returns null.
- *
- * @deprecated This method is not supported and should not be invoked.
- *
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- protected GL getGL() {
- return null;
- }
-
- /**
* Indicates whether this Canvas uses hardware acceleration.
*
* Note that this method does not define what type of hardware acceleration
@@ -205,22 +187,6 @@ public class Canvas extends BaseCanvas {
}
/**
- * @deprecated use {@link #enableZ()} instead
- * @hide */
- @Deprecated
- public void insertReorderBarrier() {
- enableZ();
- }
-
- /**
- * @deprecated use {@link #disableZ()} instead
- * @hide */
- @Deprecated
- public void insertInorderBarrier() {
- disableZ();
- }
-
- /**
* <p>Enables Z support which defaults to disabled. This allows for RenderNodes drawn with
* {@link #drawRenderNode(RenderNode)} to be re-arranged based off of their
* {@link RenderNode#getElevation()} and {@link RenderNode#getTranslationZ()}
@@ -793,7 +759,7 @@ public class Canvas extends BaseCanvas {
* @param matrix The matrix to preconcatenate with the current matrix
*/
public void concat(@Nullable Matrix matrix) {
- if (matrix != null) nConcat(mNativeCanvasWrapper, matrix.native_instance);
+ if (matrix != null) nConcat(mNativeCanvasWrapper, matrix.ni());
}
/**
@@ -811,7 +777,7 @@ public class Canvas extends BaseCanvas {
*/
public void setMatrix(@Nullable Matrix matrix) {
nSetMatrix(mNativeCanvasWrapper,
- matrix == null ? 0 : matrix.native_instance);
+ matrix == null ? 0 : matrix.ni());
}
/**
@@ -826,7 +792,7 @@ public class Canvas extends BaseCanvas {
*/
@Deprecated
public void getMatrix(@NonNull Matrix ctm) {
- nGetMatrix(mNativeCanvasWrapper, ctm.native_instance);
+ nGetMatrix(mNativeCanvasWrapper, ctm.ni());
}
/**
@@ -1169,21 +1135,12 @@ public class Canvas extends BaseCanvas {
/**
* Black-and-White: Treat edges by just rounding to nearest pixel boundary
*/
- BW(0), //!< treat edges by just rounding to nearest pixel boundary
+ BW,
/**
* Antialiased: Treat edges by rounding-out, since they may be antialiased
*/
- AA(1);
-
- EdgeType(int nativeInt) {
- this.nativeInt = nativeInt;
- }
-
- /**
- * @hide
- */
- public final int nativeInt;
+ AA;
}
/**
@@ -1386,10 +1343,7 @@ public class Canvas extends BaseCanvas {
this.nativeInt = nativeInt;
}
- /**
- * @hide
- */
- public final int nativeInt;
+ /*package*/ final int nativeInt;
}
/**
@@ -1426,9 +1380,10 @@ public class Canvas extends BaseCanvas {
nFreeTextLayoutCaches();
}
- /** @hide */
- public static void setCompatibilityVersion(int apiLevel) {
+ /*package*/ static void setCompatibilityVersion(int apiLevel) {
sCompatiblityVersion = apiLevel;
+ sCompatibilityRestore = apiLevel < Build.VERSION_CODES.M;
+ sCompatibilitySetBitmap = apiLevel < Build.VERSION_CODES.O;
nSetCompatibilityVersion(apiLevel);
}
@@ -1874,24 +1829,22 @@ public class Canvas extends BaseCanvas {
}
/**
- * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
+ * Draws the specified bitmap as an N-patch (most often, a 9-patch.)
*
* @param patch The ninepatch object to render
* @param dst The destination rectangle.
* @param paint The paint to draw the bitmap with. may be null
- * @hide
*/
public void drawPatch(@NonNull NinePatch patch, @NonNull Rect dst, @Nullable Paint paint) {
super.drawPatch(patch, dst, paint);
}
/**
- * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
+ * Draws the specified bitmap as an N-patch (most often, a 9-patch.)
*
* @param patch The ninepatch object to render
* @param dst The destination rectangle.
* @param paint The paint to draw the bitmap with. may be null
- * @hide
*/
public void drawPatch(@NonNull NinePatch patch, @NonNull RectF dst, @Nullable Paint paint) {
super.drawPatch(patch, dst, paint);
diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java
index c4bf9d3123bf..87a805379b56 100644
--- a/graphics/java/android/graphics/Color.java
+++ b/graphics/java/android/graphics/Color.java
@@ -26,7 +26,6 @@ import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.SuppressAutoDoc;
import android.util.Half;
-import com.android.internal.util.XmlUtils;
import java.util.Arrays;
import java.util.HashMap;
@@ -1476,29 +1475,6 @@ public class Color {
private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]);
private static native int nativeHSVToColor(int alpha, float hsv[]);
- /**
- * Converts an HTML color (named or numeric) to an integer RGB value.
- *
- * @param color Non-null color string.
- *
- * @return A color value, or {@code -1} if the color string could not be interpreted.
- *
- * @hide
- */
- @ColorInt
- public static int getHtmlColor(@NonNull String color) {
- Integer i = sColorNameMap.get(color.toLowerCase(Locale.ROOT));
- if (i != null) {
- return i;
- } else {
- try {
- return XmlUtils.convertValueToInt(color, -1);
- } catch (NumberFormatException nfe) {
- return -1;
- }
- }
- }
-
private static final HashMap<String, Integer> sColorNameMap;
static {
sColorNameMap = new HashMap<>();
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
deleted file mode 100644
index 6299b2c47ea1..000000000000
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.util.Arrays;
-
-/**
- * 4x5 matrix for transforming the color and alpha components of a Bitmap.
- * The matrix can be passed as single array, and is treated as follows:
- *
- * <pre>
- * [ a, b, c, d, e,
- * f, g, h, i, j,
- * k, l, m, n, o,
- * p, q, r, s, t ]</pre>
- *
- * <p>
- * When applied to a color <code>[R, G, B, A]</code>, the resulting color
- * is computed as:
- * </p>
- *
- * <pre>
- * R&rsquo; = a*R + b*G + c*B + d*A + e;
- * G&rsquo; = f*R + g*G + h*B + i*A + j;
- * B&rsquo; = k*R + l*G + m*B + n*A + o;
- * A&rsquo; = p*R + q*G + r*B + s*A + t;</pre>
- *
- * <p>
- * That resulting color <code>[R&rsquo;, G&rsquo;, B&rsquo;, A&rsquo;]</code>
- * then has each channel clamped to the <code>0</code> to <code>255</code>
- * range.
- * </p>
- *
- * <p>
- * The sample ColorMatrix below inverts incoming colors by scaling each
- * channel by <code>-1</code>, and then shifting the result up by
- * <code>255</code> to remain in the standard color space.
- * </p>
- *
- * <pre>
- * [ -1, 0, 0, 0, 255,
- * 0, -1, 0, 0, 255,
- * 0, 0, -1, 0, 255,
- * 0, 0, 0, 1, 0 ]</pre>
- */
-@SuppressWarnings({ "MismatchedReadAndWriteOfArray", "PointlessArithmeticExpression" })
-public class ColorMatrix {
- private final float[] mArray = new float[20];
-
- /**
- * Create a new colormatrix initialized to identity (as if reset() had
- * been called).
- */
- public ColorMatrix() {
- reset();
- }
-
- /**
- * Create a new colormatrix initialized with the specified array of values.
- */
- public ColorMatrix(float[] src) {
- System.arraycopy(src, 0, mArray, 0, 20);
- }
-
- /**
- * Create a new colormatrix initialized with the specified colormatrix.
- */
- public ColorMatrix(ColorMatrix src) {
- System.arraycopy(src.mArray, 0, mArray, 0, 20);
- }
-
- /**
- * Return the array of floats representing this colormatrix.
- */
- public final float[] getArray() { return mArray; }
-
- /**
- * Set this colormatrix to identity:
- * <pre>
- * [ 1 0 0 0 0 - red vector
- * 0 1 0 0 0 - green vector
- * 0 0 1 0 0 - blue vector
- * 0 0 0 1 0 ] - alpha vector
- * </pre>
- */
- public void reset() {
- final float[] a = mArray;
- Arrays.fill(a, 0);
- a[0] = a[6] = a[12] = a[18] = 1;
- }
-
- /**
- * Assign the src colormatrix into this matrix, copying all of its values.
- */
- public void set(ColorMatrix src) {
- System.arraycopy(src.mArray, 0, mArray, 0, 20);
- }
-
- /**
- * Assign the array of floats into this matrix, copying all of its values.
- */
- public void set(float[] src) {
- System.arraycopy(src, 0, mArray, 0, 20);
- }
-
- /**
- * Set this colormatrix to scale by the specified values.
- */
- public void setScale(float rScale, float gScale, float bScale,
- float aScale) {
- final float[] a = mArray;
-
- for (int i = 19; i > 0; --i) {
- a[i] = 0;
- }
- a[0] = rScale;
- a[6] = gScale;
- a[12] = bScale;
- a[18] = aScale;
- }
-
- /**
- * Set the rotation on a color axis by the specified values.
- * <p>
- * <code>axis=0</code> correspond to a rotation around the RED color
- * <code>axis=1</code> correspond to a rotation around the GREEN color
- * <code>axis=2</code> correspond to a rotation around the BLUE color
- * </p>
- */
- public void setRotate(int axis, float degrees) {
- reset();
- double radians = degrees * Math.PI / 180d;
- float cosine = (float) Math.cos(radians);
- float sine = (float) Math.sin(radians);
- switch (axis) {
- // Rotation around the red color
- case 0:
- mArray[6] = mArray[12] = cosine;
- mArray[7] = sine;
- mArray[11] = -sine;
- break;
- // Rotation around the green color
- case 1:
- mArray[0] = mArray[12] = cosine;
- mArray[2] = -sine;
- mArray[10] = sine;
- break;
- // Rotation around the blue color
- case 2:
- mArray[0] = mArray[6] = cosine;
- mArray[1] = sine;
- mArray[5] = -sine;
- break;
- default:
- throw new RuntimeException();
- }
- }
-
- /**
- * Set this colormatrix to the concatenation of the two specified
- * colormatrices, such that the resulting colormatrix has the same effect
- * as applying matB and then applying matA.
- * <p>
- * It is legal for either matA or matB to be the same colormatrix as this.
- * </p>
- */
- public void setConcat(ColorMatrix matA, ColorMatrix matB) {
- float[] tmp;
- if (matA == this || matB == this) {
- tmp = new float[20];
- } else {
- tmp = mArray;
- }
-
- final float[] a = matA.mArray;
- final float[] b = matB.mArray;
- int index = 0;
- for (int j = 0; j < 20; j += 5) {
- for (int i = 0; i < 4; i++) {
- tmp[index++] = a[j + 0] * b[i + 0] + a[j + 1] * b[i + 5] +
- a[j + 2] * b[i + 10] + a[j + 3] * b[i + 15];
- }
- tmp[index++] = a[j + 0] * b[4] + a[j + 1] * b[9] +
- a[j + 2] * b[14] + a[j + 3] * b[19] +
- a[j + 4];
- }
-
- if (tmp != mArray) {
- System.arraycopy(tmp, 0, mArray, 0, 20);
- }
- }
-
- /**
- * Concat this colormatrix with the specified prematrix.
- * <p>
- * This is logically the same as calling setConcat(this, prematrix);
- * </p>
- */
- public void preConcat(ColorMatrix prematrix) {
- setConcat(this, prematrix);
- }
-
- /**
- * Concat this colormatrix with the specified postmatrix.
- * <p>
- * This is logically the same as calling setConcat(postmatrix, this);
- * </p>
- */
- public void postConcat(ColorMatrix postmatrix) {
- setConcat(postmatrix, this);
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- /**
- * Set the matrix to affect the saturation of colors.
- *
- * @param sat A value of 0 maps the color to gray-scale. 1 is identity.
- */
- public void setSaturation(float sat) {
- reset();
- float[] m = mArray;
-
- final float invSat = 1 - sat;
- final float R = 0.213f * invSat;
- final float G = 0.715f * invSat;
- final float B = 0.072f * invSat;
-
- m[0] = R + sat; m[1] = G; m[2] = B;
- m[5] = R; m[6] = G + sat; m[7] = B;
- m[10] = R; m[11] = G; m[12] = B + sat;
- }
-
- /**
- * Set the matrix to convert RGB to YUV
- */
- public void setRGB2YUV() {
- reset();
- float[] m = mArray;
- // these coefficients match those in libjpeg
- m[0] = 0.299f; m[1] = 0.587f; m[2] = 0.114f;
- m[5] = -0.16874f; m[6] = -0.33126f; m[7] = 0.5f;
- m[10] = 0.5f; m[11] = -0.41869f; m[12] = -0.08131f;
- }
-
- /**
- * Set the matrix to convert from YUV to RGB
- */
- public void setYUV2RGB() {
- reset();
- float[] m = mArray;
- // these coefficients match those in libjpeg
- m[2] = 1.402f;
- m[5] = 1; m[6] = -0.34414f; m[7] = -0.71414f;
- m[10] = 1; m[11] = 1.772f; m[12] = 0;
- }
-
- @Override
- public boolean equals(Object obj) {
- // if (obj == this) return true; -- NaN value would mean matrix != itself
- if (!(obj instanceof ColorMatrix)) {
- return false;
- }
-
- // we don't use Arrays.equals(), since that considers NaN == NaN
- final float[] other = ((ColorMatrix) obj).mArray;
- for (int i = 0; i < 20; i++) {
- if (other[i] != mArray[i]) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 1aeafa391b41..2f978fc1fc2d 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -17,19 +17,15 @@
package android.graphics;
import android.annotation.AnyThread;
-import android.annotation.ColorInt;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.SuppressAutoDoc;
-import android.util.Pair;
import libcore.util.NativeAllocationRegistry;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
import java.util.function.DoubleUnaryOperator;
/**
@@ -872,8 +868,7 @@ public abstract class ColorSpace {
}
}
- /** @hide */
- ColorSpace(
+ /*package*/ ColorSpace(
@NonNull String name,
@NonNull Model model,
@IntRange(from = MIN_ID, to = MAX_ID) int id) {
@@ -1441,22 +1436,6 @@ public abstract class ColorSpace {
return null;
}
- /**
- * <p>Creates a new {@link Renderer} that can be used to visualize and
- * debug color spaces. See the documentation of {@link Renderer} for
- * more information.</p>
- *
- * @return A new non-null {@link Renderer} instance
- *
- * @see Renderer
- *
- * @hide
- */
- @NonNull
- public static Renderer createRenderer() {
- return new Renderer();
- }
-
static {
sNamedColorSpaces[Named.SRGB.ordinal()] = new ColorSpace.Rgb(
"sRGB IEC61966-2.1",
@@ -1701,12 +1680,10 @@ public abstract class ColorSpace {
* @param rhs 3x3 matrix, as a non-null array of 9 floats
* @return A new array of 9 floats containing the result of the multiplication
* of rhs by lhs
- *
- * @hide
*/
@NonNull
@Size(9)
- public static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) {
+ private static float[] mul3x3(@NonNull @Size(9) float[] lhs, @NonNull @Size(9) float[] rhs) {
float[] r = new float[9];
r[0] = lhs[0] * rhs[0] + lhs[3] * rhs[1] + lhs[6] * rhs[2];
r[1] = lhs[1] * rhs[0] + lhs[4] * rhs[1] + lhs[7] * rhs[2];
@@ -1775,28 +1752,6 @@ public abstract class ColorSpace {
}
/**
- * Converts values from CIE xyY to CIE L*u*v*. Y is assumed to be 1 so the
- * input xyY array only contains the x and y components. After this method
- * returns, the xyY array contains the converted u and v components.
- *
- * @param xyY The xyY value to convert to XYZ, cannot be null,
- * length must be a multiple of 2
- */
- private static void xyYToUv(@NonNull @Size(multiple = 2) float[] xyY) {
- for (int i = 0; i < xyY.length; i += 2) {
- float x = xyY[i];
- float y = xyY[i + 1];
-
- float d = -2.0f * x + 12.0f * y + 3;
- float u = (4.0f * x) / d;
- float v = (9.0f * y) / d;
-
- xyY[i] = u;
- xyY[i + 1] = v;
- }
- }
-
- /**
* <p>Computes the chromatic adaptation transform from the specified
* source white point to the specified destination white point.</p>
*
@@ -1834,8 +1789,6 @@ public abstract class ColorSpace {
* @param cct The correlated color temperature, in Kelvin
* @return Corresponding XYZ values
* @throws IllegalArgumentException If cct is invalid
- *
- * @hide
*/
@NonNull
@Size(3)
@@ -1861,38 +1814,6 @@ public abstract class ColorSpace {
}
/**
- * <p>Computes the chromaticity coordinates of a CIE series D illuminant
- * from the specified correlated color temperature (CCT). The specified CCT
- * must be greater than 0. A meaningful CCT range is [4000, 25000].</p>
- *
- * <p>The transform is computed using the methods referred to in Kang et
- * al., <i>Design of Advanced Color - Temperature Control System for HDTV
- * Applications</i>, Journal of Korean Physical Society 41, 865-871
- * (2002).</p>
- *
- * @param cct The correlated color temperature, in Kelvin
- * @return Corresponding XYZ values
- * @throws IllegalArgumentException If cct is invalid
- *
- * @hide
- */
- @NonNull
- @Size(3)
- public static float[] cctToIlluminantdXyz(@IntRange(from = 1) int cct) {
- if (cct < 1) {
- throw new IllegalArgumentException("Temperature must be greater than 0");
- }
-
- final float icct = 1.0f / cct;
- final float icct2 = icct * icct;
- final float x = cct <= 7000.0f ?
- 0.244063f + 0.09911e3f * icct + 2.9678e6f * icct2 - 4.6070e9f * icct2 * icct :
- 0.237040f + 0.24748e3f * icct + 1.9018e6f * icct2 - 2.0064e9f * icct2 * icct;
- final float y = -3.0f * x * x + 2.87f * x - 0.275f;
- return xyYToXyz(new float[] {x, y});
- }
-
- /**
* <p>Computes the chromatic adaptation transform from the specified
* source white point to the specified destination white point.</p>
*
@@ -1905,14 +1826,16 @@ public abstract class ColorSpace {
* @param srcWhitePoint The white point to adapt from
* @param dstWhitePoint The white point to adapt to
* @return A 3x3 matrix as a non-null array of 9 floats
- *
- * @hide
*/
@NonNull
@Size(9)
public static float[] chromaticAdaptation(@NonNull Adaptation adaptation,
@NonNull @Size(min = 2, max = 3) float[] srcWhitePoint,
@NonNull @Size(min = 2, max = 3) float[] dstWhitePoint) {
+ if ((srcWhitePoint.length != 2 && srcWhitePoint.length != 3)
+ || (dstWhitePoint.length != 2 && dstWhitePoint.length != 3)) {
+ throw new IllegalArgumentException("A white point array must have 2 or 3 floats");
+ }
float[] srcXyz = srcWhitePoint.length == 3 ?
Arrays.copyOf(srcWhitePoint, 3) : xyYToXyz(srcWhitePoint);
float[] dstXyz = dstWhitePoint.length == 3 ?
@@ -3925,771 +3848,4 @@ public abstract class ColorSpace {
};
}
}
-
- /**
- * <p>A color space renderer can be used to visualize and compare the gamut and
- * white point of one or more color spaces. The output is an sRGB {@link Bitmap}
- * showing a CIE 1931 xyY or a CIE 1976 UCS chromaticity diagram.</p>
- *
- * <p>The following code snippet shows how to compare the {@link Named#SRGB}
- * and {@link Named#DCI_P3} color spaces in a CIE 1931 diagram:</p>
- *
- * <pre class="prettyprint">
- * Bitmap bitmap = ColorSpace.createRenderer()
- * .size(768)
- * .clip(true)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
- * .render();
- * </pre>
- * <p>
- * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
- * <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
- * </p>
- *
- * <p>A renderer can also be used to show the location of specific colors,
- * associated with a color space, in the CIE 1931 xyY chromaticity diagram.
- * See {@link #add(ColorSpace, float, float, float, int)} for more information.</p>
- *
- * @see ColorSpace#createRenderer()
- *
- * @hide
- */
- public static class Renderer {
- private static final int NATIVE_SIZE = 1440;
- private static final float UCS_SCALE = 9.0f / 6.0f;
-
- // Number of subdivision of the inside of the spectral locus
- private static final int CHROMATICITY_RESOLUTION = 32;
- private static final double ONE_THIRD = 1.0 / 3.0;
-
- @IntRange(from = 128, to = Integer.MAX_VALUE)
- private int mSize = 1024;
-
- private boolean mShowWhitePoint = true;
- private boolean mClip = false;
- private boolean mUcs = false;
-
- private final List<Pair<ColorSpace, Integer>> mColorSpaces = new ArrayList<>(2);
- private final List<Point> mPoints = new ArrayList<>(0);
-
- private Renderer() {
- }
-
- /**
- * <p>Defines whether the chromaticity diagram should be clipped by the first
- * registered color space. The default value is false.</p>
- *
- * <p>The following code snippet and image show the default behavior:</p>
- * <pre class="prettyprint">
- * Bitmap bitmap = ColorSpace.createRenderer()
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
- * .render();
- * </pre>
- * <p>
- * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
- * <figcaption style="text-align: center;">Clipping disabled</figcaption>
- * </p>
- *
- * <p>Here is the same example with clipping enabled:</p>
- * <pre class="prettyprint">
- * Bitmap bitmap = ColorSpace.createRenderer()
- * .clip(true)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
- * .render();
- * </pre>
- * <p>
- * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
- * <figcaption style="text-align: center;">Clipping enabled</figcaption>
- * </p>
- *
- * @param clip True to clip the chromaticity diagram to the first registered color space,
- * false otherwise
- * @return This instance of {@link Renderer}
- */
- @NonNull
- public Renderer clip(boolean clip) {
- mClip = clip;
- return this;
- }
-
- /**
- * <p>Defines whether the chromaticity diagram should use the uniform
- * chromaticity scale (CIE 1976 UCS). When the uniform chromaticity scale
- * is used, the distance between two points on the diagram is approximately
- * proportional to the perceived color difference.</p>
- *
- * <p>The following code snippet shows how to enable the uniform chromaticity
- * scale. The image below shows the result:</p>
- * <pre class="prettyprint">
- * Bitmap bitmap = ColorSpace.createRenderer()
- * .uniformChromaticityScale(true)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
- * .render();
- * </pre>
- * <p>
- * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_ucs.png" />
- * <figcaption style="text-align: center;">CIE 1976 UCS diagram</figcaption>
- * </p>
- *
- * @param ucs True to render the chromaticity diagram as the CIE 1976 UCS diagram
- * @return This instance of {@link Renderer}
- */
- @NonNull
- public Renderer uniformChromaticityScale(boolean ucs) {
- mUcs = ucs;
- return this;
- }
-
- /**
- * Sets the dimensions (width and height) in pixels of the output bitmap.
- * The size must be at least 128px and defaults to 1024px.
- *
- * @param size The size in pixels of the output bitmap
- * @return This instance of {@link Renderer}
- */
- @NonNull
- public Renderer size(@IntRange(from = 128, to = Integer.MAX_VALUE) int size) {
- mSize = Math.max(128, size);
- return this;
- }
-
- /**
- * Shows or hides the white point of each color space in the output bitmap.
- * The default is true.
- *
- * @param show True to show the white point of each color space, false
- * otherwise
- * @return This instance of {@link Renderer}
- */
- @NonNull
- public Renderer showWhitePoint(boolean show) {
- mShowWhitePoint = show;
- return this;
- }
-
- /**
- * <p>Adds a color space to represent on the output CIE 1931 chromaticity
- * diagram. The color space is represented as a triangle showing the
- * footprint of its color gamut and, optionally, the location of its
- * white point.</p>
- *
- * <p class="note">Color spaces with a color model that is not RGB are
- * accepted but ignored.</p>
- *
- * <p>The following code snippet and image show an example of calling this
- * method to compare {@link Named#SRGB sRGB} and {@link Named#DCI_P3 DCI-P3}:</p>
- * <pre class="prettyprint">
- * Bitmap bitmap = ColorSpace.createRenderer()
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
- * .render();
- * </pre>
- * <p>
- * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
- * <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
- * </p>
- *
- * <p>Adding a color space extending beyond the boundaries of the
- * spectral locus will alter the size of the diagram within the output
- * bitmap as shown in this example:</p>
- * <pre class="prettyprint">
- * Bitmap bitmap = ColorSpace.createRenderer()
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
- * .add(ColorSpace.get(ColorSpace.Named.ACES), 0xff097ae9)
- * .add(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB), 0xff000000)
- * .render();
- * </pre>
- * <p>
- * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
- * <figcaption style="text-align: center;">sRGB, DCI-P3, ACES and scRGB</figcaption>
- * </p>
- *
- * @param colorSpace The color space whose gamut to render on the diagram
- * @param color The sRGB color to use to render the color space's gamut and white point
- * @return This instance of {@link Renderer}
- *
- * @see #clip(boolean)
- * @see #showWhitePoint(boolean)
- */
- @NonNull
- public Renderer add(@NonNull ColorSpace colorSpace, @ColorInt int color) {
- mColorSpaces.add(new Pair<>(colorSpace, color));
- return this;
- }
-
- /**
- * <p>Adds a color to represent as a point on the chromaticity diagram.
- * The color is associated with a color space which will be used to
- * perform the conversion to CIE XYZ and compute the location of the point
- * on the diagram. The point is rendered as a colored circle.</p>
- *
- * <p>The following code snippet and image show an example of calling this
- * method to render the location of several sRGB colors as white circles:</p>
- * <pre class="prettyprint">
- * Bitmap bitmap = ColorSpace.createRenderer()
- * .clip(true)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.0f, 0.1f, 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.1f, 0.1f, 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.2f, 0.1f, 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.3f, 0.1f, 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.4f, 0.1f, 0xffffffff)
- * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.5f, 0.1f, 0xffffffff)
- * .render();
- * </pre>
- * <p>
- * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_points.png" />
- * <figcaption style="text-align: center;">
- * Locating colors on the chromaticity diagram
- * </figcaption>
- * </p>
- *
- * @param colorSpace The color space of the color to locate on the diagram
- * @param r The first component of the color to locate on the diagram
- * @param g The second component of the color to locate on the diagram
- * @param b The third component of the color to locate on the diagram
- * @param pointColor The sRGB color to use to render the point on the diagram
- * @return This instance of {@link Renderer}
- */
- @NonNull
- public Renderer add(@NonNull ColorSpace colorSpace, float r, float g, float b,
- @ColorInt int pointColor) {
- mPoints.add(new Point(colorSpace, new float[] { r, g, b }, pointColor));
- return this;
- }
-
- /**
- * <p>Renders the {@link #add(ColorSpace, int) color spaces} and
- * {@link #add(ColorSpace, float, float, float, int) points} registered
- * with this renderer. The output bitmap is an sRGB image with the
- * dimensions specified by calling {@link #size(int)} (1204x1024px by
- * default).</p>
- *
- * @return A new non-null {@link Bitmap} with the dimensions specified
- * by {@link #size(int)} (1024x1024 by default)
- */
- @NonNull
- public Bitmap render() {
- Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
- Bitmap bitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
-
- float[] primaries = new float[6];
- float[] whitePoint = new float[2];
-
- int width = NATIVE_SIZE;
- int height = NATIVE_SIZE;
-
- Path path = new Path();
-
- setTransform(canvas, width, height, primaries);
- drawBox(canvas, width, height, paint, path);
- setUcsTransform(canvas, height);
- drawLocus(canvas, width, height, paint, path, primaries);
- drawGamuts(canvas, width, height, paint, path, primaries, whitePoint);
- drawPoints(canvas, width, height, paint);
-
- return bitmap;
- }
-
- /**
- * Draws registered points at their correct position in the xyY coordinates.
- * Each point is positioned according to its associated color space.
- *
- * @param canvas The canvas to transform
- * @param width Width in pixel of the final image
- * @param height Height in pixel of the final image
- * @param paint A pre-allocated paint used to avoid temporary allocations
- */
- private void drawPoints(@NonNull Canvas canvas, int width, int height,
- @NonNull Paint paint) {
-
- paint.setStyle(Paint.Style.FILL);
-
- float radius = 4.0f / (mUcs ? UCS_SCALE : 1.0f);
-
- float[] v = new float[3];
- float[] xy = new float[2];
-
- for (final Point point : mPoints) {
- v[0] = point.mRgb[0];
- v[1] = point.mRgb[1];
- v[2] = point.mRgb[2];
- point.mColorSpace.toXyz(v);
-
- paint.setColor(point.mColor);
-
- // XYZ to xyY, assuming Y=1.0, then to L*u*v* if needed
- float sum = v[0] + v[1] + v[2];
- xy[0] = v[0] / sum;
- xy[1] = v[1] / sum;
- if (mUcs) xyYToUv(xy);
-
- canvas.drawCircle(width * xy[0], height - height * xy[1], radius, paint);
- }
- }
-
- /**
- * Draws the color gamuts and white points of all the registered color
- * spaces. Only color spaces with an RGB color model are rendered, the
- * others are ignored.
- *
- * @param canvas The canvas to transform
- * @param width Width in pixel of the final image
- * @param height Height in pixel of the final image
- * @param paint A pre-allocated paint used to avoid temporary allocations
- * @param path A pre-allocated path used to avoid temporary allocations
- * @param primaries A pre-allocated array of 6 floats to avoid temporary allocations
- * @param whitePoint A pre-allocated array of 2 floats to avoid temporary allocations
- */
- private void drawGamuts(
- @NonNull Canvas canvas, int width, int height,
- @NonNull Paint paint, @NonNull Path path,
- @NonNull @Size(6) float[] primaries, @NonNull @Size(2) float[] whitePoint) {
-
- float radius = 4.0f / (mUcs ? UCS_SCALE : 1.0f);
-
- for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
- ColorSpace colorSpace = item.first;
- int color = item.second;
-
- if (colorSpace.getModel() != Model.RGB) continue;
-
- Rgb rgb = (Rgb) colorSpace;
- getPrimaries(rgb, primaries, mUcs);
-
- path.rewind();
- path.moveTo(width * primaries[0], height - height * primaries[1]);
- path.lineTo(width * primaries[2], height - height * primaries[3]);
- path.lineTo(width * primaries[4], height - height * primaries[5]);
- path.close();
-
- paint.setStyle(Paint.Style.STROKE);
- paint.setColor(color);
- canvas.drawPath(path, paint);
-
- // Draw the white point
- if (mShowWhitePoint) {
- rgb.getWhitePoint(whitePoint);
- if (mUcs) xyYToUv(whitePoint);
-
- paint.setStyle(Paint.Style.FILL);
- paint.setColor(color);
- canvas.drawCircle(
- width * whitePoint[0], height - height * whitePoint[1], radius, paint);
- }
- }
- }
-
- /**
- * Returns the primaries of the specified RGB color space. This method handles
- * the special case of the {@link Named#EXTENDED_SRGB} family of color spaces.
- *
- * @param rgb The color space whose primaries to extract
- * @param primaries A pre-allocated array of 6 floats that will hold the result
- * @param asUcs True if the primaries should be returned in Luv, false for xyY
- */
- @NonNull
- @Size(6)
- private static void getPrimaries(@NonNull Rgb rgb,
- @NonNull @Size(6) float[] primaries, boolean asUcs) {
- // TODO: We should find a better way to handle these cases
- if (rgb.equals(ColorSpace.get(Named.EXTENDED_SRGB)) ||
- rgb.equals(ColorSpace.get(Named.LINEAR_EXTENDED_SRGB))) {
- primaries[0] = 1.41f;
- primaries[1] = 0.33f;
- primaries[2] = 0.27f;
- primaries[3] = 1.24f;
- primaries[4] = -0.23f;
- primaries[5] = -0.57f;
- } else {
- rgb.getPrimaries(primaries);
- }
- if (asUcs) xyYToUv(primaries);
- }
-
- /**
- * Draws the CIE 1931 chromaticity diagram: the spectral locus and its inside.
- * This method respect the clip parameter.
- *
- * @param canvas The canvas to transform
- * @param width Width in pixel of the final image
- * @param height Height in pixel of the final image
- * @param paint A pre-allocated paint used to avoid temporary allocations
- * @param path A pre-allocated path used to avoid temporary allocations
- * @param primaries A pre-allocated array of 6 floats to avoid temporary allocations
- */
- private void drawLocus(
- @NonNull Canvas canvas, int width, int height, @NonNull Paint paint,
- @NonNull Path path, @NonNull @Size(6) float[] primaries) {
-
- int vertexCount = SPECTRUM_LOCUS_X.length * CHROMATICITY_RESOLUTION * 6;
- float[] vertices = new float[vertexCount * 2];
- int[] colors = new int[vertices.length];
- computeChromaticityMesh(vertices, colors);
-
- if (mUcs) xyYToUv(vertices);
- for (int i = 0; i < vertices.length; i += 2) {
- vertices[i] *= width;
- vertices[i + 1] = height - vertices[i + 1] * height;
- }
-
- // Draw the spectral locus
- if (mClip && mColorSpaces.size() > 0) {
- for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
- ColorSpace colorSpace = item.first;
- if (colorSpace.getModel() != Model.RGB) continue;
-
- Rgb rgb = (Rgb) colorSpace;
- getPrimaries(rgb, primaries, mUcs);
-
- break;
- }
-
- path.rewind();
- path.moveTo(width * primaries[0], height - height * primaries[1]);
- path.lineTo(width * primaries[2], height - height * primaries[3]);
- path.lineTo(width * primaries[4], height - height * primaries[5]);
- path.close();
-
- int[] solid = new int[colors.length];
- Arrays.fill(solid, 0xff6c6c6c);
- canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
- null, 0, solid, 0, null, 0, 0, paint);
-
- canvas.save();
- canvas.clipPath(path);
-
- canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
- null, 0, colors, 0, null, 0, 0, paint);
-
- canvas.restore();
- } else {
- canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
- null, 0, colors, 0, null, 0, 0, paint);
- }
-
- // Draw the non-spectral locus
- int index = (CHROMATICITY_RESOLUTION - 1) * 12;
- path.reset();
- path.moveTo(vertices[index], vertices[index + 1]);
- for (int x = 2; x < SPECTRUM_LOCUS_X.length; x++) {
- index += CHROMATICITY_RESOLUTION * 12;
- path.lineTo(vertices[index], vertices[index + 1]);
- }
- path.close();
-
- paint.setStrokeWidth(4.0f / (mUcs ? UCS_SCALE : 1.0f));
- paint.setStyle(Paint.Style.STROKE);
- paint.setColor(0xff000000);
- canvas.drawPath(path, paint);
- }
-
- /**
- * Draws the diagram box, including borders, tick marks, grid lines
- * and axis labels.
- *
- * @param canvas The canvas to transform
- * @param width Width in pixel of the final image
- * @param height Height in pixel of the final image
- * @param paint A pre-allocated paint used to avoid temporary allocations
- * @param path A pre-allocated path used to avoid temporary allocations
- */
- private void drawBox(@NonNull Canvas canvas, int width, int height, @NonNull Paint paint,
- @NonNull Path path) {
-
- int lineCount = 10;
- float scale = 1.0f;
- if (mUcs) {
- lineCount = 7;
- scale = UCS_SCALE;
- }
-
- // Draw the unit grid
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(2.0f);
- paint.setColor(0xffc0c0c0);
-
- for (int i = 1; i < lineCount - 1; i++) {
- float v = i / 10.0f;
- float x = (width * v) * scale;
- float y = height - (height * v) * scale;
-
- canvas.drawLine(0.0f, y, 0.9f * width, y, paint);
- canvas.drawLine(x, height, x, 0.1f * height, paint);
- }
-
- // Draw tick marks
- paint.setStrokeWidth(4.0f);
- paint.setColor(0xff000000);
- for (int i = 1; i < lineCount - 1; i++) {
- float v = i / 10.0f;
- float x = (width * v) * scale;
- float y = height - (height * v) * scale;
-
- canvas.drawLine(0.0f, y, width / 100.0f, y, paint);
- canvas.drawLine(x, height, x, height - (height / 100.0f), paint);
- }
-
- // Draw the axis labels
- paint.setStyle(Paint.Style.FILL);
- paint.setTextSize(36.0f);
- paint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
-
- Rect bounds = new Rect();
- for (int i = 1; i < lineCount - 1; i++) {
- String text = "0." + i;
- paint.getTextBounds(text, 0, text.length(), bounds);
-
- float v = i / 10.0f;
- float x = (width * v) * scale;
- float y = height - (height * v) * scale;
-
- canvas.drawText(text, -0.05f * width + 10, y + bounds.height() / 2.0f, paint);
- canvas.drawText(text, x - bounds.width() / 2.0f,
- height + bounds.height() + 16, paint);
- }
- paint.setStyle(Paint.Style.STROKE);
-
- // Draw the diagram box
- path.moveTo(0.0f, height);
- path.lineTo(0.9f * width, height);
- path.lineTo(0.9f * width, 0.1f * height);
- path.lineTo(0.0f, 0.1f * height);
- path.close();
- canvas.drawPath(path, paint);
- }
-
- /**
- * Computes and applies the Canvas transforms required to make the color
- * gamut of each color space visible in the final image.
- *
- * @param canvas The canvas to transform
- * @param width Width in pixel of the final image
- * @param height Height in pixel of the final image
- * @param primaries Array of 6 floats used to avoid temporary allocations
- */
- private void setTransform(@NonNull Canvas canvas, int width, int height,
- @NonNull @Size(6) float[] primaries) {
-
- RectF primariesBounds = new RectF();
- for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
- ColorSpace colorSpace = item.first;
- if (colorSpace.getModel() != Model.RGB) continue;
-
- Rgb rgb = (Rgb) colorSpace;
- getPrimaries(rgb, primaries, mUcs);
-
- primariesBounds.left = Math.min(primariesBounds.left, primaries[4]);
- primariesBounds.top = Math.min(primariesBounds.top, primaries[5]);
- primariesBounds.right = Math.max(primariesBounds.right, primaries[0]);
- primariesBounds.bottom = Math.max(primariesBounds.bottom, primaries[3]);
- }
-
- float max = mUcs ? 0.6f : 0.9f;
-
- primariesBounds.left = Math.min(0.0f, primariesBounds.left);
- primariesBounds.top = Math.min(0.0f, primariesBounds.top);
- primariesBounds.right = Math.max(max, primariesBounds.right);
- primariesBounds.bottom = Math.max(max, primariesBounds.bottom);
-
- float scaleX = max / primariesBounds.width();
- float scaleY = max / primariesBounds.height();
- float scale = Math.min(scaleX, scaleY);
-
- canvas.scale(mSize / (float) NATIVE_SIZE, mSize / (float) NATIVE_SIZE);
- canvas.scale(scale, scale);
- canvas.translate(
- (primariesBounds.width() - max) * width / 2.0f,
- (primariesBounds.height() - max) * height / 2.0f);
-
- // The spectrum extends ~0.85 vertically and ~0.65 horizontally
- // We shift the canvas a little bit to get nicer margins
- canvas.translate(0.05f * width, -0.05f * height);
- }
-
- /**
- * Computes and applies the Canvas transforms required to render the CIE
- * 197 UCS chromaticity diagram.
- *
- * @param canvas The canvas to transform
- * @param height Height in pixel of the final image
- */
- private void setUcsTransform(@NonNull Canvas canvas, int height) {
- if (mUcs) {
- canvas.translate(0.0f, (height - height * UCS_SCALE));
- canvas.scale(UCS_SCALE, UCS_SCALE);
- }
- }
-
- // X coordinates of the spectral locus in CIE 1931
- private static final float[] SPECTRUM_LOCUS_X = {
- 0.175596f, 0.172787f, 0.170806f, 0.170085f, 0.160343f,
- 0.146958f, 0.139149f, 0.133536f, 0.126688f, 0.115830f,
- 0.109616f, 0.099146f, 0.091310f, 0.078130f, 0.068717f,
- 0.054675f, 0.040763f, 0.027497f, 0.016270f, 0.008169f,
- 0.004876f, 0.003983f, 0.003859f, 0.004646f, 0.007988f,
- 0.013870f, 0.022244f, 0.027273f, 0.032820f, 0.038851f,
- 0.045327f, 0.052175f, 0.059323f, 0.066713f, 0.074299f,
- 0.089937f, 0.114155f, 0.138695f, 0.154714f, 0.192865f,
- 0.229607f, 0.265760f, 0.301588f, 0.337346f, 0.373083f,
- 0.408717f, 0.444043f, 0.478755f, 0.512467f, 0.544767f,
- 0.575132f, 0.602914f, 0.627018f, 0.648215f, 0.665746f,
- 0.680061f, 0.691487f, 0.700589f, 0.707901f, 0.714015f,
- 0.719017f, 0.723016f, 0.734674f, 0.717203f, 0.699732f,
- 0.682260f, 0.664789f, 0.647318f, 0.629847f, 0.612376f,
- 0.594905f, 0.577433f, 0.559962f, 0.542491f, 0.525020f,
- 0.507549f, 0.490077f, 0.472606f, 0.455135f, 0.437664f,
- 0.420193f, 0.402721f, 0.385250f, 0.367779f, 0.350308f,
- 0.332837f, 0.315366f, 0.297894f, 0.280423f, 0.262952f,
- 0.245481f, 0.228010f, 0.210538f, 0.193067f, 0.175596f
- };
- // Y coordinates of the spectral locus in CIE 1931
- private static final float[] SPECTRUM_LOCUS_Y = {
- 0.005295f, 0.004800f, 0.005472f, 0.005976f, 0.014496f,
- 0.026643f, 0.035211f, 0.042704f, 0.053441f, 0.073601f,
- 0.086866f, 0.112037f, 0.132737f, 0.170464f, 0.200773f,
- 0.254155f, 0.317049f, 0.387997f, 0.463035f, 0.538504f,
- 0.587196f, 0.610526f, 0.654897f, 0.675970f, 0.715407f,
- 0.750246f, 0.779682f, 0.792153f, 0.802971f, 0.812059f,
- 0.819430f, 0.825200f, 0.829460f, 0.832306f, 0.833833f,
- 0.833316f, 0.826231f, 0.814796f, 0.805884f, 0.781648f,
- 0.754347f, 0.724342f, 0.692326f, 0.658867f, 0.624470f,
- 0.589626f, 0.554734f, 0.520222f, 0.486611f, 0.454454f,
- 0.424252f, 0.396516f, 0.372510f, 0.351413f, 0.334028f,
- 0.319765f, 0.308359f, 0.299317f, 0.292044f, 0.285945f,
- 0.280951f, 0.276964f, 0.265326f, 0.257200f, 0.249074f,
- 0.240948f, 0.232822f, 0.224696f, 0.216570f, 0.208444f,
- 0.200318f, 0.192192f, 0.184066f, 0.175940f, 0.167814f,
- 0.159688f, 0.151562f, 0.143436f, 0.135311f, 0.127185f,
- 0.119059f, 0.110933f, 0.102807f, 0.094681f, 0.086555f,
- 0.078429f, 0.070303f, 0.062177f, 0.054051f, 0.045925f,
- 0.037799f, 0.029673f, 0.021547f, 0.013421f, 0.005295f
- };
-
- /**
- * Computes a 2D mesh representation of the CIE 1931 chromaticity
- * diagram.
- *
- * @param vertices Array of floats that will hold the mesh vertices
- * @param colors Array of floats that will hold the mesh colors
- */
- private static void computeChromaticityMesh(@NonNull float[] vertices,
- @NonNull int[] colors) {
-
- ColorSpace colorSpace = get(Named.SRGB);
-
- float[] color = new float[3];
-
- int vertexIndex = 0;
- int colorIndex = 0;
-
- for (int x = 0; x < SPECTRUM_LOCUS_X.length; x++) {
- int nextX = (x % (SPECTRUM_LOCUS_X.length - 1)) + 1;
-
- float a1 = (float) Math.atan2(
- SPECTRUM_LOCUS_Y[x] - ONE_THIRD,
- SPECTRUM_LOCUS_X[x] - ONE_THIRD);
- float a2 = (float) Math.atan2(
- SPECTRUM_LOCUS_Y[nextX] - ONE_THIRD,
- SPECTRUM_LOCUS_X[nextX] - ONE_THIRD);
-
- float radius1 = (float) Math.pow(
- sqr(SPECTRUM_LOCUS_X[x] - ONE_THIRD) +
- sqr(SPECTRUM_LOCUS_Y[x] - ONE_THIRD),
- 0.5);
- float radius2 = (float) Math.pow(
- sqr(SPECTRUM_LOCUS_X[nextX] - ONE_THIRD) +
- sqr(SPECTRUM_LOCUS_Y[nextX] - ONE_THIRD),
- 0.5);
-
- // Compute patches; each patch is a quad with a different
- // color associated with each vertex
- for (int c = 1; c <= CHROMATICITY_RESOLUTION; c++) {
- float f1 = c / (float) CHROMATICITY_RESOLUTION;
- float f2 = (c - 1) / (float) CHROMATICITY_RESOLUTION;
-
- double cr1 = radius1 * Math.cos(a1);
- double sr1 = radius1 * Math.sin(a1);
- double cr2 = radius2 * Math.cos(a2);
- double sr2 = radius2 * Math.sin(a2);
-
- // Compute the XYZ coordinates of the 4 vertices of the patch
- float v1x = (float) (ONE_THIRD + cr1 * f1);
- float v1y = (float) (ONE_THIRD + sr1 * f1);
- float v1z = 1 - v1x - v1y;
-
- float v2x = (float) (ONE_THIRD + cr1 * f2);
- float v2y = (float) (ONE_THIRD + sr1 * f2);
- float v2z = 1 - v2x - v2y;
-
- float v3x = (float) (ONE_THIRD + cr2 * f2);
- float v3y = (float) (ONE_THIRD + sr2 * f2);
- float v3z = 1 - v3x - v3y;
-
- float v4x = (float) (ONE_THIRD + cr2 * f1);
- float v4y = (float) (ONE_THIRD + sr2 * f1);
- float v4z = 1 - v4x - v4y;
-
- // Compute the sRGB representation of each XYZ coordinate of the patch
- colors[colorIndex ] = computeColor(color, v1x, v1y, v1z, colorSpace);
- colors[colorIndex + 1] = computeColor(color, v2x, v2y, v2z, colorSpace);
- colors[colorIndex + 2] = computeColor(color, v3x, v3y, v3z, colorSpace);
- colors[colorIndex + 3] = colors[colorIndex];
- colors[colorIndex + 4] = colors[colorIndex + 2];
- colors[colorIndex + 5] = computeColor(color, v4x, v4y, v4z, colorSpace);
- colorIndex += 6;
-
- // Flip the mesh upside down to match Canvas' coordinates system
- vertices[vertexIndex++] = v1x;
- vertices[vertexIndex++] = v1y;
- vertices[vertexIndex++] = v2x;
- vertices[vertexIndex++] = v2y;
- vertices[vertexIndex++] = v3x;
- vertices[vertexIndex++] = v3y;
- vertices[vertexIndex++] = v1x;
- vertices[vertexIndex++] = v1y;
- vertices[vertexIndex++] = v3x;
- vertices[vertexIndex++] = v3y;
- vertices[vertexIndex++] = v4x;
- vertices[vertexIndex++] = v4y;
- }
- }
- }
-
- @ColorInt
- private static int computeColor(@NonNull @Size(3) float[] color,
- float x, float y, float z, @NonNull ColorSpace cs) {
- color[0] = x;
- color[1] = y;
- color[2] = z;
- cs.fromXyz(color);
- return 0xff000000 |
- (((int) (color[0] * 255.0f) & 0xff) << 16) |
- (((int) (color[1] * 255.0f) & 0xff) << 8) |
- (((int) (color[2] * 255.0f) & 0xff) );
- }
-
- private static double sqr(double v) {
- return v * v;
- }
-
- private static class Point {
- @NonNull final ColorSpace mColorSpace;
- @NonNull final float[] mRgb;
- final int mColor;
-
- Point(@NonNull ColorSpace colorSpace,
- @NonNull @Size(3) float[] rgb, @ColorInt int color) {
- mColorSpace = colorSpace;
- mRgb = rgb;
- mColor = color;
- }
- }
- }
}
diff --git a/graphics/java/android/graphics/Compatibility.java b/graphics/java/android/graphics/Compatibility.java
new file mode 100644
index 000000000000..ed849127aedc
--- /dev/null
+++ b/graphics/java/android/graphics/Compatibility.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import android.annotation.SystemApi;
+
+/**
+ * Helper class for graphics classes to retrieve the targetSdkVersion, as
+ * specified by the app.
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class Compatibility {
+ private Compatibility() {}
+
+ private static int sTargetSdkVersion = 0;
+
+ /**
+ * Exposed so that ActivityThread can set it correctly once when binding the
+ * application. No other code should call this.
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static void setTargetSdkVersion(int targetSdkVersion) {
+ sTargetSdkVersion = targetSdkVersion;
+ Canvas.setCompatibilityVersion(targetSdkVersion);
+ }
+
+ /**
+ * Public for access by other packages in the module (like android.graphics.drawable),
+ * but should not be accessed outside the module.
+ * @hide
+ */
+ public static int getTargetSdkVersion() {
+ return sTargetSdkVersion;
+ }
+}
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 64ee6bf1f30c..279e2937a80a 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -84,8 +84,9 @@ public class ComposeShader extends Shader {
mPorterDuffMode = nativeMode;
}
+ /** @hide */
@Override
- long createNativeInstance(long nativeMatrix) {
+ protected long createNativeInstance(long nativeMatrix) {
mNativeInstanceShaderA = mShaderA.getNativeInstance();
mNativeInstanceShaderB = mShaderB.getNativeInstance();
return nativeCreate(nativeMatrix,
diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java
index 0430847857b6..2c25f4546771 100644
--- a/graphics/java/android/graphics/GraphicBuffer.java
+++ b/graphics/java/android/graphics/GraphicBuffer.java
@@ -97,20 +97,6 @@ public class GraphicBuffer implements Parcelable {
}
/**
- * For SurfaceControl JNI.
- * @hide
- */
- @UnsupportedAppUsage
- public static GraphicBuffer createFromExisting(int width, int height,
- int format, int usage, long unwrappedNativeObject) {
- long nativeObject = nWrapGraphicBuffer(unwrappedNativeObject);
- if (nativeObject != 0) {
- return new GraphicBuffer(width, height, format, usage, nativeObject);
- }
- return null;
- }
-
- /**
* For Bitmap until all usages are updated to AHB
* @hide
*/
@@ -313,6 +299,5 @@ public class GraphicBuffer implements Parcelable {
private static native long nReadGraphicBufferFromParcel(Parcel in);
private static native boolean nLockCanvas(long nativeObject, Canvas canvas, Rect dirty);
private static native boolean nUnlockCanvasAndPost(long nativeObject, Canvas canvas);
- private static native long nWrapGraphicBuffer(long nativeObject);
private static native GraphicBuffer nCreateFromHardwareBuffer(HardwareBuffer buffer);
}
diff --git a/graphics/java/android/graphics/GraphicsProtos.java b/graphics/java/android/graphics/GraphicsProtos.java
new file mode 100644
index 000000000000..6bc41d39ff98
--- /dev/null
+++ b/graphics/java/android/graphics/GraphicsProtos.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import android.annotation.NonNull;
+import android.util.proto.ProtoOutputStream;
+
+/**
+ * Utility class for creating protos from parcelable Graphics classes.
+ *
+ * @hide
+ */
+public final class GraphicsProtos {
+ /** GraphicsProtos can never be an instance */
+ private GraphicsProtos() {}
+
+ /**
+ * Write to a protocol buffer output stream.
+ * Protocol buffer message definition at {@link android.graphics.PointProto}
+ *
+ * @param point Point to serialize into a protocol buffer
+ * @param protoOutputStream Stream to write the Point object to.
+ * @param fieldId Field Id of the Point as defined in the parent message
+ * @hide
+ */
+ public static void dumpPointProto(
+ @NonNull Point point, @NonNull ProtoOutputStream protoOutputStream, long fieldId) {
+ final long token = protoOutputStream.start(fieldId);
+ protoOutputStream.write(PointProto.X, point.x);
+ protoOutputStream.write(PointProto.Y, point.y);
+ protoOutputStream.end(token);
+ }
+}
+
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index d08bfcf45a5c..6dd1f9939989 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -22,26 +22,33 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.TimeUtils;
+import android.view.Display;
+import android.view.Display.Mode;
import android.view.IGraphicsStats;
import android.view.IGraphicsStatsCallback;
import android.view.NativeVectorDrawableAnimator;
import android.view.PixelCopy;
import android.view.Surface;
import android.view.SurfaceHolder;
-import android.view.TextureLayer;
import android.view.animation.AnimationUtils;
import java.io.File;
import java.io.FileDescriptor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Optional;
import java.util.concurrent.Executor;
+import java.util.stream.Stream;
import sun.misc.Cleaner;
@@ -143,6 +150,8 @@ public class HardwareRenderer {
private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
+ private static int sDensityDpi = 0;
+
private final long mNativeProxy;
/** @hide */
protected RenderNode mRootNode;
@@ -155,6 +164,7 @@ public class HardwareRenderer {
* to opaque with no light source configured.
*/
public HardwareRenderer() {
+ ProcessInitializer.sInstance.initDisplayInfo();
mRootNode = RenderNode.adopt(nCreateRootRenderNode());
mRootNode.setClipToBounds(false);
mNativeProxy = nCreateProxy(!mOpaque, mIsWideGamut, mRootNode.mNativeRenderNode);
@@ -904,6 +914,20 @@ public class HardwareRenderer {
*/
public static void setIsolatedProcess(boolean isIsolated) {
nSetIsolatedProcess(isIsolated);
+ ProcessInitializer.sInstance.setIsolated(isIsolated);
+ }
+
+ /**
+ * Sends device configuration changes to the render thread, for rendering profiling views.
+ *
+ * @hide
+ */
+ public static void sendDeviceConfigurationForDebugging(Configuration config) {
+ if (config.densityDpi != Configuration.DENSITY_DPI_UNDEFINED
+ && config.densityDpi != sDensityDpi) {
+ sDensityDpi = config.densityDpi;
+ nSetDisplayDensityDpi(config.densityDpi);
+ }
}
/**
@@ -975,6 +999,17 @@ public class HardwareRenderer {
ProcessInitializer.sInstance.setPackageName(packageName);
}
+ /**
+ * Gets a context for process initialization
+ *
+ * TODO: Remove this once there is a static method for retrieving an application's context.
+ *
+ * @hide
+ */
+ public static void setContextForInit(Context context) {
+ ProcessInitializer.sInstance.setContext(context);
+ }
+
private static final class DestroyContextRunnable implements Runnable {
private final long mNativeInstance;
@@ -991,8 +1026,35 @@ public class HardwareRenderer {
private static class ProcessInitializer {
static ProcessInitializer sInstance = new ProcessInitializer();
+ // Magic values from android/data_space.h
+ private static final int INTERNAL_DATASPACE_SRGB = 142671872;
+ private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
+ private static final int INTERNAL_DATASPACE_SCRGB = 411107328;
+
+ private enum Dataspace {
+ DISPLAY_P3(ColorSpace.Named.DISPLAY_P3, INTERNAL_DATASPACE_DISPLAY_P3),
+ SCRGB(ColorSpace.Named.EXTENDED_SRGB, INTERNAL_DATASPACE_SCRGB),
+ SRGB(ColorSpace.Named.SRGB, INTERNAL_DATASPACE_SRGB);
+
+ private final ColorSpace.Named mColorSpace;
+ private final int mNativeDataspace;
+ Dataspace(ColorSpace.Named colorSpace, int nativeDataspace) {
+ this.mColorSpace = colorSpace;
+ this.mNativeDataspace = nativeDataspace;
+ }
+
+ static Optional<Dataspace> find(ColorSpace colorSpace) {
+ return Stream.of(Dataspace.values())
+ .filter(d -> ColorSpace.get(d.mColorSpace).equals(colorSpace))
+ .findFirst();
+ }
+ }
+
private boolean mInitialized = false;
+ private boolean mDisplayInitialized = false;
+ private boolean mIsolated = false;
+ private Context mContext;
private String mPackageName;
private IGraphicsStats mGraphicsStatsService;
private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
@@ -1010,6 +1072,16 @@ public class HardwareRenderer {
mPackageName = name;
}
+ synchronized void setIsolated(boolean isolated) {
+ if (mInitialized) return;
+ mIsolated = isolated;
+ }
+
+ synchronized void setContext(Context context) {
+ if (mInitialized) return;
+ mContext = context;
+ }
+
synchronized void init(long renderProxy) {
if (mInitialized) return;
mInitialized = true;
@@ -1040,6 +1112,61 @@ public class HardwareRenderer {
}
}
+ synchronized void initDisplayInfo() {
+ if (mDisplayInitialized) return;
+ if (mContext == null) return;
+
+ // If we're in an isolated sandbox mode then we shouldn't try to communicate with DMS
+ if (mIsolated) {
+ // Defensively clear out the context in case we were passed a context that can leak
+ // if we live longer than it, e.g. an activity context.
+ mContext = null;
+ mDisplayInitialized = true;
+ return;
+ }
+
+ DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+ if (dm == null) {
+ Log.d(LOG_TAG, "Failed to find DisplayManager for display-based configuration");
+ return;
+ }
+
+ Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
+ if (display == null) {
+ Log.d(LOG_TAG, "Failed to find default display for display-based configuration");
+ return;
+ }
+
+ Dataspace wideColorDataspace =
+ Optional.ofNullable(display.getPreferredWideGamutColorSpace())
+ .flatMap(Dataspace::find)
+ // Default to SRGB if the display doesn't support wide color
+ .orElse(Dataspace.SRGB);
+
+ float maxRefreshRate =
+ (float) Arrays.stream(display.getSupportedModes())
+ .mapToDouble(Mode::getRefreshRate)
+ .max()
+ .orElseGet(() -> {
+ Log.i(LOG_TAG, "Failed to find the maximum display refresh rate");
+ // Assume that the max refresh rate is 60hz if we can't find one.
+ return 60.0;
+ });
+ // Grab the physical screen dimensions from the active display mode
+ // Strictly speaking the screen resolution may not always be constant - it is for
+ // sizing the font cache for the underlying rendering thread. Since it's a
+ // heuristic we don't need to be always 100% correct.
+ Mode activeMode = display.getMode();
+ nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(),
+ activeMode.getRefreshRate(), maxRefreshRate,
+ wideColorDataspace.mNativeDataspace, display.getAppVsyncOffsetNanos(),
+ display.getPresentationDeadlineNanos());
+
+ // Defensively clear out the context
+ mContext = null;
+ mDisplayInitialized = true;
+ }
+
private void rotateBuffer() {
nRotateProcessStatsBuffer();
requestBuffer();
@@ -1189,4 +1316,10 @@ public class HardwareRenderer {
private static native void nAllocateBuffers(long nativeProxy);
private static native void nSetForceDark(long nativeProxy, boolean enabled);
+
+ private static native void nSetDisplayDensityDpi(int densityDpi);
+
+ private static native void nInitDisplayInfo(int width, int height, float refreshRate,
+ float maxRefreshRate, int wideColorDataspace, long appVsyncOffsetNanos,
+ long presentationDeadlineNanos);
}
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index c8f065ad094c..ca37917f437f 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -27,9 +27,9 @@ import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Px;
+import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.WorkerThread;
-import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
@@ -171,9 +171,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
* </pre>
*/
public final class ImageDecoder implements AutoCloseable {
- /** @hide **/
- public static int sApiLevel;
-
/**
* Source of encoded image data.
*
@@ -195,14 +192,11 @@ public final class ImageDecoder implements AutoCloseable {
public static abstract class Source {
private Source() {}
- /* @hide */
@Nullable
Resources getResources() { return null; }
- /* @hide */
int getDensity() { return Bitmap.DENSITY_NONE; }
- /* @hide */
final int computeDstDensity() {
Resources res = getResources();
if (res == null) {
@@ -212,7 +206,6 @@ public final class ImageDecoder implements AutoCloseable {
return res.getDisplayMetrics().densityDpi;
}
- /* @hide */
@NonNull
abstract ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException;
};
@@ -923,8 +916,12 @@ public final class ImageDecoder implements AutoCloseable {
/**
* Provide Resources for density scaling.
*
+ * This is a SystemApi to enable legacy behavior, so there is no need to
+ * make it public like the version above, which does not have a Resources
+ * parameter.
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@AnyThread
@NonNull
public static Source createSource(@NonNull ContentResolver cr,
@@ -944,6 +941,12 @@ public final class ImageDecoder implements AutoCloseable {
/**
* Create a new {@link Source Source} from a byte array.
*
+ * <p>Note: If this {@code Source} is passed to {@link #decodeDrawable decodeDrawable},
+ * and the encoded image is animated, the returned {@link AnimatedImageDrawable}
+ * will continue reading from {@code data}, so its contents must not
+ * be modified, even after the {@code AnimatedImageDrawable} is returned.
+ * {@code data}'s contents should never be modified during decode.</p>
+ *
* @param data byte array of compressed image data.
* @param offset offset into data for where the decoder should begin
* parsing.
@@ -954,7 +957,6 @@ public final class ImageDecoder implements AutoCloseable {
* @throws NullPointerException if data is null.
* @throws ArrayIndexOutOfBoundsException if offset and length are
* not within data.
- * @hide
*/
@AnyThread
@NonNull
@@ -972,8 +974,19 @@ public final class ImageDecoder implements AutoCloseable {
}
/**
- * See {@link #createSource(byte[], int, int).
- * @hide
+ * Create a new {@link Source Source} from a byte array.
+ *
+ * <p>Note: If this {@code Source} is passed to {@link #decodeDrawable decodeDrawable},
+ * and the encoded image is animated, the returned {@link AnimatedImageDrawable}
+ * will continue reading from {@code data}, so its contents must not
+ * be modified, even after the {@code AnimatedImageDrawable} is returned.
+ * {@code data}'s contents should never be modified during decode.</p>
+ *
+ * @param data byte array of compressed image data.
+ * @return a new Source object, which can be passed to
+ * {@link #decodeDrawable decodeDrawable} or
+ * {@link #decodeBitmap decodeBitmap}.
+ * @throws NullPointerException if data is null.
*/
@AnyThread
@NonNull
@@ -1081,11 +1094,9 @@ public final class ImageDecoder implements AutoCloseable {
* @param sampleSize Sampling rate of the encoded image.
* @return {@link android.util.Size} of the width and height after
* sampling.
- *
- * @hide
*/
@NonNull
- public Size getSampledSize(int sampleSize) {
+ private Size getSampledSize(int sampleSize) {
if (sampleSize <= 0) {
throw new IllegalArgumentException("sampleSize must be positive! "
+ "provided " + sampleSize);
@@ -1417,6 +1428,8 @@ public final class ImageDecoder implements AutoCloseable {
* {@link OnHeaderDecodedListener#onHeaderDecoded onHeaderDecoded}.</p>
*
* @hide
+ * Must be public for access from android.graphics.drawable,
+ * but must not be called from outside the UI module.
*/
public void setOutPaddingRect(@NonNull Rect outPadding) {
mOutPaddingRect = outPadding;
@@ -1921,7 +1934,8 @@ public final class ImageDecoder implements AutoCloseable {
// For P and above, only resize if it would be a downscale. Scale up prior
// to P in case the app relies on the Bitmap's size without considering density.
- if (srcDensity < dstDensity && sApiLevel >= Build.VERSION_CODES.P) {
+ if (srcDensity < dstDensity
+ && Compatibility.getTargetSdkVersion() >= Build.VERSION_CODES.P) {
return srcDensity;
}
@@ -1964,7 +1978,6 @@ public final class ImageDecoder implements AutoCloseable {
* Private method called by JNI.
*/
@SuppressWarnings("unused")
- @UnsupportedAppUsage
private int postProcessAndRelease(@NonNull Canvas canvas) {
try {
return mPostProcessor.onPostProcess(canvas);
diff --git a/graphics/java/android/graphics/LargeBitmap.java b/graphics/java/android/graphics/LargeBitmap.java
deleted file mode 100644
index 936c33813a86..000000000000
--- a/graphics/java/android/graphics/LargeBitmap.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-/**
- * LargeBitmap can be used to decode a rectangle region from an image.
- * LargeBimap is particularly useful when an original image is large and
- * you only need parts of the image.
- *
- * To create a LargeBitmap, call BitmapFactory.createLargeBitmap().
- * Given a LargeBitmap, users can call decodeRegion() repeatedly
- * to get a decoded Bitmap of the specified region.
- * @hide
- */
-public final class LargeBitmap {
- private long mNativeLargeBitmap;
- private boolean mRecycled;
-
- /* Private constructor that must received an already allocated native
- large bitmap int (pointer).
-
- This can be called from JNI code.
- */
- private LargeBitmap(long nativeLbm) {
- mNativeLargeBitmap = nativeLbm;
- mRecycled = false;
- }
-
- /**
- * Decodes a rectangle region in the image specified by rect.
- *
- * @param rect The rectangle that specified the region to be decode.
- * @param opts null-ok; Options that control downsampling.
- * inPurgeable is not supported.
- * @return The decoded bitmap, or null if the image data could not be
- * decoded.
- */
- public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
- checkRecycled("decodeRegion called on recycled large bitmap");
- if (rect.left < 0 || rect.top < 0 || rect.right > getWidth() || rect.bottom > getHeight())
- throw new IllegalArgumentException("rectangle is not inside the image");
- return nativeDecodeRegion(mNativeLargeBitmap, rect.left, rect.top,
- rect.right - rect.left, rect.bottom - rect.top, options);
- }
-
- /** Returns the original image's width */
- public int getWidth() {
- checkRecycled("getWidth called on recycled large bitmap");
- return nativeGetWidth(mNativeLargeBitmap);
- }
-
- /** Returns the original image's height */
- public int getHeight() {
- checkRecycled("getHeight called on recycled large bitmap");
- return nativeGetHeight(mNativeLargeBitmap);
- }
-
- /**
- * Frees up the memory associated with this large bitmap, and mark the
- * large bitmap as "dead", meaning it will throw an exception if decodeRegion(),
- * getWidth() or getHeight() is called.
- * This operation cannot be reversed, so it should only be called if you are
- * sure there are no further uses for the large bitmap. This is an advanced call,
- * and normally need not be called, since the normal GC process will free up this
- * memory when there are no more references to this bitmap.
- */
- public void recycle() {
- if (!mRecycled) {
- nativeClean(mNativeLargeBitmap);
- mRecycled = true;
- }
- }
-
- /**
- * Returns true if this large bitmap has been recycled.
- * If so, then it is an error to try use its method.
- *
- * @return true if the large bitmap has been recycled
- */
- public final boolean isRecycled() {
- return mRecycled;
- }
-
- /**
- * Called by methods that want to throw an exception if the bitmap
- * has already been recycled.
- */
- private void checkRecycled(String errorMessage) {
- if (mRecycled) {
- throw new IllegalStateException(errorMessage);
- }
- }
-
- protected void finalize() {
- recycle();
- }
-
- private static native Bitmap nativeDecodeRegion(long nativeLbm,
- int start_x, int start_y, int width, int height,
- BitmapFactory.Options options);
- private static native int nativeGetWidth(long nativeLbm);
- private static native int nativeGetHeight(long nativeLbm);
- private static native void nativeClean(long nativeLbm);
-}
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 3f3ad967fe97..ebe34cad0654 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -151,8 +151,9 @@ public class LinearGradient extends Shader {
this(x0, y0, x1, y1, new long[] {color0, color1}, null, tile);
}
+ /** @hide */
@Override
- long createNativeInstance(long nativeMatrix) {
+ protected long createNativeInstance(long nativeMatrix) {
return nativeCreate(nativeMatrix, mX0, mY0, mX1, mY1,
mColorLongs, mPositions, mTileMode.nativeInt,
colorSpace().getNativeInstance());
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index cf914c2c3eae..bc58febc388b 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -16,7 +16,7 @@
package android.graphics;
-import android.compat.annotation.UnsupportedAppUsage;
+import android.annotation.NonNull;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
@@ -40,8 +40,11 @@ public class Matrix {
public static final int MPERSP_1 = 7; //!< use with getValues/setValues
public static final int MPERSP_2 = 8; //!< use with getValues/setValues
- /** @hide */
- @UnsupportedAppUsage
+ /**
+ * The identity matrix. Multiplying by another matrix {@code M} returns {@code M}. This matrix
+ * is immutable, and attempting to modify it will throw an {@link IllegalStateException}.
+ */
+ @NonNull
public final static Matrix IDENTITY_MATRIX = new Matrix() {
void oops() {
throw new IllegalStateException("Matrix can not be modified");
@@ -229,11 +232,7 @@ public class Matrix {
Matrix.class.getClassLoader(), nGetNativeFinalizer());
}
- /**
- * @hide
- */
- @UnsupportedAppUsage
- public final long native_instance;
+ private final long native_instance;
/**
* Create an identity matrix
@@ -523,7 +522,7 @@ public class Matrix {
}
/**
- * Controlls how the src rect should align into the dst rect for setRectToRect().
+ * Controls how the src rect should align into the dst rect for setRectToRect().
*/
public enum ScaleToFit {
/**
@@ -783,10 +782,7 @@ public class Matrix {
return sb.toString();
}
- /**
- * @hide
- */
- public void toShortString(StringBuilder sb) {
+ private void toShortString(StringBuilder sb) {
float[] values = new float[9];
getValues(values);
sb.append('[');
@@ -811,11 +807,13 @@ public class Matrix {
}
/**
- * Print short string, to optimize dumping.
+ * Dumps a human-readable shortened string of the matrix into the given
+ * stream
*
- * @hide
+ * @param pw The {@link PrintWriter} into which the string representation of
+ * the matrix will be written.
*/
- public void printShortString(PrintWriter pw) {
+ public final void dump(@NonNull PrintWriter pw) {
float[] values = new float[9];
getValues(values);
pw.print('[');
@@ -840,7 +838,10 @@ public class Matrix {
}
- /** @hide */
+ /**
+ * @hide For access by android.graphics.pdf but must not be accessed outside the module.
+ * FIXME: PdfRenderer accesses it, but the plan is to leave it out of the module.
+ */
public final long ni() {
return native_instance;
}
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index ff3239348240..af2095713ec2 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -39,11 +39,10 @@ public class NinePatch {
* Present on a 9 patch bitmap if it optical insets were manually included,
* or if outline insets were automatically included by aapt.
*
- * @hide
+ * @hide For use by NinePatchDrawable, but must not be used outside the module.
*/
public static class InsetStruct {
@SuppressWarnings({"UnusedDeclaration"}) // called from JNI
- @UnsupportedAppUsage
InsetStruct(int opticalLeft, int opticalTop, int opticalRight, int opticalBottom,
int outlineLeft, int outlineTop, int outlineRight, int outlineBottom,
float outlineRadius, int outlineAlpha, float decodeScale) {
@@ -86,7 +85,7 @@ public class NinePatch {
/**
* Used by native code. This pointer is an instance of Res_png_9patch*.
*
- * @hide
+ * @hide for use by android.graphics, but must not be used outside the module.
*/
@UnsupportedAppUsage
public long mNativeChunk;
@@ -119,20 +118,6 @@ public class NinePatch {
mNativeChunk = validateNinePatchChunk(chunk);
}
- /**
- * @hide
- */
- public NinePatch(NinePatch patch) {
- mBitmap = patch.mBitmap;
- mSrcName = patch.mSrcName;
- if (patch.mPaint != null) {
- mPaint = new Paint(patch.mPaint);
- }
- // No need to validate the 9patch chunk again, it was done by
- // the instance we're copying from
- mNativeChunk = patch.mNativeChunk;
- }
-
@Override
protected void finalize() throws Throwable {
try {
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 84fe39290681..7811671b80d6 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -713,7 +713,7 @@ public class Path {
*/
public void addPath(@NonNull Path src, @NonNull Matrix matrix) {
if (!src.isSimplePath) isSimplePath = false;
- nAddPath(mNativePath, src.mNativePath, matrix.native_instance);
+ nAddPath(mNativePath, src.mNativePath, matrix.ni());
}
/**
@@ -777,7 +777,7 @@ public class Path {
dst.isSimplePath = false;
dstNative = dst.mNativePath;
}
- nTransform(mNativePath, matrix.native_instance, dstNative);
+ nTransform(mNativePath, matrix.ni(), dstNative);
}
/**
@@ -787,7 +787,7 @@ public class Path {
*/
public void transform(@NonNull Matrix matrix) {
isSimplePath = false;
- nTransform(mNativePath, matrix.native_instance);
+ nTransform(mNativePath, matrix.ni());
}
/** @hide */
diff --git a/graphics/java/android/graphics/PathMeasure.java b/graphics/java/android/graphics/PathMeasure.java
index bf79656addc0..5500c5217de4 100644
--- a/graphics/java/android/graphics/PathMeasure.java
+++ b/graphics/java/android/graphics/PathMeasure.java
@@ -105,7 +105,7 @@ public class PathMeasure {
* @param flags Specified what aspects should be returned in the matrix.
*/
public boolean getMatrix(float distance, Matrix matrix, int flags) {
- return native_getMatrix(native_instance, distance, matrix.native_instance, flags);
+ return native_getMatrix(native_instance, distance, matrix.ni(), flags);
}
/**
diff --git a/graphics/java/android/graphics/Point.java b/graphics/java/android/graphics/Point.java
index 9f71a0fedd05..61a47493c2ff 100644
--- a/graphics/java/android/graphics/Point.java
+++ b/graphics/java/android/graphics/Point.java
@@ -19,12 +19,9 @@ package android.graphics;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Size;
-import android.util.proto.ProtoOutputStream;
import java.io.PrintWriter;
-
/**
* Point holds two integer coordinates
*/
@@ -75,6 +72,17 @@ public class Point implements Parcelable {
return this.x == x && this.y == y;
}
+ /**
+ * Dumps a human-readable shortened string of the point into the given
+ * stream
+ *
+ * @param pw The {@link PrintWriter} into which the string representation of
+ * the point will be written.
+ */
+ public final void dump(@NonNull PrintWriter pw) {
+ pw.print("["); pw.print(x); pw.print(","); pw.print(y); pw.print("]");
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -100,11 +108,6 @@ public class Point implements Parcelable {
return "Point(" + x + ", " + y + ")";
}
- /** @hide */
- public void printShortString(@NonNull PrintWriter pw) {
- pw.print("["); pw.print(x); pw.print(","); pw.print(y); pw.print("]");
- }
-
/**
* Parcelable interface methods
*/
@@ -124,21 +127,6 @@ public class Point implements Parcelable {
out.writeInt(y);
}
- /**
- * Write to a protocol buffer output stream.
- * Protocol buffer message definition at {@link android.graphics.PointProto}
- *
- * @param protoOutputStream Stream to write the Rect object to.
- * @param fieldId Field Id of the Rect as defined in the parent message
- * @hide
- */
- public void dumpDebug(@NonNull ProtoOutputStream protoOutputStream, long fieldId) {
- final long token = protoOutputStream.start(fieldId);
- protoOutputStream.write(PointProto.X, x);
- protoOutputStream.write(PointProto.Y, y);
- protoOutputStream.end(token);
- }
-
public static final @android.annotation.NonNull Parcelable.Creator<Point> CREATOR = new Parcelable.Creator<Point>() {
/**
* Return a new point from the data in the specified parcel.
@@ -169,14 +157,4 @@ public class Point implements Parcelable {
x = in.readInt();
y = in.readInt();
}
-
- /** {@hide} */
- public static @NonNull Point convert(@NonNull Size size) {
- return new Point(size.getWidth(), size.getHeight());
- }
-
- /** {@hide} */
- public static @NonNull Size convert(@NonNull Point point) {
- return new Size(point.x, point.y);
- }
}
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index 96b7b9a78ba8..089d6de44adb 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -147,8 +147,9 @@ public class RadialGradient extends Shader {
this(centerX, centerY, radius, new long[] {centerColor, edgeColor}, null, tileMode);
}
+ /** @hide */
@Override
- long createNativeInstance(long nativeMatrix) {
+ protected long createNativeInstance(long nativeMatrix) {
return nativeCreate(nativeMatrix, mX, mY, mRadius,
mColorLongs, mPositions, mTileMode.nativeInt,
colorSpace().getNativeInstance());
diff --git a/graphics/java/android/graphics/RecordingCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
index c0e0a24583ec..22aacdecaf5d 100644
--- a/graphics/java/android/graphics/RecordingCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -19,8 +19,6 @@ package android.graphics;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Pools.SynchronizedPool;
-import android.view.DisplayListCanvas;
-import android.view.TextureLayer;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
@@ -35,13 +33,12 @@ import dalvik.annotation.optimization.FastNative;
* {@link RenderNode#endRecording()} is called. It must not be retained beyond that as it is
* internally reused.
*/
-public final class RecordingCanvas extends DisplayListCanvas {
+public final class RecordingCanvas extends BaseRecordingCanvas {
// The recording canvas pool should be large enough to handle a deeply nested
// view hierarchy because display lists are generated recursively.
private static final int POOL_LIMIT = 25;
- /** @hide */
- public static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
+ private static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
private static final SynchronizedPool<RecordingCanvas> sPool =
new SynchronizedPool<>(POOL_LIMIT);
@@ -53,7 +50,7 @@ public final class RecordingCanvas extends DisplayListCanvas {
private int mWidth;
private int mHeight;
- /** @hide */
+ /*package*/
static RecordingCanvas obtain(@NonNull RenderNode node, int width, int height) {
if (node == null) throw new IllegalArgumentException("node cannot be null");
RecordingCanvas canvas = sPool.acquire();
@@ -69,29 +66,22 @@ public final class RecordingCanvas extends DisplayListCanvas {
return canvas;
}
- /** @hide */
+ /*package*/
void recycle() {
mNode = null;
sPool.release(this);
}
- /** @hide */
+ /*package*/
long finishRecording() {
return nFinishRecording(mNativeCanvasWrapper);
}
- /** @hide */
- @Override
- public boolean isRecordingFor(Object o) {
- return o == mNode;
- }
-
///////////////////////////////////////////////////////////////////////////
// Constructors
///////////////////////////////////////////////////////////////////////////
- /** @hide */
- protected RecordingCanvas(@NonNull RenderNode node, int width, int height) {
+ private RecordingCanvas(@NonNull RenderNode node, int width, int height) {
super(nCreateDisplayListCanvas(node.mNativeRenderNode, width, height));
mDensity = 0; // disable bitmap density scaling
}
@@ -147,12 +137,12 @@ public final class RecordingCanvas extends DisplayListCanvas {
@Override
public void enableZ() {
- nInsertReorderBarrier(mNativeCanvasWrapper, true);
+ nEnableZ(mNativeCanvasWrapper, true);
}
@Override
public void disableZ() {
- nInsertReorderBarrier(mNativeCanvasWrapper, false);
+ nEnableZ(mNativeCanvasWrapper, false);
}
///////////////////////////////////////////////////////////////////////////
@@ -223,9 +213,9 @@ public final class RecordingCanvas extends DisplayListCanvas {
* Draws the specified layer onto this canvas.
*
* @param layer The layer to composite on this canvas
- * @hide
+ * @hide TODO: Make this a SystemApi for b/155905258
*/
- public void drawTextureLayer(TextureLayer layer) {
+ public void drawTextureLayer(@NonNull TextureLayer layer) {
nDrawTextureLayer(mNativeCanvasWrapper, layer.getLayerHandle());
}
@@ -302,7 +292,7 @@ public final class RecordingCanvas extends DisplayListCanvas {
@CriticalNative
private static native int nGetMaximumTextureHeight();
@CriticalNative
- private static native void nInsertReorderBarrier(long renderer, boolean enableReorder);
+ private static native void nEnableZ(long renderer, boolean enableZ);
@CriticalNative
private static native long nFinishRecording(long renderer);
@CriticalNative
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 22f5489be3b1..8aacbc7bc109 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -481,7 +481,7 @@ public final class RenderNode {
* @param outMatrix The matrix to store the transform of the RenderNode
*/
public void getMatrix(@NonNull Matrix outMatrix) {
- nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
+ nGetTransformMatrix(mNativeRenderNode, outMatrix.ni());
}
/**
@@ -491,7 +491,7 @@ public final class RenderNode {
* @param outMatrix The matrix to store the inverse transform of the RenderNode
*/
public void getInverseMatrix(@NonNull Matrix outMatrix) {
- nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
+ nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.ni());
}
///////////////////////////////////////////////////////////////////////////
@@ -797,7 +797,7 @@ public final class RenderNode {
* @hide TODO Do we want this?
*/
public boolean setStaticMatrix(Matrix matrix) {
- return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
+ return nSetStaticMatrix(mNativeRenderNode, matrix.ni());
}
/**
@@ -813,7 +813,7 @@ public final class RenderNode {
*/
public boolean setAnimationMatrix(@Nullable Matrix matrix) {
return nSetAnimationMatrix(mNativeRenderNode,
- (matrix != null) ? matrix.native_instance : 0);
+ (matrix != null) ? matrix.ni() : 0);
}
/**
@@ -830,7 +830,7 @@ public final class RenderNode {
@Nullable
public Matrix getAnimationMatrix() {
Matrix output = new Matrix();
- if (nGetAnimationMatrix(mNativeRenderNode, output.native_instance)) {
+ if (nGetAnimationMatrix(mNativeRenderNode, output.ni())) {
return output;
} else {
return null;
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index 5a3f2a96e31d..5a0b4a9b8086 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -74,8 +74,9 @@ public class RuntimeShader extends Shader {
discardNativeInstance();
}
+ /** @hide */
@Override
- long createNativeInstance(long nativeMatrix) {
+ protected long createNativeInstance(long nativeMatrix) {
return nativeCreate(mNativeInstanceRuntimeShaderFactory, nativeMatrix, mUniforms,
colorSpace().getNativeInstance(), mIsOpaque);
}
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 5335aa4725ad..fb15d0794dd7 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -20,12 +20,11 @@ import android.annotation.ColorInt;
import android.annotation.ColorLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
import libcore.util.NativeAllocationRegistry;
/**
- * Shader is the based class for objects that return horizontal spans of colors
+ * Shader is the base class for objects that return horizontal spans of colors
* during drawing. A subclass of Shader is installed in a Paint calling
* paint.setShader(shader). After that any object (other than a bitmap) that is
* drawn with that paint will get its color(s) from the shader.
@@ -47,9 +46,9 @@ public class Shader {
}
/**
- * @hide
+ * @hide Only to be used by subclasses in android.graphics.
*/
- public Shader(ColorSpace colorSpace) {
+ protected Shader(ColorSpace colorSpace) {
mColorSpace = colorSpace;
if (colorSpace == null) {
throw new IllegalArgumentException(
@@ -63,7 +62,7 @@ public class Shader {
private final ColorSpace mColorSpace;
/**
- * @hide
+ * @hide Only to be used by subclasses in android.graphics.
*/
protected ColorSpace colorSpace() {
return mColorSpace;
@@ -97,11 +96,10 @@ public class Shader {
* mirror images so that adjacent images always seam
*/
MIRROR (2);
-
+
TileMode(int nativeInt) {
this.nativeInt = nativeInt;
}
- @UnsupportedAppUsage
final int nativeInt;
}
@@ -142,11 +140,16 @@ public class Shader {
}
}
- long createNativeInstance(long nativeMatrix) {
+ /**
+ * @hide Only to be used by subclasses in the graphics package.
+ */
+ protected long createNativeInstance(long nativeMatrix) {
return 0;
}
- /** @hide */
+ /**
+ * @hide Only to be used by subclasses in the graphics package.
+ */
protected final void discardNativeInstance() {
if (mNativeInstance != 0) {
mCleaner.run();
@@ -158,14 +161,15 @@ public class Shader {
/**
* Callback for subclasses to call {@link #discardNativeInstance()} if the most recently
* constructed native instance is no longer valid.
- * @hide
+ * @hide Only to be used by subclasses in the graphics package.
*/
protected void verifyNativeInstance() {
}
/**
- * @hide
+ * @hide so it can be called by android.graphics.drawable but must not be called from outside
+ * the module.
*/
public final long getNativeInstance() {
// verify mNativeInstance is valid
@@ -173,7 +177,7 @@ public class Shader {
if (mNativeInstance == 0) {
mNativeInstance = createNativeInstance(mLocalMatrix == null
- ? 0 : mLocalMatrix.native_instance);
+ ? 0 : mLocalMatrix.ni());
if (mNativeInstance != 0) {
mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
this, mNativeInstance);
@@ -183,9 +187,9 @@ public class Shader {
}
/**
- * @hide
+ * @hide Only to be called by subclasses in the android.graphics package.
*/
- public static @ColorLong long[] convertColors(@NonNull @ColorInt int[] colors) {
+ protected static @ColorLong long[] convertColors(@NonNull @ColorInt int[] colors) {
if (colors.length < 2) {
throw new IllegalArgumentException("needs >= 2 number of colors");
}
@@ -204,9 +208,9 @@ public class Shader {
* @throws IllegalArgumentException if the colors do not all share the same,
* valid ColorSpace, or if there are less than 2 colors.
*
- * @hide
+ * @hide Only to be called by subclasses in the android.graphics package.
*/
- public static ColorSpace detectColorSpace(@NonNull @ColorLong long[] colors) {
+ protected static ColorSpace detectColorSpace(@NonNull @ColorLong long[] colors) {
if (colors.length < 2) {
throw new IllegalArgumentException("needs >= 2 number of colors");
}
diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index 08520048b787..f1ca1986bfa0 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -130,8 +130,9 @@ public class SweepGradient extends Shader {
this(cx, cy, new long[] {color0, color1}, null);
}
+ /** @hide */
@Override
- long createNativeInstance(long nativeMatrix) {
+ protected long createNativeInstance(long nativeMatrix) {
return nativeCreate(nativeMatrix, mCx, mCy, mColorLongs, mPositions,
colorSpace().getNativeInstance());
}
diff --git a/graphics/java/android/graphics/TextureLayer.java b/graphics/java/android/graphics/TextureLayer.java
new file mode 100644
index 000000000000..ac1bd6902062
--- /dev/null
+++ b/graphics/java/android/graphics/TextureLayer.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.View;
+
+import com.android.internal.util.VirtualRefBasePtr;
+
+/**
+ * TextureLayer represents a SurfaceTexture that will be composited by RenderThread into the
+ * frame when drawn in a HW accelerated Canvas. This is backed by a DeferredLayerUpdater on
+ * the native side.
+ *
+ * @hide TODO: Make this a SystemApi for b/155905258
+ */
+public final class TextureLayer implements AutoCloseable {
+ private HardwareRenderer mRenderer;
+ private VirtualRefBasePtr mFinalizer;
+
+ private TextureLayer(@NonNull HardwareRenderer renderer, long deferredUpdater) {
+ if (renderer == null || deferredUpdater == 0) {
+ throw new IllegalArgumentException("Either hardware renderer: " + renderer
+ + " or deferredUpdater: " + deferredUpdater + " is invalid");
+ }
+ mRenderer = renderer;
+ mFinalizer = new VirtualRefBasePtr(deferredUpdater);
+ }
+
+ /**
+ * Update the paint used when drawing this layer.
+ *
+ * @param paint The paint used when the layer is drawn into the destination canvas.
+ * @see View#setLayerPaint(android.graphics.Paint)
+ */
+ public void setLayerPaint(@Nullable Paint paint) {
+ nSetLayerPaint(mFinalizer.get(), paint != null ? paint.getNativeInstance() : 0);
+ mRenderer.pushLayerUpdate(this);
+ }
+
+ /**
+ * Indicates whether this layer can be rendered.
+ *
+ * @return True if the layer can be rendered into, false otherwise
+ */
+ private boolean isValid() {
+ return mFinalizer != null && mFinalizer.get() != 0;
+ }
+
+ /**
+ * Destroys resources without waiting for a GC.
+ */
+ @Override
+ public void close() {
+ if (!isValid()) {
+ // Already destroyed
+ return;
+ }
+ mRenderer.onLayerDestroyed(this);
+ mRenderer = null;
+ mFinalizer.release();
+ mFinalizer = null;
+ }
+
+ /*package*/ long getDeferredLayerUpdater() {
+ return mFinalizer.get();
+ }
+
+ /**
+ * Copies this layer into the specified bitmap.
+ *
+ * @param bitmap The bitmap to copy they layer into
+ *
+ * @return True if the copy was successful, false otherwise
+ */
+ public boolean copyInto(@NonNull Bitmap bitmap) {
+ return mRenderer.copyLayerInto(this, bitmap);
+ }
+
+ /**
+ * Update the layer's properties. Note that after calling this isValid() may
+ * return false if the requested width/height cannot be satisfied
+ *
+ * @param width The new width of this layer
+ * @param height The new height of this layer
+ * @param isOpaque Whether this layer is opaque
+ *
+ * @return true if the layer's properties will change, false if they already
+ * match the desired values.
+ */
+ public boolean prepare(int width, int height, boolean isOpaque) {
+ return nPrepare(mFinalizer.get(), width, height, isOpaque);
+ }
+
+ /**
+ * Sets an optional transform on this layer.
+ *
+ * @param matrix The transform to apply to the layer.
+ */
+ public void setTransform(@NonNull Matrix matrix) {
+ nSetTransform(mFinalizer.get(), matrix.ni());
+ mRenderer.pushLayerUpdate(this);
+ }
+
+ /**
+ * Indicates that this layer has lost its texture.
+ */
+ public void detachSurfaceTexture() {
+ mRenderer.detachSurfaceTexture(mFinalizer.get());
+ }
+
+ /*package*/ long getLayerHandle() {
+ return mFinalizer.get();
+ }
+
+ public void setSurfaceTexture(@NonNull SurfaceTexture surface) {
+ nSetSurfaceTexture(mFinalizer.get(), surface);
+ mRenderer.pushLayerUpdate(this);
+ }
+
+ public void updateSurfaceTexture() {
+ nUpdateSurfaceTexture(mFinalizer.get());
+ mRenderer.pushLayerUpdate(this);
+ }
+
+ /*package*/ static TextureLayer adoptTextureLayer(@NonNull HardwareRenderer renderer,
+ long layer) {
+ return new TextureLayer(renderer, layer);
+ }
+
+ private static native boolean nPrepare(long layerUpdater, int width, int height,
+ boolean isOpaque);
+ private static native void nSetLayerPaint(long layerUpdater, long paint);
+ private static native void nSetTransform(long layerUpdater, long matrix);
+ private static native void nSetSurfaceTexture(long layerUpdater,
+ @NonNull SurfaceTexture surface);
+ private static native void nUpdateSurfaceTexture(long layerUpdater);
+}
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 31ad81b9c346..0f356a6d2d3c 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -768,7 +768,6 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
return mLayerState.isStateful();
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mLayerState.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index d8946009483c..ebf7cea98a81 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -19,7 +19,6 @@ package android.graphics.drawable;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -563,7 +562,6 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
* callback, so no need to post.
*/
@SuppressWarnings("unused")
- @UnsupportedAppUsage
private void onAnimationEnd() {
if (mAnimationCallbacks != null) {
for (Animatable2.AnimationCallback callback : mAnimationCallbacks) {
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 9fb72cf08b51..73dbe65bd25b 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -25,8 +25,6 @@ import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityThread;
-import android.app.Application;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
@@ -368,14 +366,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
* @return whether invalid animations for vector drawable should be ignored.
*/
private static boolean shouldIgnoreInvalidAnimation() {
- Application app = ActivityThread.currentApplication();
- if (app == null || app.getApplicationInfo() == null) {
- return true;
- }
- if (app.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) {
- return true;
- }
- return false;
+ return android.graphics.Compatibility.getTargetSdkVersion() < Build.VERSION_CODES.N;
}
@Override
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 4e768c9eddfb..b291f930da37 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -17,6 +17,7 @@
package android.graphics.drawable;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
@@ -92,7 +93,6 @@ public class BitmapDrawable extends Drawable {
private BitmapState mBitmapState;
private BlendModeColorFilter mBlendModeFilter;
- @UnsupportedAppUsage
private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
private boolean mDstRectAndInsetsDirty = true;
@@ -239,9 +239,10 @@ public class BitmapDrawable extends Drawable {
}
}
- /** @hide */
- @UnsupportedAppUsage
- public void setBitmap(Bitmap bitmap) {
+ /**
+ * Switch to a new Bitmap object.
+ */
+ public void setBitmap(@Nullable Bitmap bitmap) {
if (mBitmapState.mBitmap != bitmap) {
mBitmapState.mBitmap = bitmap;
computeBitmapSize();
@@ -696,18 +697,18 @@ public class BitmapDrawable extends Drawable {
}
/**
- * @hide only needed by a hack within ProgressBar
+ * No longer needed by ProgressBar, but still here due to UnsupportedAppUsage.
*/
@UnsupportedAppUsage
- public ColorStateList getTint() {
+ private ColorStateList getTint() {
return mBitmapState.mTint;
}
/**
- * @hide only needed by a hack within ProgressBar
+ * No longer needed by ProgressBar, but still here due to UnsupportedAppUsage.
*/
@UnsupportedAppUsage
- public Mode getTintMode() {
+ private Mode getTintMode() {
return BlendMode.blendModeToPorterDuffMode(mBitmapState.mBlendMode);
}
@@ -760,7 +761,6 @@ public class BitmapDrawable extends Drawable {
|| super.isStateful();
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mBitmapState.mTint != null && mBitmapState.mTint.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index e93e7dfbe22c..2457ab85144f 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -238,7 +238,6 @@ public class ColorDrawable extends Drawable {
return mColorState.mTint != null && mColorState.mTint.isStateful();
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mColorState.mTint != null && mColorState.mTint.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 9cf12f121e0a..ed210ab40b7a 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -21,7 +21,6 @@ import android.annotation.ColorInt;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
@@ -808,10 +807,7 @@ public abstract class Drawable {
*
* @return {@code true} if {@link android.R.attr#state_focused} is specified
* for this drawable.
- *
- * @hide
*/
- @TestApi
public boolean hasFocusStateSpecified() {
return false;
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 51b299c9ee5e..89ebcbe817dd 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -243,7 +243,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return mDrawableContainerState.isStateful();
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
if (mCurrDrawable != null) {
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index e197e7123fed..98c38214adab 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -345,7 +345,6 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb
return mDrawable != null && mDrawable.isStateful();
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mDrawable != null && mDrawable.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index f053f392b97e..24d73efebe54 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1164,7 +1164,6 @@ public class GradientDrawable extends Drawable {
|| (s.mTint != null && s.mTint.isStateful());
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
final GradientState s = mGradientState;
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index cc7182c3fd1c..90412f417f38 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -467,7 +467,7 @@ public final class Icon implements Parcelable {
if ((mType == TYPE_BITMAP || mType == TYPE_ADAPTIVE_BITMAP) &&
getBitmap().isMutable() &&
getBitmap().getAllocationByteCount() >= MIN_ASHMEM_ICON_SIZE) {
- setBitmap(getBitmap().createAshmemBitmap());
+ setBitmap(getBitmap().asShared());
}
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index fb4146f04bc9..19f29aed203f 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1483,7 +1483,6 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
return mLayerState.isStateful();
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mLayerState.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 99d27ba4c469..423025e8f418 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -114,7 +114,7 @@ public class NinePatchDrawable extends Drawable {
* Create drawable from raw nine-patch data, setting initial target density
* based on the display metrics of the resources.
*
- * @hide
+ * @hide for use by android.graphics.ImageDecoder, but must not be used outside the module.
*/
public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk,
Rect padding, Rect opticalInsets, String srcName) {
@@ -582,7 +582,6 @@ public class NinePatchDrawable extends Drawable {
return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mNinePatchState.mTint != null && mNinePatchState.mTint.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index e5e4d4527fca..16ffd132a41b 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -378,7 +378,6 @@ public class RippleDrawable extends LayerDrawable {
return true;
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return true;
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 9774b59f98a9..f264d0eb363f 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -367,7 +367,6 @@ public class ShapeDrawable extends Drawable {
return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mShapeState.mTint != null && mShapeState.mTint.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 2920acbe514c..88cd4625394b 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -94,7 +94,6 @@ public class StateListDrawable extends DrawableContainer {
return true;
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mStateListState.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index e6fa866df3ab..a1ccc7b7b5e4 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -502,7 +502,6 @@ public class VectorDrawable extends Drawable {
return super.isStateful() || (mVectorState != null && mVectorState.isStateful());
}
- /** @hide */
@Override
public boolean hasFocusStateSpecified() {
return mVectorState != null && mVectorState.hasFocusStateSpecified();
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index 21ce1b8392d2..3cd709ea10e5 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -139,12 +139,12 @@ public final class PdfEditor {
getPageSize(pageIndex, size);
synchronized (PdfRenderer.sPdfiumLock) {
- nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
+ nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.ni(),
0, 0, size.x, size.y);
}
} else {
synchronized (PdfRenderer.sPdfiumLock) {
- nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
+ nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.ni(),
clip.left, clip.top, clip.right, clip.bottom);
}
}
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 54710e58687c..43de4699381f 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -434,7 +434,9 @@ public final class PdfRenderer implements AutoCloseable {
transform.postTranslate(contentLeft, contentTop);
}
- final long transformPtr = transform.native_instance;
+ // FIXME: This code is planned to be outside the UI rendering module, so it should not
+ // be able to access native instances from Bitmap, Matrix, etc.
+ final long transformPtr = transform.ni();
synchronized (sPdfiumLock) {
nativeRenderPage(mNativeDocument, mNativePage, destination.getNativeInstance(),