O(1) SkPictureUtils::ApproxBytesUsed()

Chrome wants to call this more often, and it's quite slow today.

Seems like this could be clearer if SkPictureUtils::ApproxBytesUsed() were SkPicture::approxBytesUsed().

BUG=chromium:471873

Review URL: https://codereview.chromium.org/1090943004
This commit is contained in:
mtklein 2015-04-21 15:23:59 -07:00 committed by Commit bot
parent 5ae0e2b563
commit 98b8485a4c
9 changed files with 44 additions and 45 deletions

View File

@ -260,7 +260,11 @@ private:
static bool IsValidPictInfo(const SkPictInfo& info);
// Takes ownership of the SkRecord and (optional) SnapshotArray, refs the (optional) BBH.
SkPicture(const SkRect& cullRect, SkRecord*, SnapshotArray*, SkBBoxHierarchy*);
SkPicture(const SkRect& cullRect,
SkRecord*,
SnapshotArray*,
SkBBoxHierarchy*,
size_t approxBytesUsedBySubPictures);
static SkPicture* Forwardport(const SkPictInfo&, const SkPictureData*);
static SkPictureData* Backport(const SkRecord&, const SkPictInfo&,
@ -273,6 +277,7 @@ private:
SkAutoTUnref<const SkRecord> fRecord;
SkAutoTUnref<const SkBBoxHierarchy> fBBH;
SkAutoTDelete<const SnapshotArray> fDrawablePicts;
const size_t fApproxBytesUsedBySubPictures;
// helpers for fDrawablePicts
int drawableCount() const;
@ -302,6 +307,6 @@ private:
friend class SkPictureUtils;
friend class SkRecordedDrawable;
};
SK_COMPILE_ASSERT(sizeof(SkPicture) <= 96, SkPictureSize);
SK_COMPILE_ASSERT(sizeof(SkPicture) <= 104, SkPictureSize);
#endif

View File

@ -480,12 +480,13 @@ bool SkPicture::willPlayBackBitmaps() const { return fAnalysis.fWillPlaybackBitm
int SkPicture::approximateOpCount() const { return fRecord->count(); }
SkPicture::SkPicture(const SkRect& cullRect, SkRecord* record, SnapshotArray* drawablePicts,
SkBBoxHierarchy* bbh)
SkBBoxHierarchy* bbh, size_t approxBytesUsedBySubPictures)
: fUniqueID(0)
, fCullRect(cullRect)
, fRecord(SkRef(record))
, fBBH(SkSafeRef(bbh))
, fDrawablePicts(drawablePicts) // take ownership
, fApproxBytesUsedBySubPictures(approxBytesUsedBySubPictures)
, fAnalysis(*fRecord)
{}

View File

@ -9,10 +9,11 @@
#include "SkDrawable.h"
#include "SkLayerInfo.h"
#include "SkPictureRecorder.h"
#include "SkPictureUtils.h"
#include "SkRecord.h"
#include "SkRecordDraw.h"
#include "SkRecorder.h"
#include "SkRecordOpts.h"
#include "SkRecorder.h"
#include "SkTypes.h"
SkPictureRecorder::SkPictureRecorder() {
@ -72,7 +73,12 @@ SkPicture* SkPictureRecorder::endRecordingAsPicture() {
fCullRect = bbhBound;
}
SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullRect, fRecord, pictList, fBBH));
size_t subPictureBytes = fRecorder->approxBytesUsedBySubPictures();
for (int i = 0; pictList && i < pictList->count(); i++) {
subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]);
}
SkPicture* pict =
SkNEW_ARGS(SkPicture, (fCullRect, fRecord, pictList, fBBH, subPictureBytes));
if (saveLayerData) {
pict->EXPERIMENTAL_addAccelData(saveLayerData);
@ -153,7 +159,12 @@ protected:
SkRecordComputeLayers(fBounds, *fRecord, pictList, bbh, saveLayerData);
}
SkPicture* pict = SkNEW_ARGS(SkPicture, (fBounds, fRecord, pictList, fBBH));
size_t subPictureBytes = 0;
for (int i = 0; pictList && i < pictList->count(); i++) {
subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]);
}
SkPicture* pict =
SkNEW_ARGS(SkPicture, (fBounds, fRecord, pictList, fBBH, subPictureBytes));
if (saveLayerData) {
pict->EXPERIMENTAL_addAccelData(saveLayerData);

View File

@ -5,9 +5,10 @@
* found in the LICENSE file.
*/
#include "SkRecorder.h"
#include "SkPatchUtils.h"
#include "SkPicture.h"
#include "SkPictureUtils.h"
#include "SkRecorder.h"
SkDrawableList::~SkDrawableList() {
fArray.unrefAll();
@ -33,10 +34,12 @@ void SkDrawableList::append(SkDrawable* drawable) {
SkRecorder::SkRecorder(SkRecord* record, int width, int height)
: SkCanvas(SkIRect::MakeWH(width, height), SkCanvas::kConservativeRasterClip_InitFlag)
, fApproxBytesUsedBySubPictures(0)
, fRecord(record) {}
SkRecorder::SkRecorder(SkRecord* record, const SkRect& bounds)
: SkCanvas(bounds.roundOut(), SkCanvas::kConservativeRasterClip_InitFlag)
, fApproxBytesUsedBySubPictures(0)
, fRecord(record) {}
void SkRecorder::reset(SkRecord* record, const SkRect& bounds) {
@ -47,6 +50,7 @@ void SkRecorder::reset(SkRecord* record, const SkRect& bounds) {
void SkRecorder::forgetRecord() {
fDrawableList.reset(NULL);
fApproxBytesUsedBySubPictures = 0;
fRecord = NULL;
}
@ -248,6 +252,7 @@ void SkRecorder::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
}
void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, const SkPaint* paint) {
fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic);
APPEND(DrawPicture, this->copy(paint), pic, matrix ? *matrix : SkMatrix::I());
}

View File

@ -41,6 +41,8 @@ public:
void reset(SkRecord*, const SkRect& bounds);
size_t approxBytesUsedBySubPictures() const { return fApproxBytesUsedBySubPictures; }
SkDrawableList* getDrawableList() const { return fDrawableList.get(); }
SkDrawableList* detachDrawableList() { return fDrawableList.detach(); }
@ -131,8 +133,8 @@ private:
return devBounds;
}
size_t fApproxBytesUsedBySubPictures;
SkRecord* fRecord;
SkAutoTDelete<SkDrawableList> fDrawableList;
};

