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

Commit 7e35c55f authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Updated screenshot code to reflect native changes."

parents 1175af61 689e091c
Loading
Loading
Loading
Loading
+51 −46
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ int main(int argc, char** argv)
    void const* mapbase = MAP_FAILED;
    ssize_t mapsize = -1;

    void const* base = NULL;
    void* base = NULL;
    uint32_t w, s, h, f;
    android_dataspace d;
    size_t size = 0;
@@ -179,7 +179,6 @@ int main(int argc, char** argv)
    ProcessState::self()->setThreadPoolMaxThreadCount(0);
    ProcessState::self()->startThreadPool();

    ScreenshotClient screenshot;
    sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
    if (display == NULL) {
        fprintf(stderr, "Unable to get handle for display %d\n", displayId);
@@ -199,25 +198,32 @@ int main(int argc, char** argv)
    uint8_t displayOrientation = configs[activeConfig].orientation;
    uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];

    status_t result = screenshot.update(display, Rect(),
            0 /* reqWidth */, 0 /* reqHeight */,
            INT32_MIN, INT32_MAX, /* all layers */
            false, captureOrientation);
    if (result == NO_ERROR) {
        base = screenshot.getPixels();
        w = screenshot.getWidth();
        h = screenshot.getHeight();
        s = screenshot.getStride();
        f = screenshot.getFormat();
        d = screenshot.getDataSpace();
        size = screenshot.getSize();
    sp<GraphicBuffer> outBuffer;
    status_t result = ScreenshotClient::capture(display, Rect(), 0 /* reqWidth */,
            0 /* reqHeight */, INT32_MIN, INT32_MAX, /* all layers */ false, captureOrientation,
            &outBuffer);
    if (result != NO_ERROR) {
        close(fd);
        _exit(1);
    }

    if (base != NULL) {
    result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);

    if (base == NULL) {
        close(fd);
        _exit(1);
    }

    w = outBuffer->getWidth();
    h = outBuffer->getHeight();
    s = outBuffer->getStride();
    f = outBuffer->getPixelFormat();
    d = HAL_DATASPACE_UNKNOWN;
    size = s * h * bytesPerPixel(f);

    if (png) {
        const SkImageInfo info =
                SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType,
                    dataSpaceToColorSpace(d));
            SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType, dataSpaceToColorSpace(d));
        SkPixmap pixmap(info, base, s * bytesPerPixel(f));
        struct FDWStream final : public SkWStream {
          size_t fBytesWritten = 0;
@@ -245,7 +251,6 @@ int main(int argc, char** argv)
            base = (void *)((char *)base + s*Bpp);
        }
    }
    }
    close(fd);
    if (mapbase != MAP_FAILED) {
        munmap((void *)mapbase, mapsize);
+3 −13
Original line number Diff line number Diff line
@@ -55,8 +55,6 @@ public class SurfaceControl {
    private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
            boolean allLayers, boolean useIdentityTransform);
    private static native void nativeCaptureLayers(IBinder layerHandleToken, Surface consumer,
            Rect sourceCrop, float frameScale);
    private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
            Rect sourceCrop, float frameScale);

@@ -1179,22 +1177,14 @@ public class SurfaceControl {
     * Captures a layer and its children into the provided {@link Surface}.
     *
     * @param layerHandleToken The root layer to capture.
     * @param consumer         The {@link Surface} to capture the layer into.
     * @param sourceCrop       The portion of the root surface to capture; caller may pass in 'new
     *                         Rect()' or null if no cropping is desired.
     * @param frameScale       The desired scale of the returned buffer; the raw
     *                         screen will be scaled up/down.
     *
     * @return Returns a GraphicBuffer that contains the layer capture.
     */
    public static void captureLayers(IBinder layerHandleToken, Surface consumer, Rect sourceCrop,
            float frameScale) {
        nativeCaptureLayers(layerHandleToken, consumer, sourceCrop, frameScale);
    }

    /**
     * Same as {@link #captureLayers(IBinder, Surface, Rect, float)} except this
     * captures to a {@link GraphicBuffer} instead of a {@link Surface}.
     */
    public static GraphicBuffer captureLayersToBuffer(IBinder layerHandleToken, Rect sourceCrop,
    public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
            float frameScale) {
        return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale);
    }
+1 −17
Original line number Diff line number Diff line
@@ -517,23 +517,7 @@ static jint nativeAttachAndQueueBuffer(JNIEnv *env, jclass clazz, jlong nativeOb
        jobject graphicBuffer) {
    Surface* surface = reinterpret_cast<Surface*>(nativeObject);
    sp<GraphicBuffer> bp = graphicBufferForJavaObject(env, graphicBuffer);
    if (bp == nullptr) {
        return BAD_VALUE;
    }
    int err = ((ANativeWindow*)surface)->perform(surface, NATIVE_WINDOW_API_CONNECT,
            NATIVE_WINDOW_API_CPU);
    if (err != OK) {
        return err;
    }
    err = surface->attachBuffer(bp->getNativeBuffer());
    if (err != OK) {
        return err;
    }
    err = ((ANativeWindow*)surface)->queueBuffer(surface, bp->getNativeBuffer(), -1);
    if (err != OK) {
        return err;
    }
    err = surface->disconnect(NATIVE_WINDOW_API_CPU);
    int err = Surface::attachAndQueueBuffer(surface, bp);
    return err;
}

