diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkCanvas.cpp | 31 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 33 | ||||
-rw-r--r-- | src/core/SkMatrix.cpp | 29 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 8 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 20 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 38 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 2 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 11 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 13 | ||||
-rw-r--r-- | src/core/SkRecorder.h | 2 | ||||
-rw-r--r-- | src/core/SkRecords.h | 21 |
11 files changed, 206 insertions, 2 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index fcfb641407..d7c62e8e11 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -1801,6 +1801,18 @@ void SkCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const SkPai this->onDrawSprite(bitmap, left, top, paint); } +void SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], + const SkColor colors[], int count, SkXfermode::Mode mode, + const SkRect* cull, const SkPaint* paint) { + if (count <= 0) { + return; + } + SkASSERT(atlas); + SkASSERT(xform); + SkASSERT(tex); + this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); +} + ////////////////////////////////////////////////////////////////////////////// // These are the virtual drawing methods ////////////////////////////////////////////////////////////////////////////// @@ -2449,6 +2461,25 @@ void SkCanvas::onDrawDrawable(SkDrawable* dr) { dr->draw(this); } +void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], + const SkColor colors[], int count, SkXfermode::Mode mode, + const SkRect* cull, const SkPaint* paint) { + if (cull && this->quickReject(*cull)) { + return; + } + + SkPaint pnt; + if (paint) { + pnt = *paint; + } + + LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, NULL) + while (iter.next()) { + iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); + } + LOOPER_END +} + ////////////////////////////////////////////////////////////////////////////// // These methods are NOT virtual, and therefore must call back into virtual // methods, rather than actually drawing themselves. diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 15cd7eef3b..8f7f50c863 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "SkColorFilter.h" #include "SkDevice.h" #include "SkDraw.h" #include "SkDrawFilter.h" @@ -13,6 +14,7 @@ #include "SkPatchUtils.h" #include "SkPathMeasure.h" #include "SkRasterClip.h" +#include "SkRSXform.h" #include "SkShader.h" #include "SkTextBlob.h" #include "SkTextToPathIter.h" @@ -159,6 +161,37 @@ void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const } } +void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[], + const SkRect tex[], const SkColor colors[], int count, + SkXfermode::Mode mode, const SkPaint& paint) { + SkPath path; + path.setIsVolatile(true); + + for (int i = 0; i < count; ++i) { + SkPoint quad[4]; + xform[i].toQuad(tex[i].width(), tex[i].height(), quad); + + SkMatrix localM; + localM.setRSXform(xform[i]); + localM.preTranslate(-tex[i].left(), -tex[i].top()); + + SkPaint pnt(paint); + pnt.setShader(atlas->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, + &localM))->unref(); + if (colors && colors[i] != SK_ColorWHITE) { + SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(colors[i], mode)); + pnt.setColorFilter(cf); + } + + path.rewind(); + path.addPoly(quad, 4, true); + path.setConvexity(SkPath::kConvex_Convexity); + this->drawPath(draw, path, pnt, NULL, true); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) { #ifdef SK_DEBUG SkASSERT(info.width() > 0 && info.height() > 0); diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index b47770a23b..49cffa45f5 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -7,6 +7,7 @@ #include "SkMatrix.h" #include "SkFloatBits.h" +#include "SkRSXform.h" #include "SkString.h" #include "SkNx.h" @@ -440,6 +441,22 @@ void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, SkScalar px, SkScalar py) this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); } +SkMatrix& SkMatrix::setRSXform(const SkRSXform& xform) { + fMat[kMScaleX] = xform.fSCos; + fMat[kMSkewX] = -xform.fSSin; + fMat[kMTransX] = xform.fTx; + + fMat[kMSkewY] = xform.fSSin; + fMat[kMScaleY] = xform.fSCos; + fMat[kMTransY] = xform.fTy; + + fMat[kMPersp0] = fMat[kMPersp1] = 0; + fMat[kMPersp2] = 1; + + this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); + return *this; +} + void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) { fMat[kMScaleX] = cosV; fMat[kMSkewX] = -sinV; @@ -1823,3 +1840,15 @@ bool SkDecomposeUpper2x2(const SkMatrix& matrix, return true; } + +////////////////////////////////////////////////////////////////////////////////////////////////// + +void SkRSXform::toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const { + quad[0].set(0, 0); + quad[1].set(width, 0); + quad[2].set(width, height); + quad[3].set(0, height); + SkMatrix m; + m.setRSXform(*this).mapPoints(quad, quad, 4); +} + diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index 8720e19751..07411002ae 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -71,8 +71,9 @@ enum DrawType { DRAW_TEXT_BLOB, DRAW_IMAGE, DRAW_IMAGE_RECT, + DRAW_ATLAS, - LAST_DRAWTYPE_ENUM = DRAW_IMAGE_RECT + LAST_DRAWTYPE_ENUM = DRAW_ATLAS }; // In the 'match' method, this constant will match any flavor of DRAW_BITMAP* @@ -85,6 +86,11 @@ enum DrawVertexFlags { DRAW_VERTICES_HAS_XFER = 0x08, }; +enum DrawAtlasFlags { + DRAW_ATLAS_HAS_COLORS = 1 << 0, + DRAW_ATLAS_HAS_CULL = 1 << 1, +}; + /////////////////////////////////////////////////////////////////////////////// // clipparams are packed in 5 bits // doAA:1 | regionOp:4 diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index ac71c27d22..a1bb1ba293 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -11,6 +11,7 @@ #include "SkPicturePlayback.h" #include "SkPictureRecord.h" #include "SkReader32.h" +#include "SkRSXform.h" #include "SkTextBlob.h" #include "SkTDArray.h" #include "SkTypes.h" @@ -156,6 +157,25 @@ void SkPicturePlayback::handleOp(SkReader32* reader, canvas->concat(matrix); break; } + case DRAW_ATLAS: { + const SkPaint* paint = fPictureData->getPaint(reader); + const SkImage* atlas = fPictureData->getImage(reader); + const uint32_t flags = reader->readU32(); + const int count = reader->readU32(); + const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform)); + const SkRect* tex = (const SkRect*)reader->skip(count * sizeof(SkRect)); + const SkColor* colors = NULL; + SkXfermode::Mode mode = SkXfermode::kDst_Mode; + if (flags & DRAW_ATLAS_HAS_COLORS) { + colors = (const SkColor*)reader->skip(count * sizeof(SkColor)); + mode = (SkXfermode::Mode)reader->readU32(); + } + const SkRect* cull = NULL; + if (flags & DRAW_ATLAS_HAS_CULL) { + cull = (const SkRect*)reader->skip(sizeof(SkRect)); + } + canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); + } break; case DRAW_BITMAP: { const SkPaint* paint = fPictureData->getPaint(reader); const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 32033b52db..0fbf98089a 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -11,6 +11,7 @@ #include "SkPatchUtils.h" #include "SkPixelRef.h" #include "SkRRect.h" +#include "SkRSXform.h" #include "SkTextBlob.h" #include "SkTSearch.h" @@ -99,6 +100,7 @@ static inline size_t get_paint_offset(DrawType op, size_t opSize) { 1, // DRAW_TEXT_BLOB- right after op code 1, // DRAW_IMAGE - right after op code 1, // DRAW_IMAGE_RECT - right after op code + 1, // DRAW_ATLAS - right after op code }; SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1, @@ -834,6 +836,42 @@ void SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors this->validate(initialOffset, size); } +void SkPictureRecord::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], + const SkColor colors[], int count, SkXfermode::Mode mode, + const SkRect* cull, const SkPaint* paint) { + // [op + paint-index + atlas-index + flags + count] + [xform] + [tex] + [*colors + mode] + cull + size_t size = 5 * kUInt32Size + count * sizeof(SkRSXform) + count * sizeof(SkRect); + uint32_t flags = 0; + if (colors) { + flags |= DRAW_ATLAS_HAS_COLORS; + size += count * sizeof(SkColor); + size += sizeof(uint32_t); // xfermode::mode + } + if (cull) { + flags |= DRAW_ATLAS_HAS_CULL; + size += sizeof(SkRect); + } + + size_t initialOffset = this->addDraw(DRAW_ATLAS, &size); + SkASSERT(initialOffset+get_paint_offset(DRAW_ATLAS, size) == fWriter.bytesWritten()); + this->addPaintPtr(paint); + this->addImage(atlas); + this->addInt(flags); + this->addInt(count); + fWriter.write(xform, count * sizeof(SkRSXform)); + fWriter.write(tex, count * sizeof(SkRect)); + + // write optional parameters + if (colors) { + fWriter.write(colors, count * sizeof(SkColor)); + this->addInt(mode); + } + if (cull) { + fWriter.write(cull, sizeof(SkRect)); + } + this->validate(initialOffset, size); +} + /////////////////////////////////////////////////////////////////////////////// SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) { diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index 0b6ef8b931..cee5ea35f5 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -173,6 +173,8 @@ protected: virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) override; + void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int, + SkXfermode::Mode, const SkRect*, const SkPaint*) override; void onDrawPaint(const SkPaint&) override; void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 7db7680e28..944443c8ee 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -111,6 +111,7 @@ DRAW(DrawSprite, drawSprite(r.bitmap.shallowCopy(), r.left, r.top, r.paint)); DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint)); DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint)); DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, &r.matrix, r.paint)); +DRAW(DrawAtlas, drawAtlas(r.atlas, r.xforms, r.texs, r.colors, r.count, r.mode, r.cull, r.paint)); DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors, r.xmode.get(), r.indices, r.indexCount, r.paint)); #undef DRAW @@ -451,7 +452,15 @@ private: dst.set(op.vertices, op.vertexCount); return this->adjustAndMap(dst, &op.paint); } - + + Bounds bounds(const DrawAtlas& op) const { + if (op.cull) { + return this->adjustAndMap(*op.cull, op.paint); + } else { + return fCurrentClipBounds; + } + } + Bounds bounds(const DrawPicture& op) const { SkRect dst = op.picture->cullRect(); op.matrix.mapRect(&dst); diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 4562a87f67..812fd9d49c 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -299,6 +299,19 @@ void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], xmode); } +void SkRecorder::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], + const SkColor colors[], int count, SkXfermode::Mode mode, + const SkRect* cull, const SkPaint* paint) { + APPEND(DrawAtlas, this->copy(paint), + atlas, + this->copy(xform, count), + this->copy(tex, count), + this->copy(colors, count), + count, + mode, + this->copy(cull)); +} + void SkRecorder::willSave() { APPEND(Save); } diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 7fab62d023..53c658fa6f 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -108,6 +108,8 @@ public: const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint&) override; + void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], + int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) override; void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override; void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override; diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index f4de5bdc3b..381f91438b 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -12,6 +12,7 @@ #include "SkDrawable.h" #include "SkPathPriv.h" #include "SkPicture.h" +#include "SkRSXform.h" #include "SkTextBlob.h" namespace SkRecords { @@ -58,6 +59,7 @@ namespace SkRecords { M(DrawRect) \ M(DrawSprite) \ M(DrawTextBlob) \ + M(DrawAtlas) \ M(DrawVertices) // Defines SkRecords::Type, an enum of all record types. @@ -121,6 +123,15 @@ struct T { \ A a; B b; C c; D d; E e; \ }; +#define RECORD8(T, A, a, B, b, C, c, D, d, E, e, F, f, G, g, H, h) \ +struct T { \ + static const Type kType = T##_Type; \ + T() {} \ + template <typename Z, typename Y, typename X, typename W, typename V, typename U, typename S, typename R> \ + T(Z a, Y b, X c, W d, V e, U f, S g, R h) : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {} \ + A a; B b; C c; D d; E e; F f; G g; H h; \ +}; + #define ACT_AS_PTR(ptr) \ operator T*() const { return ptr; } \ T* operator->() const { return ptr; } @@ -317,6 +328,15 @@ RECORD5(DrawPatch, SkPaint, paint, PODArray<SkPoint>, texCoords, RefBox<SkXfermode>, xmode); +RECORD8(DrawAtlas, Optional<SkPaint>, paint, + RefBox<const SkImage>, atlas, + PODArray<SkRSXform>, xforms, + PODArray<SkRect>, texs, + PODArray<SkColor>, colors, + int, count, + SkXfermode::Mode, mode, + Optional<SkRect>, cull); + // This guy is so ugly we just write it manually. struct DrawVertices { static const Type kType = DrawVertices_Type; @@ -357,6 +377,7 @@ struct DrawVertices { #undef RECORD3 #undef RECORD4 #undef RECORD5 +#undef RECORD8 } // namespace SkRecords |