diff options
author | Mike Klein <mtklein@google.com> | 2014-08-18 18:35:16 -0400 |
---|---|---|
committer | Mike Klein <mtklein@google.com> | 2014-08-18 18:35:16 -0400 |
commit | 27dc17c2972421ce9c6331662fee6389b1e795a7 (patch) | |
tree | 2a1faac45bd4acc561303aa4f6a8b0ad74dc7f38 /src/core/SkPicture.cpp | |
parent | caa80b9a46ea00a7b582d96d73302939aa21b5ee (diff) |
Revert "Move the code over using the same template type approach previously used for willPlayBackBitmaps in http://skbug.com/2702."
This reverts commit 60c2a79cfa8ceebcbafc243407564dc71f5e3b4f.
BUG=skia:
Review URL: https://codereview.chromium.org/481173003
Diffstat (limited to 'src/core/SkPicture.cpp')
-rw-r--r-- | src/core/SkPicture.cpp | 192 |
1 files changed, 11 insertions, 181 deletions
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index 1fc2bb32c8..8825123336 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -19,13 +19,11 @@ #include "SkChunkAlloc.h" #include "SkDrawPictureCallback.h" #include "SkPaintPriv.h" -#include "SkPathEffect.h" #include "SkPicture.h" +#include "SkRecordAnalysis.h" #include "SkRegion.h" -#include "SkShader.h" #include "SkStream.h" #include "SkTDArray.h" -#include "SkTLogic.h" #include "SkTSearch.h" #include "SkTime.h" @@ -48,180 +46,12 @@ template <typename T> int SafeCount(const T* obj) { /////////////////////////////////////////////////////////////////////////////// -namespace { - -// Some commands have a paint, some have an optional paint. Either way, get back a pointer. -static const SkPaint* AsPtr(const SkPaint& p) { return &p; } -static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; } - -/** SkRecords visitor to determine whether an instance may require an - "external" bitmap to rasterize. May return false positives. - Does not return true for bitmap text. - - Expected use is to determine whether images need to be decoded before - rasterizing a particular SkRecord. - */ -struct BitmapTester { - // Helpers. These create HasMember_bitmap and HasMember_paint. - SK_CREATE_MEMBER_DETECTOR(bitmap); - SK_CREATE_MEMBER_DETECTOR(paint); - - - // Main entry for visitor: - // If the command has a bitmap directly, return true. - // If the command has a paint and the paint has a bitmap, return true. - // Otherwise, return false. - template <typename T> - bool operator()(const T& r) { return CheckBitmap(r); } - - - // If the command has a bitmap, of course we're going to play back bitmaps. - template <typename T> - static SK_WHEN(HasMember_bitmap<T>, bool) CheckBitmap(const T&) { return true; } - - // If not, look for one in its paint (if it has a paint). - template <typename T> - static SK_WHEN(!HasMember_bitmap<T>, bool) CheckBitmap(const T& r) { return CheckPaint(r); } - - // If we have a paint, dig down into the effects looking for a bitmap. - template <typename T> - static SK_WHEN(HasMember_paint<T>, bool) CheckPaint(const T& r) { - const SkPaint* paint = AsPtr(r.paint); - if (paint) { - const SkShader* shader = paint->getShader(); - if (shader && - shader->asABitmap(NULL, NULL, NULL) == SkShader::kDefault_BitmapType) { - return true; - } - } - return false; - } - - // If we don't have a paint, that non-paint has no bitmap. - template <typename T> - static SK_WHEN(!HasMember_paint<T>, bool) CheckPaint(const T&) { return false; } -}; - -bool WillPlaybackBitmaps(const SkRecord& record) { - BitmapTester tester; - for (unsigned i = 0; i < record.count(); i++) { - if (record.visit<bool>(i, tester)) { - return true; - } - } - return false; -} - -/** SkRecords visitor to determine heuristically whether or not a SkPicture - will be performant when rasterized on the GPU. - */ -struct PathCounter { - SK_CREATE_MEMBER_DETECTOR(paint); - - PathCounter() - : numPaintWithPathEffectUses (0) - , numFastPathDashEffects (0) - , numAAConcavePaths (0) - , numAAHairlineConcavePaths (0) { - } - - void checkPaint(const SkPaint* paint) { - if (paint && paint->getPathEffect()) { - numPaintWithPathEffectUses++; - } - } - - void operator()(const SkRecords::DrawPoints& op) { - this->checkPaint(&op.paint); - const SkPathEffect* effect = op.paint.getPathEffect(); - if (effect) { - SkPathEffect::DashInfo info; - SkPathEffect::DashType dashType = effect->asADash(&info); - if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap() && - SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) { - numFastPathDashEffects++; - } - } - } - - void operator()(const SkRecords::DrawPath& op) { - this->checkPaint(&op.paint); - if (op.paint.isAntiAlias() && !op.path.isConvex()) { - numAAConcavePaths++; - - if (SkPaint::kStroke_Style == op.paint.getStyle() && - 0 == op.paint.getStrokeWidth()) { - numAAHairlineConcavePaths++; - } - } - } - - template <typename T> - SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) { - this->checkPaint(AsPtr(op.paint)); - } - - template <typename T> - SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing */ } - - - int numPaintWithPathEffectUses; - int numFastPathDashEffects; - int numAAConcavePaths; - int numAAHairlineConcavePaths; -}; - -bool SuitableForGpuRasterization(const SkRecord& record, - const char** reason = NULL, - int sampleCount = 0) { - PathCounter counter; - for (unsigned i = 0; i < record.count(); i++) { - record.visit<void>(i, counter); - } - - // TODO: the heuristic used here needs to be refined - static const int kNumPaintWithPathEffectsUsesTol = 1; - static const int kNumAAConcavePathsTol = 5; - - int numNonDashedPathEffects = counter.numPaintWithPathEffectUses - - counter.numFastPathDashEffects; - bool suitableForDash = (0 == counter.numPaintWithPathEffectUses) || - (numNonDashedPathEffects < kNumPaintWithPathEffectsUsesTol - && 0 == sampleCount); - - bool ret = suitableForDash && - (counter.numAAConcavePaths - counter.numAAHairlineConcavePaths) - < kNumAAConcavePathsTol; - - if (!ret && NULL != reason) { - if (!suitableForDash) { - if (0 != sampleCount) { - *reason = "Can't use multisample on dash effect."; - } else { - *reason = "Too many non dashed path effects."; - } - } else if ((counter.numAAConcavePaths - counter.numAAHairlineConcavePaths) - >= kNumAAConcavePathsTol) - *reason = "Too many anti-aliased concave paths."; - else - *reason = "Unknown reason for GPU unsuitability."; - } - return ret; -} - -} // namespace - -SkPicture::Analysis::Analysis(const SkRecord& record) - : fWillPlaybackBitmaps (WillPlaybackBitmaps(record)) - , fSuitableForGpuRasterization (SuitableForGpuRasterization(record)) { } - -/////////////////////////////////////////////////////////////////////////////// - #ifdef SK_SUPPORT_LEGACY_DEFAULT_PICTURE_CTOR // fRecord OK SkPicture::SkPicture() : fWidth(0) - , fHeight(0) { + , fHeight(0) + , fRecordWillPlayBackBitmaps(false) { this->needsNewGenID(); } #endif @@ -231,7 +61,8 @@ SkPicture::SkPicture(int width, int height, const SkPictureRecord& record, bool deepCopyOps) : fWidth(width) - , fHeight(height) { + , fHeight(height) + , fRecordWillPlayBackBitmaps(false) { this->needsNewGenID(); SkPictInfo info; @@ -306,6 +137,7 @@ SkPicture* SkPicture::clone() const { } SkPicture* clone = SkNEW_ARGS(SkPicture, (newData.detach(), fWidth, fHeight)); + clone->fRecordWillPlayBackBitmaps = fRecordWillPlayBackBitmaps; clone->fUniqueID = this->uniqueID(); // need to call method to ensure != 0 return clone; @@ -438,7 +270,8 @@ bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo SkPicture::SkPicture(SkPictureData* data, int width, int height) : fData(data) , fWidth(width) - , fHeight(height) { + , fHeight(height) + , fRecordWillPlayBackBitmaps(false) { this->needsNewGenID(); } @@ -553,11 +386,8 @@ void SkPicture::flatten(SkWriteBuffer& buffer) const { } #if SK_SUPPORT_GPU -// fRecord OK +// fRecord TODO bool SkPicture::suitableForGpuRasterization(GrContext* context, const char **reason) const { - if (fRecord.get()) { - return fAnalysis.fSuitableForGpuRasterization; - } if (NULL == fData.get()) { if (NULL != reason) { *reason = "Missing internal data."; @@ -577,7 +407,7 @@ bool SkPicture::hasText() const { // fRecord OK bool SkPicture::willPlayBackBitmaps() const { if (fRecord.get()) { - return fAnalysis.fWillPlaybackBitmaps; + return fRecordWillPlayBackBitmaps; } if (!fData.get()) { return false; @@ -611,7 +441,7 @@ SkPicture::SkPicture(int width, int height, SkRecord* record, SkBBoxHierarchy* b , fHeight(height) , fRecord(record) , fBBH(SkSafeRef(bbh)) - , fAnalysis(*record) { + , fRecordWillPlayBackBitmaps(SkRecordWillPlaybackBitmaps(*record)) { // TODO: delay as much of this work until just before first playback? if (fBBH.get()) { SkRecordFillBounds(*record, fBBH.get()); |