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