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)
     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)
     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         if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
     63             ++fNumAAHairlineConcavePaths;
     64         }
     65     }
     66 }
     67 
     68 void SkPictureContentInfo::onAddPaintPtr(const SkPaint* paint) {
     69     if (paint && paint->getPathEffect()) {
     70         ++fNumPaintWithPathEffectUses;
     71     }
     72 }
     73 
     74 void SkPictureContentInfo::onSaveLayer() {
     75     *fSaveStack.append() = kSaveLayer_Flag;
     76 }
     77 
     78 void SkPictureContentInfo::onSave() {
     79     *fSaveStack.append() = kSave_Flag;
     80 }
     81 
     82 void SkPictureContentInfo::onRestore() {
     83     SkASSERT(fSaveStack.count() > 0);
     84 
     85     bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
     86 
     87     if (fSaveStack.top() & kSaveLayer_Flag) {
     88         ++fNumLayers;
     89         if (containedSaveLayer) {
     90             ++fNumInteriorLayers;
     91         } else {
     92             ++fNumLeafLayers;
     93         }
     94         containedSaveLayer = true;
     95     }
     96 
     97     fSaveStack.pop();
     98 
     99     if (containedSaveLayer && fSaveStack.count() > 0) {
    100         fSaveStack.top() |= kContainedSaveLayer_Flag;
    101     }
    102 }
    103 
    104 void SkPictureContentInfo::rescindLastSave() {
    105     SkASSERT(fSaveStack.count() > 0);
    106     SkASSERT(fSaveStack.top() & kSave_Flag);
    107 
    108     bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
    109 
    110     fSaveStack.pop();
    111 
    112     if (containedSaveLayer && fSaveStack.count() > 0) {
    113         fSaveStack.top() |= kContainedSaveLayer_Flag;
    114     }
    115 }
    116 
    117 void SkPictureContentInfo::rescindLastSaveLayer() {
    118     SkASSERT(fSaveStack.count() > 0);
    119     SkASSERT(fSaveStack.top() & kSaveLayer_Flag);
    120 
    121     bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
    122 
    123     fSaveStack.pop();
    124 
    125     if (containedSaveLayer && fSaveStack.count() > 0) {
    126         fSaveStack.top() |= kContainedSaveLayer_Flag;
    127     }
    128 }
    129 
    130 void SkPictureContentInfo::set(const SkPictureContentInfo& src) {
    131     fNumOperations = src.fNumOperations;
    132     fNumTexts = src.fNumTexts;
    133     fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
    134     fNumFastPathDashEffects = src.fNumFastPathDashEffects;
    135     fNumAAConcavePaths = src.fNumAAConcavePaths;
    136     fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
    137     fNumLayers = src.fNumLayers;
    138     fNumInteriorLayers = src.fNumInteriorLayers;
    139     fNumLeafLayers = src.fNumLeafLayers;
    140     fSaveStack = src.fSaveStack;
    141 }
    142 
    143 void SkPictureContentInfo::reset() {
    144     fNumOperations = 0;
    145     fNumTexts = 0;
    146     fNumPaintWithPathEffectUses = 0;
    147     fNumFastPathDashEffects = 0;
    148     fNumAAConcavePaths = 0;
    149     fNumAAHairlineConcavePaths = 0;
    150     fNumLayers = 0;
    151     fNumInteriorLayers = 0;
    152     fNumLeafLayers = 0;
    153     fSaveStack.rewind();
    154 }
    155 
    156 void SkPictureContentInfo::swap(SkPictureContentInfo* other) {
    157     SkTSwap(fNumOperations, other->fNumOperations);
    158     SkTSwap(fNumTexts, other->fNumTexts);
    159     SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
    160     SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects);
    161     SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
    162     SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
    163     SkTSwap(fNumLayers, other->fNumLayers);
    164     SkTSwap(fNumInteriorLayers, other->fNumInteriorLayers);
    165     SkTSwap(fNumLeafLayers, other->fNumLeafLayers);
    166     fSaveStack.swap(other->fSaveStack);
    167 }
    168