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

Commit f6b5d187 authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

[SF] Extract {Display|Layer}RenderArea to separate files

This CL also fixes incorrect sampling bounds in RegionSamplingThread,
caused by ag/11837111.

Bug: 158599281
Test: atest libsurfaceflinger_unittest
Test: take a screenshot from launcher
Test: take a screenshot from YouTube while playing a video
Change-Id: I7e7777071e91a833a7bad4bd77e9d0c989fea9b7
parent 40270c68
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ filegroup {
        "DisplayHardware/HWComposer.cpp",
        "DisplayHardware/PowerAdvisor.cpp",
        "DisplayHardware/VirtualDisplaySurface.cpp",
        "DisplayRenderArea.cpp",
        "Effects/Daltonizer.cpp",
        "EventLog/EventLog.cpp",
        "FrameTracer/FrameTracer.cpp",
@@ -152,6 +153,7 @@ filegroup {
        "Layer.cpp",
        "LayerProtoHelper.cpp",
        "LayerRejecter.cpp",
        "LayerRenderArea.cpp",
        "LayerVector.cpp",
        "MonitoredProducer.cpp",
        "NativeWindowSurface.cpp",
+0 −120
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
#include "DisplayHardware/DisplayIdentification.h"
#include "DisplayHardware/Hal.h"
#include "DisplayHardware/PowerAdvisor.h"
#include "RenderArea.h"
#include "Scheduler/HwcStrongTypes.h"

namespace android {
@@ -246,123 +245,4 @@ struct DisplayDeviceCreationArgs {
    bool isPrimary{false};
};

class DisplayRenderArea : public RenderArea {
public:
    static std::unique_ptr<RenderArea> create(wp<const DisplayDevice> displayWeak,
                                              const Rect& sourceCrop, ui::Size reqSize,
                                              ui::Dataspace reqDataSpace, RotationFlags rotation,
                                              bool allowSecureLayers = true) {
        if (auto display = displayWeak.promote()) {
            // Using new to access a private constructor.
            return std::unique_ptr<DisplayRenderArea>(
                    new DisplayRenderArea(std::move(display), sourceCrop, reqSize, reqDataSpace,
                                          rotation, allowSecureLayers));
        }
        return nullptr;
    }

    const ui::Transform& getTransform() const override { return mTransform; }
    Rect getBounds() const override { return mDisplay->getBounds(); }
    int getHeight() const override { return mDisplay->getHeight(); }
    int getWidth() const override { return mDisplay->getWidth(); }
    bool isSecure() const override { return mAllowSecureLayers && mDisplay->isSecure(); }
    sp<const DisplayDevice> getDisplayDevice() const override { return mDisplay; }

    bool needsFiltering() const override {
        // check if the projection from the logical render area
        // to the physical render area requires filtering
        const Rect& sourceCrop = getSourceCrop();
        int width = sourceCrop.width();
        int height = sourceCrop.height();
        if (getRotationFlags() & ui::Transform::ROT_90) {
            std::swap(width, height);
        }
        return width != getReqWidth() || height != getReqHeight();
    }

    Rect getSourceCrop() const override {
        // use the projected display viewport by default.
        if (mSourceCrop.isEmpty()) {
            return mDisplay->getSourceClip();
        }

        // If there is a source crop provided then it is assumed that the device
        // was in portrait orientation. This may not logically be true, so
        // correct for the orientation error by undoing the rotation

        ui::Rotation logicalOrientation = mDisplay->getOrientation();
        if (logicalOrientation == ui::Rotation::Rotation90) {
            logicalOrientation = ui::Rotation::Rotation270;
        } else if (logicalOrientation == ui::Rotation::Rotation270) {
            logicalOrientation = ui::Rotation::Rotation90;
        }

        const auto flags = ui::Transform::toRotationFlags(logicalOrientation);
        int width = mDisplay->getSourceClip().getWidth();
        int height = mDisplay->getSourceClip().getHeight();
        ui::Transform rotation;
        rotation.set(flags, width, height);
        return rotation.transform(mSourceCrop);
    }

private:
    DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, ui::Size reqSize,
                      ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers)
          : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, display->getViewport(),
                       applyDeviceOrientation(rotation, display)),
            mDisplay(std::move(display)),
            mSourceCrop(sourceCrop),
            mAllowSecureLayers(allowSecureLayers) {}

    static RotationFlags applyDeviceOrientation(RotationFlags orientationFlag,
                                                const sp<const DisplayDevice>& device) {
        uint32_t inverseRotate90 = 0;
        uint32_t inverseReflect = 0;

        // Reverse the logical orientation.
        ui::Rotation logicalOrientation = device->getOrientation();
        if (logicalOrientation == ui::Rotation::Rotation90) {
            logicalOrientation = ui::Rotation::Rotation270;
        } else if (logicalOrientation == ui::Rotation::Rotation270) {
            logicalOrientation = ui::Rotation::Rotation90;
        }

        const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation;

        switch (orientation) {
            case ui::ROTATION_0:
                return orientationFlag;

            case ui::ROTATION_90:
                inverseRotate90 = ui::Transform::ROT_90;
                inverseReflect = ui::Transform::ROT_180;
                break;

            case ui::ROTATION_180:
                inverseReflect = ui::Transform::ROT_180;
                break;

            case ui::ROTATION_270:
                inverseRotate90 = ui::Transform::ROT_90;
                break;
        }

        const uint32_t rotate90 = orientationFlag & ui::Transform::ROT_90;
        uint32_t reflect = orientationFlag & ui::Transform::ROT_180;

        // Apply reflection for double rotation.
        if (rotate90 & inverseRotate90) {
            reflect = ~reflect & ui::Transform::ROT_180;
        }

        return static_cast<RotationFlags>((rotate90 ^ inverseRotate90) |
                                          (reflect ^ inverseReflect));
    }

    const sp<const DisplayDevice> mDisplay;
    const Rect mSourceCrop;
    const bool mAllowSecureLayers;
    const ui::Transform mTransform = ui::Transform();
};

} // namespace android
+154 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#include "DisplayRenderArea.h"
#include "DisplayDevice.h"

