diff options
author | John Reck <jreck@google.com> | 2016-04-27 14:36:51 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-04-27 14:36:53 +0000 |
commit | 7f209d37f17d4df09475137c38b84a3338c84023 (patch) | |
tree | 07856ff96c1e32df08aef9ad73b7b8216d16f9c0 /graphics/java/android/view/PixelCopy.java | |
parent | 9fa8b54589b68dc6da3a7201cad1fc43e01e59e3 (diff) | |
parent | e94cbc76d560a157c0a0d47181b4ed2a0aadbeb1 (diff) |
Merge "API tweaks to PixelCopy and make it public" into nyc-dev
Diffstat (limited to 'graphics/java/android/view/PixelCopy.java')
-rw-r--r-- | graphics/java/android/view/PixelCopy.java | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/graphics/java/android/view/PixelCopy.java b/graphics/java/android/view/PixelCopy.java new file mode 100644 index 000000000000..95c930c5264d --- /dev/null +++ b/graphics/java/android/view/PixelCopy.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.graphics.Bitmap; +import android.os.Handler; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Provides a mechanisms to issue pixel copy requests to allow for copy + * operations from {@link Surface} to {@link Bitmap} + */ +public final class PixelCopy { + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({SUCCESS, ERROR_UNKNOWN, ERROR_TIMEOUT, ERROR_SOURCE_NO_DATA, + ERROR_SOURCE_INVALID, ERROR_DESTINATION_INVALID}) + public @interface CopyResultStatus {} + + /** The pixel copy request succeeded */ + public static final int SUCCESS = 0; + + /** The pixel copy request failed with an unknown error. */ + public static final int ERROR_UNKNOWN = 1; + + /** + * A timeout occurred while trying to acquire a buffer from the source to + * copy from. + */ + public static final int ERROR_TIMEOUT = 2; + + /** + * The source has nothing to copy from. When the source is a {@link Surface} + * this means that no buffers have been queued yet. Wait for the source + * to produce a frame and try again. + */ + public static final int ERROR_SOURCE_NO_DATA = 3; + + /** + * It is not possible to copy from the source. This can happen if the source + * is hardware-protected or destroyed. + */ + public static final int ERROR_SOURCE_INVALID = 4; + + /** + * The destination isn't a valid copy target. If the destination is a bitmap + * this can occur if the bitmap is too large for the hardware to copy to. + * It can also occur if the destination has been destroyed. + */ + public static final int ERROR_DESTINATION_INVALID = 5; + + /** + * Listener for observing the completion of a PixelCopy request. + */ + public interface OnPixelCopyFinishedListener { + /** + * Callback for when a pixel copy request has completed. This will be called + * regardless of whether the copy succeeded or failed. + * + * @param copyResult Contains the resulting status of the copy request. + * This will either be {@link PixelCopy#SUCCESS} or one of the + * <code>PixelCopy.ERROR_*</code> values. + */ + void onPixelCopyFinished(@CopyResultStatus int copyResult); + } + + /** + * Requests for the display content of a {@link SurfaceView} to be copied + * into a provided {@link Bitmap}. + * + * The contents of the source will be scaled to fit exactly inside the bitmap. + * The pixel format of the source buffer will be converted, as part of the copy, + * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer + * in the SurfaceView's Surface will be used as the source of the copy. + * + * @param source The source from which to copy + * @param dest The destination of the copy. The source will be scaled to + * match the width, height, and format of this bitmap. + * @param listener Callback for when the pixel copy request completes + * @param listenerThread The callback will be invoked on this Handler when + * the copy is finished. + */ + public static void request(@NonNull SurfaceView source, @NonNull Bitmap dest, + @NonNull OnPixelCopyFinishedListener listener, @NonNull Handler listenerThread) { + request(source.getHolder().getSurface(), dest, listener, listenerThread); + } + + /** + * Requests a copy of the pixels from a {@link Surface} to be copied into + * a provided {@link Bitmap}. + * + * The contents of the source will be scaled to fit exactly inside the bitmap. + * The pixel format of the source buffer will be converted, as part of the copy, + * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer + * in the Surface will be used as the source of the copy. + * + * @param source The source from which to copy + * @param dest The destination of the copy. The source will be scaled to + * match the width, height, and format of this bitmap. + * @param listener Callback for when the pixel copy request completes + * @param listenerThread The callback will be invoked on this Handler when + * the copy is finished. + */ + public static void request(@NonNull Surface source, @NonNull Bitmap dest, + @NonNull OnPixelCopyFinishedListener listener, @NonNull Handler listenerThread) { + validateBitmapDest(dest); + // TODO: Make this actually async and fast and cool and stuff + int result = ThreadedRenderer.copySurfaceInto(source, dest); + listenerThread.post(new Runnable() { + @Override + public void run() { + listener.onPixelCopyFinished(result); + } + }); + } + + private static void validateBitmapDest(Bitmap bitmap) { + // TODO: Pre-check max texture dimens if we can + if (bitmap == null) { + throw new IllegalArgumentException("Bitmap cannot be null"); + } + if (bitmap.isRecycled()) { + throw new IllegalArgumentException("Bitmap is recycled"); + } + if (!bitmap.isMutable()) { + throw new IllegalArgumentException("Bitmap is immutable"); + } + } + + private PixelCopy() {} +} |