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

Commit abbbf46a authored by Chia-I Wu's avatar Chia-I Wu Committed by Android (Google) Code Review
Browse files

Merge changes from topic "renderarea"

* changes:
  surfaceflinger: fix race conditions in captureScreen
  surfaceflinger: remove ISurfaceComposer.h from RenderArea
  surfaceflinger: reorder width and height in RenderArea ctor
  surfaceflinger: documents RenderArea
parents 0b31ffc8 20261cb5
Loading
Loading
Loading
Loading
+5 −6
Original line number Original line Diff line number Diff line
@@ -25,7 +25,6 @@


#include <binder/IBinder.h>
#include <binder/IBinder.h>
#include <hardware/hwcomposer_defs.h>
#include <hardware/hwcomposer_defs.h>
#include <gui/ISurfaceComposer.h>
#include <math/mat4.h>
#include <math/mat4.h>
#include <renderengine/Surface.h>
#include <renderengine/Surface.h>
#include <ui/GraphicTypes.h>
#include <ui/GraphicTypes.h>
@@ -334,12 +333,12 @@ private:
class DisplayRenderArea : public RenderArea {
class DisplayRenderArea : public RenderArea {
public:
public:
    DisplayRenderArea(const sp<const DisplayDevice> device,
    DisplayRenderArea(const sp<const DisplayDevice> device,
                      ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone)
                      ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
          : DisplayRenderArea(device, device->getBounds(), device->getHeight(), device->getWidth(),
          : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(),
                              rotation) {}
                              rotation) {}
    DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight,
    DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
                      uint32_t reqWidth, ISurfaceComposer::Rotation rotation)
                      uint32_t reqHeight, ui::Transform::orientation_flags rotation)
          : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device),
          : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, rotation), mDevice(device),
                              mSourceCrop(sourceCrop) {}
                              mSourceCrop(sourceCrop) {}


    const ui::Transform& getTransform() const override { return mDevice->getTransform(); }
    const ui::Transform& getTransform() const override { return mDevice->getTransform(); }
+0 −55
Original line number Original line Diff line number Diff line
#include "RenderArea.h"
#include "RenderArea.h"


#include <gui/LayerState.h>

namespace android {
namespace android {


ui::Transform::orientation_flags fromRotation(ISurfaceComposer::Rotation rotation) {
    switch (rotation) {
        case ISurfaceComposer::eRotateNone:
            return ui::Transform::ROT_0;
        case ISurfaceComposer::eRotate90:
            return ui::Transform::ROT_90;
        case ISurfaceComposer::eRotate180:
            return ui::Transform::ROT_180;
        case ISurfaceComposer::eRotate270:
            return ui::Transform::ROT_270;
    }
    ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
    return ui::Transform::ROT_0;
}

RenderArea::RenderArea(uint32_t reqHeight, uint32_t reqWidth, CaptureFill captureFill,
                       ISurfaceComposer::Rotation rotation)
      : mReqHeight(reqHeight), mReqWidth(reqWidth), mCaptureFill(captureFill) {
    mRotationFlags = fromRotation(rotation);
}

float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
    switch(captureFill) {
    switch(captureFill) {
        case CaptureFill::CLEAR:
        case CaptureFill::CLEAR:
@@ -34,37 +11,5 @@ float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
            return 1.0f;
            return 1.0f;
    }
    }
}
}
/*
 * Checks that the requested width and height are valid and updates them to the render area
 * dimensions if they are set to 0
 */
status_t RenderArea::updateDimensions(int displayRotation) {
    // get screen geometry

    uint32_t width = getWidth();
    uint32_t height = getHeight();

    if (mRotationFlags & ui::Transform::ROT_90) {
        std::swap(width, height);
    }

    if (displayRotation & DisplayState::eOrientationSwapMask) {
        std::swap(width, height);
    }

    if ((mReqWidth > width) || (mReqHeight > height)) {
        ALOGE("size mismatch (%d, %d) > (%d, %d)", mReqWidth, mReqHeight, width, height);
        return BAD_VALUE;
    }

    if (mReqWidth == 0) {
        mReqWidth = width;
    }
    if (mReqHeight == 0) {
        mReqHeight = height;
    }

    return NO_ERROR;
}


} // namespace android
} // namespace android
+50 −17
Original line number Original line Diff line number Diff line
#pragma once
#pragma once


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


