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

Commit 17ac24b6 authored by chaviw's avatar chaviw
Browse files

Added new arguments for screenshot request

Added frameScaleX and frameScaleY to replace frameScale to allow callers
to specify an X and Y scale separately.

Added grayscale flag to allow the caller to take the screenshot
in grayscale.

Test: ScreenCaptureTest.CaptureWithGrayscale
Bug: 155825630
Change-Id: Iea043b7074707df897d80bf057d7cc3870afad89
parent 99599940
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -644,11 +644,13 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunc
status_t CaptureArgs::write(Parcel& output) const {
    SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(pixelFormat));
    SAFE_PARCEL(output.write, sourceCrop);
    SAFE_PARCEL(output.writeFloat, frameScale);
    SAFE_PARCEL(output.writeFloat, frameScaleX);
    SAFE_PARCEL(output.writeFloat, frameScaleY);
    SAFE_PARCEL(output.writeBool, captureSecureLayers);
    SAFE_PARCEL(output.writeInt32, uid);
    SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(dataspace));
    SAFE_PARCEL(output.writeBool, allowProtected);
    SAFE_PARCEL(output.writeBool, grayscale);
    return NO_ERROR;
}

@@ -657,12 +659,14 @@ status_t CaptureArgs::read(const Parcel& input) {
    SAFE_PARCEL(input.readInt32, &value);
    pixelFormat = static_cast<ui::PixelFormat>(value);
    SAFE_PARCEL(input.read, sourceCrop);
    SAFE_PARCEL(input.readFloat, &frameScale);
    SAFE_PARCEL(input.readFloat, &frameScaleX);
    SAFE_PARCEL(input.readFloat, &frameScaleY);
    SAFE_PARCEL(input.readBool, &captureSecureLayers);
    SAFE_PARCEL(input.readInt32, &uid);
    SAFE_PARCEL(input.readInt32, &value);
    dataspace = static_cast<ui::Dataspace>(value);
    SAFE_PARCEL(input.readBool, &allowProtected);
    SAFE_PARCEL(input.readBool, &grayscale);
    return NO_ERROR;
}

+4 −1
Original line number Diff line number Diff line
@@ -328,7 +328,8 @@ struct CaptureArgs {

    ui::PixelFormat pixelFormat{ui::PixelFormat::RGBA_8888};
    Rect sourceCrop;
    float frameScale{1};
    float frameScaleX{1};
    float frameScaleY{1};
    bool captureSecureLayers{false};
    int32_t uid{UNSET_UID};
    // Force capture to be in a color space. If the value is ui::Dataspace::UNKNOWN, the captured
@@ -346,6 +347,8 @@ struct CaptureArgs {
    // the contents being accessed/captured by screenshot or unsecure display.
    bool allowProtected = false;

    bool grayscale = false;

    virtual status_t write(Parcel& output) const;
    virtual status_t read(const Parcel& input);
};
+1 −1
Original line number Diff line number Diff line
@@ -451,7 +451,7 @@ void RegionSamplingThread::captureSample() {

    const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
    mFlinger.captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
                                 true /* regionSampling */, captureListener);
                                 true /* regionSampling */, false /* grayscale */, captureListener);
    ScreenCaptureResults captureResults = captureListener->waitForResults();

    std::vector<Descriptor> activeDescriptors;
+33 −26
Original line number Diff line number Diff line
@@ -4900,23 +4900,24 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co
    result.append("\n");
}

void SurfaceFlinger::updateColorMatrixLocked() {
    mat4 colorMatrix;
    if (mGlobalSaturationFactor != 1.0f) {
        // Rec.709 luma coefficients
mat4 SurfaceFlinger::calculateColorMatrix(float saturation) {
    if (saturation == 1) {
        return mat4();
    }

    float3 luminance{0.213f, 0.715f, 0.072f};
        luminance *= 1.0f - mGlobalSaturationFactor;
        mat4 saturationMatrix = mat4(
            vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f},
            vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f},
            vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f},
            vec4{0.0f, 0.0f, 0.0f, 1.0f}
        );
        colorMatrix = mClientColorMatrix * saturationMatrix * mDaltonizer();
    } else {
        colorMatrix = mClientColorMatrix * mDaltonizer();
    luminance *= 1.0f - saturation;
    mat4 saturationMatrix = mat4(vec4{luminance.r + saturation, luminance.r, luminance.r, 0.0f},
                                 vec4{luminance.g, luminance.g + saturation, luminance.g, 0.0f},
                                 vec4{luminance.b, luminance.b, luminance.b + saturation, 0.0f},
                                 vec4{0.0f, 0.0f, 0.0f, 1.0f});
    return saturationMatrix;
}

