specialize drawAtlas for raster backend
2x faster than calling drawVertices as the impl. Lots more to do in future CLs - much of the time is spent in malloc, as we cons-up private shaders. we *could* create a private shader and wack its data for each draw (breaking the immutable contract, but that may be ok for a raster-only internal-use shader...) - also spend time building the pipeline for each draw, even though all that has changed is a color payload (and the ctm). A custome stage(s) that exposed its private data could be reused with new data... Bug: skia: Change-Id: I0ff15155e37c0af7931abd34c0883701a47a048a Reviewed-on: https://skia-review.googlesource.com/c/skia/+/203168 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
ea6bb447a2
commit
560e9178bd
@ -139,7 +139,7 @@ protected:
|
|||||||
for (int i = 0; i < N; ++i) {
|
for (int i = 0; i < N; ++i) {
|
||||||
fRects[i] = SkRect::MakeXYWH(rand.nextF() * (imageW - 8),
|
fRects[i] = SkRect::MakeXYWH(rand.nextF() * (imageW - 8),
|
||||||
rand.nextF() * (imageH - 8), 8, 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);
|
fXforms[i] = SkRSXform::Make(1, 0, rand.nextF() * W, rand.nextF() * H);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ protected:
|
|||||||
atlas = fAtlas.get();
|
atlas = fAtlas.get();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < loops; i++) {
|
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);
|
cullRect, paintPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,6 +177,7 @@ skia_core_sources = [
|
|||||||
"$_src/core/SkDistanceFieldGen.h",
|
"$_src/core/SkDistanceFieldGen.h",
|
||||||
"$_src/core/SkDocument.cpp",
|
"$_src/core/SkDocument.cpp",
|
||||||
"$_src/core/SkDraw.cpp",
|
"$_src/core/SkDraw.cpp",
|
||||||
|
"$_src/core/SkDraw_atlas.cpp",
|
||||||
"$_src/core/SkDraw_text.cpp",
|
"$_src/core/SkDraw_text.cpp",
|
||||||
"$_src/core/SkDraw_vertices.cpp",
|
"$_src/core/SkDraw_vertices.cpp",
|
||||||
"$_src/core/SkDraw.h",
|
"$_src/core/SkDraw.h",
|
||||||
|
@ -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 {
|
namespace {
|
||||||
|
@ -101,6 +101,8 @@ protected:
|
|||||||
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
|
void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
|
||||||
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
|
||||||
const SkPaint& paint) override;
|
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;
|
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -68,6 +68,8 @@ public:
|
|||||||
const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode,
|
const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode,
|
||||||
const uint16_t indices[], int ptCount,
|
const uint16_t indices[], int ptCount,
|
||||||
const SkPaint& paint, const SkVertices::Bone bones[], int boneCount) const;
|
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).
|
* Overwrite the target with the path's coverage (i.e. its mask).
|
||||||
|
49
src/core/SkDraw_atlas.cpp
Normal file
49
src/core/SkDraw_atlas.cpp
Normal file
@ -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<SkShader> 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user