aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSkia_Android Canary Bot <31977622648@project.gserviceaccount.com>2018-05-08 16:55:52 +0000
committerLeon Scroggins <scroggo@google.com>2018-05-08 17:23:27 +0000
commit84af2a4ff71f8b18c8f8c07613efd14a8b4faab5 (patch)
treea655d2d5c56ac43422abf23263ed819371500044
parent5f24c982dd53c494bfb92a4c156c5768ba85664d (diff)
parent38784599f39026f54aa56b3c6e34afc15e00abd6 (diff)
downloadskia-84af2a4ff71f8b18c8f8c07613efd14a8b4faab5.tar.gz
Roll external/skia 149bd00d8..38784599f (3 commits)
https://skia.googlesource.com/skia.git/+log/149bd00d8..38784599f 2018-05-08 scroggo@google.com Cherry-pick of "Make GPU lattice/nine patch not bleed across cells." 2018-05-08 scroggo@google.com Make the src rects of truths in SkLatticeIter be integral. 2018-05-08 scroggo@google.com Reland "(Mostly) respect FilterQuality in draw[stretchy]" The AutoRoll server is located here: https://android-next-roll.skia.org Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md If the roll is causing failures, please contact the current sheriff, who should be CC'd on the roll, and stop the roller if necessary. Test: Presubmit checks will test this change. Exempt-From-Owner-Approval: The autoroll bot does not require owner approval. Bug: 77917978 Test: CtsUiRenderingTestCases Change-Id: Ib7d0abdd51981bddf36ec5c3fd84bb651f405f0f Merged-In: Iee8fe135636135e3635fb48c4bb2321213686cee
-rw-r--r--include/core/SkCanvas.h16
-rw-r--r--src/core/SkCanvas.cpp35
-rw-r--r--src/core/SkLatticeIter.cpp11
-rw-r--r--src/core/SkLatticeIter.h17
-rw-r--r--src/gpu/GrGpu.cpp1
-rw-r--r--src/gpu/GrProcessor.h1
-rw-r--r--src/gpu/GrRenderTargetContext.cpp10
-rw-r--r--src/gpu/GrRenderTargetContext.h9
-rw-r--r--src/gpu/GrTextureAdjuster.cpp17
-rw-r--r--src/gpu/GrTextureAdjuster.h14
-rw-r--r--src/gpu/GrTextureMaker.cpp8
-rw-r--r--src/gpu/GrTextureMaker.h17
-rw-r--r--src/gpu/GrTextureProducer.cpp22
-rw-r--r--src/gpu/GrTextureProducer.h34
-rw-r--r--src/gpu/SkGpuDevice.cpp117
-rw-r--r--src/gpu/SkGpuDevice.h11
-rw-r--r--src/gpu/ops/GrLatticeOp.cpp244
-rw-r--r--src/gpu/ops/GrLatticeOp.h11
-rw-r--r--src/image/SkImage_Gpu.cpp6
-rw-r--r--src/image/SkImage_Raster.cpp6
20 files changed, 410 insertions, 197 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 41f740a79b..221b05641a 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -1599,7 +1599,9 @@ public:
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
- If paint contains SkMaskFilter, generate mask from image bounds.
+ If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
+ SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
+ were kLow_SkFilterQuality.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
@@ -1728,7 +1730,9 @@ public:
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
- If paint contains SkMaskFilter, generate mask from bitmap bounds.
+ If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
+ SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
+ were kLow_SkFilterQuality.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
@@ -1828,7 +1832,9 @@ public:
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
- If paint contains SkMaskFilter, generate mask from bitmap bounds.
+ If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
+ SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
+ were kLow_SkFilterQuality.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
@@ -1856,7 +1862,9 @@ public:
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
- If paint contains SkMaskFilter, generate mask from bitmap bounds.
+ If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
+ SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
+ were kLow_SkFilterQuality.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 34b9d369ec..b29a538717 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1794,6 +1794,29 @@ void SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPa
constraint);
}
+namespace {
+class NoneOrLowQualityFilterPaint : SkNoncopyable {
+public:
+ NoneOrLowQualityFilterPaint(const SkPaint* origPaint) {
+ if (origPaint && origPaint->getFilterQuality() > kLow_SkFilterQuality) {
+ fLazyPaint.set(*origPaint);
+ fLazyPaint.get()->setFilterQuality(kLow_SkFilterQuality);
+ fPaint = fLazyPaint.get();
+ } else {
+ fPaint = origPaint;
+ }
+ }
+
+ const SkPaint* get() const {
+ return fPaint;
+ }
+
+private:
+ const SkPaint* fPaint;
+ SkLazyPaint fLazyPaint;
+};
+} // namespace
+
void SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
const SkPaint* paint) {
TRACE_EVENT0("skia", TRACE_FUNC);
@@ -1802,7 +1825,8 @@ void SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const
return;
}
if (SkLatticeIter::Valid(image->width(), image->height(), center)) {
- this->onDrawImageNine(image, center, dst, paint);
+ NoneOrLowQualityFilterPaint lowPaint(paint);
+ this->onDrawImageNine(image, center, dst, lowPaint.get());
} else {
this->drawImageRect(image, dst, paint);
}
@@ -1824,7 +1848,8 @@ void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, co
}
if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
- this->onDrawImageLattice(image, latticePlusBounds, dst, paint);
+ NoneOrLowQualityFilterPaint lowPaint(paint);
+ this->onDrawImageLattice(image, latticePlusBounds, dst, lowPaint.get());
} else {
this->drawImageRect(image, dst, paint);
}
@@ -1865,7 +1890,8 @@ void SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, con
return;
}
if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) {
- this->onDrawBitmapNine(bitmap, center, dst, paint);
+ NoneOrLowQualityFilterPaint lowPaint(paint);
+ this->onDrawBitmapNine(bitmap, center, dst, lowPaint.get());
} else {
this->drawBitmapRect(bitmap, dst, paint);
}
@@ -1886,7 +1912,8 @@ void SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
}
if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) {
- this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, paint);
+ NoneOrLowQualityFilterPaint lowPaint(paint);
+ this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, lowPaint.get());
} else {
this->drawBitmapRect(bitmap, dst, paint);
}
diff --git a/src/core/SkLatticeIter.cpp b/src/core/SkLatticeIter.cpp
index 434cce6e11..fcc12c6f21 100644
--- a/src/core/SkLatticeIter.cpp
+++ b/src/core/SkLatticeIter.cpp
@@ -76,10 +76,9 @@ static int count_scalable_pixels(const int32_t* divs, int numDivs, bool firstIsS
/**
* Set points for the src and dst rects on subsequent draw calls.
*/
-static void set_points(float* dst, float* src, const int* divs, int divCount, int srcFixed,
- int srcScalable, float srcStart, float srcEnd, float dstStart, float dstEnd,
+static void set_points(float* dst, int* src, const int* divs, int divCount, int srcFixed,
+ int srcScalable, int srcStart, int srcEnd, float dstStart, float dstEnd,
bool isScalable) {
-
float dstLen = dstEnd - dstStart;
float scale;
if (srcFixed <= dstLen) {
@@ -94,8 +93,8 @@ static void set_points(float* dst, float* src, const int* divs, int divCount, in
src[0] = srcStart;
dst[0] = dstStart;
for (int i = 0; i < divCount; i++) {
- src[i + 1] = (float) (divs[i]);
- float srcDelta = src[i + 1] - src[i];
+ src[i + 1] = divs[i];
+ int srcDelta = src[i + 1] - src[i];
float dstDelta;
if (srcFixed <= dstLen) {
dstDelta = isScalable ? scale * srcDelta : srcDelta;
@@ -254,7 +253,7 @@ SkLatticeIter::SkLatticeIter(int w, int h, const SkIRect& c, const SkRect& dst)
fNumRectsToDraw = 9;
}
-bool SkLatticeIter::next(SkRect* src, SkRect* dst, bool* isFixedColor, SkColor* fixedColor) {
+bool SkLatticeIter::next(SkIRect* src, SkRect* dst, bool* isFixedColor, SkColor* fixedColor) {
int currRect = fCurrX + fCurrY * (fSrcX.count() - 1);
if (currRect == fNumRectsInLattice) {
return false;
diff --git a/src/core/SkLatticeIter.h b/src/core/SkLatticeIter.h
index 08cdd5a965..afd0c39742 100644
--- a/src/core/SkLatticeIter.h
+++ b/src/core/SkLatticeIter.h
@@ -34,9 +34,20 @@ public:
* isFixedColor and fixedColor specify if the rectangle is filled with a fixed color.
* If (*isFixedColor) is true, then (*fixedColor) contains the rectangle color.
*/
- bool next(SkRect* src, SkRect* dst, bool* isFixedColor = nullptr,
+ bool next(SkIRect* src, SkRect* dst, bool* isFixedColor = nullptr,
SkColor* fixedColor = nullptr);
+ /** Version of above that converts the integer src rect to a scalar rect. */
+ bool next(SkRect* src, SkRect* dst, bool* isFixedColor = nullptr,
+ SkColor* fixedColor = nullptr) {
+ SkIRect isrcR;
+ if (this->next(&isrcR, dst, isFixedColor, fixedColor)) {
+ *src = SkRect::Make(isrcR);
+ return true;
+ }
+ return false;
+ }
+
/**
* Apply a matrix to the dst points.
*/
@@ -50,8 +61,8 @@ public:
}
private:
- SkTArray<SkScalar> fSrcX;
- SkTArray<SkScalar> fSrcY;
+ SkTArray<int> fSrcX;
+ SkTArray<int> fSrcY;
SkTArray<SkScalar> fDstX;
SkTArray<SkScalar> fDstY;
SkTArray<SkCanvas::Lattice::RectType> fRectTypes;
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index a53dc8a98a..ec246ae1da 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -54,6 +54,7 @@ bool GrGpu::isACopyNeededForTextureParams(int width, int height,
SkASSERT(scaleAdjust);
copyParams->fWidth = GrNextPow2(width);
copyParams->fHeight = GrNextPow2(height);
+ SkASSERT(scaleAdjust);
scaleAdjust[0] = ((SkScalar) copyParams->fWidth) / width;
scaleAdjust[1] = ((SkScalar) copyParams->fHeight) / height;
switch (textureParams.filter()) {
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index 64a28d83e9..c7704dbdf1 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -140,6 +140,7 @@ public:
kGrYUVtoRGBEffect_ClassID,
kHighContrastFilterEffect_ClassID,
kInstanceProcessor_ClassID,
+ kLatticeGP_ClassID,
kLumaColorFilterEffect_ClassID,
kMSAAQuadProcessor_ClassID,
kPDLCDXferProcessor_ClassID,
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index a95f25198b..2d760e12af 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1361,8 +1361,9 @@ void GrRenderTargetContext::drawArc(const GrClip& clip,
void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
GrPaint&& paint,
const SkMatrix& viewMatrix,
- int imageWidth,
- int imageHeight,
+ sk_sp<GrTextureProxy> image,
+ sk_sp<GrColorSpaceXform> csxf,
+ GrSamplerState::Filter filter,
std::unique_ptr<SkLatticeIter> iter,
const SkRect& dst) {
ASSERT_SINGLE_OWNER
@@ -1372,8 +1373,9 @@ void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
AutoCheckFlush acf(this->drawingManager());
- std::unique_ptr<GrDrawOp> op = GrLatticeOp::MakeNonAA(std::move(paint), viewMatrix, imageWidth,
- imageHeight, std::move(iter), dst);
+ std::unique_ptr<GrDrawOp> op =
+ GrLatticeOp::MakeNonAA(std::move(paint), viewMatrix, std::move(image), std::move(csxf),
+ filter, std::move(iter), dst);
this->addDrawOp(clip, std::move(op));
}
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 6525866ee0..04ae319578 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -309,11 +309,12 @@ public:
* Draw the image as a set of rects, specified by |iter|.
*/
void drawImageLattice(const GrClip&,
- GrPaint&& paint,
+ GrPaint&&,
const SkMatrix& viewMatrix,
- int imageWidth,
- int imageHeight,
- std::unique_ptr<SkLatticeIter> iter,
+ sk_sp<GrTextureProxy>,
+ sk_sp<GrColorSpaceXform>,
+ GrSamplerState::Filter,
+ std::unique_ptr<SkLatticeIter>,
const SkRect& dst);
/**
diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp
index fbfffb3bb8..2426a1857c 100644
--- a/src/gpu/GrTextureAdjuster.cpp
+++ b/src/gpu/GrTextureAdjuster.cpp
@@ -65,8 +65,11 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& c
return copy;
}
-sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxySafeForParams(const GrSamplerState& params,
- SkScalar scaleAdjust[2]) {
+sk_sp<GrTextureProxy> GrTextureAdjuster::onRefTextureProxyForParams(
+ const GrSamplerState& params,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* texColorSpace,
+ SkScalar scaleAdjust[2]) {
sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
CopyParams copyParams;
@@ -75,7 +78,15 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxySafeForParams(const GrSa
return nullptr;
}
+ if (texColorSpace) {
+ *texColorSpace = sk_ref_sp(fColorSpace);
+ }
+
GrGpu* gpu = fContext->contextPriv().getGpu();
+ if (!gpu) {
+ return proxy;
+ }
+
if (!gpu->isACopyNeededForTextureParams(proxy.get(), params, &copyParams, scaleAdjust)) {
return proxy;
}
@@ -100,7 +111,7 @@ std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
}
SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
sk_sp<GrTextureProxy> proxy(
- this->refTextureProxySafeForParams(samplerState, scaleAdjust));
+ this->refTextureProxyForParams(samplerState, nullptr, nullptr, scaleAdjust));
if (!proxy) {
return nullptr;
}
diff --git a/src/gpu/GrTextureAdjuster.h b/src/gpu/GrTextureAdjuster.h
index a0ce8c40db..885e39059d 100644
--- a/src/gpu/GrTextureAdjuster.h
+++ b/src/gpu/GrTextureAdjuster.h
@@ -20,11 +20,6 @@
*/
class GrTextureAdjuster : public GrTextureProducer {
public:
- /** Makes the subset of the texture safe to use with the given texture parameters. If the copy's
- size does not match subset's dimensions then the contents are scaled to fit the copy.*/
- sk_sp<GrTextureProxy> refTextureProxySafeForParams(const GrSamplerState&,
- SkScalar scaleAdjust[2]);
-
std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
const SkMatrix& textureMatrix,
const SkRect& constraintRect,
@@ -48,14 +43,19 @@ protected:
sk_sp<GrTextureProxy> originalProxyRef() const { return fOriginal; }
private:
+ sk_sp<GrTextureProxy> onRefTextureProxyForParams(const GrSamplerState&,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* proxyColorSpace,
+ SkScalar scaleAdjust[2]) override;
+
+ sk_sp<GrTextureProxy> refTextureProxyCopy(const CopyParams& copyParams, bool willBeMipped);
+
GrContext* fContext;
sk_sp<GrTextureProxy> fOriginal;
SkAlphaType fAlphaType;
SkColorSpace* fColorSpace;
uint32_t fUniqueID;
- sk_sp<GrTextureProxy> refTextureProxyCopy(const CopyParams &copyParams, bool willBeMipped);
-
typedef GrTextureProducer INHERITED;
};
diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp
index 5043675a0d..7d7431bbf2 100644
--- a/src/gpu/GrTextureMaker.cpp
+++ b/src/gpu/GrTextureMaker.cpp
@@ -13,10 +13,10 @@
#include "GrGpu.h"
#include "GrProxyProvider.h"
-sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerState& params,
- SkColorSpace* dstColorSpace,
- sk_sp<SkColorSpace>* texColorSpace,
- SkScalar scaleAdjust[2]) {
+sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSamplerState& params,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* texColorSpace,
+ SkScalar scaleAdjust[2]) {
CopyParams copyParams;
bool willBeMipped = params.filter() == GrSamplerState::Filter::kMipMap;
diff --git a/src/gpu/GrTextureMaker.h b/src/gpu/GrTextureMaker.h
index b482170d49..6c8cd0407e 100644
--- a/src/gpu/GrTextureMaker.h
+++ b/src/gpu/GrTextureMaker.h
@@ -18,18 +18,6 @@ class GrTextureMaker : public GrTextureProducer {
public:
enum class AllowedTexGenType : bool { kCheap, kAny };
- /**
- * Returns a texture that is safe for use with the params. If the size of the returned texture
- * does not match width()/height() then the contents of the original must be scaled to fit
- * the texture. Additionally, the 'scaleAdjust' must be applied to the texture matrix
- * in order to correct the absolute texture coordinates.
- * Places the color space of the texture in (*texColorSpace).
- */
- sk_sp<GrTextureProxy> refTextureProxyForParams(const GrSamplerState&,
- SkColorSpace* dstColorSpace,
- sk_sp<SkColorSpace>* texColorSpace,
- SkScalar scaleAdjust[2]);
-
std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
const SkMatrix& textureMatrix,
const SkRect& constraintRect,
@@ -77,6 +65,11 @@ protected:
GrContext* context() const { return fContext; }
private:
+ sk_sp<GrTextureProxy> onRefTextureProxyForParams(const GrSamplerState&,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* proxyColorSpace,
+ SkScalar scaleAdjust[2]) override;
+
GrContext* fContext;
typedef GrTextureProducer INHERITED;
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index f1c8c8dbd0..46a80944e6 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -207,3 +207,25 @@ std::unique_ptr<GrFragmentProcessor> GrTextureProducer::CreateFragmentProcessorF
}
}
}
+
+sk_sp<GrTextureProxy> GrTextureProducer::refTextureProxyForParams(
+ const GrSamplerState& sampler,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* proxyColorSpace,
+ SkScalar scaleAdjust[2]) {
+ // Check that the caller pre-initialized scaleAdjust
+ SkASSERT(!scaleAdjust || (scaleAdjust[0] == 1 && scaleAdjust[1] == 1));
+ // Check that if the caller passed nullptr for scaleAdjust that we're in the case where there
+ // can be no scaling.
+ SkDEBUGCODE(bool expectNoScale = (sampler.filter() != GrSamplerState::Filter::kMipMap &&
+ !sampler.isRepeated()));
+ SkASSERT(scaleAdjust || expectNoScale);
+ auto result =
+ this->onRefTextureProxyForParams(sampler, dstColorSpace, proxyColorSpace, scaleAdjust);
+
+ // Check that the "no scaling expected" case always returns a proxy of the same size as the
+ // producer.
+ SkASSERT(!result || !expectNoScale ||
+ (result->width() == this->width() && result->height() == this->height()));
+ return result;
+}
diff --git a/src/gpu/GrTextureProducer.h b/src/gpu/GrTextureProducer.h
index 88ba14afa8..467948dfa6 100644
--- a/src/gpu/GrTextureProducer.h
+++ b/src/gpu/GrTextureProducer.h
@@ -69,6 +69,35 @@ public:
const GrSamplerState::Filter* filterOrNullForBicubic,
SkColorSpace* dstColorSpace) = 0;
+ /**
+ * Returns a texture that is safe for use with the params.
+ *
+ * If the size of the returned texture does not match width()/height() then the contents of the
+ * original may have been scaled to fit the texture or the original may have been copied into
+ * a subrect of the copy. 'scaleAdjust' must be applied to the normalized texture coordinates
+ * in order to correct for the latter case.
+ *
+ * If the GrSamplerState is known to clamp and use kNearest or kBilerp filter mode then the
+ * proxy will always be unscaled and nullptr can be passed for scaleAdjust. There is a weird
+ * contract that if scaleAdjust is not null it must be initialized to {1, 1} before calling
+ * this method. (TODO: Fix this and make this function always initialize scaleAdjust).
+ *
+ * Places the color space of the texture in (*proxyColorSpace).
+ */
+ sk_sp<GrTextureProxy> refTextureProxyForParams(const GrSamplerState&,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* proxyColorSpace,
+ SkScalar scaleAdjust[2]);
+
+ sk_sp<GrTextureProxy> refTextureProxyForParams(GrSamplerState::Filter filter,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* proxyColorSpace,
+ SkScalar scaleAdjust[2]) {
+ return this->refTextureProxyForParams(
+ GrSamplerState(GrSamplerState::WrapMode::kClamp, filter), dstColorSpace,
+ proxyColorSpace, scaleAdjust);
+ }
+
virtual ~GrTextureProducer() {}
int width() const { return fWidth; }
@@ -142,6 +171,11 @@ protected:
const GrSamplerState::Filter* filterOrNullForBicubic);
private:
+ virtual sk_sp<GrTextureProxy> onRefTextureProxyForParams(const GrSamplerState&,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* proxyColorSpace,
+ SkScalar scaleAdjust[2]) = 0;
+
const int fWidth;
const int fHeight;
const bool fIsAlphaOnly;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b7ba1d40a8..9b5a5a9338 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -6,6 +6,7 @@
*/
#include "SkGpuDevice.h"
+#include "../private/SkShadowFlags.h"
#include "GrBitmapTextureMaker.h"
#include "GrBlurUtils.h"
#include "GrColorSpaceXform.h"
@@ -28,6 +29,7 @@
#include "SkImageInfoPriv.h"
#include "SkImage_Base.h"
#include "SkLatticeIter.h"
+#include "SkMakeUnique.h"
#include "SkMaskFilterBase.h"
#include "SkPathEffect.h"
#include "SkPicture.h"
@@ -48,7 +50,6 @@
#include "effects/GrBicubicEffect.h"
#include "effects/GrSimpleTextureEffect.h"
#include "effects/GrTextureDomain.h"
-#include "../private/SkShadowFlags.h"
#include "text/GrTextUtils.h"
#if SK_SUPPORT_GPU
@@ -976,15 +977,16 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap,
bitmap.height() <= fContext->caps()->maxTileSize());
SkASSERT(!samplerState.isRepeated());
+ SkScalar scales[2] = {1.f, 1.f};
sk_sp<GrTextureProxy> proxy =
- GrRefCachedBitmapTextureProxy(fContext.get(), bitmap, samplerState, nullptr);
+ GrRefCachedBitmapTextureProxy(fContext.get(), bitmap, samplerState, scales);
if (!proxy) {
return;
}
// Compute a matrix that maps the rect we will draw to the src rect.
- const SkMatrix texMatrix = SkMatrix::MakeRectToRect(dstRect, srcRect,
- SkMatrix::kFill_ScaleToFit);
+ SkMatrix texMatrix = SkMatrix::MakeRectToRect(dstRect, srcRect, SkMatrix::kFill_ScaleToFit);
+ texMatrix.postScale(scales[0], scales[1]);
// Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
// the rest from the SkPaint.
@@ -1352,66 +1354,34 @@ void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src, const S
}
}
-void SkGpuDevice::drawProducerNine(GrTextureProducer* producer,
- const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
- GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerNine", fContext.get());
-
- bool useFallback = paint.getMaskFilter() || paint.isAntiAlias() ||
- GrFSAAType::kUnifiedMSAA == fRenderTargetContext->fsaaType();
- bool doBicubic;
- GrSamplerState::Filter textureFilterMode = GrSkFilterQualityToGrFilterMode(
- paint.getFilterQuality(), this->ctm(), SkMatrix::I(),
- fContext->contextPriv().sharpenMipmappedTextures(), &doBicubic);
- if (useFallback || doBicubic || GrSamplerState::Filter::kNearest != textureFilterMode) {
- SkLatticeIter iter(producer->width(), producer->height(), center, dst);
-
- SkRect srcR, dstR;
- while (iter.next(&srcR, &dstR)) {
- this->drawTextureProducer(producer, &srcR, &dstR, SkCanvas::kStrict_SrcRectConstraint,
- this->ctm(), paint);
- }
- return;
- }
-
- static const GrSamplerState::Filter kMode = GrSamplerState::Filter::kNearest;
- auto fp = producer->createFragmentProcessor(
- SkMatrix::I(), SkRect::MakeIWH(producer->width(), producer->height()),
- GrTextureProducer::kNo_FilterConstraint, true, &kMode,
- fRenderTargetContext->colorSpaceInfo().colorSpace());
- if (!fp) {
- return;
- }
- GrPaint grPaint;
- if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext->colorSpaceInfo(), paint,
- this->ctm(), std::move(fp), producer->isAlphaOnly(),
- &grPaint)) {
- return;
+// When drawing nine-patches or n-patches, cap the filter quality at kBilerp.
+static GrSamplerState::Filter compute_lattice_filter_mode(const SkPaint& paint) {
+ if (paint.getFilterQuality() == kNone_SkFilterQuality) {
+ return GrSamplerState::Filter::kNearest;
}
- std::unique_ptr<SkLatticeIter> iter(
- new SkLatticeIter(producer->width(), producer->height(), center, dst));
- fRenderTargetContext->drawImageLattice(this->clip(), std::move(grPaint), this->ctm(),
- producer->width(), producer->height(), std::move(iter),
- dst);
+ return GrSamplerState::Filter::kBilerp;
}
void SkGpuDevice::drawImageNine(const SkImage* image,
const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
uint32_t pinnedUniqueID;
+ auto iter = skstd::make_unique<SkLatticeIter>(image->width(), image->height(), center, dst);
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(&pinnedUniqueID)) {
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
image->alphaType(), pinnedUniqueID,
as_IB(image)->onImageInfo().colorSpace());
- this->drawProducerNine(&adjuster, center, dst, paint);
+ this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
} else {
SkBitmap bm;
if (image->isLazyGenerated()) {
GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint);
- this->drawProducerNine(&maker, center, dst, paint);
+ this->drawProducerLattice(&maker, std::move(iter), dst, paint);
} else if (as_IB(image)->getROPixels(&bm,
fRenderTargetContext->colorSpaceInfo().colorSpace())) {
- this->drawBitmapNine(bm, center, dst, paint);
+ GrBitmapTextureMaker maker(fContext.get(), bm);
+ this->drawProducerLattice(&maker, std::move(iter), dst, paint);
}
}
}
@@ -1419,35 +1389,47 @@ void SkGpuDevice::drawImageNine(const SkImage* image,
void SkGpuDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
+ auto iter = skstd::make_unique<SkLatticeIter>(bitmap.width(), bitmap.height(), center, dst);
GrBitmapTextureMaker maker(fContext.get(), bitmap);
- this->drawProducerNine(&maker, center, dst, paint);
+ this->drawProducerLattice(&maker, std::move(iter), dst, paint);
}
void SkGpuDevice::drawProducerLattice(GrTextureProducer* producer,
- const SkCanvas::Lattice& lattice, const SkRect& dst,
- const SkPaint& paint) {
+ std::unique_ptr<SkLatticeIter> iter, const SkRect& dst,
+ const SkPaint& origPaint) {
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerLattice", fContext.get());
+ SkTCopyOnFirstWrite<SkPaint> paint(&origPaint);
- static const GrSamplerState::Filter kMode = GrSamplerState::Filter::kNearest;
- std::unique_ptr<GrFragmentProcessor> fp(producer->createFragmentProcessor(
- SkMatrix::I(), SkRect::MakeIWH(producer->width(), producer->height()),
- GrTextureProducer::kNo_FilterConstraint, true, &kMode,
- fRenderTargetContext->colorSpaceInfo().colorSpace()));
- if (!fp) {
+ bool useFallback = paint->getMaskFilter() || paint->isAntiAlias() ||
+ GrFSAAType::kUnifiedMSAA == fRenderTargetContext->fsaaType();
+ if (useFallback) {
+ SkRect srcR, dstR;
+ while (iter->next(&srcR, &dstR)) {
+ this->drawTextureProducer(producer, &srcR, &dstR, SkCanvas::kStrict_SrcRectConstraint,
+ this->ctm(), *paint);
+ }
return;
}
+
+ if (!producer->isAlphaOnly() && (paint->getColor() & 0x00FFFFFF) != 0x00FFFFFF) {
+ paint.writable()->setColor(SkColorSetARGB(origPaint.getAlpha(), 0xFF, 0xFF, 0xFF));
+ }
GrPaint grPaint;
- if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext->colorSpaceInfo(), paint,
- this->ctm(), std::move(fp), producer->isAlphaOnly(),
- &grPaint)) {
+ if (!SkPaintToGrPaintWithPrimitiveColor(this->context(), fRenderTargetContext->colorSpaceInfo(),
+ *paint, &grPaint)) {
return;
}
- std::unique_ptr<SkLatticeIter> iter(
- new SkLatticeIter(lattice, dst));
+ auto dstColorSpace = fRenderTargetContext->colorSpaceInfo().colorSpace();
+ const GrSamplerState::Filter filter = compute_lattice_filter_mode(*paint);
+ sk_sp<SkColorSpace> proxyColorSpace;
+ auto proxy =
+ producer->refTextureProxyForParams(filter, dstColorSpace, &proxyColorSpace, nullptr);
+ auto csxf = GrColorSpaceXform::Make(proxyColorSpace.get(), proxy->config(), dstColorSpace);
+
fRenderTargetContext->drawImageLattice(this->clip(), std::move(grPaint), this->ctm(),
- producer->width(), producer->height(), std::move(iter),
- dst);
+ std::move(proxy), std::move(csxf), filter,
+ std::move(iter), dst);
}
void SkGpuDevice::drawImageLattice(const SkImage* image,
@@ -1455,19 +1437,21 @@ void SkGpuDevice::drawImageLattice(const SkImage* image,
const SkPaint& paint) {
ASSERT_SINGLE_OWNER
uint32_t pinnedUniqueID;
+ auto iter = skstd::make_unique<SkLatticeIter>(lattice, dst);
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->refPinnedTextureProxy(&pinnedUniqueID)) {
GrTextureAdjuster adjuster(this->context(), std::move(proxy),
image->alphaType(), pinnedUniqueID,
as_IB(image)->onImageInfo().colorSpace());
- this->drawProducerLattice(&adjuster, lattice, dst, paint);
+ this->drawProducerLattice(&adjuster, std::move(iter), dst, paint);
} else {
SkBitmap bm;
if (image->isLazyGenerated()) {
GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint);
- this->drawProducerLattice(&maker, lattice, dst, paint);
+ this->drawProducerLattice(&maker, std::move(iter), dst, paint);
} else if (as_IB(image)->getROPixels(&bm,
fRenderTargetContext->colorSpaceInfo().colorSpace())) {
- this->drawBitmapLattice(bm, lattice, dst, paint);
+ GrBitmapTextureMaker maker(fContext.get(), bm);
+ this->drawProducerLattice(&maker, std::move(iter), dst, paint);
}
}
}
@@ -1476,8 +1460,9 @@ void SkGpuDevice::drawBitmapLattice(const SkBitmap& bitmap,
const SkCanvas::Lattice& lattice, const SkRect& dst,
const SkPaint& paint) {
ASSERT_SINGLE_OWNER
+ auto iter = skstd::make_unique<SkLatticeIter>(lattice, dst);
GrBitmapTextureMaker maker(fContext.get(), bitmap);
- this->drawProducerLattice(&maker, lattice, dst, paint);
+ this->drawProducerLattice(&maker, std::move(iter), dst, paint);
}
static bool init_vertices_paint(GrContext* context, const GrColorSpaceInfo& colorSpaceInfo,
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index da691a3da3..6a3f22d6e7 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -241,16 +241,9 @@ private:
const SkMatrix& srcToDstMatrix,
const SkPaint&);
- bool drawFilledDRRect(const SkMatrix& viewMatrix, const SkRRect& outer,
- const SkRRect& inner, const SkPaint& paint);
-
- void drawProducerNine(GrTextureProducer*, const SkIRect& center,
- const SkRect& dst, const SkPaint&);
-
- void drawProducerLattice(GrTextureProducer*, const SkCanvas::Lattice& lattice,
- const SkRect& dst, const SkPaint&);
+ void drawProducerLattice(GrTextureProducer*, std::unique_ptr<SkLatticeIter>, const SkRect& dst,
+ const SkPaint&);
- bool drawDashLine(const SkPoint pts[2], const SkPaint& paint);
void drawStrokedLine(const SkPoint pts[2], const SkPaint&);
void wireframeVertices(SkVertices::VertexMode, int vertexCount, const SkPoint verts[],
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 45081a02fd..79cbf9dd41 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -17,15 +17,104 @@
#include "SkMatrixPriv.h"
#include "SkPointPriv.h"
#include "SkRect.h"
-
-static sk_sp<GrGeometryProcessor> create_gp() {
- using namespace GrDefaultGeoProcFactory;
- return GrDefaultGeoProcFactory::Make(Color::kPremulGrColorAttribute_Type, Coverage::kSolid_Type,
- LocalCoords::kHasExplicit_Type, SkMatrix::I());
-}
+#include "glsl/GrGLSLColorSpaceXformHelper.h"
+#include "glsl/GrGLSLGeometryProcessor.h"
+#include "glsl/GrGLSLVarying.h"
namespace {
+class LatticeGP : public GrGeometryProcessor {
+public:
+ struct Vertex {
+ SkPoint fPosition;
+ SkPoint fTextureCoords;
+ SkRect fTextureDomain;
+ GrColor fColor;
+ };
+
+ static sk_sp<GrGeometryProcessor> Make(sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> csxf,
+ GrSamplerState::Filter filter) {
+ return sk_sp<GrGeometryProcessor>(new LatticeGP(std::move(proxy), std::move(csxf), filter));
+ }
+
+ const char* name() const override { return "LatticeGP"; }
+
+ void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
+ b->add32(GrColorSpaceXform::XformKey(fColorSpaceXform.get()));
+ }
+
+ GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override {
+ class GLSLProcessor : public GrGLSLGeometryProcessor {
+ public:
+ void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
+ FPCoordTransformIter&& transformIter) override {
+ const auto& latticeGP = proc.cast<LatticeGP>();
+ this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
+ if (fColorSpaceXformHelper.isValid()) {
+ fColorSpaceXformHelper.setData(pdman, latticeGP.fColorSpaceXform.get());
+ }
+ }
+
+ private:
+ void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
+ using Interpolation = GrGLSLVaryingHandler::Interpolation;
+ const auto& latticeGP = args.fGP.cast<LatticeGP>();
+ fColorSpaceXformHelper.emitCode(args.fUniformHandler,
+ latticeGP.fColorSpaceXform.get());
+
+ args.fVaryingHandler->emitAttributes(latticeGP);
+ this->writeOutputPosition(args.fVertBuilder, gpArgs, latticeGP.fPositions.fName);
+ this->emitTransforms(args.fVertBuilder,
+ args.fVaryingHandler,
+ args.fUniformHandler,
+ latticeGP.fTextureCoords.asShaderVar(),
+ args.fFPCoordTransformHandler);
+ args.fFragBuilder->codeAppend("float2 textureCoords;");
+ args.fVaryingHandler->addPassThroughAttribute(&latticeGP.fTextureCoords,
+ "textureCoords");
+ args.fFragBuilder->codeAppend("float4 textureDomain;");
+ args.fVaryingHandler->addPassThroughAttribute(
+ &latticeGP.fTextureDomain, "textureDomain", Interpolation::kCanBeFlat);
+ args.fVaryingHandler->addPassThroughAttribute(&latticeGP.fColors, args.fOutputColor,
+ Interpolation::kCanBeFlat);
+ args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor);
+ args.fFragBuilder->appendTextureLookupAndModulate(
+ args.fOutputColor,
+ args.fTexSamplers[0],
+ "clamp(textureCoords, textureDomain.xy, textureDomain.zw)",
+ kFloat2_GrSLType,
+ &fColorSpaceXformHelper);
+ args.fFragBuilder->codeAppend(";");
+ args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
+ }
+ GrGLSLColorSpaceXformHelper fColorSpaceXformHelper;
+ };
+ return new GLSLProcessor;
+ }
+
+private:
+ LatticeGP(sk_sp<GrTextureProxy> proxy, sk_sp<GrColorSpaceXform> csxf,
+ GrSamplerState::Filter filter)
+ : INHERITED(kLatticeGP_ClassID), fColorSpaceXform(std::move(csxf)) {
+ fPositions = this->addVertexAttrib("position", kFloat2_GrVertexAttribType);
+ fSampler.reset(std::move(proxy), filter);
+ this->addTextureSampler(&fSampler);
+ fTextureCoords = this->addVertexAttrib("textureCoords", kFloat2_GrVertexAttribType);
+ fTextureDomain = this->addVertexAttrib("textureDomain", kFloat4_GrVertexAttribType);
+ fColors = this->addVertexAttrib("color", kUByte4_norm_GrVertexAttribType);
+ }
+
+ Attribute fPositions;
+ Attribute fTextureCoords;
+ Attribute fTextureDomain;
+ Attribute fColors;
+ sk_sp<GrColorSpaceXform> fColorSpaceXform;
+ TextureSampler fSampler;
+
+ typedef GrGeometryProcessor INHERITED;
+};
+
class NonAALatticeOp final : public GrMeshDrawOp {
private:
using Helper = GrSimpleMeshDrawOpHelper;
@@ -37,25 +126,30 @@ public:
static const int kIndicesPerRect = 6;
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
- int imageWidth, int imageHeight,
+ sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXForm,
+ GrSamplerState::Filter filter,
std::unique_ptr<SkLatticeIter> iter, const SkRect& dst) {
- return Helper::FactoryHelper<NonAALatticeOp>(std::move(paint), viewMatrix, imageWidth,
- imageHeight, std::move(iter), dst);
+ return Helper::FactoryHelper<NonAALatticeOp>(std::move(paint), viewMatrix, std::move(proxy),
+ std::move(colorSpaceXForm), filter,
+ std::move(iter), dst);
}
NonAALatticeOp(Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
- int imageWidth, int imageHeight, std::unique_ptr<SkLatticeIter> iter,
+ sk_sp<GrTextureProxy> proxy, sk_sp<GrColorSpaceXform> colorSpaceXform,
+ GrSamplerState::Filter filter, std::unique_ptr<SkLatticeIter> iter,
const SkRect& dst)
- : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kNone) {
+ : INHERITED(ClassID())
+ , fHelper(helperArgs, GrAAType::kNone)
+ , fProxy(std::move(proxy))
+ , fColorSpaceXform(std::move(colorSpaceXform))
+ , fFilter(filter) {
Patch& patch = fPatches.push_back();
patch.fViewMatrix = viewMatrix;
patch.fColor = color;
patch.fIter = std::move(iter);
patch.fDst = dst;
- fImageWidth = imageWidth;
- fImageHeight = imageHeight;
-
// setup bounds
this->setTransformedBounds(patch.fDst, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
@@ -84,14 +178,19 @@ public:
RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip,
GrPixelConfigIsClamped dstIsClamped) override {
- return fHelper.xpRequiresDstTexture(caps, clip, dstIsClamped,
- GrProcessorAnalysisCoverage::kNone,
- &fPatches.front().fColor);
+ auto opaque = GrColorIsOpaque(fPatches[0].fColor) && GrPixelConfigIsOpaque(fProxy->config())
+ ? GrProcessorAnalysisColor::Opaque::kYes
+ : GrProcessorAnalysisColor::Opaque::kNo;
+ auto analysisColor = GrProcessorAnalysisColor(opaque);
+ auto result = fHelper.xpRequiresDstTexture(
+ caps, clip, dstIsClamped, GrProcessorAnalysisCoverage::kNone, &analysisColor);
+ analysisColor.isConstant(&fPatches[0].fColor);
+ return result;
}
private:
void onPrepareDraws(Target* target) override {
- sk_sp<GrGeometryProcessor> gp(create_gp());
+ auto gp = LatticeGP::Make(fProxy, fColorSpaceXform, fFilter);
if (!gp) {
SkDebugf("Couldn't create GrGeometryProcessor\n");
return;
@@ -128,24 +227,35 @@ private:
patch.fIter->mapDstScaleTranslate(patch.fViewMatrix);
}
- SkRect srcR, dstR;
+ SkIRect srcR;
+ SkRect dstR;
intptr_t patchVerts = verts;
+ Sk4f scales(1.f / fProxy->width(), 1.f / fProxy->height(),
+ 1.f / fProxy->width(), 1.f / fProxy->height());
+ static const Sk4f kDomainOffsets(0.5f, 0.5f, -0.5f, -0.5f);
+ static const Sk4f kFlipOffsets(0.f, 1, 0.f, 1.f);
+ static const Sk4f kFlipMuls(1.f, -1.f, 1.f, -1.f);
while (patch.fIter->next(&srcR, &dstR)) {
- SkPoint* positions = reinterpret_cast<SkPoint*>(verts);
- SkPointPriv::SetRectTriStrip(positions, dstR.fLeft, dstR.fTop, dstR.fRight,
- dstR.fBottom, vertexStride);
-
- // Setup local coords
- static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
- SkPoint* coords = reinterpret_cast<SkPoint*>(verts + kLocalOffset);
- SkPointPriv::SetRectTriStrip(coords, srcR.fLeft, srcR.fTop, srcR.fRight,
- srcR.fBottom, vertexStride);
-
- static const int kColorOffset = sizeof(SkPoint);
- GrColor* vertColor = reinterpret_cast<GrColor*>(verts + kColorOffset);
- for (int j = 0; j < 4; ++j) {
- *vertColor = patch.fColor;
- vertColor = (GrColor*)((intptr_t)vertColor + vertexStride);
+ auto vertices = reinterpret_cast<LatticeGP::Vertex*>(verts);
+ SkPointPriv::SetRectTriStrip(&vertices->fPosition, dstR.fLeft, dstR.fTop,
+ dstR.fRight, dstR.fBottom, vertexStride);
+ Sk4f coords(SkIntToScalar(srcR.fLeft), SkIntToScalar(srcR.fTop),
+ SkIntToScalar(srcR.fRight), SkIntToScalar(srcR.fBottom));
+ Sk4f domain = coords + kDomainOffsets;
+ coords *= scales;
+ domain *= scales;
+ if (fProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
+ coords = kFlipMuls * coords + kFlipOffsets;
+ domain = SkNx_shuffle<0, 3, 2, 1>(kFlipMuls * domain + kFlipOffsets);
+ }
+ SkPointPriv::SetRectTriStrip(&vertices->fTextureCoords, coords[0], coords[1],
+ coords[2], coords[3], vertexStride);
+ for (int j = 0; j < kVertsPerRect; ++j) {
+ vertices[j].fTextureDomain = {domain[0], domain[1], domain[2], domain[3]};
+ }
+
+ for (int j = 0; j < kVertsPerRect; ++j) {
+ vertices[j].fColor = patch.fColor;
}
verts += kVertsPerRect * vertexStride;
}
@@ -162,13 +272,19 @@ private:
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
NonAALatticeOp* that = t->cast<NonAALatticeOp>();
+ if (fProxy != that->fProxy) {
+ return false;
+ }
+ if (fFilter != that->fFilter) {
+ return false;
+ }
+ if (GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get())) {
+ return false;
+ }
if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
return false;
}
- SkASSERT(this->fImageWidth == that->fImageWidth &&
- this->fImageHeight == that->fImageHeight);
-
fPatches.move_back_n(that->fPatches.count(), that->fPatches.begin());
this->joinBounds(*that);
return true;
@@ -183,8 +299,9 @@ private:
Helper fHelper;
SkSTArray<1, Patch, true> fPatches;
- int fImageWidth;
- int fImageHeight;
+ sk_sp<GrTextureProxy> fProxy;
+ sk_sp<GrColorSpaceXform> fColorSpaceXform;
+ GrSamplerState::Filter fFilter;
typedef GrMeshDrawOp INHERITED;
};
@@ -192,15 +309,19 @@ private:
} // anonymous namespace
namespace GrLatticeOp {
-std::unique_ptr<GrDrawOp> MakeNonAA(GrPaint&& paint, const SkMatrix& viewMatrix, int imageWidth,
- int imageHeight, std::unique_ptr<SkLatticeIter> iter,
- const SkRect& dst) {
- return NonAALatticeOp::Make(std::move(paint), viewMatrix, imageWidth, imageHeight,
- std::move(iter), dst);
+std::unique_ptr<GrDrawOp> MakeNonAA(GrPaint&& paint, const SkMatrix& viewMatrix,
+ sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
+ GrSamplerState::Filter filter,
+ std::unique_ptr<SkLatticeIter> iter, const SkRect& dst) {
+ return NonAALatticeOp::Make(std::move(paint), viewMatrix, std::move(proxy),
+ std::move(colorSpaceXform), filter, std::move(iter), dst);
}
};
#if GR_TEST_UTILS
+#include "GrContextPriv.h"
+#include "GrProxyProvider.h"
/** Randomly divides subset into count divs. */
static void init_random_divs(int divs[], int count, int subsetStart, int subsetStop,
@@ -239,7 +360,6 @@ static void init_random_divs(int divs[], int count, int subsetStart, int subsetS
GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) {
SkCanvas::Lattice lattice;
- int imgW, imgH;
// We loop because our random lattice code can produce an invalid lattice in the case where
// there is a single div separator in both x and y and both are aligned with the left and top
// edge of the image subset, respectively.
@@ -248,19 +368,26 @@ GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) {
std::unique_ptr<SkCanvas::Lattice::RectType[]> flags;
std::unique_ptr<SkColor[]> colors;
SkIRect subset;
+ GrSurfaceDesc desc;
+ desc.fConfig = kRGBA_8888_GrPixelConfig;
+ desc.fWidth = random->nextRangeU(1, 1000);
+ desc.fHeight = random->nextRangeU(1, 1000);
+ desc.fOrigin =
+ random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
+ auto proxy = context->contextPriv().proxyProvider()->createProxy(
+ desc, SkBackingFit::kExact, SkBudgeted::kYes);
+
do {
- imgW = random->nextRangeU(1, 1000);
- imgH = random->nextRangeU(1, 1000);
if (random->nextBool()) {
- subset.fLeft = random->nextULessThan(imgW);
- subset.fRight = random->nextRangeU(subset.fLeft + 1, imgW);
- subset.fTop = random->nextULessThan(imgH);
- subset.fBottom = random->nextRangeU(subset.fTop + 1, imgH);
+ subset.fLeft = random->nextULessThan(desc.fWidth);
+ subset.fRight = random->nextRangeU(subset.fLeft + 1, desc.fWidth);
+ subset.fTop = random->nextULessThan(desc.fHeight);
+ subset.fBottom = random->nextRangeU(subset.fTop + 1, desc.fHeight);
} else {
- subset.setXYWH(0, 0, imgW, imgH);
+ subset.setXYWH(0, 0, desc.fWidth, desc.fHeight);
}
- // SkCanvas::Lattice allows bounds to be null. However, SkCanvas creates a temp Lattice with a
- // non-null bounds before creating a SkLatticeIter since SkLatticeIter requires a bounds.
+ // SkCanvas::Lattice allows bounds to be null. However, SkCanvas creates a temp Lattice with
+ // a non-null bounds before creating a SkLatticeIter since SkLatticeIter requires a bounds.
lattice.fBounds = &subset;
lattice.fXCount = random->nextRangeU(1, subset.width());
lattice.fYCount = random->nextRangeU(1, subset.height());
@@ -285,8 +412,7 @@ GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) {
lattice.fRectTypes = nullptr;
lattice.fColors = nullptr;
}
- } while (!SkLatticeIter::Valid(imgW, imgH, lattice));
-
+ } while (!SkLatticeIter::Valid(desc.fWidth, desc.fHeight, lattice));
SkRect dst;
dst.fLeft = random->nextRangeScalar(-2000.5f, 1000.f);
dst.fTop = random->nextRangeScalar(-2000.5f, 1000.f);
@@ -294,7 +420,11 @@ GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) {
dst.fBottom = dst.fTop + random->nextRangeScalar(0.5f, 1000.f);
std::unique_ptr<SkLatticeIter> iter(new SkLatticeIter(lattice, dst));
SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random);
- return NonAALatticeOp::Make(std::move(paint), viewMatrix, imgW, imgH, std::move(iter), dst);
+ auto csxf = GrTest::TestColorXform(random);
+ GrSamplerState::Filter filter =
+ random->nextBool() ? GrSamplerState::Filter::kNearest : GrSamplerState::Filter::kBilerp;
+ return NonAALatticeOp::Make(std::move(paint), viewMatrix, std::move(proxy), std::move(csxf),
+ filter, std::move(iter), dst);
}
#endif
diff --git a/src/gpu/ops/GrLatticeOp.h b/src/gpu/ops/GrLatticeOp.h
index cce8f322d8..ab3b8ea733 100644
--- a/src/gpu/ops/GrLatticeOp.h
+++ b/src/gpu/ops/GrLatticeOp.h
@@ -9,18 +9,21 @@
#define GLatticeOp_DEFINED
#include <memory>
-#include "GrTypes.h"
+#include "GrSamplerState.h"
+#include "SkRefCnt.h"
class GrDrawOp;
class GrPaint;
class SkLatticeIter;
+class GrTextureProxy;
+class GrColorSpaceXform;
class SkMatrix;
struct SkRect;
namespace GrLatticeOp {
-std::unique_ptr<GrDrawOp> MakeNonAA(GrPaint&& paint, const SkMatrix& viewMatrix, int imageWidth,
- int imageHeight, std::unique_ptr<SkLatticeIter> iter,
- const SkRect& dst);
+std::unique_ptr<GrDrawOp> MakeNonAA(GrPaint&&, const SkMatrix& viewMatrix, sk_sp<GrTextureProxy>,
+ sk_sp<GrColorSpaceXform>, GrSamplerState::Filter,
+ std::unique_ptr<SkLatticeIter>, const SkRect& dst);
};
#endif
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index ad89e926f8..69f2d39e48 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -123,13 +123,9 @@ sk_sp<GrTextureProxy> SkImage_Gpu::asTextureProxyRef(GrContext* context,
return nullptr;
}
- if (texColorSpace) {
- *texColorSpace = this->fColorSpace;
- }
-
GrTextureAdjuster adjuster(fContext, fProxy, this->alphaType(), this->uniqueID(),
this->fColorSpace.get());
- return adjuster.refTextureProxySafeForParams(params, scaleAdjust);
+ return adjuster.refTextureProxyForParams(params, dstColorSpace, texColorSpace, scaleAdjust);
}
static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index a92b751140..9d7e3b1c2b 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -178,16 +178,12 @@ sk_sp<GrTextureProxy> SkImage_Raster::asTextureProxyRef(GrContext* context,
return nullptr;
}
- if (texColorSpace) {
- *texColorSpace = sk_ref_sp(fBitmap.colorSpace());
- }
-
uint32_t uniqueID;
sk_sp<GrTextureProxy> tex = this->refPinnedTextureProxy(&uniqueID);
if (tex) {
GrTextureAdjuster adjuster(context, fPinnedProxy, fBitmap.alphaType(), fPinnedUniqueID,
fBitmap.colorSpace());
- return adjuster.refTextureProxySafeForParams(params, scaleAdjust);
+ return adjuster.refTextureProxyForParams(params, dstColorSpace, texColorSpace, scaleAdjust);
}
return GrRefCachedBitmapTextureProxy(context, fBitmap, params, scaleAdjust);