diff --git a/bench/RTreeBench.cpp b/bench/RTreeBench.cpp index 95f55c9a8f..5442f7e261 100644 --- a/bench/RTreeBench.cpp +++ b/bench/RTreeBench.cpp @@ -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 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; } diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index 1eff2c6e65..936291a58a 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -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); diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h index 75e7eb545c..aebdf8ffe3 100644 --- a/include/gpu/SkGpuDevice.h +++ b/include/gpu/SkGpuDevice.h @@ -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& atlased, diff --git a/src/core/SkBBoxHierarchy.h b/src/core/SkBBoxHierarchy.h index b42f708bc7..fd9680c6aa 100644 --- a/src/core/SkBBoxHierarchy.h +++ b/src/core/SkBBoxHierarchy.h @@ -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* results) const = 0; + virtual void search(const SkRect& query, SkTDArray* results) const = 0; virtual void clear() = 0; diff --git a/src/core/SkBBoxHierarchyRecord.cpp b/src/core/SkBBoxHierarchyRecord.cpp index 8cdd1d9618..f4e79fa828 100644 --- a/src/core/SkBBoxHierarchyRecord.cpp +++ b/src/core/SkBBoxHierarchyRecord.cpp @@ -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() { diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index 6239763c3d..e958f9648c 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -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); diff --git a/src/core/SkPictureData.cpp b/src/core/SkPictureData.cpp index 86a338899e..e5a004ef3a 100644 --- a/src/core/SkPictureData.cpp +++ b/src/core/SkPictureData.cpp @@ -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; } diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h index 14c51860dd..a5f1ae0b24 100644 --- a/src/core/SkPictureData.h +++ b/src/core/SkPictureData.h @@ -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; diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index a64bf0ff5e..78b65d6d7b 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -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(); diff --git a/src/core/SkRTree.cpp b/src/core/SkRTree.cpp index 3985fb1285..77f94e2eed 100644 --- a/src/core/SkRTree.cpp +++ b/src/core/SkRTree.cpp @@ -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* results) const { +void SkRTree::search(const SkRect& fquery, SkTDArray* 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)) { diff --git a/src/core/SkRTree.h b/src/core/SkRTree.h index 6487b324ef..8e980246ac 100644 --- a/src/core/SkRTree.h +++ b/src/core/SkRTree.h @@ -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* results) const SK_OVERRIDE; + virtual void search(const SkRect& query, SkTDArray* results) const SK_OVERRIDE; virtual void clear() SK_OVERRIDE; bool isEmpty() const { return 0 == fCount; } diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index a52baed0a2..7985e2ba05 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -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 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 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 fBounds; + // Conservative identity-space bounds for each op in the SkRecord. + SkAutoTMalloc 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 fSaveStack; diff --git a/src/core/SkTileGrid.cpp b/src/core/SkTileGrid.cpp index 17102f50e2..84dc949b36 100644 --- a/src/core/SkTileGrid.cpp +++ b/src/core/SkTileGrid.cpp @@ -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* results) const { - SkIRect adjusted = query; +void SkTileGrid::search(const SkRect& query, SkTDArray* 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 diff --git a/src/core/SkTileGrid.h b/src/core/SkTileGrid.h index 41463310b6..1e34a61d52 100644 --- a/src/core/SkTileGrid.h +++ b/src/core/SkTileGrid.h @@ -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* results) const SK_OVERRIDE; + virtual void search(const SkRect& query, SkTDArray* results) const SK_OVERRIDE; virtual void clear() SK_OVERRIDE; diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 693e16c0e3..61ae5ce829 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -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 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 ops(picture->EXPERIMENTAL_getActiveOps(query)); + SkAutoTDelete 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& atlased, + const SkTDArray& atlased, const SkTDArray& 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()); diff --git a/tests/BBoxHierarchyTest.cpp b/tests/BBoxHierarchyTest.cpp index 305543b7eb..b9cbbc4f9a 100644 --- a/tests/BBoxHierarchyTest.cpp +++ b/tests/BBoxHierarchyTest.cpp @@ -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& found) { + // TODO(mtklein): no need to do this after everything's SkRects + query.roundOut(); + SkTDArray 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 hits; - SkIRect query = random_rect(rand); + SkRect query = random_rect(rand); tree.search(query, &hits); REPORTER_ASSERT(reporter, verify_query(query, rects, hits)); } diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp index 98ebf6a01e..3535e8e3bf 100644 --- a/tests/PictureTest.cpp +++ b/tests/PictureTest.cpp @@ -1808,12 +1808,12 @@ struct CountingBBH : public SkBBoxHierarchy { CountingBBH() : searchCalls(0) {} - virtual void search(const SkIRect& query, SkTDArray* results) const { + virtual void search(const SkRect& query, SkTDArray* 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; } diff --git a/tests/RTreeTest.cpp b/tests/RTreeTest.cpp index ae8c005170..087f19a7ef 100644 --- a/tests/RTreeTest.cpp +++ b/tests/RTreeTest.cpp @@ -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& found) { + // TODO(mtklein): no need to do this after everything's SkRects + query.roundOut(); + SkTDArray 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 hits; - SkIRect query = random_rect(rand); + SkRect query = random_rect(rand); tree.search(query, &hits); REPORTER_ASSERT(reporter, verify_query(query, rects, hits)); } diff --git a/tests/RecordDrawTest.cpp b/tests/RecordDrawTest.cpp index 91ed2f06a9..b9ab2dce25 100644 --- a/tests/RecordDrawTest.cpp +++ b/tests/RecordDrawTest.cpp @@ -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* results) const SK_OVERRIDE {} + virtual void search(const SkRect& query, SkTDArray* 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 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)); } } diff --git a/tests/TileGridTest.cpp b/tests/TileGridTest.cpp index f6a9f876eb..81f383d97e 100644 --- a/tests/TileGridTest.cpp +++ b/tests/TileGridTest.cpp @@ -31,7 +31,7 @@ public: SkTDArray 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); }