From ca10953d9ca38a5486c11cc50ac3fd27d4281e12 Mon Sep 17 00:00:00 2001 From: reed Date: Thu, 25 Jun 2015 16:25:25 -0700 Subject: [PATCH] implement drawAtlas natively on gpu-device BUG=skia: Review URL: https://codereview.chromium.org/1216433002 --- samplecode/SampleAtlas.cpp | 10 +++++---- src/core/SkMatrix.cpp | 15 +++++++++++++ src/gpu/SkGpuDevice.cpp | 44 ++++++++++++++++++++++++++++++++++++++ src/gpu/SkGpuDevice.h | 2 ++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/samplecode/SampleAtlas.cpp b/samplecode/SampleAtlas.cpp index adf3f5e3a4..ed208c3a77 100644 --- a/samplecode/SampleAtlas.cpp +++ b/samplecode/SampleAtlas.cpp @@ -68,11 +68,13 @@ class DrawAtlasDrawable : public SkDrawable { fVelocity.fX = -fVelocity.fX; } if (fCenter.fY > bounds.bottom()) { - SkASSERT(fVelocity.fY > 0); - fVelocity.fY = -fVelocity.fY; + if (fVelocity.fY > 0) { + fVelocity.fY = -fVelocity.fY; + } } else if (fCenter.fY < bounds.top()) { - SkASSERT(fVelocity.fY < 0); - fVelocity.fY = -fVelocity.fY; + if (fVelocity.fY < 0) { + fVelocity.fY = -fVelocity.fY; + } } fScale += fDScale; diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 49cffa45f5..4f94013d3c 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1844,11 +1844,26 @@ bool SkDecomposeUpper2x2(const SkMatrix& matrix, ////////////////////////////////////////////////////////////////////////////////////////////////// void SkRSXform::toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const { +#if 0 + // This is the slow way, but it documents what we're doing 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); +#else + const SkScalar m00 = fSCos; + const SkScalar m01 = -fSSin; + const SkScalar m02 = fTx; + const SkScalar m10 = -m01; + const SkScalar m11 = m00; + const SkScalar m12 = fTy; + + quad[0].set(m02, m12); + quad[1].set(m00 * width + m02, m10 * width + m12); + quad[2].set(m00 * width + m01 * height + m02, m10 * width + m11 * height + m12); + quad[3].set(m01 * height + m02, m11 * height + m12); +#endif } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index d0f8d46ee8..17d837be42 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1639,6 +1639,50 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, /////////////////////////////////////////////////////////////////////////////// +static void append_quad_indices(uint16_t indices[], int quadIndex) { + int i = quadIndex * 4; + indices[0] = i + 0; indices[1] = i + 1; indices[2] = i + 2; + indices[3] = i + 2; indices[4] = i + 3; indices[5] = i + 0; +} + +void SkGpuDevice::drawAtlas(const SkDraw& d, const SkImage* atlas, const SkRSXform xform[], + const SkRect texRect[], const SkColor colors[], int count, + SkXfermode::Mode mode, const SkPaint& paint) { + if (paint.isAntiAlias()) { + this->INHERITED::drawAtlas(d, atlas, xform, texRect, colors, count, mode, paint); + return; + } + + SkPaint p(paint); + p.setShader(atlas->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); + + const int vertCount = count * 4; + const int indexCount = count * 6; + SkAutoTMalloc vertStorage(vertCount * 2); + SkPoint* verts = vertStorage.get(); + SkPoint* texs = verts + vertCount; + SkAutoTMalloc indexStorage(indexCount); + uint16_t* indices = indexStorage.get(); + SkAutoTUnref xfer(SkXfermode::Create(mode)); + + for (int i = 0; i < count; ++i) { + xform[i].toQuad(texRect[i].width(), texRect[i].height(), verts); + texRect[i].toQuad(texs); + append_quad_indices(indices, i); + verts += 4; + texs += 4; + indices += 6; + } + + verts = vertStorage.get(); + texs = verts + vertCount; + indices = indexStorage.get(); + this->drawVertices(d, SkCanvas::kTriangles_VertexMode, vertCount, verts, texs, colors, xfer, + indices, indexCount, p); +} + +/////////////////////////////////////////////////////////////////////////////// + void SkGpuDevice::drawText(const SkDraw& draw, const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) { diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index 9fa756c29a..86507657cd 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -111,6 +111,8 @@ public: const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint&) override; + void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[], + const SkColor[], int count, SkXfermode::Mode, const SkPaint&) override; virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override; void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;