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

Commit 3b14b7db authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topic "RenderArea"

* changes:
  Respect source crop when capturing layers.
  libgui: add docs to geometry states and captureScreen
  surfaceflinger: fix captureScreen for landscape LCM
  surfaceflinger: improve RenderArea needsFiltering
  surfaceflinger: respect install orientation in DisplayRenderArea
  surfaceflinger: add install orientation to DisplayDevice
  surfaceflinger: make mPrimaryDisplayOrientation static
  surfaceflinger: clean up captureScreen
  surfaceflinger: silence some RenderArea errors
  surfaceflinger: fix race conditions in captureScreen
  surfaceflinger: remove ISurfaceComposer.h from RenderArea
  surfaceflinger: reorder width and height in RenderArea ctor
  surfaceflinger: documents RenderArea
parents 81c1bf02 76607ada
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -174,8 +174,25 @@ public:
    virtual status_t setActiveColorMode(const sp<IBinder>& display,
            ui::ColorMode colorMode) = 0;

    /* Capture the specified screen. requires READ_FRAME_BUFFER permission
     * This function will fail if there is a secure window on screen.
    /**
     * Capture the specified screen. This requires READ_FRAME_BUFFER
     * permission.  This function will fail if there is a secure window on
     * screen.
     *
     * This function can capture a subregion (the source crop) of the screen.
     * The subregion can be optionally rotated.  It will also be scaled to
     * match the size of the output buffer.
     *
     * At the moment, sourceCrop is ignored and is always set to the visible
     * region (projected display viewport) of the screen.
     *
     * reqWidth and reqHeight specifies the size of the buffer.  When either
     * of them is 0, they are set to the size of the logical display viewport.
     *
     * When useIdentityTransform is true, layer transformations are disabled.
     *
     * rotation specifies the rotation of the source crop (and the pixels in
     * it) around its center.
     */
    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
+14 −0
Original line number Diff line number Diff line
@@ -152,10 +152,24 @@ struct DisplayState {
    sp<IBinder> token;
    sp<IGraphicBufferProducer> surface;
    uint32_t layerStack;

    // These states define how layers are projected onto the physical display.
    //
    // Layers are first clipped to `viewport'.  They are then translated and
    // scaled from `viewport' to `frame'.  Finally, they are rotated according
    // to `orientation', `width', and `height'.
    //
    // For example, assume viewport is Rect(0, 0, 200, 100), frame is Rect(20,
    // 10, 420, 210), and the size of the display is WxH.  When orientation is
    // 0, layers will be scaled by a factor of 2 and translated by (20, 10).
    // When orientation is 1, layers will be additionally rotated by 90
    // degrees around the origin clockwise and translated by (W, 0).
    uint32_t orientation;
    Rect viewport;
    Rect frame;

    uint32_t width, height;

    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
};
+1 −1
Original line number Diff line number Diff line
@@ -204,7 +204,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip,

    if (!blackOutLayer) {
        // TODO: we could be more subtle with isFixedSize()
        const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize();
        const bool useFiltering = needsFiltering(renderArea) || isFixedSize();

        // Query the texture matrix given our current filtering mode.
        float textureMatrix[16];
+3 −2
Original line number Diff line number Diff line
@@ -224,6 +224,7 @@ DisplayDevice::DisplayDevice(
        std::unique_ptr<RE::Surface> renderSurface,
        int displayWidth,
        int displayHeight,
        int displayInstallOrientation,
        bool hasWideColorGamut,
        const HdrCapabilities& hdrCapabilities,
        const int32_t supportedPerFrameMetadata,
@@ -239,6 +240,7 @@ DisplayDevice::DisplayDevice(
      mSurface{std::move(renderSurface)},
      mDisplayWidth(displayWidth),
      mDisplayHeight(displayHeight),
      mDisplayInstallOrientation(displayInstallOrientation),
      mPageFlipCount(0),
      mIsSecure(isSecure),
      mLayerStack(NO_LAYER_STACK),
@@ -610,9 +612,8 @@ void DisplayDevice::setProjection(int orientation,
    // need to take care of primary display rotation for mGlobalTransform
    // for case if the panel is not installed aligned with device orientation
    if (mType == DisplayType::DISPLAY_PRIMARY) {
        int primaryDisplayOrientation = mFlinger->getPrimaryDisplayOrientation();
        DisplayDevice::orientationToTransfrom(
                (orientation + primaryDisplayOrientation) % (DisplayState::eOrientation270 + 1),
                (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1),
                w, h, &R);
    }

+97 −9
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
#include <math/mat4.h>

#include <binder/IBinder.h>
#include <gui/ISurfaceComposer.h>
#include <gui/LayerState.h>
#include <hardware/hwcomposer_defs.h>
#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
@@ -88,6 +88,7 @@ public:
            std::unique_ptr<RE::Surface> renderSurface,
            int displayWidth,
            int displayHeight,
            int displayInstallOrientation,
            bool hasWideColorGamut,
            const HdrCapabilities& hdrCapabilities,
            const int32_t supportedPerFrameMetadata,
@@ -111,6 +112,7 @@ public:

    int         getWidth() const;
    int         getHeight() const;
    int         getInstallOrientation() const { return mDisplayInstallOrientation; }

    void                    setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers);
    const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const;
@@ -234,6 +236,7 @@ private:
    std::unique_ptr<RE::Surface> mSurface;
    int             mDisplayWidth;
    int             mDisplayHeight;
    const int       mDisplayInstallOrientation;
    mutable uint32_t mPageFlipCount;
    String8         mDisplayName;
    bool            mIsSecure;
@@ -337,12 +340,14 @@ struct DisplayDeviceState {
class DisplayRenderArea : public RenderArea {
public:
    DisplayRenderArea(const sp<const DisplayDevice> device,
                      ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone)
          : DisplayRenderArea(device, device->getBounds(), device->getHeight(), device->getWidth(),
                      Transform::orientation_flags rotation = Transform::ROT_0)
          : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(),
                              rotation) {}
    DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight,
                      uint32_t reqWidth, ISurfaceComposer::Rotation rotation)
          : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device),
    DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
                      uint32_t reqHeight, Transform::orientation_flags rotation)
          : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE,
                       getDisplayRotation(rotation, device->getInstallOrientation())),
            mDevice(device),
            mSourceCrop(sourceCrop) {}

    const Transform& getTransform() const override { return mDevice->getTransform(); }
