Small cleanups to drawVertices
Change-Id: I16301e6fb7193ba67b9fea292f931fda480c8ac3 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/420956 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
1a3f4ab490
commit
d1d0a9f1f3
@ -126,8 +126,13 @@ public:
|
||||
|
||||
private:
|
||||
void drawBitmapAsMask(const SkBitmap&, const SkSamplingOptions&, const SkPaint&) const;
|
||||
void draw_fixed_vertices(const SkVertices*, SkBlendMode, const SkPaint&, const SkMatrix&,
|
||||
const SkPoint dev2[], const SkPoint3 dev3[], SkArenaAlloc*) const;
|
||||
void drawFixedVertices(const SkVertices* vertices,
|
||||
SkBlendMode blendMode,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix& ctmInverse,
|
||||
const SkPoint* dev2,
|
||||
const SkPoint3* dev3,
|
||||
SkArenaAlloc* outerAlloc) const;
|
||||
|
||||
void drawPath(const SkPath&,
|
||||
const SkPaint&,
|
||||
|
@ -22,62 +22,6 @@
|
||||
#include "src/shaders/SkComposeShader.h"
|
||||
#include "src/shaders/SkShaderBase.h"
|
||||
|
||||
// Compute the crossing point (across zero) for the two values, expressed as a
|
||||
// normalized 0...1 value. If curr is 0, returns 0. If next is 0, returns 1.
|
||||
//
|
||||
static float compute_t(float curr, float next) {
|
||||
SkASSERT((curr > 0 && next <= 0) || (curr <= 0 && next > 0));
|
||||
float t = curr / (curr - next);
|
||||
SkASSERT(t >= 0 && t <= 1);
|
||||
return t;
|
||||
}
|
||||
|
||||
static SkPoint3 lerp(SkPoint3 curr, SkPoint3 next, float t) {
|
||||
return curr + t * (next - curr);
|
||||
}
|
||||
|
||||
// tol is the nudge away from zero, to keep the numerics nice.
|
||||
// Think of it as our near-clipping-plane (or w-plane).
|
||||
static SkPoint3 clip(SkPoint3 curr, SkPoint3 next, float tol) {
|
||||
// Return the point between curr and next where the fZ value corses tol.
|
||||
// To be (really) perspective correct, we should be computing baesd on 1/Z, not Z.
|
||||
// For now, this is close enough (and faster).
|
||||
return lerp(curr, next, compute_t(curr.fZ - tol, next.fZ - tol));
|
||||
}
|
||||
|
||||
constexpr int kMaxClippedTrianglePointCount = 4;
|
||||
// Clip a triangle (based on its homogeneous W values), and return the projected polygon.
|
||||
// Since we only clip against one "edge"/plane, the max number of points in the clipped
|
||||
// polygon is 4.
|
||||
static int clip_triangle(SkPoint dst[], const int idx[3], const SkPoint3 pts[]) {
|
||||
SkPoint3 outPoints[4];
|
||||
SkPoint3* outP = outPoints;
|
||||
const float tol = 0.05f;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
int curr = idx[i];
|
||||
int next = idx[(i + 1) % 3];
|
||||
if (pts[curr].fZ > tol) {
|
||||
*outP++ = pts[curr];
|
||||
if (pts[next].fZ <= tol) { // curr is IN, next is OUT
|
||||
*outP++ = clip(pts[curr], pts[next], tol);
|
||||
}
|
||||
} else {
|
||||
if (pts[next].fZ > tol) { // curr is OUT, next is IN
|
||||
*outP++ = clip(pts[curr], pts[next], tol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int count = outP - outPoints;
|
||||
SkASSERT(count == 0 || count == 3 || count == 4);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
float scale = 1.0f / outPoints[i].fZ;
|
||||
dst[i].set(outPoints[i].fX * scale, outPoints[i].fY * scale);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
struct Matrix43 {
|
||||
float fMat[12]; // column major
|
||||
|
||||
@ -239,11 +183,67 @@ static void fill_triangle_2(const VertState& state, SkBlitter* blitter, const Sk
|
||||
SkScan::FillTriangle(tmp, rc, blitter);
|
||||
}
|
||||
|
||||
static constexpr int kMaxClippedTrianglePointCount = 4;
|
||||
static void fill_triangle_3(const VertState& state, SkBlitter* blitter, const SkRasterClip& rc,
|
||||
const SkPoint3 dev3[]) {
|
||||
// Compute the crossing point (across zero) for the two values, expressed as a
|
||||
// normalized 0...1 value. If curr is 0, returns 0. If next is 0, returns 1.
|
||||
auto computeT = [](float curr, float next) {
|
||||
// Check that 0 is between next and curr.
|
||||
SkASSERT((next <= 0 && 0 < curr) || (curr <= 0 && 0 < next));
|
||||
float t = curr / (curr - next);
|
||||
SkASSERT(0 <= t && t <= 1);
|
||||
return t;
|
||||
};
|
||||
|
||||
auto lerp = [](SkPoint3 curr, SkPoint3 next, float t) {
|
||||
return curr + t * (next - curr);
|
||||
};
|
||||
|
||||
constexpr float tol = 0.05f;
|
||||
// tol is the nudge away from zero, to keep the numerics nice.
|
||||
// Think of it as our near-clipping-plane (or w-plane).
|
||||
auto clip = [&](SkPoint3 curr, SkPoint3 next) {
|
||||
// Return the point between curr and next where the fZ value crosses tol.
|
||||
// To be (really) perspective correct, we should be computing based on 1/Z, not Z.
|
||||
// For now, this is close enough (and faster).
|
||||
return lerp(curr, next, computeT(curr.fZ - tol, next.fZ - tol));
|
||||
};
|
||||
|
||||
// Clip a triangle (based on its homogeneous W values), and return the projected polygon.
|
||||
// Since we only clip against one "edge"/plane, the max number of points in the clipped
|
||||
// polygon is 4.
|
||||
auto clipTriangle = [&](SkPoint dst[], const int idx[3], const SkPoint3 pts[]) -> int {
|
||||
SkPoint3 outPoints[kMaxClippedTrianglePointCount];
|
||||
SkPoint3* outP = outPoints;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
int curr = idx[i];
|
||||
int next = idx[(i + 1) % 3];
|
||||
if (pts[curr].fZ > tol) {
|
||||
*outP++ = pts[curr];
|
||||
if (pts[next].fZ <= tol) { // curr is IN, next is OUT
|
||||
*outP++ = clip(pts[curr], pts[next]);
|
||||
}
|
||||
} else {
|
||||
if (pts[next].fZ > tol) { // curr is OUT, next is IN
|
||||
*outP++ = clip(pts[curr], pts[next]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int count = SkTo<int>(outP - outPoints);
|
||||
SkASSERT(count == 0 || count == 3 || count == 4);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
float scale = 1.0f / outPoints[i].fZ;
|
||||
dst[i].set(outPoints[i].fX * scale, outPoints[i].fY * scale);
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
SkPoint tmp[kMaxClippedTrianglePointCount];
|
||||
int idx[] = { state.f0, state.f1, state.f2 };
|
||||
if (int n = clip_triangle(tmp, idx, dev3)) {
|
||||
if (int n = clipTriangle(tmp, idx, dev3)) {
|
||||
// TODO: SkScan::FillConvexPoly(tmp, n, ...);
|
||||
SkASSERT(n == 3 || n == 4);
|
||||
SkScan::FillTriangle(tmp, rc, blitter);
|
||||
@ -263,10 +263,10 @@ static void fill_triangle(const VertState& state, SkBlitter* blitter, const SkRa
|
||||
}
|
||||
}
|
||||
|
||||
void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
const SkPaint& paint, const SkMatrix& ctmInv,
|
||||
const SkPoint dev2[], const SkPoint3 dev3[],
|
||||
SkArenaAlloc* outerAlloc) const {
|
||||
void SkDraw::drawFixedVertices(const SkVertices* vertices, SkBlendMode blendMode,
|
||||
const SkPaint& paint, const SkMatrix& ctmInverse,
|
||||
const SkPoint* dev2, const SkPoint3* dev3,
|
||||
SkArenaAlloc* outerAlloc) const {
|
||||
SkVerticesPriv info(vertices->priv());
|
||||
|
||||
const int vertexCount = info.vertexCount();
|
||||
@ -289,7 +289,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
// itself insists we don't pass kSrc or kDst to it.
|
||||
//
|
||||
if (colors && textures) {
|
||||
switch (bmode) {
|
||||
switch (blendMode) {
|
||||
case SkBlendMode::kSrc:
|
||||
colors = nullptr;
|
||||
break;
|
||||
@ -327,8 +327,8 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
triShader = outerAlloc->make<SkTriColorShader>(compute_is_opaque(colors, vertexCount),
|
||||
usePerspective);
|
||||
if (shader) {
|
||||
shader = outerAlloc->make<SkShader_Blend>(bmode,
|
||||
sk_ref_sp(triShader), sk_ref_sp(shader));
|
||||
shader = outerAlloc->make<SkShader_Blend>(blendMode,
|
||||
sk_ref_sp(triShader), sk_ref_sp(shader));
|
||||
} else {
|
||||
shader = triShader;
|
||||
}
|
||||
@ -342,7 +342,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
this->fRC->clipShader())) {
|
||||
while (vertProc(&state)) {
|
||||
if (triShader &&
|
||||
!triShader->update(ctmInv, positions, dstColors,
|
||||
!triShader->update(ctmInverse, positions, dstColors,
|
||||
state.f0, state.f1, state.f2)) {
|
||||
continue;
|
||||
}
|
||||
@ -374,7 +374,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, outerAlloc,
|
||||
fRC->clipShader())) {
|
||||
while (vertProc(&state)) {
|
||||
if (triShader && !triShader->update(ctmInv, positions, dstColors,
|
||||
if (triShader && !triShader->update(ctmInverse, positions, dstColors,
|
||||
state.f0, state.f1, state.f2)) {
|
||||
continue;
|
||||
}
|
||||
@ -390,7 +390,7 @@ void SkDraw::draw_fixed_vertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
} else {
|
||||
// must rebuild pipeline for each triangle, to pass in the computed ctm
|
||||
while (vertProc(&state)) {
|
||||
if (triShader && !triShader->update(ctmInv, positions, dstColors,
|
||||
if (triShader && !triShader->update(ctmInverse, positions, dstColors,
|
||||
state.f0, state.f1, state.f2)) {
|
||||
continue;
|
||||
}
|
||||
@ -459,5 +459,5 @@ void SkDraw::drawVertices(const SkVertices* vertices, SkBlendMode bmode,
|
||||
}
|
||||
}
|
||||
|
||||
this->draw_fixed_vertices(vertices, bmode, paint, ctmInv, dev2, dev3, &outerAlloc);
|
||||
this->drawFixedVertices(vertices, bmode, paint, ctmInv, dev2, dev3, &outerAlloc);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user