Add SkMatrix::getPerspectiveTypeMaskOnly() and SkMatrix::isTriviallyIdentity().
Reduces profile time in setConcat() and computeTypeMask() for demos that do a lot of matrix concatenation. git-svn-id: http://skia.googlecode.com/svn/trunk@2191 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
a8540416f6
commit
dd5f7442f6
@ -10,6 +10,7 @@
|
||||
|
||||
#include "GrContext.h"
|
||||
#include "GrPathUtils.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTrace.h"
|
||||
|
||||
|
||||
@ -372,9 +373,6 @@ FINISHED:
|
||||
void GrDefaultPathRenderer::onDrawPath(GrDrawTarget::StageBitfield stages,
|
||||
bool stencilOnly) {
|
||||
|
||||
SK_TRACE_EVENT1("GrDefaultPathRenderer::onDrawPath",
|
||||
"points", SkStringPrintf("%i", path.countPoints()).c_str());
|
||||
|
||||
GrMatrix viewM = fTarget->getViewMatrix();
|
||||
// In order to tesselate the path we get a bound on how much the matrix can
|
||||
// stretch when mapping to screen coordinates.
|
||||
@ -502,8 +500,6 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawTarget::StageBitfield stages,
|
||||
}
|
||||
|
||||
{
|
||||
SK_TRACE_EVENT1("GrDefaultPathRenderer::onDrawPath::renderPasses",
|
||||
"verts", SkStringPrintf("%i", vert - base).c_str());
|
||||
for (int p = 0; p < passCount; ++p) {
|
||||
fTarget->setDrawFace(drawFace[p]);
|
||||
if (NULL != passes[p]) {
|
||||
|
@ -67,10 +67,11 @@ public:
|
||||
bool preservesAxisAlignment() const { return this->rectStaysRect(); }
|
||||
|
||||
/**
|
||||
* Returns true if the perspective contains perspective elements.
|
||||
* Returns true if the matrix contains perspective elements.
|
||||
*/
|
||||
bool hasPerspective() const {
|
||||
return SkToBool(this->getType() & kPerspective_Mask);
|
||||
return SkToBool(this->getPerspectiveTypeMaskOnly() &
|
||||
kPerspective_Mask);
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -536,6 +537,11 @@ private:
|
||||
*/
|
||||
kRectStaysRect_Mask = 0x10,
|
||||
|
||||
/** Set if the perspective bit is valid even though the rest of
|
||||
the matrix is Unknown.
|
||||
*/
|
||||
kOnlyPerspectiveValid_Mask = 0x40,
|
||||
|
||||
kUnknown_Mask = 0x80,
|
||||
|
||||
kORableMasks = kTranslate_Mask |
|
||||
@ -554,10 +560,13 @@ private:
|
||||
mutable uint8_t fTypeMask;
|
||||
|
||||
uint8_t computeTypeMask() const;
|
||||
uint8_t computePerspectiveTypeMask() const;
|
||||
|
||||
void setTypeMask(int mask) {
|
||||
// allow kUnknown or a valid mask
|
||||
SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask);
|
||||
SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
|
||||
((kUnknown_Mask | kOnlyPerspectiveValid_Mask | kPerspective_Mask) & mask)
|
||||
== mask);
|
||||
fTypeMask = SkToU8(mask);
|
||||
}
|
||||
|
||||
@ -572,6 +581,24 @@ private:
|
||||
fTypeMask &= ~mask;
|
||||
}
|
||||
|
||||
TypeMask getPerspectiveTypeMaskOnly() const {
|
||||
if ((fTypeMask & kUnknown_Mask) &&
|
||||
!(fTypeMask & kOnlyPerspectiveValid_Mask)) {
|
||||
fTypeMask = this->computePerspectiveTypeMask();
|
||||
}
|
||||
return (TypeMask)(fTypeMask & 0xF);
|
||||
}
|
||||
|
||||
/** Returns true if we already know that the matrix is identity;
|
||||
false otherwise.
|
||||
*/
|
||||
bool isTriviallyIdentity() const {
|
||||
if (fTypeMask & kUnknown_Mask) {
|
||||
return false;
|
||||
}
|
||||
return ((fTypeMask & 0xF) == 0);
|
||||
}
|
||||
|
||||
static bool Poly2Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
|
||||
static bool Poly3Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
|
||||
static bool Poly4Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
|
||||
|
@ -56,6 +56,18 @@ enum {
|
||||
static const int32_t kPersp1Int = (1 << 30);
|
||||
#endif
|
||||
|
||||
uint8_t SkMatrix::computePerspectiveTypeMask() const {
|
||||
unsigned mask = kOnlyPerspectiveValid_Mask | kUnknown_Mask;
|
||||
|
||||
if (SkScalarAs2sCompliment(fMat[kMPersp0]) |
|
||||
SkScalarAs2sCompliment(fMat[kMPersp1]) |
|
||||
(SkScalarAs2sCompliment(fMat[kMPersp2]) - kPersp1Int)) {
|
||||
mask |= kPerspective_Mask;
|
||||
}
|
||||
|
||||
return SkToU8(mask);
|
||||
}
|
||||
|
||||
uint8_t SkMatrix::computeTypeMask() const {
|
||||
unsigned mask = 0;
|
||||
|
||||
@ -165,7 +177,7 @@ bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) {
|
||||
fMat[kMTransY] += SkScalarMul(fMat[kMSkewY], dx) +
|
||||
SkScalarMul(fMat[kMScaleY], dy);
|
||||
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -180,7 +192,7 @@ bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) {
|
||||
if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) {
|
||||
fMat[kMTransX] += dx;
|
||||
fMat[kMTransY] += dy;
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -324,7 +336,7 @@ void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV,
|
||||
fMat[kMPersp0] = fMat[kMPersp1] = 0;
|
||||
fMat[kMPersp2] = kMatrix22Elem;
|
||||
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
|
||||
void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) {
|
||||
@ -339,7 +351,7 @@ void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) {
|
||||
fMat[kMPersp0] = fMat[kMPersp1] = 0;
|
||||
fMat[kMPersp2] = kMatrix22Elem;
|
||||
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
|
||||
void SkMatrix::setRotate(SkScalar degrees, SkScalar px, SkScalar py) {
|
||||
@ -392,7 +404,7 @@ void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
|
||||
fMat[kMPersp0] = fMat[kMPersp1] = 0;
|
||||
fMat[kMPersp2] = kMatrix22Elem;
|
||||
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
|
||||
void SkMatrix::setSkew(SkScalar sx, SkScalar sy) {
|
||||
@ -407,7 +419,7 @@ void SkMatrix::setSkew(SkScalar sx, SkScalar sy) {
|
||||
fMat[kMPersp0] = fMat[kMPersp1] = 0;
|
||||
fMat[kMPersp2] = kMatrix22Elem;
|
||||
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
|
||||
bool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
|
||||
@ -573,12 +585,12 @@ static void normalize_perspective(SkScalar mat[9]) {
|
||||
}
|
||||
|
||||
bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
|
||||
TypeMask aType = a.getType();
|
||||
TypeMask bType = b.getType();
|
||||
TypeMask aType = a.getPerspectiveTypeMaskOnly();
|
||||
TypeMask bType = b.getPerspectiveTypeMaskOnly();
|
||||
|
||||
if (0 == aType) {
|
||||
if (a.isTriviallyIdentity()) {
|
||||
*this = b;
|
||||
} else if (0 == bType) {
|
||||
} else if (b.isTriviallyIdentity()) {
|
||||
*this = a;
|
||||
} else {
|
||||
SkMatrix tmp;
|
||||
@ -615,6 +627,7 @@ bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
|
||||
}
|
||||
|
||||
normalize_perspective(tmp.fMat);
|
||||
tmp.setTypeMask(kUnknown_Mask);
|
||||
} else { // not perspective
|
||||
if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMScaleX],
|
||||
a.fMat[kMSkewX], b.fMat[kMSkewY], &tmp.fMat[kMScaleX])) {
|
||||
@ -652,10 +665,12 @@ bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) {
|
||||
|
||||
tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0;
|
||||
tmp.fMat[kMPersp2] = kMatrix22Elem;
|
||||
//SkDebugf("Concat mat non-persp type: %d\n", tmp.getType());
|
||||
//SkASSERT(!(tmp.getType() & kPerspective_Mask));
|
||||
tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
*this = tmp;
|
||||
}
|
||||
this->setTypeMask(kUnknown_Mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -829,6 +844,7 @@ bool SkMatrix::invert(SkMatrix* inv) const {
|
||||
}
|
||||
inv->fMat[kMPersp2] = SkFixedToFract(inv->fMat[kMPersp2]);
|
||||
#endif
|
||||
inv->setTypeMask(kUnknown_Mask);
|
||||
} else { // not perspective
|
||||
#ifdef SK_SCALAR_IS_FIXED
|
||||
Sk64 tx, ty;
|
||||
@ -877,6 +893,7 @@ bool SkMatrix::invert(SkMatrix* inv) const {
|
||||
inv->fMat[kMPersp0] = 0;
|
||||
inv->fMat[kMPersp1] = 0;
|
||||
inv->fMat[kMPersp2] = kMatrix22Elem;
|
||||
inv->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
|
||||
if (inv == &tmp) {
|
||||
|
@ -1480,7 +1480,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
||||
const SkPaint& paint) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
|
||||
if (draw.fMatrix->hasPerspective()) {
|
||||
// this guy will just call our drawPath()
|
||||
draw.drawText((const char*)text, byteLength, x, y, paint);
|
||||
} else {
|
||||
@ -1508,7 +1508,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
|
||||
const SkPaint& paint) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
|
||||
if (draw.fMatrix->hasPerspective()) {
|
||||
// this guy will just call our drawPath()
|
||||
draw.drawPosText((const char*)text, byteLength, pos, constY,
|
||||
scalarsPerPos, paint);
|
||||
|
Loading…
Reference in New Issue
Block a user