namespace android {
namespace {

RenderArea::RotationFlags applyDeviceOrientation(RenderArea::RotationFlags rotation,
                                                 const DisplayDevice& display) {
    uint32_t inverseRotate90 = 0;
    uint32_t inverseReflect = 0;

    // Reverse the logical orientation.
    ui::Rotation logicalOrientation = display.getOrientation();
    if (logicalOrientation == ui::Rotation::Rotation90) {
        logicalOrientation = ui::Rotation::Rotation270;
    } else if (logicalOrientation == ui::Rotation::Rotation270) {
        logicalOrientation = ui::Rotation::Rotation90;
    }

    const ui::Rotation orientation = display.getPhysicalOrientation() + logicalOrientation;

    switch (orientation) {
        case ui::ROTATION_0:
            return rotation;

        case ui::ROTATION_90:
            inverseRotate90 = ui::Transform::ROT_90;
            inverseReflect = ui::Transform::ROT_180;
            break;

        case ui::ROTATION_180:
            inverseReflect = ui::Transform::ROT_180;
            break;

        case ui::ROTATION_270:
            inverseRotate90 = ui::Transform::ROT_90;
            break;
    }

    const uint32_t rotate90 = rotation & ui::Transform::ROT_90;
    uint32_t reflect = rotation & ui::Transform::ROT_180;

    // Apply reflection for double rotation.
    if (rotate90 & inverseRotate90) {
        reflect = ~reflect & ui::Transform::ROT_180;
    }

    return static_cast<RenderArea::RotationFlags>((rotate90 ^ inverseRotate90) |
                                                  (reflect ^ inverseReflect));
}

} // namespace

std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak,
                                                      const Rect& sourceCrop, ui::Size reqSize,
                                                      ui::Dataspace reqDataSpace,
                                                      RotationFlags rotation,
                                                      bool allowSecureLayers) {
    if (auto display = displayWeak.promote()) {
        // Using new to access a private constructor.
        return std::unique_ptr<DisplayRenderArea>(
                new DisplayRenderArea(std::move(display), sourceCrop, reqSize, reqDataSpace,
                                      rotation, allowSecureLayers));
    }
    return nullptr;
}

DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop,
                                     ui::Size reqSize, ui::Dataspace reqDataSpace,
                                     RotationFlags rotation, bool allowSecureLayers)
      : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, display->getViewport(),
                   applyDeviceOrientation(rotation, *display)),
        mDisplay(std::move(display)),
        mSourceCrop(sourceCrop),
        mAllowSecureLayers(allowSecureLayers) {}

const ui::Transform& DisplayRenderArea::getTransform() const {
    return mTransform;
}

Rect DisplayRenderArea::getBounds() const {
    return mDisplay->getBounds();
}

int DisplayRenderArea::getHeight() const {
    return mDisplay->getHeight();
}

int DisplayRenderArea::getWidth() const {
    return mDisplay->getWidth();
}

bool DisplayRenderArea::isSecure() const {
    return mAllowSecureLayers && mDisplay->isSecure();
}

sp<const DisplayDevice> DisplayRenderArea::getDisplayDevice() const {
    return mDisplay;
}

bool DisplayRenderArea::needsFiltering() const {
    // check if the projection from the logical render area
    // to the physical render area requires filtering
    const Rect& sourceCrop = getSourceCrop();
    int width = sourceCrop.width();
    int height = sourceCrop.height();
    if (getRotationFlags() & ui::Transform::ROT_90) {
        std::swap(width, height);
    }
    return width != getReqWidth() || height != getReqHeight();
}

