gfx/skia/trunk/src/core/SkRasterClip.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /*
     2  * Copyright 2010 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkRasterClip.h"
    11 SkRasterClip::SkRasterClip() {
    12     fIsBW = true;
    13     fIsEmpty = true;
    14     fIsRect = false;
    15     SkDEBUGCODE(this->validate();)
    16 }
    18 SkRasterClip::SkRasterClip(const SkRasterClip& src) {
    19     AUTO_RASTERCLIP_VALIDATE(src);
    21     fIsBW = src.fIsBW;
    22     if (fIsBW) {
    23         fBW = src.fBW;
    24     } else {
    25         fAA = src.fAA;
    26     }
    28     fIsEmpty = src.isEmpty();
    29     fIsRect = src.isRect();
    30     SkDEBUGCODE(this->validate();)
    31 }
    33 SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
    34     fIsBW = true;
    35     fIsEmpty = this->computeIsEmpty();  // bounds might be empty, so compute
    36     fIsRect = !fIsEmpty;
    37     SkDEBUGCODE(this->validate();)
    38 }
    40 SkRasterClip::~SkRasterClip() {
    41     SkDEBUGCODE(this->validate();)
    42 }
    44 bool SkRasterClip::isComplex() const {
    45     return fIsBW ? fBW.isComplex() : !fAA.isEmpty();
    46 }
    48 const SkIRect& SkRasterClip::getBounds() const {
    49     return fIsBW ? fBW.getBounds() : fAA.getBounds();
    50 }
    52 bool SkRasterClip::setEmpty() {
    53     AUTO_RASTERCLIP_VALIDATE(*this);
    55     fIsBW = true;
    56     fBW.setEmpty();
    57     fAA.setEmpty();
    58     fIsEmpty = true;
    59     fIsRect = false;
    60     return false;
    61 }
    63 bool SkRasterClip::setRect(const SkIRect& rect) {
    64     AUTO_RASTERCLIP_VALIDATE(*this);
    66     fIsBW = true;
    67     fAA.setEmpty();
    68     fIsRect = fBW.setRect(rect);
    69     fIsEmpty = !fIsRect;
    70     return fIsRect;
    71 }
    73 bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
    74     AUTO_RASTERCLIP_VALIDATE(*this);
    76     if (this->isBW() && !doAA) {
    77         (void)fBW.setPath(path, clip);
    78     } else {
    79         // TODO: since we are going to over-write fAA completely (aren't we?)
    80         // we should just clear our BW data (if any) and set fIsAA=true
    81         if (this->isBW()) {
    82             this->convertToAA();
    83         }
    84         (void)fAA.setPath(path, &clip, doAA);
    85     }
    86     return this->updateCacheAndReturnNonEmpty();
    87 }
    89 bool SkRasterClip::setPath(const SkPath& path, const SkIRect& clip, bool doAA) {
    90     SkRegion tmp;
    91     tmp.setRect(clip);
    92     return this->setPath(path, tmp, doAA);
    93 }
    95 bool SkRasterClip::op(const SkIRect& rect, SkRegion::Op op) {
    96     AUTO_RASTERCLIP_VALIDATE(*this);
    98     fIsBW ? fBW.op(rect, op) : fAA.op(rect, op);
    99     return this->updateCacheAndReturnNonEmpty();
   100 }
   102 bool SkRasterClip::op(const SkRegion& rgn, SkRegion::Op op) {
   103     AUTO_RASTERCLIP_VALIDATE(*this);
   105     if (fIsBW) {
   106         (void)fBW.op(rgn, op);
   107     } else {
   108         SkAAClip tmp;
   109         tmp.setRegion(rgn);
   110         (void)fAA.op(tmp, op);
   111     }
   112     return this->updateCacheAndReturnNonEmpty();
   113 }
   115 bool SkRasterClip::op(const SkRasterClip& clip, SkRegion::Op op) {
   116     AUTO_RASTERCLIP_VALIDATE(*this);
   117     clip.validate();
   119     if (this->isBW() && clip.isBW()) {
   120         (void)fBW.op(clip.fBW, op);
   121     } else {
   122         SkAAClip tmp;
   123         const SkAAClip* other;
   125         if (this->isBW()) {
   126             this->convertToAA();
   127         }
   128         if (clip.isBW()) {
   129             tmp.setRegion(clip.bwRgn());
   130             other = &tmp;
   131         } else {
   132             other = &clip.aaRgn();
   133         }
   134         (void)fAA.op(*other, op);
   135     }
   136     return this->updateCacheAndReturnNonEmpty();
   137 }
   139 /**
   140  *  Our antialiasing currently has a granularity of 1/4 of a pixel along each
   141  *  axis. Thus we can treat an axis coordinate as an integer if it differs
   142  *  from its nearest int by < half of that value (1.8 in this case).
   143  */
   144 static bool nearly_integral(SkScalar x) {
   145     static const SkScalar domain = SK_Scalar1 / 4;
   146     static const SkScalar halfDomain = domain / 2;
   148     x += halfDomain;
   149     return x - SkScalarFloorToScalar(x) < domain;
   150 }
   152 bool SkRasterClip::op(const SkRect& r, SkRegion::Op op, bool doAA) {
   153     AUTO_RASTERCLIP_VALIDATE(*this);
   155     if (fIsBW && doAA) {
   156         // check that the rect really needs aa, or is it close enought to
   157         // integer boundaries that we can just treat it as a BW rect?
   158         if (nearly_integral(r.fLeft) && nearly_integral(r.fTop) &&
   159             nearly_integral(r.fRight) && nearly_integral(r.fBottom)) {
   160             doAA = false;
   161         }
   162     }
   164     if (fIsBW && !doAA) {
   165         SkIRect ir;
   166         r.round(&ir);
   167         (void)fBW.op(ir, op);
   168     } else {
   169         if (fIsBW) {
   170             this->convertToAA();
   171         }
   172         (void)fAA.op(r, op, doAA);
   173     }
   174     return this->updateCacheAndReturnNonEmpty();
   175 }
   177 void SkRasterClip::translate(int dx, int dy, SkRasterClip* dst) const {
   178     if (NULL == dst) {
   179         return;
   180     }
   182     AUTO_RASTERCLIP_VALIDATE(*this);
   184     if (this->isEmpty()) {
   185         dst->setEmpty();
   186         return;
   187     }
   188     if (0 == (dx | dy)) {
   189         *dst = *this;
   190         return;
   191     }
   193     dst->fIsBW = fIsBW;
   194     if (fIsBW) {
   195         fBW.translate(dx, dy, &dst->fBW);
   196         dst->fAA.setEmpty();
   197     } else {
   198         fAA.translate(dx, dy, &dst->fAA);
   199         dst->fBW.setEmpty();
   200     }
   201     dst->updateCacheAndReturnNonEmpty();
   202 }
   204 bool SkRasterClip::quickContains(const SkIRect& ir) const {
   205     return fIsBW ? fBW.quickContains(ir) : fAA.quickContains(ir);
   206 }
   208 ///////////////////////////////////////////////////////////////////////////////
   210 const SkRegion& SkRasterClip::forceGetBW() {
   211     AUTO_RASTERCLIP_VALIDATE(*this);
   213     if (!fIsBW) {
   214         fBW.setRect(fAA.getBounds());
   215     }
   216     return fBW;
   217 }
   219 void SkRasterClip::convertToAA() {
   220     AUTO_RASTERCLIP_VALIDATE(*this);
   222     SkASSERT(fIsBW);
   223     fAA.setRegion(fBW);
   224     fIsBW = false;
   225     (void)this->updateCacheAndReturnNonEmpty();
   226 }
   228 #ifdef SK_DEBUG
   229 void SkRasterClip::validate() const {
   230     // can't ever assert that fBW is empty, since we may have called forceGetBW
   231     if (fIsBW) {
   232         SkASSERT(fAA.isEmpty());
   233     }
   235     fBW.validate();
   236     fAA.validate();
   238     SkASSERT(this->computeIsEmpty() == fIsEmpty);
   239     SkASSERT(this->computeIsRect() == fIsRect);
   240 }
   241 #endif
   243 ///////////////////////////////////////////////////////////////////////////////
   245 SkAAClipBlitterWrapper::SkAAClipBlitterWrapper() {
   246     SkDEBUGCODE(fClipRgn = NULL;)
   247     SkDEBUGCODE(fBlitter = NULL;)
   248 }
   250 SkAAClipBlitterWrapper::SkAAClipBlitterWrapper(const SkRasterClip& clip,
   251                                                SkBlitter* blitter) {
   252     this->init(clip, blitter);
   253 }
   255 SkAAClipBlitterWrapper::SkAAClipBlitterWrapper(const SkAAClip* aaclip,
   256                                                SkBlitter* blitter) {
   257     SkASSERT(blitter);
   258     SkASSERT(aaclip);
   259     fBWRgn.setRect(aaclip->getBounds());
   260     fAABlitter.init(blitter, aaclip);
   261     // now our return values
   262     fClipRgn = &fBWRgn;
   263     fBlitter = &fAABlitter;
   264 }
   266 void SkAAClipBlitterWrapper::init(const SkRasterClip& clip, SkBlitter* blitter) {
   267     SkASSERT(blitter);
   268     if (clip.isBW()) {
   269         fClipRgn = &clip.bwRgn();
   270         fBlitter = blitter;
   271     } else {
   272         const SkAAClip& aaclip = clip.aaRgn();
   273         fBWRgn.setRect(aaclip.getBounds());
   274         fAABlitter.init(blitter, &aaclip);
   275         // now our return values
   276         fClipRgn = &fBWRgn;
   277         fBlitter = &fAABlitter;
   278     }
   279 }

mercurial