Add layer counting to SkPictureRecord
This will be used for a SkPicture::suitableForOptimization entry point. Committed: https://skia.googlesource.com/skia/+/4a2b2e8ed2e35171bf98bad68a69daaced11ec7c R=bsalomon@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/464433002
This commit is contained in:
parent
ea13afff6e
commit
c019ec412b
@ -71,6 +71,62 @@ void SkPictureContentInfo::onAddPaintPtr(const SkPaint* paint) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::onSaveLayer() {
|
||||
*fSaveStack.append() = kSaveLayer_Flag;
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::onSave() {
|
||||
*fSaveStack.append() = kSave_Flag;
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::onRestore() {
|
||||
SkASSERT(fSaveStack.count() > 0);
|
||||
|
||||
bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
|
||||
|
||||
if (fSaveStack.top() & kSaveLayer_Flag) {
|
||||
++fNumLayers;
|
||||
if (containedSaveLayer) {
|
||||
++fNumInteriorLayers;
|
||||
} else {
|
||||
++fNumLeafLayers;
|
||||
}
|
||||
containedSaveLayer = true;
|
||||
}
|
||||
|
||||
fSaveStack.pop();
|
||||
|
||||
if (containedSaveLayer && fSaveStack.count() > 0) {
|
||||
fSaveStack.top() |= kContainedSaveLayer_Flag;
|
||||
}
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::rescindLastSave() {
|
||||
SkASSERT(fSaveStack.count() > 0);
|
||||
SkASSERT(fSaveStack.top() & kSave_Flag);
|
||||
|
||||
bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
|
||||
|
||||
fSaveStack.pop();
|
||||
|
||||
if (containedSaveLayer && fSaveStack.count() > 0) {
|
||||
fSaveStack.top() |= kContainedSaveLayer_Flag;
|
||||
}
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::rescindLastSaveLayer() {
|
||||
SkASSERT(fSaveStack.count() > 0);
|
||||
SkASSERT(fSaveStack.top() & kSaveLayer_Flag);
|
||||
|
||||
bool containedSaveLayer = fSaveStack.top() & kContainedSaveLayer_Flag;
|
||||
|
||||
fSaveStack.pop();
|
||||
|
||||
if (containedSaveLayer && fSaveStack.count() > 0) {
|
||||
fSaveStack.top() |= kContainedSaveLayer_Flag;
|
||||
}
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::set(const SkPictureContentInfo& src) {
|
||||
fNumOperations = src.fNumOperations;
|
||||
fNumTexts = src.fNumTexts;
|
||||
@ -78,6 +134,10 @@ void SkPictureContentInfo::set(const SkPictureContentInfo& src) {
|
||||
fNumFastPathDashEffects = src.fNumFastPathDashEffects;
|
||||
fNumAAConcavePaths = src.fNumAAConcavePaths;
|
||||
fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
|
||||
fNumLayers = src.fNumLayers;
|
||||
fNumInteriorLayers = src.fNumInteriorLayers;
|
||||
fNumLeafLayers = src.fNumLeafLayers;
|
||||
fSaveStack = src.fSaveStack;
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::reset() {
|
||||
@ -87,6 +147,10 @@ void SkPictureContentInfo::reset() {
|
||||
fNumFastPathDashEffects = 0;
|
||||
fNumAAConcavePaths = 0;
|
||||
fNumAAHairlineConcavePaths = 0;
|
||||
fNumLayers = 0;
|
||||
fNumInteriorLayers = 0;
|
||||
fNumLeafLayers = 0;
|
||||
fSaveStack.rewind();
|
||||
}
|
||||
|
||||
void SkPictureContentInfo::swap(SkPictureContentInfo* other) {
|
||||
@ -96,4 +160,8 @@ void SkPictureContentInfo::swap(SkPictureContentInfo* other) {
|
||||
SkTSwap(fNumFastPathDashEffects, other->fNumFastPathDashEffects);
|
||||
SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
|
||||
SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
|
||||
SkTSwap(fNumLayers, other->fNumLayers);
|
||||
SkTSwap(fNumInteriorLayers, other->fNumInteriorLayers);
|
||||
SkTSwap(fNumLeafLayers, other->fNumLeafLayers);
|
||||
fSaveStack.swap(other->fSaveStack);
|
||||
}
|
||||
|
@ -17,6 +17,11 @@ public:
|
||||
|
||||
int numOperations() const { return fNumOperations; }
|
||||
bool hasText() const { return fNumTexts > 0; }
|
||||
|
||||
int numLayers() const { return fNumLayers; }
|
||||
int numInteriorLayers() const { return fNumInteriorLayers; }
|
||||
int numLeafLayers() const { return fNumLeafLayers; }
|
||||
|
||||
bool suitableForGpuRasterization(GrContext* context, const char **reason,
|
||||
int sampleCount) const;
|
||||
|
||||
@ -27,6 +32,12 @@ public:
|
||||
void onAddPaintPtr(const SkPaint* paint);
|
||||
void onDrawText() { ++fNumTexts; }
|
||||
|
||||
void onSaveLayer();
|
||||
void onSave();
|
||||
void onRestore();
|
||||
void rescindLastSave();
|
||||
void rescindLastSaveLayer();
|
||||
|
||||
void set(const SkPictureContentInfo& src);
|
||||
void reset();
|
||||
void swap(SkPictureContentInfo* other);
|
||||
@ -49,6 +60,25 @@ private:
|
||||
// This field is incremented every time a drawPath call is
|
||||
// issued for a hairline stroked concave path.
|
||||
int fNumAAHairlineConcavePaths;
|
||||
// These fields track the different layer flavors. fNumLayers is just
|
||||
// a count of all saveLayers, fNumInteriorLayers is the number of layers
|
||||
// with a layer inside them, fNumLeafLayers is the number of layers with
|
||||
// no layer inside them.
|
||||
int fNumLayers;
|
||||
int fNumInteriorLayers;
|
||||
int fNumLeafLayers;
|
||||
|
||||
enum Flags {
|
||||
kSave_Flag = 0x1,
|
||||
kSaveLayer_Flag = 0x2,
|
||||
|
||||
// Did the current save or saveLayer contain another saveLayer.
|
||||
// Percolated back down the save stack.
|
||||
kContainedSaveLayer_Flag = 0x4
|
||||
};
|
||||
|
||||
// Stack of save vs saveLayer information to track nesting
|
||||
SkTDArray<uint32_t> fSaveStack;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -617,6 +617,9 @@ bool SkPictureData::suitableForGpuRasterization(GrContext* context, const char *
|
||||
}
|
||||
}
|
||||
|
||||
bool SkPictureData::suitableForLayerOptimization() const {
|
||||
return fContentInfo.numLayers() > 0;
|
||||
}
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -150,6 +150,8 @@ public:
|
||||
*/
|
||||
bool suitableForGpuRasterization(GrContext* context, const char **reason,
|
||||
GrPixelConfig config, SkScalar dpi) const;
|
||||
|
||||
bool suitableForLayerOptimization() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
@ -151,6 +151,8 @@ void SkPictureRecord::willSave() {
|
||||
}
|
||||
|
||||
void SkPictureRecord::recordSave() {
|
||||
fContentInfo.onSave();
|
||||
|
||||
// op only
|
||||
size_t size = kSaveSize;
|
||||
size_t initialOffset = this->addDraw(SAVE, &size);
|
||||
@ -179,6 +181,8 @@ SkCanvas::SaveLayerStrategy SkPictureRecord::willSaveLayer(const SkRect* bounds,
|
||||
|
||||
void SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint,
|
||||
SaveFlags flags) {
|
||||
fContentInfo.onSaveLayer();
|
||||
|
||||
// op + bool for 'bounds'
|
||||
size_t size = 2 * kUInt32Size;
|
||||
if (NULL != bounds) {
|
||||
@ -508,8 +512,10 @@ enum PictureRecordOptType {
|
||||
};
|
||||
|
||||
enum PictureRecordOptFlags {
|
||||
kSkipIfBBoxHierarchy_Flag = 0x1, // Optimization should be skipped if the
|
||||
// SkPicture has a bounding box hierarchy.
|
||||
kSkipIfBBoxHierarchy_Flag = 0x1, // Optimization should be skipped if the
|
||||
// SkPicture has a bounding box hierarchy.
|
||||
kRescindLastSave_Flag = 0x2,
|
||||
kRescindLastSaveLayer_Flag = 0x4,
|
||||
};
|
||||
|
||||
struct PictureRecordOpt {
|
||||
@ -528,9 +534,10 @@ static const PictureRecordOpt gPictureRecordOpts[] = {
|
||||
// SkPictureStateTree, and applying the optimization introduces significant
|
||||
// record time overhead because it requires rewinding contents that were
|
||||
// recorded into the BBoxHierarchy.
|
||||
{ collapse_save_clip_restore, kRewind_OptType, kSkipIfBBoxHierarchy_Flag },
|
||||
{ remove_save_layer1, kCollapseSaveLayer_OptType, 0 },
|
||||
{ remove_save_layer2, kCollapseSaveLayer_OptType, 0 }
|
||||
{ collapse_save_clip_restore, kRewind_OptType,
|
||||
kSkipIfBBoxHierarchy_Flag|kRescindLastSave_Flag },
|
||||
{ remove_save_layer1, kCollapseSaveLayer_OptType, kRescindLastSaveLayer_Flag },
|
||||
{ remove_save_layer2, kCollapseSaveLayer_OptType, kRescindLastSaveLayer_Flag }
|
||||
};
|
||||
|
||||
// This is called after an optimization has been applied to the command stream
|
||||
@ -585,6 +592,11 @@ void SkPictureRecord::willRestore() {
|
||||
// Some optimization fired so don't add the RESTORE
|
||||
apply_optimization_to_bbh(gPictureRecordOpts[opt].fType,
|
||||
fStateTree, fBoundingHierarchy);
|
||||
if (gPictureRecordOpts[opt].fFlags & kRescindLastSave_Flag) {
|
||||
fContentInfo.rescindLastSave();
|
||||
} else if (gPictureRecordOpts[opt].fFlags & kRescindLastSaveLayer_Flag) {
|
||||
fContentInfo.rescindLastSaveLayer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -601,6 +613,8 @@ void SkPictureRecord::willRestore() {
|
||||
}
|
||||
|
||||
void SkPictureRecord::recordRestore(bool fillInSkips) {
|
||||
fContentInfo.onRestore();
|
||||
|
||||
if (fillInSkips) {
|
||||
this->fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten());
|
||||
}
|
||||
|
@ -1850,6 +1850,10 @@ SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info) {
|
||||
void SkGpuDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
|
||||
fContext->getLayerCache()->processDeletedPictures();
|
||||
|
||||
if (NULL != picture->fData.get() && !picture->fData->suitableForLayerOptimization()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
|
||||
|
||||
const SkPicture::AccelData* existing = picture->EXPERIMENTAL_getAccelData(key);
|
||||
|
Loading…
Reference in New Issue
Block a user