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

Commit 3ab68558 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

change how we store Region data internally

We used to keep the bounds of the region as a
separate rectangle. Instead we now store it as the last
element of the Vector<> of Rects.

This has the benefit of being slightly more efficient when
copying regions and reduces the overhead of small regions,
but more importantly will allow us to export the underlaying
SharedBuffer (eventually).

Change-Id: I80790e4fb1a09a747a5616000cfef852ac4ce9e9
parent 4c0a1705
Loading
Loading
Loading
Loading
+8 −6
Original line number Original line Diff line number Diff line
@@ -41,10 +41,10 @@ public:
                        
                        
        Region& operator = (const Region& rhs);
        Region& operator = (const Region& rhs);


    inline  bool        isEmpty() const     { return mBounds.isEmpty();  }
    inline  bool        isEmpty() const     { return getBounds().isEmpty(); }
    inline  bool        isRect() const      { return mStorage.isEmpty(); }
    inline  bool        isRect() const      { return mStorage.size() == 1; }


    inline  Rect        getBounds() const   { return mBounds; }
    inline  Rect        getBounds() const   { return mStorage[mStorage.size() - 1]; }
    inline  Rect        bounds() const      { return getBounds(); }
    inline  Rect        bounds() const      { return getBounds(); }


            // the region becomes its bounds
            // the region becomes its bounds
@@ -114,7 +114,6 @@ public:


    /* no user serviceable parts here... */
    /* no user serviceable parts here... */
            
            
            size_t      getRects(Vector<Rect>& rectList) const;
            Rect const* getArray(size_t* count) const;
            Rect const* getArray(size_t* count) const;


            
            
@@ -156,7 +155,10 @@ private:


    static bool validate(const Region& reg, const char* name);
    static bool validate(const Region& reg, const char* name);
    
    
    Rect            mBounds;
    // mStorage is a (manually) sorted array of Rects describing the region
    // with an extra Rect as the last element which is set to the
    // bounds of the region. However, if the region is
    // a simple Rect then mStorage contains only that rect.
    Vector<Rect> mStorage;
    Vector<Rect> mStorage;
};
};


+30 −43
Original line number Original line Diff line number Diff line
@@ -48,22 +48,20 @@ enum {


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


Region::Region()
Region::Region() {
    : mBounds(0,0)
    mStorage.add(Rect(0,0));
{
}
}


Region::Region(const Region& rhs)
Region::Region(const Region& rhs)
    : mBounds(rhs.mBounds), mStorage(rhs.mStorage)
    : mStorage(rhs.mStorage)
{
{
#if VALIDATE_REGIONS
#if VALIDATE_REGIONS
    validate(rhs, "rhs copy-ctor");
    validate(rhs, "rhs copy-ctor");
#endif
#endif
}
}


Region::Region(const Rect& rhs)
Region::Region(const Rect& rhs) {
    : mBounds(rhs)
    mStorage.add(rhs);
{
}
}


Region::~Region()
Region::~Region()
@@ -76,40 +74,46 @@ Region& Region::operator = (const Region& rhs)
    validate(*this, "this->operator=");
    validate(*this, "this->operator=");
    validate(rhs, "rhs.operator=");
    validate(rhs, "rhs.operator=");
#endif
#endif
    mBounds = rhs.mBounds;
    mStorage = rhs.mStorage;
    mStorage = rhs.mStorage;
    return *this;
    return *this;
}
}


Region& Region::makeBoundsSelf()
Region& Region::makeBoundsSelf()
{
{
    if (mStorage.size() >= 2) {
        const Rect bounds(getBounds());
        mStorage.clear();
        mStorage.clear();
        mStorage.add(bounds);
    }
    return *this;
    return *this;
}
}


void Region::clear()
void Region::clear()
{
{
    mBounds.clear();
    mStorage.clear();
    mStorage.clear();
    mStorage.add(Rect(0,0));
}
}


void Region::set(const Rect& r)
void Region::set(const Rect& r)
{
{
    mBounds = r;
    mStorage.clear();
    mStorage.clear();
    mStorage.add(r);
}
}


void Region::set(uint32_t w, uint32_t h)
void Region::set(uint32_t w, uint32_t h)
{
{
    mBounds = Rect(int(w), int(h));
    mStorage.clear();
    mStorage.clear();
    mStorage.add(Rect(w,h));
}
}


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


