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&,
SkAutoTUnref<const SkRecord> fRecord;
SkAutoTUnref<const SkBBoxHierarchy> fBBH;
SkAutoTDelete<const SnapshotArray> fDrawablePicts;
+ const size_t fApproxBytesUsedBySubPictures;
// helpers for fDrawablePicts
int drawableCount() const;
friend class SkPictureUtils;
friend class SkRecordedDrawable;
};
-SK_COMPILE_ASSERT(sizeof(SkPicture) <= 96, SkPictureSize);
+SK_COMPILE_ASSERT(sizeof(SkPicture) <= 104, SkPictureSize);
#endif
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)
{}
#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() {
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);
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);
* found in the LICENSE file.
*/
-#include "SkRecorder.h"
#include "SkPatchUtils.h"
#include "SkPicture.h"
+#include "SkPictureUtils.h"
+#include "SkRecorder.h"
SkDrawableList::~SkDrawableList() {
fArray.unrefAll();
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) {
void SkRecorder::forgetRecord() {
fDrawableList.reset(NULL);
+ fApproxBytesUsedBySubPictures = 0;
fRecord = NULL;
}
}
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());
}
void reset(SkRecord*, const SkRect& bounds);
+ size_t approxBytesUsedBySubPictures() const { return fApproxBytesUsedBySubPictures; }
+
SkDrawableList* getDrawableList() const { return fDrawableList.get(); }
SkDrawableList* detachDrawableList() { return fDrawableList.detach(); }
return devBounds;
}
+ size_t fApproxBytesUsedBySubPictures;
SkRecord* fRecord;
-
SkAutoTDelete<SkDrawableList> fDrawableList;
};
};
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) {}
while (alloc < bytes + sizeof(Block)) {
alloc *= 2;
}
+ fBytesAllocated += alloc;
fBlock = Block::Alloc(fBlock, alloc, flags);
fByte = fBlock->data();
fRemaining = alloc - sizeof(Block);
//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;
-}
}
// 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;
struct Block;
Block* fBlock;
};
-SK_COMPILE_ASSERT(sizeof(SkVarAlloc) <= 24, SkVarAllocSize);
+SK_COMPILE_ASSERT(sizeof(SkVarAlloc) <= 32, SkVarAllocSize);
#endif//SkVarAlloc_DEFINED
#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);
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;
}
// 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;