Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2010 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #include "GrClip.h"
     12 
     13 GrClip::GrClip() {
     14     fConservativeBounds.setEmpty();
     15     fConservativeBoundsValid = true;
     16 }
     17 
     18 GrClip::GrClip(const GrClip& src) {
     19     *this = src;
     20 }
     21 
     22 GrClip::GrClip(const GrIRect& rect) {
     23     this->setFromIRect(rect);
     24 }
     25 
     26 GrClip::GrClip(const GrRect& rect) {
     27     this->setFromRect(rect);
     28 }
     29 
     30 GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
     31                const GrRect* bounds) {
     32     this->setFromIterator(iter, tx, ty, bounds);
     33 }
     34 
     35 GrClip::~GrClip() {}
     36 
     37 GrClip& GrClip::operator=(const GrClip& src) {
     38     fList = src.fList;
     39     fConservativeBounds = src.fConservativeBounds;
     40     fConservativeBoundsValid = src.fConservativeBoundsValid;
     41     return *this;
     42 }
     43 
     44 void GrClip::setEmpty() {
     45     fList.reset();
     46     fConservativeBounds.setEmpty();
     47     fConservativeBoundsValid = true;
     48 }
     49 
     50 void GrClip::setFromRect(const GrRect& r) {
     51     fList.reset();
     52     if (r.isEmpty()) {
     53         // use a canonical empty rect for == testing.
     54         setEmpty();
     55     } else {
     56         fList.push_back();
     57         fList.back().fRect = r;
     58         fList.back().fType = kRect_ClipType;
     59         fList.back().fOp = kReplace_SetOp;
     60         fConservativeBounds = r;
     61         fConservativeBoundsValid = true;
     62     }
     63 }
     64 
     65 void GrClip::setFromIRect(const GrIRect& r) {
     66     fList.reset();
     67     if (r.isEmpty()) {
     68         // use a canonical empty rect for == testing.
     69         setEmpty();
     70     } else {
     71         fList.push_back();
     72         fList.back().fRect.set(r);
     73         fList.back().fType = kRect_ClipType;
     74         fList.back().fOp = kReplace_SetOp;
     75         fConservativeBounds.set(r);
     76         fConservativeBoundsValid = true;
     77     }
     78 }
     79 
     80 static void intersectWith(SkRect* dst, const SkRect& src) {
     81     if (!dst->intersect(src)) {
     82         dst->setEmpty();
     83     }
     84 }
     85 
     86 void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
     87                              const GrRect* conservativeBounds) {
     88     fList.reset();
     89 
     90     int rectCount = 0;
     91 
     92     // compute bounds for common case of series of intersecting rects.
     93     bool isectRectValid = true;
     94 
     95     if (iter) {
     96         for (iter->rewind(); !iter->isDone(); iter->next()) {
     97             Element& e = fList.push_back();
     98             e.fType = iter->getType();
     99             e.fOp = iter->getOp();
    100             // iterators should not emit replace
    101             GrAssert(kReplace_SetOp != e.fOp);
    102             switch (e.fType) {
    103                 case kRect_ClipType:
    104                     iter->getRect(&e.fRect);
    105                     if (tx || ty) {
    106                         e.fRect.offset(tx, ty);
    107                     }
    108                     ++rectCount;
    109                     if (isectRectValid) {
    110                         if (kIntersect_SetOp == e.fOp) {
    111                             GrAssert(fList.count() <= 2);
    112                             if (fList.count() > 1) {
    113                                 GrAssert(2 == rectCount);
    114                                 rectCount = 1;
    115                                 fList.pop_back();
    116                                 GrAssert(kRect_ClipType == fList.back().fType);
    117                                 intersectWith(&fList.back().fRect, e.fRect);
    118                             }
    119                         } else {
    120                             isectRectValid = false;
    121                         }
    122                     }
    123                     break;
    124                 case kPath_ClipType:
    125                     e.fPath = *iter->getPath();
    126                     if (tx || ty) {
    127                         e.fPath.offset(tx, ty);
    128                     }
    129                     e.fPathFill = iter->getPathFill();
    130                     isectRectValid = false;
    131                     break;
    132                 default:
    133                     GrCrash("Unknown clip element type.");
    134             }
    135         }
    136     }
    137     fConservativeBoundsValid = false;
    138     if (isectRectValid && rectCount) {
    139         fConservativeBounds = fList[0].fRect;
    140         fConservativeBoundsValid = true;
    141     } else if (NULL != conservativeBounds) {
    142         fConservativeBounds = *conservativeBounds;
    143         fConservativeBoundsValid = true;
    144     }
    145 }
    146