View File

@ -27,13 +27,15 @@ struct SkVarAlloc::Block {
};
SkVarAlloc::SkVarAlloc(size_t minLgSize)
: fByte(NULL)
: fBytesAllocated(0)
, fByte(NULL)
, fRemaining(0)
, fLgSize(minLgSize)
, fBlock(NULL) {}
SkVarAlloc::SkVarAlloc(size_t minLgSize, char* storage, size_t len)
: fByte(storage)
: fBytesAllocated(0)
, fByte(storage)
, fRemaining(len)
, fLgSize(minLgSize)
, fBlock(NULL) {}
@ -54,6 +56,7 @@ void SkVarAlloc::makeSpace(size_t bytes, unsigned flags) {
while (alloc < bytes + sizeof(Block)) {
alloc *= 2;
}
fBytesAllocated += alloc;
fBlock = Block::Alloc(fBlock, alloc, flags);
fByte = fBlock->data();
fRemaining = alloc - sizeof(Block);
@ -65,23 +68,3 @@ void SkVarAlloc::makeSpace(size_t bytes, unsigned flags) {
//SkASSERT(alloc == malloc_usable_size(fBlock));
#endif
}
static size_t heap_size(void* p) {
#if defined(SK_BUILD_FOR_MAC)
return malloc_size(p);
#elif defined(SK_BUILD_FOR_UNIX) && !defined(__UCLIBC__)
return malloc_usable_size(p);
#elif defined(SK_BUILD_FOR_WIN32)
return _msize(p);
#else
return 0; // Tough luck.
#endif
}
size_t SkVarAlloc::approxBytesAllocated() const {
size_t sum = 0;
for (Block* b = fBlock; b; b = b->prev) {
sum += heap_size(b);
}
return sum;
}

View File

@ -35,12 +35,14 @@ public:
}
// Returns our best estimate of the number of bytes we've allocated.
// (We intentionally do not track this precisely to save space.)
size_t approxBytesAllocated() const;
// (We may not track this precisely to save space.)
size_t approxBytesAllocated() const { return fBytesAllocated; }
private:
void makeSpace(size_t bytes, unsigned flags);
size_t fBytesAllocated;
char* fByte;
unsigned fRemaining;
unsigned fLgSize;
@ -48,6 +50,6 @@ private:
struct Block;
Block* fBlock;
};
SK_COMPILE_ASSERT(sizeof(SkVarAlloc) <= 24, SkVarAllocSize);
SK_COMPILE_ASSERT(sizeof(SkVarAlloc) <= 32, SkVarAllocSize);
#endif//SkVarAlloc_DEFINED

View File

@ -12,13 +12,6 @@
#include "SkRecord.h"
#include "SkShader.h"
struct MeasureRecords {
template <typename T> size_t operator()(const T& op) { return 0; }
size_t operator()(const SkRecords::DrawPicture& op) {
return SkPictureUtils::ApproximateBytesUsed(op.picture);
}
};
size_t SkPictureUtils::ApproximateBytesUsed(const SkPicture* pict) {
size_t byteCount = sizeof(*pict);
@ -26,10 +19,7 @@ size_t SkPictureUtils::ApproximateBytesUsed(const SkPicture* pict) {
if (pict->fBBH.get()) {
byteCount += pict->fBBH->bytesUsed();
}
MeasureRecords visitor;
for (unsigned curOp = 0; curOp < pict->fRecord->count(); curOp++) {
byteCount += pict->fRecord->visit<size_t>(curOp, visitor);
}
byteCount += pict->fApproxBytesUsedBySubPictures;
return byteCount;
}

View File

@ -1119,7 +1119,7 @@ static void test_bytes_used(skiatest::Reporter* reporter) {
// Protect against any unintentional bloat.
size_t approxUsed = SkPictureUtils::ApproximateBytesUsed(empty.get());
REPORTER_ASSERT(reporter, approxUsed <= 416);
REPORTER_ASSERT(reporter, approxUsed <= 432);
// Sanity check of nested SkPictures.
SkPictureRecorder r2;