Implement SkPicture::bytesUsed() for SkRecord backend

BUG=chromium:230419
R=mtklein@google.com,reed@google.com

Review URL: https://codereview.chromium.org/490253003
This commit is contained in:
tomhudson 2014-11-19 10:41:14 -08:00 коммит произвёл Commit bot
Родитель 72f92acd47
Коммит 158fcaa031
11 изменённых файлов: 95 добавлений и 0 удалений

Просмотреть файл

@ -300,6 +300,7 @@ private:
friend class SkPictureRecorder; // SkRecord-based constructor.
friend class GrLayerHoister; // access to fRecord
friend class ReplaceDraw;
friend class SkPictureUtils;
typedef SkRefCnt INHERITED;
};

Просмотреть файл

@ -78,6 +78,14 @@ public:
* and rect information.
*/
static void GatherPixelRefsAndRects(SkPicture* pict, SkPixelRefContainer* prCont);
/**
* How many bytes are allocated to hold the SkPicture.
* Includes operations, parameters, bounding data, deletion listeners;
* includes nested SkPictures, but does not include large objects that
* SkRecord holds a reference to (e.g. paths, or pixels backing bitmaps).
*/
static size_t ApproximateBytesUsed(const SkPicture* pict);
};
#endif

Просмотреть файл

@ -33,6 +33,8 @@ public:
*/
virtual void search(const SkRect& query, SkTDArray<unsigned>* results) const = 0;
virtual size_t bytesUsed() const = 0;
SK_DECLARE_INST_COUNT(SkBBoxHierarchy)
private:
typedef SkRefCnt INHERITED;

Просмотреть файл

@ -170,3 +170,11 @@ void SkRTree::search(Node* node, const SkRect& query, SkTDArray<unsigned>* resul
}
}
}
size_t SkRTree::bytesUsed() const {
size_t byteCount = sizeof(SkRTree);
byteCount += fNodes.reserved() * sizeof(Node);
return byteCount;
}

Просмотреть файл

@ -43,6 +43,7 @@ public:
virtual void insert(SkAutoTMalloc<SkRect>* boundsArray, int N) SK_OVERRIDE;
virtual void search(const SkRect& query, SkTDArray<unsigned>* results) const SK_OVERRIDE;
virtual size_t bytesUsed() const SK_OVERRIDE;
// Methods and constants below here are only public for tests.
@ -54,6 +55,7 @@ public:
// These values were empirically determined to produce reasonable performance in most cases.
static const int kMinChildren = 6,
kMaxChildren = 11;
private:
struct Node;

Просмотреть файл

@ -113,6 +113,12 @@ public:
return fRecords[i].set(this->allocCommand<T>());
}
// Does not return the bytes in any pointers embedded in the Records; callers
// need to iterate with a visitor to measure those they care for.
size_t bytesUsed() const { return fAlloc.approxBytesAllocated() +
fReserved * (sizeof(Record) + sizeof(Type8)) +
sizeof(SkRecord); }
private:
// Implementation notes!
//

Просмотреть файл

@ -175,3 +175,14 @@ void SkTileGrid::search(const SkRect& originalQuery, SkTDArray<unsigned>* result
}
}
size_t SkTileGrid::bytesUsed() const {
size_t byteCount = sizeof(SkTileGrid);
size_t opCount = 0;
for (int i = 0; i < fXTiles * fYTiles; i++) {
opCount += fTiles[i].reserved();
}
byteCount += opCount * sizeof(unsigned);
return byteCount;
}

Просмотреть файл

@ -27,6 +27,8 @@ public:
// For testing.
int tileCount(int x, int y) { return fTiles[y * fXTiles + x].count(); }
virtual size_t bytesUsed() const SK_OVERRIDE;
private:
void reserve(int);
void shrinkToFit();

Просмотреть файл

@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
#include "SkBBoxHierarchy.h"
#include "SkBitmapDevice.h"
#include "SkCanvas.h"
#include "SkData.h"
@ -12,6 +13,7 @@
#include "SkPictureUtils.h"
#include "SkPixelRef.h"
#include "SkRRect.h"
#include "SkRecord.h"
#include "SkShader.h"
class PixelRefSet {
@ -215,3 +217,29 @@ SkData* SkPictureUtils::GatherPixelRefs(const SkPicture* pict, const SkRect& are
}
return data;
}
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);
byteCount += pict->fRecord->bytesUsed();
if (pict->fBBH.get()) {
byteCount += pict->fBBH->bytesUsed();
}
byteCount +=
pict->fDeletionListeners.reserved() * sizeof(SkPicture::DeletionListener*) +
pict->fDeletionListeners.count() * sizeof(SkPicture::DeletionListener);
MeasureRecords visitor;
for (unsigned curOp = 0; curOp < pict->fRecord->count(); curOp++) {
byteCount += pict->fRecord->visit<size_t>(curOp, visitor);
}
return byteCount;
}

Просмотреть файл

@ -24,6 +24,7 @@
#include "SkPixelRef.h"
#include "SkRRect.h"
#include "SkRandom.h"
#include "SkRecord.h"
#include "SkShader.h"
#include "SkStream.h"
@ -1721,6 +1722,29 @@ static void test_gen_id(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, hasData->uniqueID() != empty->uniqueID());
}
static void test_bytes_used(skiatest::Reporter* reporter) {
SkPictureRecorder recorder;
recorder.beginRecording(0, 0);
SkAutoTUnref<SkPicture> empty(recorder.endRecording());
// Sanity check to make sure we aren't under-measuring.
REPORTER_ASSERT(reporter, SkPictureUtils::ApproximateBytesUsed(empty.get()) >=
sizeof(SkPicture) + sizeof(SkRecord));
// Protect against any unintentional bloat.
REPORTER_ASSERT(reporter, SkPictureUtils::ApproximateBytesUsed(empty.get()) <= 184);
// Sanity check of nested SkPictures.
SkPictureRecorder r2;
r2.beginRecording(0, 0);
r2.getRecordingCanvas()->drawPicture(empty.get());
SkAutoTUnref<SkPicture> nested(r2.endRecording());
REPORTER_ASSERT(reporter, SkPictureUtils::ApproximateBytesUsed(nested.get()) >
SkPictureUtils::ApproximateBytesUsed(empty.get()));
}
DEF_TEST(Picture, reporter) {
#ifdef SK_DEBUG
test_deleting_empty_picture();
@ -1743,6 +1767,7 @@ DEF_TEST(Picture, reporter) {
test_hierarchical(reporter);
test_gen_id(reporter);
test_savelayer_extraction(reporter);
test_bytes_used(reporter);
}
static void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) {
@ -1837,6 +1862,7 @@ struct CountingBBH : public SkBBoxHierarchy {
}
virtual void insert(SkAutoTMalloc<SkRect>*, int) SK_OVERRIDE {}
virtual size_t bytesUsed() const { return 0; }
};
class SpoonFedBBHFactory : public SkBBHFactory {

Просмотреть файл

@ -109,6 +109,7 @@ struct TestBBH : public SkBBoxHierarchy {
}
virtual void search(const SkRect& query, SkTDArray<unsigned>* results) const SK_OVERRIDE {}
virtual size_t bytesUsed() const SK_OVERRIDE { return 0; }
struct Entry {
unsigned opIndex;