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

Commit 29a7d0d6 authored by Romain Guy's avatar Romain Guy Committed by Android Git Automerger
Browse files

am 68c02e25: Merge "Preliminary support for clipRect(Rect, Op)"

* commit '68c02e25':
  Preliminary support for clipRect(Rect, Op)
parents 193b0cf4 68c02e25
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -12734,9 +12734,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     * </p>
     *
     * <p>
     * The actual mesurement work of a view is performed in
     * The actual measurement work of a view is performed in
     * {@link #onMeasure(int, int)}, called by this method. Therefore, only
     * {@link #onMeasure(int, int)} can and must be overriden by subclasses.
     * {@link #onMeasure(int, int)} can and must be overridden by subclasses.
     * </p>
     *
     *
+14 −0
Original line number Diff line number Diff line
@@ -55,43 +55,51 @@ public:
            void        set(uint32_t w, uint32_t h);
        
            Region&     orSelf(const Rect& rhs);
            Region&     xorSelf(const Rect& rhs);
            Region&     andSelf(const Rect& rhs);
            Region&     subtractSelf(const Rect& rhs);

            // boolean operators, applied on this
            Region&     orSelf(const Region& rhs);
            Region&     xorSelf(const Region& rhs);
            Region&     andSelf(const Region& rhs);
            Region&     subtractSelf(const Region& rhs);

            // boolean operators
    const   Region      merge(const Rect& rhs) const;
    const   Region      mergeExclusive(const Rect& rhs) const;
    const   Region      intersect(const Rect& rhs) const;
    const   Region      subtract(const Rect& rhs) const;

            // boolean operators
    const   Region      merge(const Region& rhs) const;
    const   Region      mergeExclusive(const Region& rhs) const;
    const   Region      intersect(const Region& rhs) const;
    const   Region      subtract(const Region& rhs) const;

            // these translate rhs first
            Region&     translateSelf(int dx, int dy);
            Region&     orSelf(const Region& rhs, int dx, int dy);
            Region&     xorSelf(const Region& rhs, int dx, int dy);
            Region&     andSelf(const Region& rhs, int dx, int dy);
            Region&     subtractSelf(const Region& rhs, int dx, int dy);

            // these translate rhs first
    const   Region      translate(int dx, int dy) const;
    const   Region      merge(const Region& rhs, int dx, int dy) const;
    const   Region      mergeExclusive(const Region& rhs, int dx, int dy) const;
    const   Region      intersect(const Region& rhs, int dx, int dy) const;
    const   Region      subtract(const Region& rhs, int dx, int dy) const;

    // convenience operators overloads
    inline  const Region      operator | (const Region& rhs) const;
    inline  const Region      operator ^ (const Region& rhs) const;
    inline  const Region      operator & (const Region& rhs) const;
    inline  const Region      operator - (const Region& rhs) const;
    inline  const Region      operator + (const Point& pt) const;

    inline  Region&     operator |= (const Region& rhs);
    inline  Region&     operator ^= (const Region& rhs);
    inline  Region&     operator &= (const Region& rhs);
    inline  Region&     operator -= (const Region& rhs);
    inline  Region&     operator += (const Point& pt);
@@ -158,6 +166,9 @@ private:
const Region Region::operator | (const Region& rhs) const {
    return merge(rhs);
}
const Region Region::operator ^ (const Region& rhs) const {
    return mergeExclusive(rhs);
}
const Region Region::operator & (const Region& rhs) const {
    return intersect(rhs);
}
@@ -172,6 +183,9 @@ const Region Region::operator + (const Point& pt) const {
Region& Region::operator |= (const Region& rhs) {
    return orSelf(rhs);
}
Region& Region::operator ^= (const Region& rhs) {
    return xorSelf(rhs);
}
Region& Region::operator &= (const Region& rhs) {
    return andSelf(rhs);
}
+121 −19
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ Snapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0),
    transform = &mTransformRoot;
    clipRect = &mClipRectRoot;
    region = NULL;
    clipRegion = NULL;
}

/**
@@ -52,8 +53,21 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags):
    if (saveFlags & SkCanvas::kClip_SaveFlag) {
        mClipRectRoot.set(*s->clipRect);
        clipRect = &mClipRectRoot;
#if STENCIL_BUFFER_SIZE
        if (s->clipRegion) {
            mClipRegionRoot.merge(*s->clipRegion);
            clipRegion = &mClipRegionRoot;
        } else {
            clipRegion = NULL;
        }
#else
        clipRegion = NULL;
#endif
    } else {
        clipRect = s->clipRect;
#if STENCIL_BUFFER_SIZE
        clipRegion = s->clipRegion;
#endif
    }

    if (s->flags & Snapshot::kFlagFboTarget) {
@@ -68,6 +82,77 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags):
// Clipping
///////////////////////////////////////////////////////////////////////////////

void Snapshot::ensureClipRegion() {
#if STENCIL_BUFFER_SIZE
    if (!clipRegion) {
        clipRegion = &mClipRegionRoot;
        android::Rect tmp(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
        clipRegion->set(tmp);
    }
#endif
}

void Snapshot::copyClipRectFromRegion() {
#if STENCIL_BUFFER_SIZE
    if (!clipRegion->isEmpty()) {
        android::Rect bounds(clipRegion->bounds());
        clipRect->set(bounds.left, bounds.top, bounds.right, bounds.bottom);

        if (clipRegion->isRect()) {
            clipRegion->clear();
            clipRegion = NULL;
        }
    } else {
        clipRect->setEmpty();
        clipRegion = NULL;
    }
#endif
}

bool Snapshot::clipRegionOr(float left, float top, float right, float bottom) {
#if STENCIL_BUFFER_SIZE
    android::Rect tmp(left, top, right, bottom);
    clipRegion->orSelf(tmp);
    copyClipRectFromRegion();
    return true;
#else
    return false;
#endif
}

bool Snapshot::clipRegionXor(float left, float top, float right, float bottom) {
#if STENCIL_BUFFER_SIZE
    android::Rect tmp(left, top, right, bottom);
    clipRegion->xorSelf(tmp);
    copyClipRectFromRegion();
    return true;
#else
    return false;
#endif
}

bool Snapshot::clipRegionAnd(float left, float top, float right, float bottom) {
#if STENCIL_BUFFER_SIZE
    android::Rect tmp(left, top, right, bottom);
    clipRegion->andSelf(tmp);
    copyClipRectFromRegion();
    return true;
#else
    return false;
#endif
}

bool Snapshot::clipRegionNand(float left, float top, float right, float bottom) {
#if STENCIL_BUFFER_SIZE
    android::Rect tmp(left, top, right, bottom);
    clipRegion->subtractSelf(tmp);
    copyClipRectFromRegion();
    return true;
#else
    return false;
#endif
}

bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
    Rect r(left, top, right, bottom);
    transform->mapRect(r);
@@ -77,33 +162,47 @@ bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::
bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
    bool clipped = false;

    // NOTE: The unimplemented operations require support for regions
    // Supporting regions would require using a stencil buffer instead
    // of the scissor. The stencil buffer itself is not too expensive
    // (memory cost excluded) but on fillrate limited devices, managing
    // the stencil might have a negative impact on the framerate.
    switch (op) {
        case SkRegion::kDifference_Op:
        case SkRegion::kDifference_Op: {
            ensureClipRegion();
            clipped = clipRegionNand(r.left, r.top, r.right, r.bottom);
            break;
        case SkRegion::kIntersect_Op:
        }
        case SkRegion::kIntersect_Op: {
            if (CC_UNLIKELY(clipRegion)) {
                clipped = clipRegionOr(r.left, r.top, r.right, r.bottom);
            } else {
                clipped = clipRect->intersect(r);
                if (!clipped) {
                    clipRect->setEmpty();
                    clipped = true;
                }
            }
            break;
        case SkRegion::kUnion_Op:
        }
        case SkRegion::kUnion_Op: {
            if (CC_UNLIKELY(clipRegion)) {
                clipped = clipRegionAnd(r.left, r.top, r.right, r.bottom);
            } else {
                clipped = clipRect->unionWith(r);
            }
            break;
        case SkRegion::kXOR_Op:
        }
        case SkRegion::kXOR_Op: {
            ensureClipRegion();
            clipped = clipRegionXor(r.left, r.top, r.right, r.bottom);
            break;
        case SkRegion::kReverseDifference_Op:
        }
        case SkRegion::kReverseDifference_Op: {
            // TODO!!!!!!!
            break;
        case SkRegion::kReplace_Op:
            clipRect->set(r);
        }
        case SkRegion::kReplace_Op: {
            setClip(r.left, r.top, r.right, r.bottom);
            clipped = true;
            break;
        }
    }

    if (clipped) {
        flags |= Snapshot::kFlagClipSet;
@@ -114,6 +213,10 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {

void Snapshot::setClip(float left, float top, float right, float bottom) {
    clipRect->set(left, top, right, bottom);
    if (clipRegion) {
        clipRegion->clear();
        clipRegion = NULL;
    }
    flags |= Snapshot::kFlagClipSet;
}

@@ -129,8 +232,7 @@ const Rect& Snapshot::getLocalClip() {

void Snapshot::resetClip(float left, float top, float right, float bottom) {
    clipRect = &mClipRectRoot;
    clipRect->set(left, top, right, bottom);
    flags |= Snapshot::kFlagClipSet;
    setClip(left, top, right, bottom);
}

///////////////////////////////////////////////////////////////////////////////
+24 −1
Original line number Diff line number Diff line
@@ -181,7 +181,7 @@ public:
    mat4* transform;

    /**
     * Current clip region. The clip is stored in canvas-space coordinates,
     * Current clip rect. The clip is stored in canvas-space coordinates,
     * (screen-space coordinates in the regular case.)
     *
     * This is a reference to a rect owned by this snapshot or another
@@ -189,6 +189,17 @@ public:
     */
    Rect* clipRect;

    /**
     * Current clip region. The clip is stored in canvas-space coordinates,
     * (screen-space coordinates in the regular case.)
     *
     * This is a reference to a region owned by this snapshot or another
     * snapshot. This pointer must not be freed. See ::mClipRegionRoot.
     *
     * This field is used only if STENCIL_BUFFER_SIZE is > 0.
     */
    Region* clipRegion;

    /**
     * The ancestor layer's dirty region.
     *
@@ -198,10 +209,22 @@ public:
    Region* region;

private:
    void ensureClipRegion();
    void copyClipRectFromRegion();

    bool clipRegionOr(float left, float top, float right, float bottom);
    bool clipRegionXor(float left, float top, float right, float bottom);
    bool clipRegionAnd(float left, float top, float right, float bottom);
    bool clipRegionNand(float left, float top, float right, float bottom);

    mat4 mTransformRoot;
    Rect mClipRectRoot;
    Rect mLocalClip;

#if STENCIL_BUFFER_SIZE
    Region mClipRegionRoot;
#endif

}; // class Snapshot

}; // namespace uirenderer
+19 −0
Original line number Diff line number Diff line
@@ -126,6 +126,9 @@ void Region::addRectUnchecked(int l, int t, int r, int b)
Region& Region::orSelf(const Rect& r) {
    return operationSelf(r, op_or);
}
Region& Region::xorSelf(const Rect& r) {
    return operationSelf(r, op_xor);
}
Region& Region::andSelf(const Rect& r) {
    return operationSelf(r, op_and);
}
@@ -143,6 +146,9 @@ Region& Region::operationSelf(const Rect& r, int op) {
Region& Region::orSelf(const Region& rhs) {
    return operationSelf(rhs, op_or);
}
Region& Region::xorSelf(const Region& rhs) {
    return operationSelf(rhs, op_xor);
}
Region& Region::andSelf(const Region& rhs) {
    return operationSelf(rhs, op_and);
}
@@ -165,6 +171,9 @@ Region& Region::translateSelf(int x, int y) {
const Region Region::merge(const Rect& rhs) const {
    return operation(rhs, op_or);
}
const Region Region::mergeExclusive(const Rect& rhs) const {
    return operation(rhs, op_xor);
}
const Region Region::intersect(const Rect& rhs) const {
    return operation(rhs, op_and);
}
@@ -182,6 +191,9 @@ const Region Region::operation(const Rect& rhs, int op) const {
const Region Region::merge(const Region& rhs) const {
    return operation(rhs, op_or);
}
const Region Region::mergeExclusive(const Region& rhs) const {
    return operation(rhs, op_xor);
}
const Region Region::intersect(const Region& rhs) const {
    return operation(rhs, op_and);
}
@@ -205,6 +217,9 @@ const Region Region::translate(int x, int y) const {
Region& Region::orSelf(const Region& rhs, int dx, int dy) {
    return operationSelf(rhs, dx, dy, op_or);
}
Region& Region::xorSelf(const Region& rhs, int dx, int dy) {
    return operationSelf(rhs, dx, dy, op_xor);
}
Region& Region::andSelf(const Region& rhs, int dx, int dy) {
    return operationSelf(rhs, dx, dy, op_and);
}
@@ -222,6 +237,9 @@ Region& Region::operationSelf(const Region& rhs, int dx, int dy, int op) {
const Region Region::merge(const Region& rhs, int dx, int dy) const {
    return operation(rhs, dx, dy, op_or);
}
const Region Region::mergeExclusive(const Region& rhs, int dx, int dy) const {
    return operation(rhs, dx, dy, op_xor);
}
const Region Region::intersect(const Region& rhs, int dx, int dy) const {
    return operation(rhs, dx, dy, op_and);
}
@@ -421,6 +439,7 @@ void Region::boolean_operation(int op, Region& dst,
    SkRegion::Op sk_op;
    switch (op) {
        case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break;
        case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break;
        case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break;
        case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break;
    }
Loading