#include <functional>
#include <functional>


namespace android {
namespace android {


// RenderArea describes a rectangular area that layers can be rendered to.
//
// There is a logical render area and a physical render area.  When a layer is
// rendered to the render area, it is first transformed and clipped to the logical
// render area.  The transformed and clipped layer is then projected onto the
// physical render area.
class RenderArea {
class RenderArea {

public:
public:
    enum class CaptureFill {CLEAR, OPAQUE};
    enum class CaptureFill {CLEAR, OPAQUE};


    static float getCaptureFillValue(CaptureFill captureFill);
    static float getCaptureFillValue(CaptureFill captureFill);


    RenderArea(uint32_t reqHeight, uint32_t reqWidth, CaptureFill captureFill,
    RenderArea(uint32_t reqWidth, uint32_t reqHeight, CaptureFill captureFill,
               ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone);
               ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
          : mReqWidth(reqWidth),
            mReqHeight(reqHeight),
            mCaptureFill(captureFill),
            mRotationFlags(rotation) {}


    virtual ~RenderArea() = default;
    virtual ~RenderArea() = default;


    virtual const ui::Transform& getTransform() const = 0;
    // Invoke drawLayers to render layers into the render area.
    virtual Rect getBounds() const = 0;
    virtual void render(std::function<void()> drawLayers) { drawLayers(); }
    virtual int getHeight() const = 0;

    virtual int getWidth() const = 0;
    // Returns true if the render area is secure.  A secure layer should be
    // blacked out / skipped when rendered to an insecure render area.
    virtual bool isSecure() const = 0;
    virtual bool isSecure() const = 0;

    // Returns true if the otherwise disabled layer filtering should be
    // enabled when rendering to this render area.
    virtual bool needsFiltering() const = 0;
    virtual bool needsFiltering() const = 0;

    // Returns the transform to be applied on layers to transform them into
    // the logical render area.
    virtual const ui::Transform& getTransform() const = 0;

    // Returns the size of the logical render area.  Layers are clipped to the
    // logical render area.
    virtual int getWidth() const = 0;
    virtual int getHeight() const = 0;
    virtual Rect getBounds() const = 0;

    // Returns the source crop of the render area.  The source crop defines
    // how layers are projected from the logical render area onto the physical
    // render area.  It can be larger than the logical render area.  It can
    // also be optionally rotated.
    //
    // Layers are first clipped to the source crop (in addition to being
    // clipped to the logical render area already).  The source crop and the
    // layers are then rotated around the center of the source crop, and
    // scaled to the physical render area linearly.
    virtual Rect getSourceCrop() const = 0;
    virtual Rect getSourceCrop() const = 0;


    virtual void render(std::function<void()> drawLayers) { drawLayers(); }
    // Returns the rotation of the source crop and the layers.
    ui::Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };


    int getReqHeight() const { return mReqHeight; };
    // Returns the size of the physical render area.
    int getReqWidth() const { return mReqWidth; };
    int getReqWidth() const { return mReqWidth; };
    ui::Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
    int getReqHeight() const { return mReqHeight; };
    status_t updateDimensions(int displayRotation);