void Region::addRectUnchecked(int l, int t, int r, int b)
void Region::addRectUnchecked(int l, int t, int r, int b)
{
{
    mStorage.add(Rect(l,t,r,b));
    Rect rect(l,t,r,b);
    size_t where = mStorage.size() - 1;
    mStorage.insertAt(rect, where, 1);

#if VALIDATE_REGIONS
#if VALIDATE_REGIONS
    validate(*this, "addRectUnchecked");
    validate(*this, "addRectUnchecked");
#endif
#endif
@@ -252,7 +256,7 @@ const Region Region::operation(const Region& rhs, int dx, int dy, int op) const
// to obtain an optimal region.
// to obtain an optimal region.
class Region::rasterizer : public region_operator<Rect>::region_rasterizer 
class Region::rasterizer : public region_operator<Rect>::region_rasterizer 
{
{
    Rect& bounds;
    Rect bounds;
    Vector<Rect>& storage;
    Vector<Rect>& storage;
    Rect* head;
    Rect* head;
    Rect* tail;
    Rect* tail;
@@ -260,10 +264,7 @@ class Region::rasterizer : public region_operator<Rect>::region_rasterizer
    Rect* cur;
    Rect* cur;
public:
public:
    rasterizer(Region& reg) 
    rasterizer(Region& reg) 
        : bounds(reg.mBounds), storage(reg.mStorage), head(), tail(), cur() {
        : bounds(INT_MAX, 0, INT_MIN, 0), storage(reg.mStorage), head(), tail(), cur() {
        bounds.top = bounds.bottom = 0;
        bounds.left   = INT_MAX;
        bounds.right  = INT_MIN;
        storage.clear();
        storage.clear();
    }
    }


@@ -281,6 +282,7 @@ public:
            bounds.left  = 0;
            bounds.left  = 0;
            bounds.right = 0;
            bounds.right = 0;
        }
        }
        storage.add(bounds);
    }
    }
    
    
    virtual void operator()(const Rect& rect) {
    virtual void operator()(const Rect& rect) {
@@ -372,6 +374,9 @@ bool Region::validate(const Region& reg, const char* name)
                reg.getBounds().left, reg.getBounds().top, 
                reg.getBounds().left, reg.getBounds().top, 
                reg.getBounds().right, reg.getBounds().bottom);
                reg.getBounds().right, reg.getBounds().bottom);
    }
    }
    if (reg.mStorage.size() == 2) {
        ALOGE("mStorage size is 2, which is never valid");
    }
    if (result == false) {
    if (result == false) {
        reg.dump(name);
        reg.dump(name);
    }
    }
@@ -533,7 +538,6 @@ void Region::translate(Region& reg, int dx, int dy)
#if VALIDATE_REGIONS
#if VALIDATE_REGIONS
        validate(reg, "translate (before)");
        validate(reg, "translate (before)");
#endif
#endif
        reg.mBounds.translate(dx, dy);
        size_t count = reg.mStorage.size();
        size_t count = reg.mStorage.size();
        Rect* rects = reg.mStorage.editArray();
        Rect* rects = reg.mStorage.editArray();
        while (count) {
        while (count) {
@@ -556,12 +560,11 @@ void Region::translate(Region& dst, const Region& reg, int dx, int dy)
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


size_t Region::getSize() const {
size_t Region::getSize() const {
    return (mStorage.size() + 1) * sizeof(Rect);
    return mStorage.size() * sizeof(Rect);
}
}


status_t Region::flatten(void* buffer) const {
status_t Region::flatten(void* buffer) const {
    Rect* rects = reinterpret_cast<Rect*>(buffer);
    Rect* rects = reinterpret_cast<Rect*>(buffer);
    *rects++ = mBounds;
    memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
    memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
    return NO_ERROR;
    return NO_ERROR;
}
}
@@ -570,8 +573,6 @@ status_t Region::unflatten(void const* buffer, size_t size) {
    mStorage.clear();
    mStorage.clear();
    if (size >= sizeof(Rect)) {
    if (size >= sizeof(Rect)) {
        Rect const* rects = reinterpret_cast<Rect const*>(buffer);
        Rect const* rects = reinterpret_cast<Rect const*>(buffer);
        mBounds = *rects++;
        size -= sizeof(Rect);
        size_t count = size / sizeof(Rect);
        size_t count = size / sizeof(Rect);
        if (count > 0) {
        if (count > 0) {
            ssize_t err = mStorage.insertAt(0, count);
            ssize_t err = mStorage.insertAt(0, count);
@@ -581,25 +582,21 @@ status_t Region::unflatten(void const* buffer, size_t size) {
            memcpy(mStorage.editArray(), rects, count*sizeof(Rect));
            memcpy(mStorage.editArray(), rects, count*sizeof(Rect));
        }
        }
    }
    }
#if VALIDATE_REGIONS
    validate(*this, "Region::unflatten");
#endif
    return NO_ERROR;
    return NO_ERROR;
}
}


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


Region::const_iterator Region::begin() const {
Region::const_iterator Region::begin() const {
    return isRect() ? &mBounds : mStorage.array();
    return mStorage.array();
}
}


Region::const_iterator Region::end() const {
Region::const_iterator Region::end() const {
    if (isRect()) {
    size_t numRects = isRect() ? 1 : mStorage.size() - 1;
        if (isEmpty()) {
    return mStorage.array() + numRects;
            return &mBounds;
        } else {
            return &mBounds + 1;
        }
    } else {
        return mStorage.array() + mStorage.size();
    }
}
}


Rect const* Region::getArray(size_t* count) const {
Rect const* Region::getArray(size_t* count) const {
@@ -609,16 +606,6 @@ Rect const* Region::getArray(size_t* count) const {
    return b;
    return b;
}
}


size_t Region::getRects(Vector<Rect>& rectList) const
{
    rectList = mStorage;
    if (rectList.isEmpty()) {
        rectList.clear();
        rectList.add(mBounds);
    }
    return rectList.size();
}

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


void Region::dump(String8& out, const char* what, uint32_t flags) const
void Region::dump(String8& out, const char* what, uint32_t flags) const