Convert BBH APIs to use SkRect.
Still TODO: convert internals of SkTileGrid.cpp and SkRTree.cpp to work in floats too. NOTREECHECKS=true BUG=skia:1021 R=robertphillips@google.com, reed@google.com, mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/511613002
This commit is contained in:
parent
3031350e05
commit
533eb782ed
@ -13,12 +13,12 @@
|
||||
#include "SkString.h"
|
||||
|
||||
// confine rectangles to a smallish area, so queries generally hit something, and overlap occurs:
|
||||
static const int GENERATE_EXTENTS = 1000;
|
||||
static const SkScalar GENERATE_EXTENTS = 1000.0f;
|
||||
static const int NUM_BUILD_RECTS = 500;
|
||||
static const int NUM_QUERY_RECTS = 5000;
|
||||
static const int GRID_WIDTH = 100;
|
||||
|
||||
typedef SkIRect (*MakeRectProc)(SkRandom&, int, int);
|
||||
typedef SkRect (*MakeRectProc)(SkRandom&, int, int);
|
||||
|
||||
// Time how long it takes to build an R-Tree either bulk-loaded or not
|
||||
class RTreeBuildBench : public Benchmark {
|
||||
@ -115,32 +115,32 @@ protected:
|
||||
SkRandom rand;
|
||||
for (int i = 0; i < loops; ++i) {
|
||||
SkTDArray<void*> hits;
|
||||
SkIRect query;
|
||||
SkRect query;
|
||||
switch(fQuery) {
|
||||
case kSmall_QueryType:
|
||||
query.fLeft = rand.nextU() % GENERATE_EXTENTS;
|
||||
query.fTop = rand.nextU() % GENERATE_EXTENTS;
|
||||
query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
|
||||
query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
|
||||
query.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
query.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
query.fRight = query.fLeft + (GENERATE_EXTENTS / 20);
|
||||
query.fBottom = query.fTop + (GENERATE_EXTENTS / 20);
|
||||
break;
|
||||
case kLarge_QueryType:
|
||||
query.fLeft = rand.nextU() % GENERATE_EXTENTS;
|
||||
query.fTop = rand.nextU() % GENERATE_EXTENTS;
|
||||
query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
|
||||
query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
|
||||
query.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
query.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
query.fRight = query.fLeft + (GENERATE_EXTENTS / 2);
|
||||
query.fBottom = query.fTop + (GENERATE_EXTENTS / 2);
|
||||
break;
|
||||
case kFull_QueryType:
|
||||
query.fLeft = -GENERATE_EXTENTS;
|
||||
query.fTop = -GENERATE_EXTENTS;
|
||||
query.fRight = 2 * GENERATE_EXTENTS;
|
||||
query.fLeft = -GENERATE_EXTENTS;
|
||||
query.fTop = -GENERATE_EXTENTS;
|
||||
query.fRight = 2 * GENERATE_EXTENTS;
|
||||
query.fBottom = 2 * GENERATE_EXTENTS;
|
||||
break;
|
||||
default: // fallthrough
|
||||
case kRandom_QueryType:
|
||||
query.fLeft = rand.nextU() % GENERATE_EXTENTS;
|
||||
query.fTop = rand.nextU() % GENERATE_EXTENTS;
|
||||
query.fRight = query.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
|
||||
query.fBottom = query.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 2);
|
||||
query.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
query.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
query.fRight = query.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
|
||||
query.fBottom = query.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/2);
|
||||
break;
|
||||
};
|
||||
fTree->search(query, &hits);
|
||||
@ -155,34 +155,34 @@ private:
|
||||
typedef Benchmark INHERITED;
|
||||
};
|
||||
|
||||
static inline SkIRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
|
||||
SkIRect out = {0, 0, index + 1, index + 1};
|
||||
static inline SkRect make_concentric_rects_increasing(SkRandom&, int index, int numRects) {
|
||||
SkRect out = SkRect::MakeWH(SkIntToScalar(index+1), SkIntToScalar(index+1));
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline SkIRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
|
||||
SkIRect out;
|
||||
out.fLeft = index % GRID_WIDTH;
|
||||
out.fTop = index / GRID_WIDTH;
|
||||
out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
|
||||
out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
|
||||
static inline SkRect make_XYordered_rects(SkRandom& rand, int index, int numRects) {
|
||||
SkRect out;
|
||||
out.fLeft = SkIntToScalar(index % GRID_WIDTH);
|
||||
out.fTop = SkIntToScalar(index / GRID_WIDTH);
|
||||
out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
|
||||
out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
|
||||
return out;
|
||||
}
|
||||
static inline SkIRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
|
||||
SkIRect out;
|
||||
out.fLeft = index / GRID_WIDTH;
|
||||
out.fTop = index % GRID_WIDTH;
|
||||
out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
|
||||
out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 3);
|
||||
static inline SkRect make_YXordered_rects(SkRandom& rand, int index, int numRects) {
|
||||
SkRect out;
|
||||
out.fLeft = SkIntToScalar(index / GRID_WIDTH);
|
||||
out.fTop = SkIntToScalar(index % GRID_WIDTH);
|
||||
out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
|
||||
out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/3);
|
||||
return out;
|
||||
}
|
||||
|
||||
static inline SkIRect make_random_rects(SkRandom& rand, int index, int numRects) {
|
||||
SkIRect out;
|
||||
out.fLeft = rand.nextS() % GENERATE_EXTENTS;
|
||||
out.fTop = rand.nextS() % GENERATE_EXTENTS;
|
||||
out.fRight = out.fLeft + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
|
||||
out.fBottom = out.fTop + 1 + rand.nextU() % (GENERATE_EXTENTS / 5);
|
||||
static inline SkRect make_random_rects(SkRandom& rand, int index, int numRects) {
|
||||
SkRect out;
|
||||
out.fLeft = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
out.fTop = rand.nextRangeF(0, GENERATE_EXTENTS);
|
||||
out.fRight = out.fLeft + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
|
||||
out.fBottom = out.fTop + 1 + rand.nextRangeF(0, GENERATE_EXTENTS/5);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -288,7 +288,7 @@ private:
|
||||
/** PRIVATE / EXPERIMENTAL -- do not call
|
||||
Return the operations required to render the content inside 'queryRect'.
|
||||
*/
|
||||
const OperationList* EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const;
|
||||
const OperationList* EXPERIMENTAL_getActiveOps(const SkRect& queryRect) const;
|
||||
|
||||
void createHeader(SkPictInfo* info) const;
|
||||
static bool IsValidPictInfo(const SkPictInfo& info);
|
||||
|
@ -144,7 +144,7 @@ protected:
|
||||
|
||||
static bool FindLayersToHoist(const GrAccelData *gpuData,
|
||||
const SkPicture::OperationList* ops,
|
||||
const SkIRect& query,
|
||||
const SkRect& query,
|
||||
bool* pullForward);
|
||||
void drawLayers(const SkPicture* picture,
|
||||
const SkTDArray<GrCachedLayer*>& atlased,
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
* structures than repeated inserts) until flushDeferredInserts is called or the first
|
||||
* search.
|
||||
*/
|
||||
virtual void insert(void* data, const SkIRect& bounds, bool defer = false) = 0;
|
||||
virtual void insert(void* data, const SkRect& bounds, bool defer = false) = 0;
|
||||
|
||||
/**
|
||||
* If any insertions have been deferred, this forces them to be inserted
|
||||
@ -59,7 +59,7 @@ public:
|
||||
/**
|
||||
* Populate 'results' with data pointers corresponding to bounding boxes that intersect 'query'
|
||||
*/
|
||||
virtual void search(const SkIRect& query, SkTDArray<void*>* results) const = 0;
|
||||
virtual void search(const SkRect& query, SkTDArray<void*>* results) const = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
|
||||
|
@ -20,10 +20,8 @@ SkBBoxHierarchyRecord::SkBBoxHierarchyRecord(const SkISize& size,
|
||||
}
|
||||
|
||||
void SkBBoxHierarchyRecord::handleBBox(const SkRect& bounds) {
|
||||
SkIRect r;
|
||||
bounds.roundOut(&r);
|
||||
SkPictureStateTree::Draw* draw = fStateTree->appendDraw(this->writeStream().bytesWritten());
|
||||
fBoundingHierarchy->insert(draw, r, true);
|
||||
fBoundingHierarchy->insert(draw, bounds, true);
|
||||
}
|
||||
|
||||
void SkBBoxHierarchyRecord::willSave() {
|
||||
|
@ -335,7 +335,7 @@ const SkMatrix& SkPicture::OperationList::matrix(int index) const {
|
||||
}
|
||||
|
||||
// fRecord TODO(robert) / kind of OK in a non-optimal sense
|
||||
const SkPicture::OperationList* SkPicture::EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const {
|
||||
const SkPicture::OperationList* SkPicture::EXPERIMENTAL_getActiveOps(const SkRect& queryRect) const {
|
||||
SkASSERT(NULL != fData.get());
|
||||
if (NULL != fData.get()) {
|
||||
return fData->getActiveOps(queryRect);
|
||||
|
@ -635,7 +635,7 @@ bool SkPictureData::parseBuffer(SkReadBuffer& buffer) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const SkPicture::OperationList* SkPictureData::getActiveOps(const SkIRect& query) const {
|
||||
const SkPicture::OperationList* SkPictureData::getActiveOps(const SkRect& query) const {
|
||||
if (NULL == fStateTree || NULL == fBoundingHierarchy) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
|
||||
virtual ~SkPictureData();
|
||||
|
||||
const SkPicture::OperationList* getActiveOps(const SkIRect& queryRect) const;
|
||||
const SkPicture::OperationList* getActiveOps(const SkRect& queryRect) const;
|
||||
|
||||
void serialize(SkWStream*, SkPicture::EncodeBitmap) const;
|
||||
void flatten(SkWriteBuffer&) const;
|
||||
|
@ -71,18 +71,15 @@ const SkPicture::OperationList* SkPicturePlayback::getActiveOps(const SkCanvas*
|
||||
if (fUseBBH) {
|
||||
SkRect clipBounds;
|
||||
if (canvas->getClipBounds(&clipBounds)) {
|
||||
SkIRect query;
|
||||
clipBounds.roundOut(&query);
|
||||
|
||||
return fPictureData->getActiveOps(query);
|
||||
return fPictureData->getActiveOps(clipBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Initialize the state tree iterator. Return false if there is nothing left to draw.
|
||||
bool SkPicturePlayback::initIterator(SkPictureStateTree::Iterator* iter,
|
||||
bool SkPicturePlayback::initIterator(SkPictureStateTree::Iterator* iter,
|
||||
SkCanvas* canvas,
|
||||
const SkPicture::OperationList *activeOpsList) {
|
||||
|
||||
@ -172,9 +169,9 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback)
|
||||
}
|
||||
}
|
||||
|
||||
void SkPicturePlayback::handleOp(SkReader32* reader,
|
||||
DrawType op,
|
||||
uint32_t size,
|
||||
void SkPicturePlayback::handleOp(SkReader32* reader,
|
||||
DrawType op,
|
||||
uint32_t size,
|
||||
SkCanvas* canvas,
|
||||
const SkMatrix& initialMatrix) {
|
||||
switch (op) {
|
||||
@ -310,7 +307,7 @@ void SkPicturePlayback::handleOp(SkReader32* reader,
|
||||
break;
|
||||
case DRAW_PATCH: {
|
||||
const SkPaint& paint = *fPictureData->getPaint(reader);
|
||||
|
||||
|
||||
const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts *
|
||||
sizeof(SkPoint));
|
||||
uint32_t flag = reader->readInt();
|
||||
|
@ -44,7 +44,14 @@ SkRTree::~SkRTree() {
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void SkRTree::insert(void* data, const SkIRect& bounds, bool defer) {
|
||||
void SkRTree::insert(void* data, const SkRect& fbounds, bool defer) {
|
||||
SkIRect bounds;
|
||||
if (fbounds.isLargest()) {
|
||||
bounds.setLargest();
|
||||
} else {
|
||||
fbounds.roundOut(&bounds);
|
||||
}
|
||||
|
||||
this->validate();
|
||||
if (bounds.isEmpty()) {
|
||||
SkASSERT(false);
|
||||
@ -102,7 +109,9 @@ void SkRTree::flushDeferredInserts() {
|
||||
this->validate();
|
||||
}
|
||||
|
||||
void SkRTree::search(const SkIRect& query, SkTDArray<void*>* results) const {
|
||||
void SkRTree::search(const SkRect& fquery, SkTDArray<void*>* results) const {
|
||||
SkIRect query;
|
||||
fquery.roundOut(&query);
|
||||
this->validate();
|
||||
SkASSERT(0 == fDeferredInserts.count()); // If this fails, you should have flushed.
|
||||
if (!this->isEmpty() && SkIRect::IntersectsNoEmptyCheck(fRoot.fBounds, query)) {
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
* @param bounds The corresponding bounding box
|
||||
* @param defer Can this insert be deferred? (this may be ignored)
|
||||
*/
|
||||
virtual void insert(void* data, const SkIRect& bounds, bool defer = false) SK_OVERRIDE;
|
||||
virtual void insert(void* data, const SkRect& bounds, bool defer = false) SK_OVERRIDE;
|
||||
|
||||
/**
|
||||
* If any inserts have been deferred, this will add them into the tree
|
||||
@ -77,7 +77,7 @@ public:
|
||||
/**
|
||||
* Given a query rectangle, populates the passed-in array with the elements it intersects
|
||||
*/
|
||||
virtual void search(const SkIRect& query, SkTDArray<void*>* results) const SK_OVERRIDE;
|
||||
virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE;
|
||||
|
||||
virtual void clear() SK_OVERRIDE;
|
||||
bool isEmpty() const { return 0 == fCount; }
|
||||
|
@ -16,15 +16,12 @@ void SkRecordDraw(const SkRecord& record,
|
||||
|
||||
if (NULL != bbh) {
|
||||
// Draw only ops that affect pixels in the canvas's current clip.
|
||||
SkIRect query;
|
||||
|
||||
// The SkRecord and BBH were recorded in identity space. This canvas
|
||||
// is not necessarily in that same space. getClipBounds() returns us
|
||||
// this canvas' clip bounds transformed back into identity space, which
|
||||
// lets us query the BBH.
|
||||
SkRect clipBounds = { 0, 0, 0, 0 };
|
||||
(void)canvas->getClipBounds(&clipBounds);
|
||||
clipBounds.roundOut(&query);
|
||||
SkRect query = { 0, 0, 0, 0 };
|
||||
(void)canvas->getClipBounds(&query);
|
||||
|
||||
SkTDArray<void*> ops;
|
||||
bbh->search(query, &ops);
|
||||
@ -123,7 +120,7 @@ public:
|
||||
FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.count()) {
|
||||
// Calculate bounds for all ops. This won't go quite in order, so we'll need
|
||||
// to store the bounds separately then feed them in to the BBH later in order.
|
||||
const SkIRect largest = SkIRect::MakeLargest();
|
||||
const Bounds largest = Bounds::MakeLargest();
|
||||
fCTM = &SkMatrix::I();
|
||||
fCurrentClipBounds = largest;
|
||||
for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) {
|
||||
@ -158,9 +155,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// In this file, SkRect are in local coordinates, Bounds are translated back to identity space.
|
||||
typedef SkRect Bounds;
|
||||
|
||||
struct SaveBounds {
|
||||
int controlOps; // Number of control ops in this Save block, including the Save.
|
||||
SkIRect bounds; // Bounds of everything in the block.
|
||||
Bounds bounds; // Bounds of everything in the block.
|
||||
const SkPaint* paint; // Unowned. If set, adjusts the bounds of all ops in this block.
|
||||
};
|
||||
|
||||
@ -171,11 +171,11 @@ private:
|
||||
template <typename T> void updateClipBounds(const T&) { /* most ops don't change the clip */ }
|
||||
// Each of these devBounds fields is the state of the device bounds after the op.
|
||||
// So Restore's devBounds are those bounds saved by its paired Save or SaveLayer.
|
||||
void updateClipBounds(const Restore& op) { fCurrentClipBounds = op.devBounds; }
|
||||
void updateClipBounds(const ClipPath& op) { fCurrentClipBounds = op.devBounds; }
|
||||
void updateClipBounds(const ClipRRect& op) { fCurrentClipBounds = op.devBounds; }
|
||||
void updateClipBounds(const ClipRect& op) { fCurrentClipBounds = op.devBounds; }
|
||||
void updateClipBounds(const ClipRegion& op) { fCurrentClipBounds = op.devBounds; }
|
||||
void updateClipBounds(const Restore& op) { fCurrentClipBounds = Bounds::Make(op.devBounds); }
|
||||
void updateClipBounds(const ClipPath& op) { fCurrentClipBounds = Bounds::Make(op.devBounds); }
|
||||
void updateClipBounds(const ClipRRect& op) { fCurrentClipBounds = Bounds::Make(op.devBounds); }
|
||||
void updateClipBounds(const ClipRect& op) { fCurrentClipBounds = Bounds::Make(op.devBounds); }
|
||||
void updateClipBounds(const ClipRegion& op) { fCurrentClipBounds = Bounds::Make(op.devBounds); }
|
||||
void updateClipBounds(const SaveLayer& op) {
|
||||
if (op.bounds) {
|
||||
fCurrentClipBounds.intersect(this->adjustAndMap(*op.bounds, op.paint));
|
||||
@ -207,7 +207,7 @@ private:
|
||||
|
||||
void pushSaveBlock(const SkPaint* paint) {
|
||||
// Starting a new Save block. Push a new entry to represent that.
|
||||
SaveBounds sb = { 0, SkIRect::MakeEmpty(), paint };
|
||||
SaveBounds sb = { 0, Bounds::MakeEmpty(), paint };
|
||||
fSaveStack.push(sb);
|
||||
this->pushControl();
|
||||
}
|
||||
@ -217,13 +217,13 @@ private:
|
||||
return paint && (paint->getImageFilter() || paint->getColorFilter());
|
||||
}
|
||||
|
||||
SkIRect popSaveBlock() {
|
||||
Bounds popSaveBlock() {
|
||||
// We're done the Save block. Apply the block's bounds to all control ops inside it.
|
||||
SaveBounds sb;
|
||||
fSaveStack.pop(&sb);
|
||||
|
||||
// If the paint affects transparent black, we can't trust any of our calculated bounds.
|
||||
const SkIRect& bounds =
|
||||
const Bounds& bounds =
|
||||
PaintMayAffectTransparentBlack(sb.paint) ? fCurrentClipBounds : sb.bounds;
|
||||
|
||||
while (sb.controlOps --> 0) {
|
||||
@ -244,12 +244,12 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void popControl(const SkIRect& bounds) {
|
||||
void popControl(const Bounds& bounds) {
|
||||
fBounds[fControlIndices.top()] = bounds;
|
||||
fControlIndices.pop();
|
||||
}
|
||||
|
||||
void updateSaveBounds(const SkIRect& bounds) {
|
||||
void updateSaveBounds(const Bounds& bounds) {
|
||||
// If we're in a Save block, expand its bounds to cover these bounds too.
|
||||
if (!fSaveStack.isEmpty()) {
|
||||
fSaveStack.top().bounds.join(bounds);
|
||||
@ -257,49 +257,49 @@ private:
|
||||
}
|
||||
|
||||
// FIXME: this method could use better bounds
|
||||
SkIRect bounds(const DrawText&) const { return fCurrentClipBounds; }
|
||||
Bounds bounds(const DrawText&) const { return fCurrentClipBounds; }
|
||||
|
||||
SkIRect bounds(const Clear&) const { return SkIRect::MakeLargest(); } // Ignores the clip.
|
||||
SkIRect bounds(const DrawPaint&) const { return fCurrentClipBounds; }
|
||||
SkIRect bounds(const NoOp&) const { return SkIRect::MakeEmpty(); } // NoOps don't draw.
|
||||
Bounds bounds(const Clear&) const { return Bounds::MakeLargest(); } // Ignores the clip.
|
||||
Bounds bounds(const DrawPaint&) const { return fCurrentClipBounds; }
|
||||
Bounds bounds(const NoOp&) const { return Bounds::MakeEmpty(); } // NoOps don't draw.
|
||||
|
||||
SkIRect bounds(const DrawSprite& op) const {
|
||||
Bounds bounds(const DrawSprite& op) const {
|
||||
const SkBitmap& bm = op.bitmap;
|
||||
return SkIRect::MakeXYWH(op.left, op.top, bm.width(), bm.height()); // Ignores the matrix.
|
||||
return Bounds::MakeXYWH(op.left, op.top, bm.width(), bm.height()); // Ignores the matrix.
|
||||
}
|
||||
|
||||
SkIRect bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); }
|
||||
SkIRect bounds(const DrawOval& op) const { return this->adjustAndMap(op.oval, &op.paint); }
|
||||
SkIRect bounds(const DrawRRect& op) const {
|
||||
Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); }
|
||||
Bounds bounds(const DrawOval& op) const { return this->adjustAndMap(op.oval, &op.paint); }
|
||||
Bounds bounds(const DrawRRect& op) const {
|
||||
return this->adjustAndMap(op.rrect.rect(), &op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawDRRect& op) const {
|
||||
Bounds bounds(const DrawDRRect& op) const {
|
||||
return this->adjustAndMap(op.outer.rect(), &op.paint);
|
||||
}
|
||||
|
||||
SkIRect bounds(const DrawBitmapRectToRect& op) const {
|
||||
Bounds bounds(const DrawBitmapRectToRect& op) const {
|
||||
return this->adjustAndMap(op.dst, op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawBitmapNine& op) const {
|
||||
Bounds bounds(const DrawBitmapNine& op) const {
|
||||
return this->adjustAndMap(op.dst, op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawBitmap& op) const {
|
||||
Bounds bounds(const DrawBitmap& op) const {
|
||||
const SkBitmap& bm = op.bitmap;
|
||||
return this->adjustAndMap(SkRect::MakeXYWH(op.left, op.top, bm.width(), bm.height()),
|
||||
op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawBitmapMatrix& op) const {
|
||||
Bounds bounds(const DrawBitmapMatrix& op) const {
|
||||
const SkBitmap& bm = op.bitmap;
|
||||
SkRect dst = SkRect::MakeWH(bm.width(), bm.height());
|
||||
op.matrix.mapRect(&dst);
|
||||
return this->adjustAndMap(dst, op.paint);
|
||||
}
|
||||
|
||||
SkIRect bounds(const DrawPath& op) const {
|
||||
Bounds bounds(const DrawPath& op) const {
|
||||
return op.path.isInverseFillType() ? fCurrentClipBounds
|
||||
: this->adjustAndMap(op.path.getBounds(), &op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawPoints& op) const {
|
||||
Bounds bounds(const DrawPoints& op) const {
|
||||
SkRect dst;
|
||||
dst.set(op.pts, op.count);
|
||||
|
||||
@ -309,18 +309,18 @@ private:
|
||||
|
||||
return this->adjustAndMap(dst, &op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawPatch& op) const {
|
||||
Bounds bounds(const DrawPatch& op) const {
|
||||
SkRect dst;
|
||||
dst.set(op.cubics, SkPatchUtils::kNumCtrlPts);
|
||||
return this->adjustAndMap(dst, &op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawVertices& op) const {
|
||||
Bounds bounds(const DrawVertices& op) const {
|
||||
SkRect dst;
|
||||
dst.set(op.vertices, op.vertexCount);
|
||||
return this->adjustAndMap(dst, &op.paint);
|
||||
}
|
||||
|
||||
SkIRect bounds(const DrawPicture& op) const {
|
||||
Bounds bounds(const DrawPicture& op) const {
|
||||
SkRect dst = SkRect::MakeWH(op.picture->width(), op.picture->height());
|
||||
if (op.matrix) {
|
||||
op.matrix->mapRect(&dst);
|
||||
@ -328,10 +328,10 @@ private:
|
||||
return this->adjustAndMap(dst, op.paint);
|
||||
}
|
||||
|
||||
SkIRect bounds(const DrawPosText& op) const {
|
||||
Bounds bounds(const DrawPosText& op) const {
|
||||
const int N = op.paint.countText(op.text, op.byteLength);
|
||||
if (N == 0) {
|
||||
return SkIRect::MakeEmpty();
|
||||
return Bounds::MakeEmpty();
|
||||
}
|
||||
|
||||
SkRect dst;
|
||||
@ -339,10 +339,10 @@ private:
|
||||
AdjustTextForFontMetrics(&dst, op.paint);
|
||||
return this->adjustAndMap(dst, &op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawPosTextH& op) const {
|
||||
Bounds bounds(const DrawPosTextH& op) const {
|
||||
const int N = op.paint.countText(op.text, op.byteLength);
|
||||
if (N == 0) {
|
||||
return SkIRect::MakeEmpty();
|
||||
return Bounds::MakeEmpty();
|
||||
}
|
||||
|
||||
SkScalar left = op.xpos[0], right = op.xpos[0];
|
||||
@ -354,7 +354,7 @@ private:
|
||||
AdjustTextForFontMetrics(&dst, op.paint);
|
||||
return this->adjustAndMap(dst, &op.paint);
|
||||
}
|
||||
SkIRect bounds(const DrawTextOnPath& op) const {
|
||||
Bounds bounds(const DrawTextOnPath& op) const {
|
||||
SkRect dst = op.path.getBounds();
|
||||
|
||||
// Pad all sides by the maximum padding in any direction we'd normally apply.
|
||||
@ -370,7 +370,7 @@ private:
|
||||
return this->adjustAndMap(dst, &op.paint);
|
||||
}
|
||||
|
||||
SkIRect bounds(const DrawTextBlob& op) const {
|
||||
Bounds bounds(const DrawTextBlob& op) const {
|
||||
SkRect dst = op.blob->bounds();
|
||||
dst.offset(op.x, op.y);
|
||||
// TODO: remove when implicit bounds are plumbed through
|
||||
@ -415,8 +415,8 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adjust rect for all paints that may affect its geometry, then map it to device space.
|
||||
SkIRect adjustAndMap(SkRect rect, const SkPaint* paint) const {
|
||||
// Adjust rect for all paints that may affect its geometry, then map it to identity space.
|
||||
Bounds adjustAndMap(SkRect rect, const SkPaint* paint) const {
|
||||
// Inverted rectangles really confuse our BBHs.
|
||||
rect.sort();
|
||||
|
||||
@ -434,26 +434,24 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
// Map the rect back to device space.
|
||||
// Map the rect back to identity space.
|
||||
fCTM->mapRect(&rect);
|
||||
SkIRect devRect;
|
||||
rect.roundOut(&devRect);
|
||||
|
||||
// Nothing can draw outside the current clip.
|
||||
// (Only bounded ops call into this method, so oddballs like Clear don't matter here.)
|
||||
devRect.intersect(fCurrentClipBounds);
|
||||
return devRect;
|
||||
rect.intersect(fCurrentClipBounds);
|
||||
return rect;
|
||||
}
|
||||
|
||||
// Conservative device bounds for each op in the SkRecord.
|
||||
SkAutoTMalloc<SkIRect> fBounds;
|
||||
// Conservative identity-space bounds for each op in the SkRecord.
|
||||
SkAutoTMalloc<Bounds> fBounds;
|
||||
|
||||
// We walk fCurrentOp through the SkRecord, as we go using updateCTM()
|
||||
// and updateClipBounds() to maintain the exact CTM (fCTM) and conservative
|
||||
// device bounds of the current clip (fCurrentClipBounds).
|
||||
// identity-space bounds of the current clip (fCurrentClipBounds).
|
||||
unsigned fCurrentOp;
|
||||
const SkMatrix* fCTM;
|
||||
SkIRect fCurrentClipBounds;
|
||||
Bounds fCurrentClipBounds;
|
||||
|
||||
// Used to track the bounds of Save/Restore blocks and the control ops inside them.
|
||||
SkTDArray<SaveBounds> fSaveStack;
|
||||
|
@ -23,13 +23,15 @@ SkTileGrid::~SkTileGrid() {
|
||||
SkDELETE_ARRAY(fTiles);
|
||||
}
|
||||
|
||||
void SkTileGrid::insert(void* data, const SkIRect& bounds, bool) {
|
||||
SkASSERT(!bounds.isEmpty());
|
||||
SkIRect dilatedBounds = bounds;
|
||||
|
||||
// Dilating the largest SkIRect will overflow. Other nearly-largest rects may overflow too,
|
||||
// but we don't make active use of them like we do the largest.
|
||||
if (!bounds.isLargest()) {
|
||||
void SkTileGrid::insert(void* data, const SkRect& fbounds, bool) {
|
||||
SkASSERT(!fbounds.isEmpty());
|
||||
SkIRect dilatedBounds;
|
||||
if (fbounds.isLargest()) {
|
||||
// Dilating the largest SkIRect will overflow. Other nearly-largest rects may overflow too,
|
||||
// but we don't make active use of them like we do the largest.
|
||||
dilatedBounds.setLargest();
|
||||
} else {
|
||||
fbounds.roundOut(&dilatedBounds);
|
||||
dilatedBounds.outset(fInfo.fMargin.width(), fInfo.fMargin.height());
|
||||
dilatedBounds.offset(fInfo.fOffset);
|
||||
}
|
||||
@ -67,8 +69,9 @@ static int divide_ceil(int x, int y) {
|
||||
// require 512 tiles of size 256 x 256 pixels.
|
||||
static const int kStackAllocationTileCount = 1024;
|
||||
|
||||
void SkTileGrid::search(const SkIRect& query, SkTDArray<void*>* results) const {
|
||||
SkIRect adjusted = query;
|
||||
void SkTileGrid::search(const SkRect& query, SkTDArray<void*>* results) const {
|
||||
SkIRect adjusted;
|
||||
query.roundOut(&adjusted);
|
||||
|
||||
// The inset is to counteract the outset that was applied in 'insert'
|
||||
// The outset/inset is to optimize for lookups of size
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
* @param bounds The bounding box, should not be empty.
|
||||
* @param defer Ignored; SkTileGrid does not defer insertions.
|
||||
*/
|
||||
virtual void insert(void* data, const SkIRect& bounds, bool) SK_OVERRIDE;
|
||||
virtual void insert(void* data, const SkRect& bounds, bool) SK_OVERRIDE;
|
||||
|
||||
virtual void flushDeferredInserts() SK_OVERRIDE {};
|
||||
|
||||
@ -36,7 +36,7 @@ public:
|
||||
* Populate 'results' with data pointers corresponding to bounding boxes that intersect 'query'.
|
||||
* This will be fastest if the query is an exact match to a single grid tile.
|
||||
*/
|
||||
virtual void search(const SkIRect& query, SkTDArray<void*>* results) const SK_OVERRIDE;
|
||||
virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE;
|
||||
|
||||
virtual void clear() SK_OVERRIDE;
|
||||
|
||||
|
@ -1617,7 +1617,7 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
CHECK_SHOULD_DRAW(draw, false);
|
||||
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext);
|
||||
|
||||
|
||||
const uint16_t* outIndices;
|
||||
SkAutoTDeleteArray<uint16_t> outAlloc(NULL);
|
||||
GrPrimitiveType primType;
|
||||
@ -1625,13 +1625,13 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
|
||||
// If both textures and vertex-colors are NULL, strokes hairlines with the paint's color.
|
||||
if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) {
|
||||
|
||||
|
||||
texs = NULL;
|
||||
|
||||
|
||||
SkPaint copy(paint);
|
||||
copy.setStyle(SkPaint::kStroke_Style);
|
||||
copy.setStrokeWidth(0);
|
||||
|
||||
|
||||
// we ignore the shader if texs is null.
|
||||
SkPaint2GrPaintNoShader(this->context(), copy, SkColor2GrColor(copy.getColor()),
|
||||
NULL == colors, &grPaint);
|
||||
@ -1648,13 +1648,13 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
triangleCount = n - 2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
VertState state(vertexCount, indices, indexCount);
|
||||
VertState::Proc vertProc = state.chooseProc(vmode);
|
||||
|
||||
|
||||
//number of indices for lines per triangle with kLines
|
||||
indexCount = triangleCount * 6;
|
||||
|
||||
|
||||
outAlloc.reset(SkNEW_ARRAY(uint16_t, indexCount));
|
||||
outIndices = outAlloc.get();
|
||||
uint16_t* auxIndices = outAlloc.get();
|
||||
@ -1671,7 +1671,7 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
} else {
|
||||
outIndices = indices;
|
||||
primType = gVertexMode2PrimitiveType[vmode];
|
||||
|
||||
|
||||
if (NULL == texs || NULL == paint.getShader()) {
|
||||
SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(paint.getColor()),
|
||||
NULL == colors, &grPaint);
|
||||
@ -1879,7 +1879,7 @@ static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
|
||||
// Return true if any layers are suitable for hoisting
|
||||
bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData,
|
||||
const SkPicture::OperationList* ops,
|
||||
const SkIRect& query,
|
||||
const SkRect& query,
|
||||
bool* pullForward) {
|
||||
bool anyHoisted = false;
|
||||
|
||||
@ -1929,12 +1929,12 @@ bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData,
|
||||
for (int j = 0; j < gpuData->numSaveLayers(); ++j) {
|
||||
const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j);
|
||||
|
||||
SkIRect layerRect = SkIRect::MakeXYWH(info.fOffset.fX,
|
||||
info.fOffset.fY,
|
||||
info.fSize.fWidth,
|
||||
info.fSize.fHeight);
|
||||
SkRect layerRect = SkRect::MakeXYWH(SkIntToScalar(info.fOffset.fX),
|
||||
SkIntToScalar(info.fOffset.fY),
|
||||
SkIntToScalar(info.fSize.fWidth),
|
||||
SkIntToScalar(info.fSize.fHeight));
|
||||
|
||||
if (!SkIRect::Intersects(query, layerRect)) {
|
||||
if (!SkRect::Intersects(query, layerRect)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1986,12 +1986,11 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
||||
if (!mainCanvas->getClipBounds(&clipBounds)) {
|
||||
return true;
|
||||
}
|
||||
SkIRect query;
|
||||
clipBounds.roundOut(&query);
|
||||
|
||||
SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getActiveOps(query));
|
||||
SkAutoTDelete<const SkPicture::OperationList> ops(
|
||||
picture->EXPERIMENTAL_getActiveOps(clipBounds));
|
||||
|
||||
if (!FindLayersToHoist(gpuData, ops.get(), query, pullForward.get())) {
|
||||
if (!FindLayersToHoist(gpuData, ops.get(), clipBounds, pullForward.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2005,9 +2004,9 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
||||
if (pullForward[i]) {
|
||||
const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
|
||||
|
||||
GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(),
|
||||
info.fSaveLayerOpID,
|
||||
info.fRestoreOpID,
|
||||
GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(),
|
||||
info.fSaveLayerOpID,
|
||||
info.fRestoreOpID,
|
||||
info.fCTM);
|
||||
|
||||
SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
|
||||
@ -2030,7 +2029,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
||||
}
|
||||
|
||||
layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD
|
||||
wrap_texture(layer->texture(),
|
||||
wrap_texture(layer->texture(),
|
||||
!layer->isAtlased() ? desc.fWidth : layer->texture()->width(),
|
||||
!layer->isAtlased() ? desc.fHeight : layer->texture()->height(),
|
||||
layerInfo->fBM);
|
||||
@ -2066,7 +2065,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawLayers(const SkPicture* picture,
|
||||
const SkTDArray<GrCachedLayer*>& atlased,
|
||||
const SkTDArray<GrCachedLayer*>& atlased,
|
||||
const SkTDArray<GrCachedLayer*>& nonAtlased) {
|
||||
// Render the atlased layers that require it
|
||||
if (atlased.count() > 0) {
|
||||
@ -2171,7 +2170,7 @@ void SkGpuDevice::unlockLayers(const SkPicture* picture) {
|
||||
}
|
||||
|
||||
#if DISABLE_CACHING
|
||||
// This code completely clears out the atlas. It is required when
|
||||
// This code completely clears out the atlas. It is required when
|
||||
// caching is disabled so the atlas doesn't fill up and force more
|
||||
// free floating layers
|
||||
fContext->getLayerCache()->purge(picture->uniqueID());
|
||||
|
@ -17,20 +17,20 @@ static const int NUM_RECTS = 200;
|
||||
static const size_t NUM_ITERATIONS = 100;
|
||||
static const size_t NUM_QUERIES = 50;
|
||||
|
||||
static const int MAX_SIZE = 1000;
|
||||
static const SkScalar MAX_SIZE = 1000.0f;
|
||||
|
||||
struct DataRect {
|
||||
SkIRect rect;
|
||||
SkRect rect;
|
||||
void* data;
|
||||
};
|
||||
|
||||
static SkIRect random_rect(SkRandom& rand) {
|
||||
SkIRect rect = {0,0,0,0};
|
||||
static SkRect random_rect(SkRandom& rand) {
|
||||
SkRect rect = {0,0,0,0};
|
||||
while (rect.isEmpty()) {
|
||||
rect.fLeft = rand.nextS() % MAX_SIZE;
|
||||
rect.fRight = rand.nextS() % MAX_SIZE;
|
||||
rect.fTop = rand.nextS() % MAX_SIZE;
|
||||
rect.fBottom = rand.nextS() % MAX_SIZE;
|
||||
rect.fLeft = rand.nextRangeF(0, MAX_SIZE);
|
||||
rect.fRight = rand.nextRangeF(0, MAX_SIZE);
|
||||
rect.fTop = rand.nextRangeF(0, MAX_SIZE);
|
||||
rect.fBottom = rand.nextRangeF(0, MAX_SIZE);
|
||||
rect.sort();
|
||||
}
|
||||
return rect;
|
||||
@ -43,12 +43,15 @@ static void random_data_rects(SkRandom& rand, DataRect out[], int n) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool verify_query(SkIRect query, DataRect rects[],
|
||||
static bool verify_query(SkRect query, DataRect rects[],
|
||||
SkTDArray<void*>& found) {
|
||||
// TODO(mtklein): no need to do this after everything's SkRects
|
||||
query.roundOut();
|
||||
|
||||
SkTDArray<void*> expected;
|
||||
// manually intersect with every rectangle
|
||||
for (int i = 0; i < NUM_RECTS; ++i) {
|
||||
if (SkIRect::IntersectsNoEmptyCheck(query, rects[i].rect)) {
|
||||
if (SkRect::Intersects(query, rects[i].rect)) {
|
||||
expected.push(rects[i].data);
|
||||
}
|
||||
}
|
||||
@ -73,7 +76,7 @@ static void run_queries(skiatest::Reporter* reporter, SkRandom& rand, DataRect r
|
||||
SkBBoxHierarchy& tree) {
|
||||
for (size_t i = 0; i < NUM_QUERIES; ++i) {
|
||||
SkTDArray<void*> hits;
|
||||
SkIRect query = random_rect(rand);
|
||||
SkRect query = random_rect(rand);
|
||||
tree.search(query, &hits);
|
||||
REPORTER_ASSERT(reporter, verify_query(query, rects, hits));
|
||||
}
|
||||
|
@ -1808,12 +1808,12 @@ struct CountingBBH : public SkBBoxHierarchy {
|
||||
|
||||
CountingBBH() : searchCalls(0) {}
|
||||
|
||||
virtual void search(const SkIRect& query, SkTDArray<void*>* results) const {
|
||||
virtual void search(const SkRect& query, SkTDArray<void*>* results) const {
|
||||
this->searchCalls++;
|
||||
}
|
||||
|
||||
// All other methods unimplemented.
|
||||
virtual void insert(void* data, const SkIRect& bounds, bool defer) {}
|
||||
virtual void insert(void* data, const SkRect& bounds, bool defer) {}
|
||||
virtual void flushDeferredInserts() {}
|
||||
virtual void clear() {}
|
||||
virtual int getCount() const { return 0; }
|
||||
|
@ -18,17 +18,17 @@ static const size_t NUM_ITERATIONS = 100;
|
||||
static const size_t NUM_QUERIES = 50;
|
||||
|
||||
struct DataRect {
|
||||
SkIRect rect;
|
||||
SkRect rect;
|
||||
void* data;
|
||||
};
|
||||
|
||||
static SkIRect random_rect(SkRandom& rand) {
|
||||
SkIRect rect = {0,0,0,0};
|
||||
static SkRect random_rect(SkRandom& rand) {
|
||||
SkRect rect = {0,0,0,0};
|
||||
while (rect.isEmpty()) {
|
||||
rect.fLeft = rand.nextS() % 1000;
|
||||
rect.fRight = rand.nextS() % 1000;
|
||||
rect.fTop = rand.nextS() % 1000;
|
||||
rect.fBottom = rand.nextS() % 1000;
|
||||
rect.fLeft = rand.nextRangeF(0, 1000);
|
||||
rect.fRight = rand.nextRangeF(0, 1000);
|
||||
rect.fTop = rand.nextRangeF(0, 1000);
|
||||
rect.fBottom = rand.nextRangeF(0, 1000);
|
||||
rect.sort();
|
||||
}
|
||||
return rect;
|
||||
@ -41,12 +41,16 @@ static void random_data_rects(SkRandom& rand, DataRect out[], int n) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool verify_query(SkIRect query, DataRect rects[],
|
||||
static bool verify_query(SkRect query, DataRect rects[],
|
||||
SkTDArray<void*>& found) {
|
||||
// TODO(mtklein): no need to do this after everything's SkRects
|
||||
query.roundOut();
|
||||
|
||||
SkTDArray<void*> expected;
|
||||
|
||||
// manually intersect with every rectangle
|
||||
for (int i = 0; i < NUM_RECTS; ++i) {
|
||||
if (SkIRect::IntersectsNoEmptyCheck(query, rects[i].rect)) {
|
||||
if (SkRect::Intersects(query, rects[i].rect)) {
|
||||
expected.push(rects[i].data);
|
||||
}
|
||||
}
|
||||
@ -71,7 +75,7 @@ static void run_queries(skiatest::Reporter* reporter, SkRandom& rand, DataRect r
|
||||
SkRTree& tree) {
|
||||
for (size_t i = 0; i < NUM_QUERIES; ++i) {
|
||||
SkTDArray<void*> hits;
|
||||
SkIRect query = random_rect(rand);
|
||||
SkRect query = random_rect(rand);
|
||||
tree.search(query, &hits);
|
||||
REPORTER_ASSERT(reporter, verify_query(query, rects, hits));
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ DEF_TEST(RecordDraw_SetMatrixClobber, r) {
|
||||
}
|
||||
|
||||
struct TestBBH : public SkBBoxHierarchy {
|
||||
virtual void insert(void* data, const SkIRect& bounds, bool defer) SK_OVERRIDE {
|
||||
virtual void insert(void* data, const SkRect& bounds, bool defer) SK_OVERRIDE {
|
||||
Entry e = { (uintptr_t)data, bounds };
|
||||
entries.push(e);
|
||||
}
|
||||
@ -105,14 +105,14 @@ struct TestBBH : public SkBBoxHierarchy {
|
||||
|
||||
virtual void flushDeferredInserts() SK_OVERRIDE {}
|
||||
|
||||
virtual void search(const SkIRect& query, SkTDArray<void*>* results) const SK_OVERRIDE {}
|
||||
virtual void search(const SkRect& query, SkTDArray<void*>* results) const SK_OVERRIDE {}
|
||||
virtual void clear() SK_OVERRIDE {}
|
||||
virtual void rewindInserts() SK_OVERRIDE {}
|
||||
virtual int getDepth() const SK_OVERRIDE { return -1; }
|
||||
|
||||
struct Entry {
|
||||
uintptr_t data;
|
||||
SkIRect bounds;
|
||||
SkRect bounds;
|
||||
};
|
||||
SkTDArray<Entry> entries;
|
||||
};
|
||||
@ -137,6 +137,6 @@ DEF_TEST(RecordDraw_BBH, r) {
|
||||
for (int i = 0; i < bbh.entries.count(); i++) {
|
||||
REPORTER_ASSERT(r, bbh.entries[i].data == (uintptr_t)i);
|
||||
|
||||
REPORTER_ASSERT(r, bbh.entries[i].bounds == SkIRect::MakeWH(400, 480));
|
||||
REPORTER_ASSERT(r, bbh.entries[i].bounds == SkRect::MakeWH(400, 480));
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
SkTDArray<SkRect> fRects;
|
||||
};
|
||||
|
||||
static void verifyTileHits(skiatest::Reporter* reporter, SkIRect rect,
|
||||
static void verifyTileHits(skiatest::Reporter* reporter, SkRect rect,
|
||||
uint32_t tileMask, int borderPixels = 0) {
|
||||
SkTileGridFactory::TileGridInfo info;
|
||||
info.fMargin.set(borderPixels, borderPixels);
|
||||
@ -223,29 +223,29 @@ DEF_TEST(TileGrid_OverlapOffsetQueryAlignment, reporter) {
|
||||
|
||||
DEF_TEST(TileGrid, reporter) {
|
||||
// Out of bounds
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(30, 0, 1, 1), 0);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(0, 30, 1, 1), 0);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(-10, 0, 1, 1), 0);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(0, -10, 1, 1), 0);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(30, 0, 1, 1), 0);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(0, 30, 1, 1), 0);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(-10, 0, 1, 1), 0);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(0, -10, 1, 1), 0);
|
||||
|
||||
// Dilation for AA consideration
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 9, 9), kTopLeft_Tile);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 10, 10), kAll_Tile);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(9, 9, 1, 1), kAll_Tile);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(10, 10, 1, 1), kAll_Tile);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(11, 11, 1, 1), kBottomRight_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 9, 9), kTopLeft_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 10, 10), kAll_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(9, 9, 1, 1), kAll_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(10, 10, 1, 1), kAll_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(11, 11, 1, 1), kBottomRight_Tile);
|
||||
|
||||
// BorderPixels
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 6, 6), kTopLeft_Tile, 1);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(0, 0, 7, 7), kAll_Tile, 1);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(9, 9, 1, 1), kAll_Tile, 1);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(10, 10, 1, 1), kBottomRight_Tile, 1);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(17, 17, 1, 1), kBottomRight_Tile, 1);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 6, 6), kTopLeft_Tile, 1);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(0, 0, 7, 7), kAll_Tile, 1);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(9, 9, 1, 1), kAll_Tile, 1);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(10, 10, 1, 1), kBottomRight_Tile, 1);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(17, 17, 1, 1), kBottomRight_Tile, 1);
|
||||
|
||||
// BBoxes that overlap tiles
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(5, 5, 10, 1), kTopLeft_Tile | kTopRight_Tile);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(5, 5, 1, 10), kTopLeft_Tile |
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(5, 5, 10, 1), kTopLeft_Tile | kTopRight_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(5, 5, 1, 10), kTopLeft_Tile |
|
||||
kBottomLeft_Tile);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(5, 5, 10, 10), kAll_Tile);
|
||||
verifyTileHits(reporter, SkIRect::MakeXYWH(-10, -10, 40, 40), kAll_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(5, 5, 10, 10), kAll_Tile);
|
||||
verifyTileHits(reporter, SkRect::MakeXYWH(-10, -10, 40, 40), kAll_Tile);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user