Rect DisplayRenderArea::getSourceCrop() const {
    // use the projected display viewport by default.
    if (mSourceCrop.isEmpty()) {
        return mDisplay->getSourceClip();
    }

    // If there is a source crop provided then it is assumed that the device
    // was in portrait orientation. This may not logically be true, so
    // correct for the orientation error by undoing the rotation

    ui::Rotation logicalOrientation = mDisplay->getOrientation();
    if (logicalOrientation == ui::Rotation::Rotation90) {
        logicalOrientation = ui::Rotation::Rotation270;
    } else if (logicalOrientation == ui::Rotation::Rotation270) {
        logicalOrientation = ui::Rotation::Rotation90;
    }

    const auto flags = ui::Transform::toRotationFlags(logicalOrientation);
    int width = mDisplay->getSourceClip().getWidth();
    int height = mDisplay->getSourceClip().getHeight();
    ui::Transform rotation;
    rotation.set(flags, width, height);
    return rotation.transform(mSourceCrop);
}

} // namespace android
 No newline at end of file
+54 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#pragma once

#include <ui/GraphicTypes.h>
#include <ui/Transform.h>

#include "RenderArea.h"

namespace android {

class DisplayDevice;

class DisplayRenderArea : public RenderArea {
public:
    static std::unique_ptr<RenderArea> create(wp<const DisplayDevice>, const Rect& sourceCrop,
                                              ui::Size reqSize, ui::Dataspace,
                                              RotationFlags rotation,
                                              bool allowSecureLayers = true);

    const ui::Transform& getTransform() const override;
    Rect getBounds() const override;
    int getHeight() const override;
    int getWidth() const override;
    bool isSecure() const override;
    sp<const DisplayDevice> getDisplayDevice() const override;
    bool needsFiltering() const override;
    Rect getSourceCrop() const override;

private:
    DisplayRenderArea(sp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize,
                      ui::Dataspace, RotationFlags rotation, bool allowSecureLayers = true);

    const sp<const DisplayDevice> mDisplay;
    const Rect mSourceCrop;
    const bool mAllowSecureLayers;
    const ui::Transform mTransform;
};

} // namespace android
 No newline at end of file
+113 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#include <ui/GraphicTypes.h>
#include <ui/Transform.h>

#include "ContainerLayer.h"
#include "DisplayDevice.h"
#include "Layer.h"
#include "LayerRenderArea.h"
#include "SurfaceFlinger.h"

namespace android {
namespace {

struct ReparentForDrawing {
    const sp<Layer>& oldParent;

    ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent,
                       const Rect& drawingBounds)
          : oldParent(oldParent) {
        // Compute and cache the bounds for the new parent layer.
        newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(),
                                 0.f /* shadowRadius */);
        oldParent->setChildrenDrawingParent(newParent);
    }
    ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); }
};

} // namespace

LayerRenderArea::LayerRenderArea(SurfaceFlinger& flinger, sp<Layer> layer, const Rect& crop,
                                 ui::Size reqSize, ui::Dataspace reqDataSpace, bool childrenOnly,
                                 const Rect& displayViewport)
      : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, displayViewport),
        mLayer(std::move(layer)),
        mCrop(crop),
        mFlinger(flinger),
        mChildrenOnly(childrenOnly) {}

const ui::Transform& LayerRenderArea::getTransform() const {
    return mTransform;
}

Rect LayerRenderArea::getBounds() const {
    return mLayer->getBufferSize(mLayer->getDrawingState());
}

int LayerRenderArea::getHeight() const {
    return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
}

int LayerRenderArea::getWidth() const {
    return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth();
}

bool LayerRenderArea::isSecure() const {
    return false;
}

bool LayerRenderArea::needsFiltering() const {
    return mNeedsFiltering;
}

sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const {
    return nullptr;
}

Rect LayerRenderArea::getSourceCrop() const {
    if (mCrop.isEmpty()) {
        return getBounds();
    } else {
        return mCrop;
    }
}

void LayerRenderArea::render(std::function<void()> drawLayers) {
    using namespace std::string_literals;

    const Rect sourceCrop = getSourceCrop();
    // no need to check rotation because there is none
    mNeedsFiltering = sourceCrop.width() != getReqWidth() || sourceCrop.height() != getReqHeight();

    if (!mChildrenOnly) {
        mTransform = mLayer->getTransform().inverse();
        drawLayers();
    } else {
        uint32_t w = static_cast<uint32_t>(getWidth());
        uint32_t h = static_cast<uint32_t>(getHeight());
        // In the "childrenOnly" case we reparent the children to a screenshot
        // layer which has no properties set and which does not draw.
        sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer(
                {&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()});

        ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop);
        drawLayers();
    }
}

} // namespace android
Loading