diff --git a/bench/VertBench.cpp b/bench/VertBench.cpp index 1834408680..3646c385f4 100644 --- a/bench/VertBench.cpp +++ b/bench/VertBench.cpp @@ -139,7 +139,7 @@ protected: for (int i = 0; i < N; ++i) { fRects[i] = SkRect::MakeXYWH(rand.nextF() * (imageW - 8), rand.nextF() * (imageH - 8), 8, 8); - fColors[i] = rand.nextU(); + fColors[i] = rand.nextU() | 0xFF000000; fXforms[i] = SkRSXform::Make(1, 0, rand.nextF() * W, rand.nextF() * H); } } @@ -155,7 +155,7 @@ protected: atlas = fAtlas.get(); } for (int i = 0; i < loops; i++) { - canvas->drawAtlas(atlas, fXforms, fRects, colors, N, SkBlendMode::kSrcOver, + canvas->drawAtlas(atlas, fXforms, fRects, colors, N, SkBlendMode::kModulate, cullRect, paintPtr); } } diff --git a/gn/core.gni b/gn/core.gni index feb19c5c4d..b05cbf364d 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -177,6 +177,7 @@ skia_core_sources = [ "$_src/core/SkDistanceFieldGen.h", "$_src/core/SkDocument.cpp", "$_src/core/SkDraw.cpp", + "$_src/core/SkDraw_atlas.cpp", "$_src/core/SkDraw_text.cpp", "$_src/core/SkDraw_vertices.cpp", "$_src/core/SkDraw.h", diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index bf0d4e5aa7..d5c0ff00de 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -575,6 +575,17 @@ void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPain } } +void SkBitmapDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[], + const SkRect tex[], const SkColor colors[], int count, + SkBlendMode mode, const SkPaint& paint) { + // set this to true for performance comparisons with the old drawVertices way + if (false) { + this->INHERITED::drawAtlas(atlas, xform, tex, colors, count, mode, paint); + return; + } + BDDraw(this).drawAtlas(atlas, xform, tex, colors, count, mode, paint); +} + /////////////////////////////////////////////////////////////////////////////// namespace { diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h index b8d8b7e583..2f961ab8e0 100644 --- a/src/core/SkBitmapDevice.h +++ b/src/core/SkBitmapDevice.h @@ -101,6 +101,8 @@ protected: void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override; void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode, const SkPaint& paint) override; + void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int count, + SkBlendMode, const SkPaint&) override; void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override; /////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h index 8865102faf..b42249437f 100644 --- a/src/core/SkDraw.h +++ b/src/core/SkDraw.h @@ -68,6 +68,8 @@ public: const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode, const uint16_t indices[], int ptCount, const SkPaint& paint, const SkVertices::Bone bones[], int boneCount) const; + void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int count, + SkBlendMode, const SkPaint&); /** * Overwrite the target with the path's coverage (i.e. its mask). diff --git a/src/core/SkDraw_atlas.cpp b/src/core/SkDraw_atlas.cpp new file mode 100644 index 0000000000..717adaea41 --- /dev/null +++ b/src/core/SkDraw_atlas.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkColorFilter.h" +#include "include/core/SkRSXform.h" +#include "src/core/SkDraw.h" +#include "src/core/SkScan.h" +#include "src/shaders/SkShaderBase.h" + +void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect textures[], + const SkColor colors[], int count, SkBlendMode bmode, const SkPaint& paint) { + SkDraw draw(*this); + SkPaint p(paint); + + p.setAntiAlias(false); // we never respect this for drawAtlas(or drawVertices) + p.setStyle(SkPaint::kFill_Style); + p.setShader(nullptr); + p.setMaskFilter(nullptr); + + sk_sp atlasShader; + if (atlas) { + atlasShader = atlas->makeShader(); + } + + SkMatrix xf; + for (int i = 0; i < count; ++i) { + if (colors) { + if (atlasShader) { + p.setShader(SkShaders::Blend(bmode, + SkShaders::Color(colors[i]), + atlasShader)); + p.setColor4f(paint.getColor4f(), nullptr); + } else { + p.setColor(colors[i]); // modulate with paint.getAlpha()? + } + } else { + p.setShader(atlasShader); + } + xf.setRSXform(xform[i]); + xf.preTranslate(-textures[i].fLeft, -textures[i].fTop); + xf.postConcat(*fMatrix); + draw.fMatrix = &xf; + draw.drawRect(textures[i], p); + } +}