Perform SkPicture analysis lazily.

I realized when writing the comment on https://crrev.com/1135363002/
that I'd really just sketched out the entire thing, so I couldn't help
but actually write up a working CL.  How does this do for your benchmark?

BUG=chromium:487075

Review URL: https://codereview.chromium.org/1130123006
This commit is contained in:
mtklein 2015-05-13 19:26:14 -07:00 committed by Commit bot
parent 88c23fc6e8
commit c30806f9f1
2 changed files with 13 additions and 6 deletions

View File

@ -10,6 +10,7 @@
#define SkPicture_DEFINED #define SkPicture_DEFINED
#include "SkImageDecoder.h" #include "SkImageDecoder.h"
#include "SkLazyPtr.h"
#include "SkRefCnt.h" #include "SkRefCnt.h"
#include "SkTDArray.h" #include "SkTDArray.h"
@ -293,7 +294,9 @@ private:
uint8_t fNumSlowPathsAndDashEffects; uint8_t fNumSlowPathsAndDashEffects;
bool fWillPlaybackBitmaps : 1; bool fWillPlaybackBitmaps : 1;
bool fHasText : 1; bool fHasText : 1;
} fAnalysis; };
SkLazyPtr<Analysis> fAnalysis;
const Analysis& analysis() const;
friend class SkPictureRecorder; // SkRecord-based constructor. friend class SkPictureRecorder; // SkRecord-based constructor.
friend class GrLayerHoister; // access to fRecord friend class GrLayerHoister; // access to fRecord

View File

@ -137,7 +137,7 @@ struct SkPicture::PathCounter {
// Recurse into nested pictures. // Recurse into nested pictures.
void operator()(const SkRecords::DrawPicture& op) { void operator()(const SkRecords::DrawPicture& op) {
const SkPicture::Analysis& analysis = op.picture->fAnalysis; const SkPicture::Analysis& analysis = op.picture->analysis();
fNumSlowPathsAndDashEffects += analysis.fNumSlowPathsAndDashEffects; fNumSlowPathsAndDashEffects += analysis.fNumSlowPathsAndDashEffects;
} }
@ -438,14 +438,19 @@ void SkPicture::flatten(SkWriteBuffer& buffer) const {
} }
} }
const SkPicture::Analysis& SkPicture::analysis() const {
auto create = [&](){ return SkNEW_ARGS(Analysis, (*fRecord)); };
return *fAnalysis.get(create);
}
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
bool SkPicture::suitableForGpuRasterization(GrContext*, const char **reason) const { bool SkPicture::suitableForGpuRasterization(GrContext*, const char **reason) const {
return fAnalysis.suitableForGpuRasterization(reason, 0); return this->analysis().suitableForGpuRasterization(reason, 0);
} }
#endif #endif
bool SkPicture::hasText() const { return fAnalysis.fHasText; } bool SkPicture::hasText() const { return this->analysis().fHasText; }
bool SkPicture::willPlayBackBitmaps() const { return fAnalysis.fWillPlaybackBitmaps; } bool SkPicture::willPlayBackBitmaps() const { return this->analysis().fWillPlaybackBitmaps; }
int SkPicture::approximateOpCount() const { return fRecord->count(); } int SkPicture::approximateOpCount() const { return fRecord->count(); }
SkPicture::SkPicture(const SkRect& cullRect, SkPicture::SkPicture(const SkRect& cullRect,
@ -461,7 +466,6 @@ SkPicture::SkPicture(const SkRect& cullRect,
, fBBH(bbh) // Take ownership of caller's ref. , fBBH(bbh) // Take ownership of caller's ref.
, fAccelData(accelData) // Take ownership of caller's ref. , fAccelData(accelData) // Take ownership of caller's ref.
, fApproxBytesUsedBySubPictures(approxBytesUsedBySubPictures) , fApproxBytesUsedBySubPictures(approxBytesUsedBySubPictures)
, fAnalysis(*fRecord)
{} {}