+27 −65
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ static jobject nativeScreenshotToBuffer(JNIEnv* env, jclass clazz,
        maxLayer = INT32_MAX;
    }
    sp<GraphicBuffer> buffer;
    status_t res = ScreenshotClient::captureToBuffer(displayToken,
    status_t res = ScreenshotClient::capture(displayToken,
            sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform,
            rotation, &buffer);
    if (res != NO_ERROR) {
@@ -201,15 +201,18 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
        maxLayer = INT32_MAX;
    }

    res = screenshot->update(displayToken, sourceCrop, width, height,
        minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation));
    sp<GraphicBuffer> buffer;
    res = ScreenshotClient::capture(displayToken, sourceCrop, width, height,
        minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation), &buffer);
    if (res != NO_ERROR) {
        return NULL;
    }

    SkColorType colorType;
    SkAlphaType alphaType;
    switch (screenshot->getFormat()) {

    PixelFormat format = buffer->getPixelFormat();
    switch (format) {
        case PIXEL_FORMAT_RGBX_8888: {
            colorType = kRGBA_8888_SkColorType;
            alphaType = kOpaque_SkAlphaType;
@@ -235,33 +238,12 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
        }
    }

    sk_sp<SkColorSpace> colorSpace;
    if (screenshot->getDataSpace() == HAL_DATASPACE_DISPLAY_P3) {
        colorSpace = SkColorSpace::MakeRGB(
                SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
    } else {
        colorSpace = SkColorSpace::MakeSRGB();
    }

    SkImageInfo screenshotInfo = SkImageInfo::Make(screenshot->getWidth(),
                                                   screenshot->getHeight(),
                                                   colorType,
                                                   alphaType,
                                                   colorSpace);

    const size_t rowBytes =
            screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());

    if (!screenshotInfo.width() || !screenshotInfo.height()) {
        return NULL;
    }
    SkImageInfo info = SkImageInfo::Make(buffer->getWidth(), buffer->getHeight(),
                                         colorType, alphaType,
                                         SkColorSpace::MakeSRGB());

    auto bitmap = new Bitmap(
            (void*) screenshot->getPixels(), (void*) screenshot.get(), DeleteScreenshot,
            screenshotInfo, rowBytes);
    screenshot.release();
    bitmap->setImmutable();
    return bitmap::createBitmap(env, bitmap,
    auto bitmap = sk_sp<Bitmap>(new Bitmap(buffer.get(), info));
    return bitmap::createBitmap(env, bitmap.release(),
                                android::bitmap::kBitmapCreateFlag_Premultiplied, NULL);
}

@@ -269,32 +251,7 @@ static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
        jobject surfaceObj, jobject sourceCropObj, jint width, jint height,
        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
    if (displayToken != NULL) {
        sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
        if (consumer != 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);

            if (allLayers) {
                minLayer = INT32_MIN;
                maxLayer = INT32_MAX;
            }
            ScreenshotClient::capture(displayToken,
                    consumer->getIGraphicBufferProducer(), sourceCrop,
                    width, height, minLayer, maxLayer,
                    useIdentityTransform);
        }
    }
}

static void nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
        jobject surfaceObj, jobject sourceCropObj, jfloat frameScale) {

    sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
    if (layerHandle == NULL) {
    if (displayToken == NULL) {
        return;
    }

@@ -308,11 +265,19 @@ static void nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleTo
        sourceCrop = rectFromObj(env, sourceCropObj);
    }

    ScreenshotClient::captureLayers(layerHandle, consumer->getIGraphicBufferProducer(), sourceCrop,
            frameScale);
    if (allLayers) {
        minLayer = INT32_MIN;
        maxLayer = INT32_MAX;
    }

static jobject nativeCaptureLayersToBuffer(JNIEnv* env, jclass clazz, jobject layerHandleToken,
    sp<GraphicBuffer> buffer;
    ScreenshotClient::capture(displayToken, sourceCrop, width, height, minLayer, maxLayer,
                              useIdentityTransform, 0, &buffer);

    Surface::attachAndQueueBuffer(consumer.get(), buffer);
}

static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
        jobject sourceCropObj, jfloat frameScale) {

    sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
@@ -326,8 +291,7 @@ static jobject nativeCaptureLayersToBuffer(JNIEnv* env, jclass clazz, jobject la
    }

    sp<GraphicBuffer> buffer;
    status_t res = ScreenshotClient::captureLayersToBuffer(layerHandle, sourceCrop, frameScale,
            &buffer);
    status_t res = ScreenshotClient::captureLayers(layerHandle, sourceCrop, frameScale, &buffer);
    if (res != NO_ERROR) {
        return NULL;
    }
@@ -1010,10 +974,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
    {"nativeScreenshotToBuffer",
     "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/GraphicBuffer;",
     (void*)nativeScreenshotToBuffer },
    {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;F)V",
            (void*)nativeCaptureLayers },
    {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
            (void*)nativeCaptureLayersToBuffer },
            (void*)nativeCaptureLayers },
};

int register_android_view_SurfaceControl(JNIEnv* env)
+2 −2
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
        Matrix matrix = new Matrix();
        int overlayColor = 0x40FFFFFF;

        Bitmap picture = Bitmap.createBitmap(previewWidth, previewHeight, data.image.getConfig());
        Bitmap picture = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
        matrix.setTranslate((previewWidth - mImageWidth) / 2, (previewHeight - mImageHeight) / 2);
        c.setBitmap(picture);
        c.drawBitmap(data.image, matrix, paint);
@@ -171,7 +171,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {

        // Note, we can't use the preview for the small icon, since it is non-square
        float scale = (float) iconSize / Math.min(mImageWidth, mImageHeight);
        Bitmap icon = Bitmap.createBitmap(iconSize, iconSize, data.image.getConfig());
        Bitmap icon = Bitmap.createBitmap(iconSize, iconSize, Bitmap.Config.ARGB_8888);
        matrix.setScale(scale, scale);
        matrix.postTranslate((iconSize - (scale * mImageWidth)) / 2,
                (iconSize - (scale * mImageHeight)) / 2);
Loading