    // Returns the fill color of the physical render area.  Regions not
    // covered by any rendered layer should be filled with this color.
    CaptureFill getCaptureFill() const { return mCaptureFill; };
    CaptureFill getCaptureFill() const { return mCaptureFill; };


private:
private:
    uint32_t mReqHeight;
    const uint32_t mReqWidth;
    uint32_t mReqWidth;
    const uint32_t mReqHeight;
    ui::Transform::orientation_flags mRotationFlags;
    const CaptureFill mCaptureFill;
    CaptureFill mCaptureFill;
    const ui::Transform::orientation_flags mRotationFlags;
};
};


} // namespace android
} // namespace android
+64 −13
Original line number Original line Diff line number Diff line
@@ -143,6 +143,21 @@ bool isWideColorMode(const ColorMode colorMode) {
    return false;
    return false;
}
}


ui::Transform::orientation_flags fromSurfaceComposerRotation(ISurfaceComposer::Rotation rotation) {
    switch (rotation) {
        case ISurfaceComposer::eRotateNone:
            return ui::Transform::ROT_0;
        case ISurfaceComposer::eRotate90:
            return ui::Transform::ROT_90;
        case ISurfaceComposer::eRotate180:
            return ui::Transform::ROT_180;
        case ISurfaceComposer::eRotate270:
            return ui::Transform::ROT_270;
    }
    ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
    return ui::Transform::ROT_0;
}

#pragma clang diagnostic pop
#pragma clang diagnostic pop


class ConditionalLock {
class ConditionalLock {
@@ -4902,7 +4917,13 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,


    if (!displayToken) return BAD_VALUE;
    if (!displayToken) return BAD_VALUE;


    const auto display = getDisplayDeviceLocked(displayToken);
    auto renderAreaRotation = fromSurfaceComposerRotation(rotation);

    sp<DisplayDevice> display;
    {
        Mutex::Autolock _l(mStateLock);

        display = getDisplayDeviceLocked(displayToken);
        if (!display) return BAD_VALUE;
        if (!display) return BAD_VALUE;


        const Rect& dispScissor = display->getScissor();
        const Rect& dispScissor = display->getScissor();
@@ -4915,7 +4936,31 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,
            }
            }
        }
        }


    DisplayRenderArea renderArea(display, sourceCrop, reqHeight, reqWidth, rotation);
        // get screen geometry
        uint32_t width = display->getWidth();
        uint32_t height = display->getHeight();

        if (renderAreaRotation & ui::Transform::ROT_90) {
            std::swap(width, height);
        }

        if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
            std::swap(width, height);
        }

        if ((reqWidth > width) || (reqHeight > height)) {
            ALOGE("size mismatch (%d, %d) > (%d, %d)", reqWidth, reqHeight, width, height);
        } else {
            if (reqWidth == 0) {
                reqWidth = width;
            }
            if (reqHeight == 0) {
                reqHeight = height;
            }
        }
    }

    DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, renderAreaRotation);


    auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
    auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
                                    display, minLayerZ, maxLayerZ, std::placeholders::_1);
                                    display, minLayerZ, maxLayerZ, std::placeholders::_1);
@@ -4931,7 +4976,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
    public:
    public:
        LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
        LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
                        int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
                        int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
              : RenderArea(reqHeight, reqWidth, CaptureFill::CLEAR),
              : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR),
                mLayer(layer),
                mLayer(layer),
                mCrop(crop),
                mCrop(crop),
                mFlinger(flinger),
                mFlinger(flinger),
@@ -5023,6 +5068,14 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
    int32_t reqWidth = crop.width() * frameScale;
    int32_t reqWidth = crop.width() * frameScale;
    int32_t reqHeight = crop.height() * frameScale;
    int32_t reqHeight = crop.height() * frameScale;


    // really small crop or frameScale
    if (reqWidth <= 0) {
        reqWidth = 1;
    }
    if (reqHeight <= 0) {
        reqHeight = 1;
    }

    LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly);
    LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly);


    auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) {
    auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) {
@@ -5044,8 +5097,6 @@ status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
                                             bool useIdentityTransform) {
                                             bool useIdentityTransform) {
    ATRACE_CALL();
    ATRACE_CALL();


    renderArea.updateDimensions(mPrimaryDisplayOrientation);

    const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
    const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
            GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
            GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
    *outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),
    *outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),