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:
parent
5ae0e2b563
commit
98b8485a4c
@ -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
|
||||
|
@ -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)
|
||||
{}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user