Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ce0793a authored by Rob Carr's avatar Rob Carr Committed by Android (Google) Code Review
Browse files

Merge "Expose SurfaceControl method to screenshot to GraphicBuffer."

parents c8544152 6486d31d
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import android.graphics.Bitmap;
import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder;
@@ -42,6 +43,9 @@ public class SurfaceControl {
    private static native Bitmap nativeScreenshot(IBinder displayToken,
            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
            boolean allLayers, boolean useIdentityTransform, int rotation);
    private static native GraphicBuffer nativeScreenshotToBuffer(IBinder displayToken,
            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
            boolean allLayers, boolean useIdentityTransform, int rotation);
    private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
            boolean allLayers, boolean useIdentityTransform);
@@ -827,6 +831,19 @@ public class SurfaceControl {
                minLayer, maxLayer, false, useIdentityTransform, rotation);
    }

    /**
     * Like {@link SurfaceControl#screenshot(Rect, int, int, int, int, boolean, int)}
     * but returns a GraphicBuffer.
     */
    public static GraphicBuffer screenshotToBuffer(Rect sourceCrop, int width, int height,
            int minLayer, int maxLayer, boolean useIdentityTransform,
            int rotation) {
        IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
        return nativeScreenshotToBuffer(displayToken, sourceCrop, width, height,
                minLayer, maxLayer, false, useIdentityTransform, rotation);
    }

    /**
     * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but
     * includes all Surfaces in the screenshot.
+11 −2
Original line number Diff line number Diff line
@@ -101,6 +101,13 @@ public:
// GraphicBuffer lifecycle
// ----------------------------------------------------------------------------

static jlong android_graphics_GraphicBuffer_wrap(JNIEnv* env, jobject clazz,
        jlong unwrapped) {
    sp<GraphicBuffer> b(reinterpret_cast<GraphicBuffer*>(unwrapped));
    GraphicBufferWrapper* wrapper = new GraphicBufferWrapper(b);
    return reinterpret_cast<jlong>(wrapper);
}

static jlong android_graphics_GraphicBuffer_create(JNIEnv* env, jobject clazz,
        jint width, jint height, jint format, jint usage) {

@@ -298,7 +305,9 @@ static const JNINativeMethod gMethods[] = {
    { "nLockCanvas", "(JLandroid/graphics/Canvas;Landroid/graphics/Rect;)Z",
            (void*) android_graphics_GraphicBuffer_lockCanvas },
    { "nUnlockCanvasAndPost", "(JLandroid/graphics/Canvas;)Z",
            (void*) android_graphics_GraphicBuffer_unlockCanvasAndPost }
            (void*) android_graphics_GraphicBuffer_unlockCanvasAndPost },
    { "nWrapGraphicBuffer", "(J)J",
            (void*) android_graphics_GraphicBuffer_wrap }
};

int register_android_graphics_GraphicBuffer(JNIEnv* env) {
+54 −6
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#define LOG_TAG "SurfaceControl"
#define LOG_NDEBUG 0

#include "android_os_Parcel.h"
#include "android_util_Binder.h"
@@ -89,6 +90,11 @@ static struct {
    jmethodID ctor;
} gHdrCapabilitiesClassInfo;

static struct {
    jclass clazz;
    jmethodID builder;
} gGraphicBufferClassInfo;

// ----------------------------------------------------------------------------

static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
@@ -123,6 +129,44 @@ static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
    }
}

static Rect rectFromObj(JNIEnv* env, jobject rectObj) {
    int left = env->GetIntField(rectObj, gRectClassInfo.left);
    int top = env->GetIntField(rectObj, gRectClassInfo.top);
    int right = env->GetIntField(rectObj, gRectClassInfo.right);
    int bottom = env->GetIntField(rectObj, gRectClassInfo.bottom);
    return Rect(left, top, right, bottom);
}

static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz,
        jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
        int rotation) {
    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
    if (displayToken == NULL) {
        return NULL;
    }
    Rect sourceCrop = rectFromObj(env, sourceCropObj);
    if (allLayers) {
        minLayer = 0;
        maxLayer = -1;
    }
    sp<GraphicBuffer> buffer;
    status_t res = ScreenshotClient::captureToBuffer(displayToken,
            sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform,
            rotation, &buffer);
    if (res != NO_ERROR) {
        return NULL;
    }

    return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
            gGraphicBufferClassInfo.builder,
            buffer->getWidth(),
            buffer->getHeight(),
            buffer->getPixelFormat(),
            buffer->getUsage(),
            (void*)buffer.get());
}

static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
        jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
@@ -132,11 +176,7 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
        return NULL;
    }

    int left = env->GetIntField(sourceCropObj, gRectClassInfo.left);
    int top = env->GetIntField(sourceCropObj, gRectClassInfo.top);
    int right = env->GetIntField(sourceCropObj, gRectClassInfo.right);
    int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom);
    Rect sourceCrop(left, top, right, bottom);
    Rect sourceCrop = rectFromObj(env, sourceCropObj);

    std::unique_ptr<ScreenshotClient> screenshot(new ScreenshotClient());
    status_t res;
@@ -787,6 +827,9 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeGetHandle },
    {"nativeGetTransformToDisplayInverse", "(J)Z",
     (void*)nativeGetTransformToDisplayInverse },
    {"nativeScreenshotToBuffer",
     "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/GraphicBuffer;",
     (void*)nativeScreenshotToBuffer },
};

int register_android_view_SurfaceControl(JNIEnv* env)
@@ -836,6 +879,11 @@ int register_android_view_SurfaceControl(JNIEnv* env)
    gHdrCapabilitiesClassInfo.ctor = GetMethodIDOrDie(env, hdrCapabilitiesClazz, "<init>",
            "([IFFF)V");

    jclass graphicsBufferClazz = FindClassOrDie(env, "android/graphics/GraphicBuffer");
    gGraphicBufferClassInfo.clazz = MakeGlobalRefOrDie(env, graphicsBufferClazz);
    gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
            "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");

    return err;
}

+14 −0
Original line number Diff line number Diff line
@@ -92,6 +92,19 @@ public class GraphicBuffer implements Parcelable {
        mNativeObject = nativeObject;
    }

    /**
     * For SurfaceControl JNI.
     * @hide
     */
    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;
    }

    /**
     * Returns the width of this buffer in pixels.
     */
@@ -286,4 +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);
}