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

Commit bb7272f1 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "fix SF buffer cropping"

parents e7a8b17e 6b44267a
Loading
Loading
Loading
Loading
+42 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2013 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.
 */

#ifndef ANDROID_SF_FLOAT_RECT
#define ANDROID_SF_FLOAT_RECT

#include <utils/TypeHelpers.h>

namespace android {

class FloatRect
{
public:
    float left;
    float top;
    float right;
    float bottom;

    inline FloatRect() { }
    inline FloatRect(const Rect& other)
        : left(other.left), top(other.top), right(other.right), bottom(other.bottom) { }

    inline float getWidth() const { return right - left; }
    inline float getHeight() const { return bottom - top; }
};

}; // namespace android

#endif // ANDROID_SF_FLOAT_RECT
+19 −3
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <sys/types.h>
#include <sys/types.h>
#include <math.h>


#include <utils/CallStack.h>
#include <utils/CallStack.h>
#include <utils/Errors.h>
#include <utils/Errors.h>
@@ -880,10 +881,25 @@ public:
        getLayer()->transform = transform;
        getLayer()->transform = transform;
    }
    }
    virtual void setFrame(const Rect& frame) {
    virtual void setFrame(const Rect& frame) {
        reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
        getLayer()->displayFrame = reinterpret_cast<hwc_rect_t const&>(frame);
    }
    virtual void setCrop(const FloatRect& crop) {
        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
            getLayer()->sourceCropf = reinterpret_cast<hwc_frect_t const&>(crop);
        } else {
            /*
             * Since h/w composer didn't support a flot crop rect before version 1.3,
             * using integer coordinates instead produces a different output from the GL code in
             * Layer::drawWithOpenGL(). The difference can be large if the buffer crop to
             * window size ratio is large and a window crop is defined
             * (i.e.: if we scale the buffer a lot and we also crop it with a window crop).
             */
            hwc_rect_t& r = getLayer()->sourceCrop;
            r.left  = int(ceilf(crop.left));
            r.top   = int(ceilf(crop.top));
            r.right = int(floorf(crop.right));
            r.bottom= int(floorf(crop.bottom));
        }
        }
    virtual void setCrop(const Rect& crop) {
        reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
    }
    }
    virtual void setVisibleRegionScreen(const Region& reg) {
    virtual void setVisibleRegionScreen(const Region& reg) {
        // Region::getSharedBuffer creates a reference to the underlying
        // Region::getSharedBuffer creates a reference to the underlying
+2 −1
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ namespace android {


class GraphicBuffer;
class GraphicBuffer;
class Fence;
class Fence;
class FloatRect;
class Region;
class Region;
class String8;
class String8;
class SurfaceFlinger;
class SurfaceFlinger;
@@ -158,7 +159,7 @@ public:
        virtual void setBlending(uint32_t blending) = 0;
        virtual void setBlending(uint32_t blending) = 0;
        virtual void setTransform(uint32_t transform) = 0;
        virtual void setTransform(uint32_t transform) = 0;
        virtual void setFrame(const Rect& frame) = 0;
        virtual void setFrame(const Rect& frame) = 0;
        virtual void setCrop(const Rect& crop) = 0;
        virtual void setCrop(const FloatRect& crop) = 0;
        virtual void setVisibleRegionScreen(const Region& reg) = 0;
        virtual void setVisibleRegionScreen(const Region& reg) = 0;
        virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
        virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
        virtual void setAcquireFenceFd(int fenceFd) = 0;
        virtual void setAcquireFenceFd(int fenceFd) = 0;
+14 −27
Original line number Original line Diff line number Diff line
@@ -257,10 +257,6 @@ Rect Layer::getContentCrop() const {
    return crop;
    return crop;
}
}


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

static Rect reduce(const Rect& win, const Region& exclude) {
static Rect reduce(const Rect& win, const Region& exclude) {
    if (CC_LIKELY(exclude.isEmpty())) {
    if (CC_LIKELY(exclude.isEmpty())) {
        return win;
        return win;
@@ -281,18 +277,10 @@ Rect Layer::computeBounds() const {
    return reduce(win, s.activeTransparentRegion);
    return reduce(win, s.activeTransparentRegion);
}
}


Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
    /*
     * The way we compute the crop (aka. texture coordinates when we have a
     * Layer) produces a different output from the GL code in
     * drawWithOpenGL() due to HWC being limited to integers. The difference
     * can be large if getContentTransform() contains a large scale factor.
     * See comments in drawWithOpenGL() for more details.
     */

    // the content crop is the area of the content that gets scaled to the
    // the content crop is the area of the content that gets scaled to the
    // layer's size.
    // layer's size.
    Rect crop(getContentCrop());
    FloatRect crop(getContentCrop());


    // the active.crop is the area of the window that gets cropped, but not
    // the active.crop is the area of the window that gets cropped, but not
    // scaled in any ways.
    // scaled in any ways.
@@ -300,10 +288,10 @@ Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {


    // apply the projection's clipping to the window crop in
    // apply the projection's clipping to the window crop in
    // layerstack space, and convert-back to layer space.
    // layerstack space, and convert-back to layer space.
    // if there are no window scaling (or content scaling) involved,
    // if there are no window scaling involved, this operation will map to full
    // this operation will map to full pixels in the buffer.
    // pixels in the buffer.
    // NOTE: should we revert to GL composition if a scaling is involved
    // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
    // since it cannot be represented in the HWC API?
    // a viewport clipping and a window transform. we should use floating point to fix this.
    Rect activeCrop(s.transform.transform(s.active.crop));
    Rect activeCrop(s.transform.transform(s.active.crop));
    activeCrop.intersect(hw->getViewport(), &activeCrop);
    activeCrop.intersect(hw->getViewport(), &activeCrop);
    activeCrop = s.transform.inverse().transform(activeCrop);
    activeCrop = s.transform.inverse().transform(activeCrop);
@@ -319,7 +307,7 @@ Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
        // Transform the window crop to match the buffer coordinate system,
        // Transform the window crop to match the buffer coordinate system,
        // which means using the inverse of the current transform set on the
        // which means using the inverse of the current transform set on the
        // SurfaceFlingerConsumer.
        // SurfaceFlingerConsumer.
        uint32_t invTransform = getContentTransform();
        uint32_t invTransform = mCurrentTransform;
        int winWidth = s.active.w;
        int winWidth = s.active.w;
        int winHeight = s.active.h;
        int winHeight = s.active.h;
        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
@@ -331,15 +319,14 @@ Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
        const Rect winCrop = activeCrop.transform(
        const Rect winCrop = activeCrop.transform(
                invTransform, s.active.w, s.active.h);
                invTransform, s.active.w, s.active.h);


        // the code below essentially performs a scaled intersection
        // below, crop is intersected with winCrop expressed in crop's coordinate space
        // of crop and winCrop
        float xScale = crop.getWidth()  / float(winWidth);
        float xScale = float(crop.width()) / float(winWidth);
        float yScale = crop.getHeight() / float(winHeight);
        float yScale = float(crop.height()) / float(winHeight);


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


        crop.left   += insetL;
        crop.left   += insetL;
        crop.top    += insetT;
        crop.top    += insetT;
+2 −7
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@
#include "Transform.h"
#include "Transform.h"


#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/FloatRect.h"


namespace android {
namespace android {


@@ -279,12 +280,6 @@ public:
     */
     */
    Rect getContentCrop() const;
    Rect getContentCrop() const;


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

    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------


    void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
    void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
@@ -334,7 +329,7 @@ private:
    bool needsFiltering(const sp<const DisplayDevice>& hw) const;
    bool needsFiltering(const sp<const DisplayDevice>& hw) const;


    uint32_t getEffectiveUsage(uint32_t usage) const;
    uint32_t getEffectiveUsage(uint32_t usage) const;
    Rect computeCrop(const sp<const DisplayDevice>& hw) const;
    FloatRect computeCrop(const sp<const DisplayDevice>& hw) const;
    bool isCropped() const;
    bool isCropped() const;
    static bool getOpacityForFormat(uint32_t format);
    static bool getOpacityForFormat(uint32_t format);