Ignore:
Timestamp:
May 16, 2011, 2:37:27 AM (11 years ago)
Author:
Sam Hocevar
Message:

imlib: started refactoring the dirty rectangle system.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • abuse/trunk/src/imlib/image.cpp

    r667 r670  
    160160        for(int j = 0; j < m_size.y; j++)
    161161            memset(scan_line(j), color, m_size.x);
    162     AddDirty(0, 0, m_size.x, m_size.y);
     162    AddDirty(vec2i(0), m_size);
    163163    Unlock();
    164164}
     
    272272    yi = p2.y; yc = p1.y;
    273273
    274     AddDirty(xc, yc, xi + 1, yi + 1);
     274    AddDirty(vec2i(xc, yc), vec2i(xi + 1, yi + 1));
    275275    dcx = p1.x; dcy = p1.y;
    276276    xc = (p2.x - p1.x);
     
    351351    vec2i span = bb - aa;
    352352
    353     AddDirty(pos.x, pos.y, pos.x + span.x, pos.y + span.y);
     353    AddDirty(pos, pos + span);
    354354
    355355    Lock();
     
    457457void image_descriptor::ReduceDirties()
    458458{
    459     dirty_rect *p = (dirty_rect *)dirties.first();
    460     int x1 = 6000, y1 = 6000, x2 = -1, y2 = -1;
    461 
    462     for (int i = dirties.Count(); i--; )
    463     {
    464         x1 = Min(x1, p->dx1); y1 = Min(y1, p->dy1);
    465         x2 = Max(x1, p->dx1); y2 = Max(y1, p->dy1);
     459    vec2i aa(6000), bb(-1);
     460
     461    for (dirty_rect *p = (dirty_rect *)dirties.first(); p; )
     462    {
     463        aa = Min(aa, p->m_aa);
     464        bb = Max(bb, p->m_bb);
    466465        dirty_rect *tmp = (dirty_rect *)p->Next();
    467466        dirties.unlink(p);
     
    469468        p = tmp;
    470469    }
    471     dirties.add_front(new dirty_rect(x1, y1, x2, y2));
    472 }
    473 
    474 void image_descriptor::delete_dirty(int x1, int y1, int x2, int y2)
     470    dirties.add_front(new dirty_rect(aa, bb));
     471}
     472
     473void image_descriptor::DeleteDirty(vec2i aa, vec2i bb)
    475474{
    476475    int ax1, ay1, ax2, ay2;
     
    480479        return;
    481480
    482     x1 = Max(0, x1); x2 = Min(m_size.x, x2);
    483     y1 = Max(0, y1); y2 = Min(m_size.y, y2);
    484 
    485     if (x1 >= x2 || y1 >= y2)
     481    aa = Max(aa, vec2i(0));
     482    bb = Min(bb, m_size);
     483
     484    if (!(aa < bb))
    486485        return;
    487486
     
    495494
    496495        // are the two touching?
    497         if (x2 <= p->dx1 || y2 <= p->dy1 || x1 > p->dx2 || y1 > p->dy2)
     496        if (!(bb > p->m_aa && aa <= p->m_bb))
    498497            continue;
    499498
    500499        // does it take a x slice off? (across)
    501         if (x2 >= p->dx2 + 1 && x1 <= p->dx1)
    502         {
    503             if (y2 >= p->dy2 + 1 && y1 <= p->dy1)
     500        if (bb.x >= p->m_bb.x + 1 && aa.x <= p->m_aa.x)
     501        {
     502            if (bb.y >= p->m_bb.y + 1 && aa.y <= p->m_aa.y)
    504503            {
    505504                dirties.unlink(p);
    506505                delete p;
    507506            }
    508             else if (y2 >= p->dy2 + 1)
    509                 p->dy2 = y1 - 1;
    510             else if (y1 <= p->dy1)
    511                 p->dy1 = y2;
     507            else if (bb.y >= p->m_bb.y + 1)
     508                p->m_bb.y = aa.y - 1;
     509            else if (aa.y <= p->m_aa.y)
     510                p->m_aa.y = bb.y;
    512511            else
    513512            {
    514                 dirties.add_front(new dirty_rect(p->dx1, p->dy1, p->dx2, y1-1));
    515                 p->dy1 = y2;
     513                dirties.add_front(new dirty_rect(p->m_aa, vec2i(p->m_bb.x, aa.y - 1)));
     514                p->m_aa.y = bb.y;
    516515            }
    517516        }
    518517        // does it take a y slice off (down)
    519         else if (y2 - 1>=p->dy2 && y1<=p->dy1)
    520         {
    521             if (x2 - 1>=p->dx2)
    522                 p->dx2=x1-1;
    523             else if (x1<=p->dx1)
    524                 p->dx1=x2;
     518        else if (bb.y - 1 >= p->m_bb.y && aa.y <= p->m_aa.y)
     519        {
     520            if (bb.x - 1 >= p->m_bb.x)
     521                p->m_bb.x = aa.x - 1;
     522            else if (aa.x <= p->m_aa.x)
     523                p->m_aa.x = bb.x;
    525524            else
    526525            {
    527                 dirties.add_front(new dirty_rect(p->dx1, p->dy1, x1-1, p->dy2));
    528                 p->dx1=x2;
     526                dirties.add_front(new dirty_rect(p->m_aa, vec2i(aa.x - 1, p->m_bb.y)));
     527                p->m_aa.x = bb.x;
    529528            }
    530529        }
     
    532531        else
    533532        {
    534             if (x2 - 1>=p->dx2)      { ax1=p->dx1; ax2=x1; }
    535             else if (x1<=p->dx1) { ax1=x2; ax2=p->dx2+1; }
    536             else                { ax1=p->dx1; ax2=x1; }
    537             if (y2 - 1>=p->dy2)      { ay1=y1; ay2=p->dy2+1; }
    538             else if (y1<=p->dy1) { ay1=p->dy1; ay2=y2; }
    539             else                { ay1=y1; ay2=y2; }
    540             dirties.add_front(new dirty_rect(ax1, ay1, ax2-1, ay2-1));
    541 
    542             if (x2 - 1>=p->dx2 || x1<=p->dx1)  { ax1=p->dx1; ax2=p->dx2+1; }
    543             else                         { ax1=x2; ax2=p->dx2+1; }
    544 
    545             if (y2 - 1>=p->dy2)
    546             { if (ax1==p->dx1) { ay1=p->dy1; ay2=y1; }
    547                           else { ay1=y1; ay2=p->dy2+1;   } }
    548             else if (y1<=p->dy1) { if (ax1==p->dx1) { ay1=y2; ay2=p->dy2+1; }
    549                                              else  { ay1=p->dy1; ay2=y2; } }
    550             else           { if (ax1==p->dx1) { ay1=p->dy1; ay2=y1; }
    551                              else { ay1=y1; ay2=y2; } }
    552             dirties.add_front(new dirty_rect(ax1, ay1, ax2 - 1, ay2 - 1));
    553 
    554             if (x1>p->dx1 && x2 - 1<p->dx2)
     533            if (bb.x - 1 >= p->m_bb.x) { ax1=p->m_aa.x; ax2 = aa.x; }
     534            else if (aa.x<=p->m_aa.x) { ax1=bb.x; ax2=p->m_bb.x+1; }
     535            else { ax1=p->m_aa.x; ax2=aa.x; }
     536
     537            if (bb.y - 1>=p->m_bb.y) { ay1=aa.y; ay2=p->m_bb.y+1; }
     538            else if (aa.y<=p->m_aa.y) { ay1=p->m_aa.y; ay2=bb.y; }
     539            else { ay1=aa.y; ay2=bb.y; }
     540
     541            dirties.add_front(new dirty_rect(vec2i(ax1, ay1), vec2i(ax2 - 1, ay2 - 1)));
     542
     543            if (bb.x - 1>=p->m_bb.x || aa.x<=p->m_aa.x)  { ax1=p->m_aa.x; ax2=p->m_bb.x+1; }
     544            else { ax1=bb.x; ax2=p->m_bb.x+1; }
     545
     546            if (bb.y - 1>=p->m_bb.y)
     547            { if (ax1==p->m_aa.x) { ay1=p->m_aa.y; ay2=aa.y; }
     548              else { ay1=aa.y; ay2=p->m_bb.y+1;   } }
     549            else if (aa.y<=p->m_aa.y) { if (ax1==p->m_aa.x) { ay1=bb.y; ay2=p->m_bb.y+1; }
     550                                        else  { ay1=p->m_aa.y; ay2=bb.y; } }
     551            else { if (ax1==p->m_aa.x) { ay1=p->m_aa.y; ay2=aa.y; }
     552                   else { ay1=aa.y; ay2=bb.y; } }
     553            dirties.add_front(new dirty_rect(vec2i(ax1, ay1), vec2i(ax2 - 1, ay2 - 1)));
     554
     555            if (aa.x > p->m_aa.x && bb.x - 1 < p->m_bb.x)
    555556            {
    556                 if (y1>p->dy1 && y2 - 1<p->dy2)
     557                if (aa.y > p->m_aa.y && bb.y - 1 < p->m_bb.y)
    557558                {
    558                     dirties.add_front(new dirty_rect(p->dx1, p->dy1, p->dx2, y1-1));
    559                     dirties.add_front(new dirty_rect(p->dx1, y2, p->dx2, p->dy2));
     559                    dirties.add_front(new dirty_rect(p->m_aa, vec2i(p->m_bb.x, aa.y - 1)));
     560                    dirties.add_front(new dirty_rect(vec2i(p->m_aa.x, bb.y), p->m_bb));
    560561                }
    561                 else if (y1<=p->dy1)
    562                     dirties.add_front(new dirty_rect(p->dx1, y2, p->dx2, p->dy2));
     562                else if (aa.y <= p->m_aa.y)
     563                    dirties.add_front(new dirty_rect(vec2i(p->m_aa.x, bb.y), p->m_bb));
    563564                else
    564                     dirties.add_front(new dirty_rect(p->dx1, p->dy1, p->dx2, y1-1));
     565                    dirties.add_front(new dirty_rect(p->m_aa, vec2i(p->m_bb.x, aa.y - 1)));
    565566            }
    566             else if (y1>p->dy1 && y2 - 1<p->dy2)
    567                 dirties.add_front(new dirty_rect(p->dx1, y2, p->dx2, p->dy2));
     567            else if (aa.y > p->m_aa.y && bb.y - 1 < p->m_bb.y)
     568                dirties.add_front(new dirty_rect(vec2i(p->m_aa.x, bb.y), p->m_bb));
    568569            dirties.unlink(p);
    569570            delete p;
     
    573574
    574575// specifies that an area is a dirty
    575 void image_descriptor::AddDirty(int x1, int y1, int x2, int y2)
     576void image_descriptor::AddDirty(vec2i aa, vec2i bb)
    576577{
    577578    dirty_rect *p;
     
    579580        return;
    580581
    581     x1 = Max(0, x1); x2 = Min(m_size.x, x2);
    582     y1 = Max(0, y1); y2 = Min(m_size.y, y2);
    583 
    584     if (x1 >= x2 || y1 >= y2)
     582    aa = Max(aa, vec2i(0));
     583    bb = Min(bb, m_size);
     584
     585    if (!(aa < bb))
    585586        return;
    586587
    587588    int i = dirties.Count();
    588589    if (!i)
    589         dirties.add_front(new dirty_rect(x1, y1, x2 - 1, y2 - 1));
     590        dirties.add_front(new dirty_rect(aa, bb - vec2i(1)));
    590591    else if (i >= MAX_DIRTY)
    591592    {
    592         dirties.add_front(new dirty_rect(x1, y1, x2 - 1, y2 - 1));
     593        dirties.add_front(new dirty_rect(aa, bb - vec2i(1)));
    593594        ReduceDirties();  // reduce to one dirty rectangle, we have to many
    594595    }
     
    599600
    600601        // check to see if this new rectangle completly encloses the check rectangle
    601         if (x1<=p->dx1 && y1<=p->dy1 && x2>=p->dx2+1 && y2>=p->dy2+1)
     602        if (aa.x<=p->m_aa.x && aa.y<=p->m_aa.y && bb.x>=p->m_bb.x+1 && bb.y>=p->m_bb.y+1)
    602603        {
    603604          dirty_rect *tmp=(dirty_rect*) p->Next();
     
    608609          else p=tmp;
    609610        }
    610         else if (!(x2 - 1 <p->dx1 || y2 - 1 <p->dy1 || x1>p->dx2 || y1>p->dy2))
    611         {
    612 
    613 
    614 
    615 /*          if (x1<=p->dx1) { a+=p->dx1-x1; ax1=x1; } else ax1=p->dx1;
    616           if (y1<=p->dy1) { a+=p->dy1-y1; ay1=y1; } else ay1=p->dy1;
    617           if (x2 - 1 >=p->dx2) { a+=x2 - 1 -p->dx2; ax2=x2 - 1; } else ax2=p->dx2;
    618           if (y2 - 1 >=p->dy2) { a+=y2 - 1 -p->dy2; ay2=y2 - 1; } else ay2=p->dy2;
     611        else if (!(bb.x - 1 <p->m_aa.x || bb.y - 1 <p->m_aa.y || aa.x>p->m_bb.x || aa.y>p->m_bb.y))
     612        {
     613
     614
     615
     616/*          if (x1<=p->m_aa.x) { a+=p->m_aa.x-x1; ax1=x1; } else ax1=p->m_aa.x;
     617          if (y1<=p->m_aa.y) { a+=p->m_aa.y-y1; ay1=y1; } else ay1=p->m_aa.y;
     618          if (x2 - 1 >=p->m_bb.x) { a+=x2 - 1 -p->m_bb.x; ax2=x2 - 1; } else ax2=p->m_bb.x;
     619          if (y2 - 1 >=p->m_bb.y) { a+=y2 - 1 -p->m_bb.y; ay2=y2 - 1; } else ay2=p->m_bb.y;
    619620
    620621      if (a<50)
    621       { p->dx1=ax1;                         // then expand the dirty
    622         p->dy1=ay1;
    623         p->dx2=ax2;
    624         p->dy2=ay2;
     622      { p->m_aa.x=ax1;                         // then expand the dirty
     623        p->m_aa.y=ay1;
     624        p->m_bb.x=ax2;
     625        p->m_bb.y=ay2;
    625626        return ;
    626627      }
    627628      else */
    628629            {
    629               if (x1<p->dx1)
    630                 AddDirty(x1, Max(y1, p->dy1), p->dx1, Min(y2, p->dy2 + 1));
    631               if (x2>p->dx2+1)
    632                 AddDirty(p->dx2+1, Max(y1, p->dy1), x2, Min(y2, p->dy2 + 1));
    633               if (y1<p->dy1)
    634                 AddDirty(x1, y1, x2, p->dy1);
    635               if (y2 - 1>p->dy2)
    636                 AddDirty(x1, p->dy2+1, x2, y2);
     630              if (aa.x < p->m_aa.x)
     631                AddDirty(vec2i(aa.x, Max(aa.y, p->m_aa.y)),
     632                         vec2i(p->m_aa.x, Min(bb.y, p->m_bb.y + 1)));
     633              if (bb.x > p->m_bb.x + 1)
     634                AddDirty(vec2i(p->m_bb.x + 1, Max(aa.y, p->m_aa.y)),
     635                         vec2i(bb.x, Min(bb.y, p->m_bb.y + 1)));
     636              if (aa.y < p->m_aa.y)
     637                AddDirty(aa, vec2i(bb.x, p->m_aa.y));
     638              if (bb.y - 1 > p->m_bb.y)
     639                AddDirty(vec2i(aa.x, p->m_bb.y + 1), bb);
    637640              return ;
    638641            }
    639             p=(dirty_rect *)p->Next();
    640           } else p=(dirty_rect *)p->Next();
     642            p = (dirty_rect *)p->Next();
     643          } else p = (dirty_rect *)p->Next();
    641644
    642645      }
    643       CHECK(x1 < x2 && y1 < y2);
    644       dirties.add_end(new dirty_rect(x1, y1, x2 - 1, y2 - 1));
     646      CHECK(aa < bb);
     647      dirties.add_end(new dirty_rect(aa, bb - vec2i(1)));
    645648    }
    646649}
     
    672675        memset(scan_line(y) + p1.x, color, (p2.x - p1.x + 1));
    673676    Unlock();
    674     AddDirty(p1.x, p1.y, p2.x + 1, p2.y + 1);
     677    AddDirty(p1, p2 + vec2i(1));
    675678}
    676679
     
    705708  Unlock();
    706709
    707   AddDirty(x1, y1, x2 + 1, y2 + 1);
     710  AddDirty(vec2i(x1, y1), vec2i(x2 + 1, y2 + 1));
    708711}
    709712
     
    816819    if (yd<0) { ysrc++; ydst++; } else { ysrc--; ydst--; }
    817820  }
    818   AddDirty(x1, y1, x2 + 1, y2 + 1);
     821  AddDirty(vec2i(x1, y1), vec2i(x2 + 1, y2 + 1));
    819822}
    820823
Note: See TracChangeset for help on using the changeset viewer.