Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2014 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  */
      7 
      8 #include "SkPaint.h"
      9 #include "SkPathEffect.h"
     10 #include "SkPictureContentInfo.h"
     11 
     12 bool SkPictureContentInfo::suitableForGpuRasterization(GrContext* context, const char **reason,
     13                                                        int sampleCount) const {
     14     // TODO: the heuristic used here needs to be refined
     15     static const int kNumPaintWithPathEffectUsesTol = 1;
     16     static const int kNumAAConcavePaths = 5;
     17 
     18     SkASSERT(fNumAAHairlineConcavePaths <= fNumAAConcavePaths);
     19 
     20     int numNonDashedPathEffects = fNumPaintWithPathEffectUses -
     21                                   fNumFastPathDashEffects;
     22 
     23     bool suitableForDash = (0 == fNumPaintWithPathEffectUses) ||
     24                            (numNonDashedPathEffects < kNumPaintWithPathEffectUsesTol
     25                             && 0 == sampleCount);
     26 
     27     bool ret = suitableForDash &&
     28                     (fNumAAConcavePaths - fNumAAHairlineConcavePaths - fNumAADFEligibleConcavePaths)
     29                     < kNumAAConcavePaths;
     30     if (!ret && reason) {
     31         if (!suitableForDash) {
     32             if (0 != sampleCount) {
     33                 *reason = "Can't use multisample on dash effect.";
     34             } else {
     35                 *reason = "Too many non dashed path effects.";
     36             }
     37         } else if ((fNumAAConcavePaths - fNumAAHairlineConcavePaths - fNumAADFEligibleConcavePaths)
     38                     >= kNumAAConcavePaths) {
     39             *reason = "Too many anti-aliased concave paths.";
     40         } else {
     41             *reason = "Unknown reason for GPU unsuitability.";
     42         }
     43     }
     44     return ret;
     45 }
     46 
     47 void SkPictureContentInfo::onDrawPoints(size_t count, const SkPaint& paint) {
     48     if (paint.getPathEffect() != NULL) {
     49         SkPathEffect::DashInfo info;
     50         SkPathEffect::DashType dashType = paint.getPathEffect()->asADash(&info);
     51         if (2 == count && SkPaint::kRound_Cap != paint.getStrokeCap() &&
     52             SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
     53             ++fNumFastPathDashEffects;
     54         }
     55     }
     56 }
     57 
     58 void SkPictureContentInfo::onDrawPath(const SkPath& path, const SkPaint& paint) {
     59     if (paint.isAntiAlias() && !path.isConvex()) {
     60         ++fNumAAConcavePaths;
     61 
     62         SkPaint::Style paintStyle = paint.getStyle();
     63         const SkRect& pathBounds = path.getBounds();
     64         if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
     65             ++fNumAAHairlineConcavePaths;
     66         } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width() < 64.f &&
     67                    pathBounds.height() < 64.f && !path.isVolatile()) {
     68             ++fNumAADFEligibleConcavePaths;
     69         }
     70     }
     71 }
     72 
     73 void SkPictureContentInfo::onAddPaintPtr(const SkPaint* paint) {
     74     if (paint && paint->getPathEffect()) {
     75         ++fNumPaintWithPathEffectUses;
     76     }
     77 }
     78 
     79 void SkPictureContentInfo::onSaveLayer() {
     80     *fSaveStack.append() = kSaveLayer_Flag;
     81 }
     82 
     83 void SkPictureContentInfo::onSave() {
     84     *fSaveStack.append() = kSave_Flag;
     85 }
     86 
     87 void SkPictureContentInfo::onRestore() {
     88     SkASSERT(fSaveStack.count() > 0);
     89 
     90     bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
     91 
     92     if (fSaveStack.top() & kSaveLayer_Flag) {
     93         ++fNumLayers;
     94         if (containedSaveLayer) {
     95             ++fNumInteriorLayers;
     96         } else {
     97             ++fNumLeafLayers;
     98         }
     99         containedSaveLayer = true;
    100     }
    101 
    102     fSaveStack.pop();
    103 
    104     if (containedSaveLayer && fSaveStack.count() > 0) {
    105         fSaveStack.top() |= kContainedSaveLayer_Flag;
    106     }
    107 }
    108 
    109 void SkPictureContentInfo::rescindLastSave() {
    110     SkASSERT(fSaveStack.count() > 0);
    111     SkASSERT(fSaveStack.top() & kSave_Flag);
    112 
    113     bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
    114 
    115     fSaveStack.pop();
    116 
    117     if (containedSaveLayer && fSaveStack.count() > 0) {
    118         fSaveStack.top() |= kContainedSaveLayer_Flag;
    119     }
    120 }
    121 
    122 void SkPictureContentInfo::rescindLastSaveLayer() {
    123     SkASSERT(fSaveStack.count() > 0);
    124     SkASSERT(fSaveStack.top() & kSaveLayer_Flag);
    125 
    126     bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
    127 
    128     fSaveStack.pop();
    129 
    130     if (containedSaveLayer && fSaveStack.count() > 0) {
    131         fSaveStack.top() |= kContainedSaveLayer_Flag;
    132     }
    133 }
    134 
    135 void SkPictureContentInfo::set(const SkPictureContentInfo& src) {
    136     fNumOperations = src.fNumOperations;
    137     fNumTexts = src.fNumTexts;
    138     fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
    139     fNumFastPathDashEffects = src.fNumFastPathDashEffects;
    140     fNumAAConcavePaths = src.fNumAAConcavePaths;
    141     fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
    142     fNumAADFEligibleConcavePaths = src.fNumAADFEligibleConcavePaths;
    143     fNumLayers = src.fNumLayers;
    144     fNumInteriorLayers = src.fNumInteriorLayers;
    145     fNumLeafLayers = src.fNumLeafLayers;
    146     fSaveStack = src.fSaveStack;
    147 }
    148 
    149 void SkPictureContentInfo::reset() {
    150     fNumOperations = 0;
    151     fNumTexts = 0;
    152     fNumPaintWithPathEffectUses = 0;
    153     fNumFastPathDashEffects = 0;
    154     fNumAAConcavePaths = 0;
    155     fNumAAHairlineConcavePaths = 0;
    156     fNumAADFEligibleConcavePaths = 0;
    157     fNumLayers = 0;
    158     fNumInteriorLayers = 0;
    159     fNumLeafLayers = 0;
    160     fSaveStack.rewind();
    161 }
    162 
    163 void SkPictureContentInfo::swap(SkPictureContentInfo* other) {
    164     SkTSwap(fNumOperations, other->fNumOperations);
    165     SkTSwap(fNumTexts, other->fNumTexts);
    166     SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
    167     SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects);
    168     SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
    169     SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
    170     SkTSwap(fNumAADFEligibleConcavePaths, other->fNumAADFEligibleConcavePaths);
    171     SkTSwap(fNumLayers, other->fNumLayers);
    172     SkTSwap(fNumInteriorLayers, other->fNumInteriorLayers);
    173     SkTSwap(fNumLeafLayers, other->fNumLeafLayers);
    174     fSaveStack.swap(other->fSaveStack);
    175 }
    176