void SurfaceFlinger::updateColorMatrixLocked() {
    mat4 colorMatrix =
            mClientColorMatrix * calculateColorMatrix(mGlobalSaturationFactor) * mDaltonizer();

    if (mCurrentState.colorMatrix != colorMatrix) {
        mCurrentState.colorMatrix = colorMatrix;
        mCurrentState.colorMatrixChanged = true;
@@ -5628,7 +5629,8 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
    };

    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
                               args.pixelFormat, args.allowProtected, captureListener);
                               args.pixelFormat, args.allowProtected, args.grayscale,
                               captureListener);
}

status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack,
@@ -5664,7 +5666,7 @@ status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack,

    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
                               ui::PixelFormat::RGBA_8888, false /* allowProtected */,
                               captureListener);
                               false /* grayscale */, captureListener);
}

status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
@@ -5710,12 +5712,12 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
            crop.bottom = parentSourceBounds.getHeight();
        }

        if (crop.isEmpty() || args.frameScale <= 0.0f) {
        if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) {
            // Error out if the layer has no source bounds (i.e. they are boundless) and a source
            // crop was not specified, or an invalid frame scale was provided.
            return BAD_VALUE;
        }
        reqSize = ui::Size(crop.width() * args.frameScale, crop.height() * args.frameScale);
        reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY);

        for (const auto& handle : args.excludeHandles) {
            sp<Layer> excludeLayer = fromHandleLocked(handle).promote();
@@ -5785,13 +5787,14 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
    };

    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
                               args.pixelFormat, args.allowProtected, captureListener);
                               args.pixelFormat, args.allowProtected, args.grayscale,
                               captureListener);
}

status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
                                             TraverseLayersFunction traverseLayers,
                                             ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
                                             const bool allowProtected,
                                             bool allowProtected, bool grayscale,
                                             const sp<IScreenCaptureListener>& captureListener) {
    ATRACE_CALL();

@@ -5822,12 +5825,13 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
                                             static_cast<android_pixel_format>(reqPixelFormat),
                                             1 /* layerCount */, usage, "screenshot");
    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
                               false /* regionSampling */, captureListener);
                               false /* regionSampling */, grayscale, captureListener);
}

status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
                                             TraverseLayersFunction traverseLayers,
                                             sp<GraphicBuffer>& buffer, const bool regionSampling,
                                             sp<GraphicBuffer>& buffer, bool regionSampling,
                                             bool grayscale,
                                             const sp<IScreenCaptureListener>& captureListener) {
    ATRACE_CALL();

@@ -5843,7 +5847,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
        if (mRefreshPending) {
            ALOGW("Skipping screenshot for now");
            captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, regionSampling,
                                captureListener);
                                grayscale, captureListener);
            return;
        }
        ScreenCaptureResults captureResults;
@@ -5858,7 +5862,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
        status_t result = NO_ERROR;
        renderArea->render([&] {
            result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, forSystem,
                                            regionSampling, captureResults);
                                            regionSampling, grayscale, captureResults);
        });

        captureResults.result = result;
@@ -5871,7 +5875,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
                                                TraverseLayersFunction traverseLayers,
                                                const sp<GraphicBuffer>& buffer, bool forSystem,
                                                bool regionSampling,
                                                bool regionSampling, bool grayscale,
                                                ScreenCaptureResults& captureResults) {
    ATRACE_CALL();

@@ -5912,6 +5916,9 @@ status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
    clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace();
    clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance;

    const float colorSaturation = grayscale ? 0 : 1;
    clientCompositionDisplay.colorTransform = calculateColorMatrix(colorSaturation);

    const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill());

    compositionengine::LayerFE::LayerSettings fillLayer;
+6 −3
Original line number Diff line number Diff line
@@ -810,13 +810,14 @@ private:
    void startBootAnim();

    status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize,
                                 ui::PixelFormat, const bool allowProtected,
                                 ui::PixelFormat, bool allowProtected, bool grayscale,
                                 const sp<IScreenCaptureListener>&);
    status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, sp<GraphicBuffer>&,
                                 bool regionSampling, const sp<IScreenCaptureListener>&);
                                 bool regionSampling, bool grayscale,
                                 const sp<IScreenCaptureListener>&);
    status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction,
                                    const sp<GraphicBuffer>&, bool forSystem, bool regionSampling,
                                    ScreenCaptureResults&);
                                    bool grayscale, ScreenCaptureResults&);

    sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock);
    sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock);
@@ -1019,6 +1020,8 @@ private:

    void onFrameRateFlexibilityTokenReleased();

    static mat4 calculateColorMatrix(float saturation);

    void updateColorMatrixLocked();

    // Verify that transaction is being called by an approved process:
Loading