add SkMatrixPriv for specialized helpers
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2268443002 Review-Url: https://codereview.chromium.org/2268443002
This commit is contained in:
parent
0a8efd7355
commit
a39667c848
@ -842,6 +842,7 @@ private:
|
||||
static const MapPtsProc gMapPtsProcs[];
|
||||
|
||||
friend class SkPerspIter;
|
||||
friend class SkMatrixPriv;
|
||||
};
|
||||
SK_END_REQUIRE_DENSE
|
||||
|
||||
|
@ -1102,6 +1102,15 @@ void SkMatrix::mapVectors(SkPoint dst[], const SkPoint src[], int count) const {
|
||||
}
|
||||
}
|
||||
|
||||
static Sk4f sort_as_rect(const Sk4f& ltrb) {
|
||||
Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]);
|
||||
Sk4f min = Sk4f::Min(ltrb, rblt);
|
||||
Sk4f max = Sk4f::Max(ltrb, rblt);
|
||||
// We can extract either pair [0,1] or [2,3] from min and max and be correct, but on
|
||||
// ARM this sequence generates the fastest (a single instruction).
|
||||
return Sk4f(min[2], min[3], max[0], max[1]);
|
||||
}
|
||||
|
||||
void SkMatrix::mapRectScaleTranslate(SkRect* dst, const SkRect& src) const {
|
||||
SkASSERT(dst);
|
||||
SkASSERT(this->isScaleTranslate());
|
||||
@ -1112,20 +1121,19 @@ void SkMatrix::mapRectScaleTranslate(SkRect* dst, const SkRect& src) const {
|
||||
SkScalar ty = fMat[kMTransY];
|
||||
Sk4f scale(sx, sy, sx, sy);
|
||||
Sk4f trans(tx, ty, tx, ty);
|
||||
|
||||
Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans;
|
||||
// need to sort so we're not inverted
|
||||
Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]);
|
||||
Sk4f min = Sk4f::Min(ltrb, rblt);
|
||||
Sk4f max = Sk4f::Max(ltrb, rblt);
|
||||
// We can extract either pair [0,1] or [2,3] from min and max and be correct, but on
|
||||
// ARM this sequence generates the fastest (a single instruction).
|
||||
Sk4f(min[2], min[3], max[0], max[1]).store(&dst->fLeft);
|
||||
sort_as_rect(Sk4f::Load(&src.fLeft) * scale + trans).store(&dst->fLeft);
|
||||
}
|
||||
|
||||
bool SkMatrix::mapRect(SkRect* dst, const SkRect& src) const {
|
||||
SkASSERT(dst);
|
||||
|
||||
if (this->getType() <= kTranslate_Mask) {
|
||||
SkScalar tx = fMat[kMTransX];
|
||||
SkScalar ty = fMat[kMTransY];
|
||||
Sk4f trans(tx, ty, tx, ty);
|
||||
sort_as_rect(Sk4f::Load(&src.fLeft) + trans).store(&dst->fLeft);
|
||||
return true;
|
||||
}
|
||||
if (this->isScaleTranslate()) {
|
||||
this->mapRectScaleTranslate(dst, src);
|
||||
return true;
|
||||
|
70
src/core/SkMatrixPriv.h
Normal file
70
src/core/SkMatrixPriv.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkMatrixPriv_DEFINE
|
||||
#define SkMatrixPriv_DEFINE
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkNx.h"
|
||||
|
||||
class SkMatrixPriv {
|
||||
public:
|
||||
/**
|
||||
* Attempt to map the rect through the inverse of the matrix. If it is not invertible,
|
||||
* then this returns false and dst is unchanged.
|
||||
*/
|
||||
static bool SK_WARN_UNUSED_RESULT InverseMapRect(const SkMatrix& mx,
|
||||
SkRect* dst, const SkRect& src) {
|
||||
if (mx.getType() <= SkMatrix::kTranslate_Mask) {
|
||||
SkScalar tx = mx.getTranslateX();
|
||||
SkScalar ty = mx.getTranslateY();
|
||||
Sk4f trans(tx, ty, tx, ty);
|
||||
(Sk4f::Load(&src.fLeft) - trans).store(&dst->fLeft);
|
||||
return true;
|
||||
}
|
||||
// Insert other special-cases here (e.g. scale+translate)
|
||||
|
||||
// general case
|
||||
SkMatrix inverse;
|
||||
if (mx.invert(&inverse)) {
|
||||
inverse.mapRect(dst, src);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void MapPointsWithStride(const SkMatrix& mx, SkPoint pts[], size_t stride, int count) {
|
||||
SkASSERT(stride >= sizeof(SkPoint));
|
||||
SkASSERT(0 == stride % sizeof(SkScalar));
|
||||
|
||||
SkMatrix::TypeMask tm = mx.getType();
|
||||
|
||||
if (SkMatrix::kIdentity_Mask == tm) {
|
||||
return;
|
||||
}
|
||||
if (SkMatrix::kTranslate_Mask == tm) {
|
||||
const SkScalar tx = mx.getTranslateX();
|
||||
const SkScalar ty = mx.getTranslateY();
|
||||
Sk2s trans(tx, ty);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(Sk2s::Load(&pts->fX) + trans).store(&pts->fX);
|
||||
pts = (SkPoint*)((intptr_t)pts + stride);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Insert other special-cases here (e.g. scale+translate)
|
||||
|
||||
// general case
|
||||
SkMatrix::MapXYProc proc = mx.getMapXYProc();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
proc(mx, pts->fX, pts->fY, pts);
|
||||
pts = (SkPoint*)((intptr_t)pts + stride);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -37,6 +37,7 @@
|
||||
#include "../private/GrAuditTrail.h"
|
||||
|
||||
#include "SkLatticeIter.h"
|
||||
#include "SkMatrixPriv.h"
|
||||
|
||||
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fDrawingManager->getContext())
|
||||
#define ASSERT_SINGLE_OWNER \
|
||||
@ -260,12 +261,10 @@ void GrDrawContext::drawPaint(const GrClip& clip,
|
||||
// map the four corners and bound them with a new rect. This will not
|
||||
// produce a correct result for some perspective matrices.
|
||||
if (!isPerspective) {
|
||||
SkMatrix inverse;
|
||||
if (!viewMatrix.invert(&inverse)) {
|
||||
if (!SkMatrixPriv::InverseMapRect(viewMatrix, &r, r)) {
|
||||
SkDebugf("Could not invert matrix\n");
|
||||
return;
|
||||
}
|
||||
inverse.mapRect(&r);
|
||||
this->drawRect(clip, *paint, viewMatrix, r);
|
||||
} else {
|
||||
SkMatrix localMatrix;
|
||||
@ -314,17 +313,13 @@ static bool crop_filled_rect(const GrRenderTarget* rt, const GrClip& clip,
|
||||
return true;
|
||||
}
|
||||
|
||||
SkMatrix inverseViewMatrix;
|
||||
if (!viewMatrix.invert(&inverseViewMatrix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkIRect clipDevBounds;
|
||||
SkRect clipBounds;
|
||||
SkASSERT(inverseViewMatrix.rectStaysRect());
|
||||
|
||||
clip.getConservativeBounds(rt->width(), rt->height(), &clipDevBounds);
|
||||
inverseViewMatrix.mapRect(&clipBounds, SkRect::Make(clipDevBounds));
|
||||
if (!SkMatrixPriv::InverseMapRect(viewMatrix, &clipBounds, SkRect::Make(clipDevBounds))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (localRect) {
|
||||
if (!rect->intersects(clipBounds)) {
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "GrQuad.h"
|
||||
#include "GrVertexBatch.h"
|
||||
|
||||
#include "SkMatrixPriv.h"
|
||||
|
||||
static const int kVertsPerInstance = 4;
|
||||
static const int kIndicesPerInstance = 6;
|
||||
|
||||
@ -47,7 +49,7 @@ static void tesselate(intptr_t vertices,
|
||||
rect.fRight, rect.fBottom, vertexStride);
|
||||
|
||||
if (viewMatrix) {
|
||||
viewMatrix->mapPointsWithStride(positions, vertexStride, kVertsPerInstance);
|
||||
SkMatrixPriv::MapPointsWithStride(*viewMatrix, positions, vertexStride, kVertsPerInstance);
|
||||
}
|
||||
|
||||
// Setup local coords
|
||||
|
Loading…
Reference in New Issue
Block a user