@@ -350,10 +355,93 @@ public:
    int getHeight() const override { return mDevice->getHeight(); }
    int getWidth() const override { return mDevice->getWidth(); }
    bool isSecure() const override { return mDevice->isSecure(); }
    bool needsFiltering() const override { return mDevice->needsFiltering(); }
    Rect getSourceCrop() const override { return mSourceCrop; }

    bool needsFiltering() const override {
        // check if the projection from the logical display to the physical
        // display needs filtering
        if (mDevice->needsFiltering()) {
            return true;
        }

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

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

        const int orientation = mDevice->getInstallOrientation();
        if (orientation == DisplayState::eOrientationDefault) {
            return mSourceCrop;
        }

        // Install orientation is transparent to the callers.  Apply it now.
        uint32_t flags = 0x00;
        switch (orientation) {
            case DisplayState::eOrientation90:
                flags = Transform::ROT_90;
                break;
            case DisplayState::eOrientation180:
                flags = Transform::ROT_180;
                break;
            case DisplayState::eOrientation270:
                flags = Transform::ROT_270;
                break;
        }
        Transform tr;
        tr.set(flags, getWidth(), getHeight());
        return tr.transform(mSourceCrop);
    }

private:
    // Install orientation is transparent to the callers.  We need to cancel
    // it out by modifying rotation flags.
    static Transform::orientation_flags getDisplayRotation(
            Transform::orientation_flags rotation, int orientation) {
        if (orientation == DisplayState::eOrientationDefault) {
            return rotation;
        }

        // convert hw orientation into flag presentation
        // here inverse transform needed
        uint8_t hw_rot_90 = 0x00;
        uint8_t hw_flip_hv = 0x00;
        switch (orientation) {
            case DisplayState::eOrientation90:
                hw_rot_90 = Transform::ROT_90;
                hw_flip_hv = Transform::ROT_180;
                break;
            case DisplayState::eOrientation180:
                hw_flip_hv = Transform::ROT_180;
                break;
            case DisplayState::eOrientation270:
                hw_rot_90 = Transform::ROT_90;
                break;
        }

        // transform flags operation
        // 1) flip H V if both have ROT_90 flag
        // 2) XOR these flags
        uint8_t rotation_rot_90 = rotation & Transform::ROT_90;
        uint8_t rotation_flip_hv = rotation & Transform::ROT_180;
        if (rotation_rot_90 & hw_rot_90) {
            rotation_flip_hv = (~rotation_flip_hv) & Transform::ROT_180;
        }

        return static_cast<Transform::orientation_flags>(
                (rotation_rot_90 ^ hw_rot_90) | (rotation_flip_hv ^ hw_flip_hv));
    }

    const sp<const DisplayDevice> mDevice;
    const Rect mSourceCrop;
};
Loading