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

Commit a8bca8d8 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

refactor the crop region for hwc is calculated/set

- the crop region is now always calculated and set
  in LayerBase::setGeometry which uses new virtuals to
  access the "content" crop and transform (which are
  provided by the Layer subclass)

Change-Id: Ib7769bdec0917dd248f926600c14ddf9ea84897a
parent f5f714aa
Loading
Loading
Loading
Loading
+12 −35
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <math.h>

#include <cutils/compiler.h>
#include <cutils/native_handle.h>
@@ -200,46 +199,25 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
    return NO_ERROR;
}

Rect Layer::computeBufferCrop() const {
    // Start with the SurfaceFlingerConsumer's buffer crop...
Rect Layer::getContentCrop() const {
    // this is the crop rectangle that applies to the buffer
    // itself (as opposed to the window)
    Rect crop;
    if (!mCurrentCrop.isEmpty()) {
        // if the buffer crop is defined, we use that
        crop = mCurrentCrop;
    } else if (mActiveBuffer != NULL) {
        crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
        // otherwise we use the whole buffer
        crop = mActiveBuffer->getBounds();
    } else {
        // if we don't have a buffer yet, we use an empty/invalid crop
        crop.makeInvalid();
        return crop;
    }

    // ... then reduce that in the same proportions as the window crop reduces
    // the window size.
    const State& s(drawingState());
    if (!s.active.crop.isEmpty()) {
        // Transform the window crop to match the buffer coordinate system,
        // which means using the inverse of the current transform set on the
        // SurfaceFlingerConsumer.
        uint32_t invTransform = mCurrentTransform;
        int winWidth = s.active.w;
        int winHeight = s.active.h;
        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
            winWidth = s.active.h;
            winHeight = s.active.w;
        }
        Rect winCrop = s.active.crop.transform(invTransform,
                s.active.w, s.active.h);

        float xScale = float(crop.width()) / float(winWidth);
        float yScale = float(crop.height()) / float(winHeight);
        crop.left += int(ceilf(float(winCrop.left) * xScale));
        crop.top += int(ceilf(float(winCrop.top) * yScale));
        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
    return crop;
}

    return crop;
uint32_t Layer::getContentTransform() const {
    return mCurrentTransform;
}

void Layer::setGeometry(
@@ -278,7 +256,6 @@ void Layer::setGeometry(
    } else {
        layer.setTransform(finalTransform);
    }
    layer.setCrop(computeBufferCrop());
}

void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
+3 −1
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ public:
    // the current orientation of the display device.
    virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const;

    virtual Rect getContentCrop() const;
    virtual uint32_t getContentTransform() const;

protected:
    virtual void onFirstRef();
    virtual void dump(String8& result, char* scratch, size_t size) const;
@@ -115,7 +118,6 @@ private:

    uint32_t getEffectiveUsage(uint32_t usage) const;
    bool isCropped() const;
    Rect computeBufferCrop() const;
    static bool getOpacityForFormat(uint32_t format);

    // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
+60 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <math.h>

#include <utils/Errors.h>
#include <utils/Log.h>
@@ -267,6 +268,61 @@ Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) {
    return result;
}


Rect LayerBase::getContentCrop() const {
    // regular layers just use their active area as the content crop
    const State& s(drawingState());
    return Rect(s.active.w, s.active.h);
}

uint32_t LayerBase::getContentTransform() const {
    // regular layers don't have a content transform
    return 0;
}

Rect LayerBase::computeCrop(const sp<const DisplayDevice>& hw) const {
    // the content crop is the area of the content that gets scaled to the
    // layer's size.
    Rect crop(getContentCrop());

    // the active.crop is the area of the window that gets cropped, but not
    // scaled in any ways.
    const State& s(drawingState());
    Rect activeCrop(s.active.crop);
    if (!activeCrop.isEmpty()) {
        // Transform the window crop to match the buffer coordinate system,
        // which means using the inverse of the current transform set on the
        // SurfaceFlingerConsumer.
        uint32_t invTransform = getContentTransform();
        int winWidth = s.active.w;
        int winHeight = s.active.h;
        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
            winWidth = s.active.h;
            winHeight = s.active.w;
        }
        const Rect winCrop = activeCrop.transform(
                invTransform, s.active.w, s.active.h);

        // the code below essentially performs a scaled intersection
        // of crop and winCrop
        float xScale = float(crop.width()) / float(winWidth);
        float yScale = float(crop.height()) / float(winHeight);

        int insetL = int(ceilf( winCrop.left                * xScale));
        int insetT = int(ceilf( winCrop.top                 * yScale));
        int insetR = int(ceilf((winWidth  - winCrop.right ) * xScale));
        int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));

        crop.left   += insetL;
        crop.top    += insetT;
        crop.right  -= insetR;
        crop.bottom -= insetB;
    }
    return crop;
}

void LayerBase::setGeometry(
    const sp<const DisplayDevice>& hw,
        HWComposer::HWCLayerInterface& layer)
@@ -290,15 +346,13 @@ void LayerBase::setGeometry(
    }


    Rect bounds(computeBounds());

    // apply the layer's transform, followed by the display's global transform
    // here we're guaranteed that the layer's transform preserves rects

    const Transform& tr = hw->getTransform();
    Rect frame(tr.transform(s.transform.transform(bounds)));
    layer.setFrame(frame);
    layer.setCrop(bounds);
    Rect frame(s.transform.transform(computeBounds()));
    const Transform& tr(hw->getTransform());
    layer.setFrame(tr.transform(frame));
    layer.setCrop(computeCrop(hw));
}

void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw,
+15 −0
Original line number Diff line number Diff line
@@ -260,6 +260,18 @@ public:
     */
    virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const { }

    /**
     * returns the rectangle that crops the content of the layer and scales it
     * to the layer's size.
     */
    virtual Rect getContentCrop() const;

    /*
     * returns the transform bits (90 rotation / h-flip / v-flip) of the
     * layer's content
     */
    virtual uint32_t getContentTransform() const;

    /** always call base class first */
    virtual void dump(String8& result, char* scratch, size_t size) const;
    virtual void shortDump(String8& result, char* scratch, size_t size) const;
@@ -282,6 +294,9 @@ public:
    void setFiltering(bool filtering);
    bool getFiltering() const;

private:
    Rect computeCrop(const sp<const DisplayDevice>& hw) const;

protected:
          void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
                  GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const;