[graphite] Use new Transform concat functions in text code
Uses Transform::Identity() and preTranslate() in places to simplify code and reduce matrix copying/multiplications. Reworks DirectMaskSubRun's boundsAndTransform() function to use preTranslate() and concatInverse() to similarly reduce matrix copies and multiplications. It keeps fInitialPositionMatrix as an SkMatrix as long as possible, and similarly does not copy localToDevice until its determined that concatInverse() and preTranslate() need to be used (vs. the integer-only translation). Change-Id: Ia2ba266f952d3c71fb3afc30f3ba0b904bb4bede Reviewed-on: https://skia-review.googlesource.com/c/skia/+/555002 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
afe25662ee
commit
d289afdd6c
@ -648,10 +648,9 @@ void Device::drawGeometry(const Transform& localToDevice,
|
||||
// TODO: The tessellating path renderers haven't implemented perspective yet, so transform to
|
||||
// device space so we draw something approximately correct (barring local coord issues).
|
||||
if (geometry.isShape() && localToDevice.type() == Transform::Type::kProjection) {
|
||||
static const Transform kIdentity{SkM44()};
|
||||
SkPath devicePath = geometry.shape().asPath();
|
||||
devicePath.transform(localToDevice.matrix().asM33());
|
||||
this->drawGeometry(kIdentity, Geometry(Shape(devicePath)), paint, style, flags);
|
||||
this->drawGeometry(Transform::Identity(), Geometry(Shape(devicePath)), paint, style, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -764,7 +763,7 @@ void Device::drawClipShape(const Transform& localToDevice,
|
||||
if (localToDevice.type() == Transform::Type::kProjection) {
|
||||
SkPath devicePath = geometry.shape().asPath();
|
||||
devicePath.transform(localToDevice.matrix().asM33());
|
||||
fDC->recordDraw(*renderer, Transform({}), Geometry(Shape(devicePath)), clip, order,
|
||||
fDC->recordDraw(*renderer, Transform::Identity(), Geometry(Shape(devicePath)), clip, order,
|
||||
nullptr, nullptr);
|
||||
} else {
|
||||
fDC->recordDraw(*renderer, localToDevice, geometry, clip, order, nullptr, nullptr);
|
||||
|
@ -1552,33 +1552,37 @@ std::tuple<bool, int> DirectMaskSubRun::regenerateAtlas(int begin, int end,
|
||||
|
||||
std::tuple<Rect, Transform> DirectMaskSubRun::boundsAndDeviceMatrix(const Transform& localToDevice,
|
||||
SkPoint drawOrigin) const {
|
||||
SkM44 positionMatrix(localToDevice.matrix());
|
||||
positionMatrix.preTranslate(drawOrigin.x(), drawOrigin.y());
|
||||
SkM44 initialMatrix(fInitialPositionMatrix);
|
||||
const SkPoint offset = {positionMatrix.rc(0,3) - initialMatrix.rc(0,3),
|
||||
positionMatrix.rc(1,3) - initialMatrix.rc(1,3)};
|
||||
|
||||
const bool compatibleMatrix = positionMatrix.rc(0,0) == initialMatrix.rc(0,0) &&
|
||||
positionMatrix.rc(0,1) == initialMatrix.rc(0,1) &&
|
||||
positionMatrix.rc(1,0) == initialMatrix.rc(1,0) &&
|
||||
positionMatrix.rc(1,1) == initialMatrix.rc(1,1) &&
|
||||
// The baked-in matrix differs from the current localToDevice by a translation if the upper 2x2
|
||||
// remains the same, and there's no perspective. Since there's no projection, Z is irrelevant
|
||||
// so it's okay that fInitialPositionMatrix is an SkMatrix and has discarded the 3rd row/col,
|
||||
// and can ignore those values in localToDevice.
|
||||
const SkM44& positionMatrix = localToDevice.matrix();
|
||||
const bool compatibleMatrix = positionMatrix.rc(0,0) == fInitialPositionMatrix.rc(0,0) &&
|
||||
positionMatrix.rc(0,1) == fInitialPositionMatrix.rc(0,1) &&
|
||||
positionMatrix.rc(1,0) == fInitialPositionMatrix.rc(1,0) &&
|
||||
positionMatrix.rc(1,1) == fInitialPositionMatrix.rc(1,1) &&
|
||||
localToDevice.type() != Transform::Type::kProjection &&
|
||||
!fInitialPositionMatrix.hasPerspective();
|
||||
|
||||
if (compatibleMatrix && SkScalarIsInt(offset.x()) && SkScalarIsInt(offset.y())) {
|
||||
// Handle the integer offset case.
|
||||
// The offset should be integer, but make sure.
|
||||
SkM44 translate = SkM44::Translate(SkScalarRoundToInt(offset.x()),
|
||||
SkScalarRoundToInt(offset.y()));
|
||||
return {Rect(fGlyphDeviceBounds.rect()), Transform(translate)};
|
||||
} else if (SkM44 inverse; initialMatrix.invert(&inverse)) {
|
||||
SkM44 viewDifference = positionMatrix * inverse;
|
||||
return {Rect(fGlyphDeviceBounds.rect()), Transform(viewDifference)};
|
||||
if (compatibleMatrix) {
|
||||
const SkV4 mappedOrigin = positionMatrix.map(drawOrigin.x(), drawOrigin.y(), 0.f, 1.f);
|
||||
const SkV2 offset = {mappedOrigin.x - fInitialPositionMatrix.getTranslateX(),
|
||||
mappedOrigin.y - fInitialPositionMatrix.getTranslateY()};
|
||||
if (SkScalarIsInt(offset.x) && SkScalarIsInt(offset.y)) {
|
||||
// The offset is an integer (but make sure), which means the generated mask can be
|
||||
// accessed without changing how texels would be sampled.
|
||||
return {Rect(fGlyphDeviceBounds.rect()),
|
||||
Transform(SkM44::Translate(SkScalarRoundToInt(offset.x),
|
||||
SkScalarRoundToInt(offset.y)))};
|
||||
}
|
||||
}
|
||||
|
||||
// initialPositionMatrix is singular. Do nothing.
|
||||
static const Transform kInvalid{SkM44(SkM44::kNaN_Constructor)};
|
||||
return {Rect::InfiniteInverted(), kInvalid};
|
||||
// Otherwise compute the relative transformation from fInitialPositionMatrix to localToDevice,
|
||||
// with the drawOrigin applied. If fInitialPositionMatrix or the concatenation is not invertible
|
||||
// the returned Transform is marked invalid and the draw will be automatically dropped.
|
||||
return {Rect(fGlyphDeviceBounds.rect()),
|
||||
localToDevice.preTranslate(drawOrigin.x(), drawOrigin.y())
|
||||
.concatInverse(SkM44(fInitialPositionMatrix))};
|
||||
}
|
||||
|
||||
template<typename VertexData>
|
||||
@ -1949,9 +1953,8 @@ std::tuple<bool, int> TransformedMaskSubRun::regenerateAtlas(int begin, int end,
|
||||
|
||||
std::tuple<Rect, Transform> TransformedMaskSubRun::boundsAndDeviceMatrix(
|
||||
const Transform& localToDevice, SkPoint drawOrigin) const {
|
||||
SkM44 positionMatrix(localToDevice.matrix());
|
||||
positionMatrix.preTranslate(drawOrigin.x(), drawOrigin.y());
|
||||
return {Rect(fVertexFiller.localRect()), Transform(positionMatrix)};
|
||||
return {Rect(fVertexFiller.localRect()),
|
||||
localToDevice.preTranslate(drawOrigin.x(), drawOrigin.y())};
|
||||
}
|
||||
|
||||
void TransformedMaskSubRun::fillVertexData(DrawWriter*,
|
||||
@ -2286,9 +2289,8 @@ SDFTSubRun::regenerateAtlas(int begin, int end, Recorder *recorder) const {
|
||||
|
||||
std::tuple<Rect, Transform> SDFTSubRun::boundsAndDeviceMatrix(const Transform& localToDevice,
|
||||
SkPoint drawOrigin) const {
|
||||
SkM44 positionMatrix(localToDevice.matrix());
|
||||
positionMatrix.preTranslate(drawOrigin.x(), drawOrigin.y());
|
||||
return {Rect(fVertexFiller.localRect()), Transform(positionMatrix)};
|
||||
return {Rect(fVertexFiller.localRect()),
|
||||
localToDevice.preTranslate(drawOrigin.x(), drawOrigin.y())};
|
||||
}
|
||||
|
||||
void SDFTSubRun::fillVertexData(DrawWriter*,
|
||||
|
Loading…
Reference in New Issue
Block a user