Revert "Use unnormalized coords all the way through with GL_TEXTURE_RECTANGLE textures."
This reverts commit 10273c1d5f
.
Reason for revert: bad gms
Original change's description:
> Use unnormalized coords all the way through with GL_TEXTURE_RECTANGLE textures.
>
> We used to unnormalize them in the shader via SkSL.
>
> This allows us to support GL_TEXTURE_RECTANGLE without having textureSize()
> available in GLSL.
>
> Change-Id: Ibe63a302228811933ef000251db4cad9aaf4f2ea
> Reviewed-on: https://skia-review.googlesource.com/c/174068
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>
TBR=bsalomon@google.com,brianosman@google.com
Change-Id: I9bf38e1040578becba28ac8cccd81e2af2844278
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/175252
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
69e5785d9f
commit
47be94abd1
@ -30,7 +30,9 @@ protected:
|
||||
return SkString("rectangle_texture");
|
||||
}
|
||||
|
||||
SkISize onISize() override { return SkISize::Make(1200, 500); }
|
||||
SkISize onISize() override {
|
||||
return SkISize::Make(1035, 240);
|
||||
}
|
||||
|
||||
void fillPixels(int width, int height, void *pixels) {
|
||||
SkBitmap bmp;
|
||||
@ -44,7 +46,7 @@ protected:
|
||||
SkShader::kClamp_TileMode));
|
||||
canvas.drawPaint(paint);
|
||||
|
||||
SkColor colors1[] = {0xFFA07010, 0xFFA02080};
|
||||
SkColor colors1[] = { 0xFFA07010 , 0xFFA02080 };
|
||||
paint.setAntiAlias(true);
|
||||
paint.setShader(SkGradientShader::MakeLinear(pts, colors1, nullptr, 2,
|
||||
SkShader::kClamp_TileMode));
|
||||
@ -52,8 +54,8 @@ protected:
|
||||
SkIntToScalar(width + height) / 5, paint);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> createRectangleTextureImg(GrContext* context, GrSurfaceOrigin origin, int width,
|
||||
int height, const uint32_t* pixels) {
|
||||
sk_sp<SkImage> createRectangleTextureImg(GrContext* context, int width, int height,
|
||||
void* pixels) {
|
||||
if (!context) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -86,36 +88,34 @@ protected:
|
||||
}
|
||||
|
||||
const GrGLInterface* gl = glCtx->interface();
|
||||
// Useful for debugging whether errors result from use of RECTANGLE
|
||||
// static constexpr GrGLenum kTarget = GR_GL_TEXTURE_2D;
|
||||
static constexpr GrGLenum kTarget = GR_GL_TEXTURE_RECTANGLE;
|
||||
// Useful for debugging whether errors result from use of RECTANGLE
|
||||
// #define TARGET GR_GL_TEXTURE_2D
|
||||
#define TARGET GR_GL_TEXTURE_RECTANGLE
|
||||
GrGLuint id = 0;
|
||||
GR_GL_CALL(gl, GenTextures(1, &id));
|
||||
GR_GL_CALL(gl, BindTexture(kTarget, id));
|
||||
GR_GL_CALL(gl, TexParameteri(kTarget, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
|
||||
GR_GL_CALL(gl, TexParameteri(kTarget, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
|
||||
GR_GL_CALL(gl, TexParameteri(kTarget, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
|
||||
GR_GL_CALL(gl, TexParameteri(kTarget, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
|
||||
std::unique_ptr<uint32_t[]> tempPixels;
|
||||
if (origin == kBottomLeft_GrSurfaceOrigin) {
|
||||
tempPixels.reset(new uint32_t[width * height]);
|
||||
for (int y = 0; y < height; ++y) {
|
||||
std::copy_n(pixels + width * (height - y - 1), width, tempPixels.get() + width * y);
|
||||
}
|
||||
pixels = tempPixels.get();
|
||||
}
|
||||
GR_GL_CALL(gl, TexImage2D(kTarget, 0, GR_GL_RGBA, width, height, 0, format,
|
||||
GR_GL_UNSIGNED_BYTE, pixels));
|
||||
GR_GL_CALL(gl, BindTexture(TARGET, id));
|
||||
GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_MAG_FILTER,
|
||||
GR_GL_NEAREST));
|
||||
GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_MIN_FILTER,
|
||||
GR_GL_NEAREST));
|
||||
GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_WRAP_S,
|
||||
GR_GL_CLAMP_TO_EDGE));
|
||||
GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_WRAP_T,
|
||||
GR_GL_CLAMP_TO_EDGE));
|
||||
GR_GL_CALL(gl, TexImage2D(TARGET, 0, GR_GL_RGBA, width, height, 0,
|
||||
format, GR_GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
|
||||
context->resetContext();
|
||||
GrGLTextureInfo info;
|
||||
info.fID = id;
|
||||
info.fTarget = kTarget;
|
||||
info.fTarget = TARGET;
|
||||
info.fFormat = GR_GL_RGBA8;
|
||||
|
||||
GrBackendTexture rectangleTex(width, height, GrMipMapped::kNo, info);
|
||||
|
||||
if (sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture(context, rectangleTex, origin,
|
||||
if (sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture(context, rectangleTex,
|
||||
kTopLeft_GrSurfaceOrigin,
|
||||
kRGBA_8888_SkColorType)) {
|
||||
return image;
|
||||
}
|
||||
@ -136,15 +136,9 @@ protected:
|
||||
|
||||
SkPMColor pixels[kWidth * kHeight];
|
||||
this->fillPixels(kWidth, kHeight, pixels);
|
||||
sk_sp<SkImage> rectImg(this->createRectangleTextureImg(context, kWidth, kHeight, pixels));
|
||||
|
||||
sk_sp<SkImage> rectImgs[] = {
|
||||
this->createRectangleTextureImg(context, kTopLeft_GrSurfaceOrigin, kWidth, kHeight,
|
||||
pixels),
|
||||
this->createRectangleTextureImg(context, kBottomLeft_GrSurfaceOrigin, kWidth,
|
||||
kHeight, pixels),
|
||||
};
|
||||
SkASSERT(SkToBool(rectImgs[0]) == SkToBool(rectImgs[1]));
|
||||
if (!rectImgs[0]) {
|
||||
if (!rectImg) {
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
const char* kMsg = "Could not create rectangle texture image.";
|
||||
@ -153,56 +147,39 @@ protected:
|
||||
}
|
||||
|
||||
constexpr SkFilterQuality kQualities[] = {
|
||||
kNone_SkFilterQuality,
|
||||
kLow_SkFilterQuality,
|
||||
kMedium_SkFilterQuality,
|
||||
kHigh_SkFilterQuality,
|
||||
kNone_SkFilterQuality,
|
||||
kLow_SkFilterQuality,
|
||||
kMedium_SkFilterQuality,
|
||||
kHigh_SkFilterQuality,
|
||||
};
|
||||
|
||||
constexpr SkScalar kScales[] = {1.0f, 1.2f, 0.75f};
|
||||
constexpr SkScalar kScales[] = { 1.0f, 1.2f, 0.75f };
|
||||
|
||||
canvas->translate(kPad, kPad);
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(rectImgs); ++i) {
|
||||
for (auto s : kScales) {
|
||||
canvas->save();
|
||||
canvas->scale(s, s);
|
||||
for (auto q : kQualities) {
|
||||
// drawImage
|
||||
SkPaint plainPaint;
|
||||
plainPaint.setFilterQuality(q);
|
||||
canvas->drawImage(rectImgs[i], 0, 0, &plainPaint);
|
||||
canvas->translate(kWidth + kPad, 0);
|
||||
for (auto s : kScales) {
|
||||
canvas->save();
|
||||
canvas->scale(s, s);
|
||||
for (auto q : kQualities) {
|
||||
SkPaint plainPaint;
|
||||
plainPaint.setFilterQuality(q);
|
||||
canvas->drawImage(rectImg.get(), 0, 0, &plainPaint);
|
||||
canvas->translate(kWidth + kPad, 0);
|
||||
|
||||
// clamp/clamp shader
|
||||
SkPaint clampPaint;
|
||||
clampPaint.setFilterQuality(q);
|
||||
clampPaint.setShader(rectImgs[i]->makeShader());
|
||||
canvas->drawRect(SkRect::MakeWH(1.5f * kWidth, 1.5f * kHeight), clampPaint);
|
||||
canvas->translate(kWidth * 1.5f + kPad, 0);
|
||||
SkPaint clampPaint;
|
||||
clampPaint.setFilterQuality(q);
|
||||
clampPaint.setShader(rectImg->makeShader());
|
||||
canvas->drawRect(SkRect::MakeWH(1.5f * kWidth, 1.5f * kHeight), clampPaint);
|
||||
canvas->translate(kWidth * 1.5f + kPad, 0);
|
||||
|
||||
// repeat/mirror shader
|
||||
SkPaint repeatPaint;
|
||||
repeatPaint.setFilterQuality(q);
|
||||
repeatPaint.setShader(rectImgs[i]->makeShader(SkShader::kRepeat_TileMode,
|
||||
SkShader::kMirror_TileMode));
|
||||
canvas->drawRect(SkRect::MakeWH(1.5f * kWidth, 1.5f * kHeight), repeatPaint);
|
||||
canvas->translate(1.5f * kWidth + kPad, 0);
|
||||
|
||||
// drawImageRect with kStrict
|
||||
auto srcRect = SkRect::MakeXYWH(.25f * rectImgs[i]->width(),
|
||||
.25f * rectImgs[i]->height(),
|
||||
.50f * rectImgs[i]->width(),
|
||||
.50f * rectImgs[i]->height());
|
||||
auto dstRect = SkRect::MakeXYWH(0, 0,
|
||||
.50f * rectImgs[i]->width(),
|
||||
.50f * rectImgs[i]->height());
|
||||
canvas->drawImageRect(rectImgs[i], srcRect, dstRect, &plainPaint,
|
||||
SkCanvas::kStrict_SrcRectConstraint);
|
||||
canvas->translate(kWidth * .5f + kPad, 0);
|
||||
}
|
||||
canvas->restore();
|
||||
canvas->translate(0, kPad + 1.5f * kHeight * s);
|
||||
SkPaint repeatPaint;
|
||||
repeatPaint.setFilterQuality(q);
|
||||
repeatPaint.setShader(rectImg->makeShader(SkShader::kRepeat_TileMode,
|
||||
SkShader::kMirror_TileMode));
|
||||
canvas->drawRect(SkRect::MakeWH(1.5f * kWidth, 1.5f * kHeight), repeatPaint);
|
||||
canvas->translate(1.5f * kWidth + kPad, 0);
|
||||
}
|
||||
canvas->restore();
|
||||
canvas->translate(0, kPad + 1.5f * kHeight * s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,6 @@ enum GrSLType {
|
||||
*/
|
||||
enum class GrTextureType {
|
||||
k2D,
|
||||
/* Rectangle uses unnormalized texture coordinates. */
|
||||
kRectangle,
|
||||
kExternal
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
GrCoordTransform(GrTextureProxy* proxy) {
|
||||
SkASSERT(proxy);
|
||||
SkDEBUGCODE(fInProcessor = false);
|
||||
this->reset(SkMatrix::I(), proxy);
|
||||
this->reset(SkMatrix::I(), proxy, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,7 +46,7 @@ public:
|
||||
GrCoordTransform(const SkMatrix& m, GrTextureProxy* proxy) {
|
||||
SkASSERT(proxy);
|
||||
SkDEBUGCODE(fInProcessor = false);
|
||||
this->reset(m, proxy);
|
||||
this->reset(m, proxy, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,6 +57,24 @@ public:
|
||||
this->reset(m);
|
||||
}
|
||||
|
||||
void reset(const SkMatrix& m, GrTextureProxy* proxy, bool normalize) {
|
||||
SkASSERT(proxy);
|
||||
SkASSERT(!fInProcessor);
|
||||
|
||||
fMatrix = m;
|
||||
fProxy = proxy;
|
||||
fNormalize = normalize;
|
||||
fReverseY = kBottomLeft_GrSurfaceOrigin == proxy->origin();
|
||||
}
|
||||
|
||||
void reset(const SkMatrix& m) {
|
||||
SkASSERT(!fInProcessor);
|
||||
fMatrix = m;
|
||||
fProxy = nullptr;
|
||||
fNormalize = false;
|
||||
fReverseY = false;
|
||||
}
|
||||
|
||||
GrCoordTransform& operator= (const GrCoordTransform& that) {
|
||||
SkASSERT(!fInProcessor);
|
||||
fMatrix = that.fMatrix;
|
||||
@ -101,15 +119,6 @@ public:
|
||||
GrTexture* peekTexture() const { return fProxy->peekTexture(); }
|
||||
|
||||
private:
|
||||
void reset(const SkMatrix& m, GrTextureProxy* proxy = nullptr) {
|
||||
SkASSERT(!fInProcessor);
|
||||
|
||||
fMatrix = m;
|
||||
fProxy = proxy;
|
||||
fNormalize = proxy && proxy->textureType() != GrTextureType::kRectangle;
|
||||
fReverseY = proxy && kBottomLeft_GrSurfaceOrigin == proxy->origin();
|
||||
}
|
||||
|
||||
// The textures' effect is to optionally normalize the final matrix, so a blind
|
||||
// equality check could be misleading
|
||||
bool operator==(const GrCoordTransform& that) const;
|
||||
|
@ -165,15 +165,8 @@ void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman,
|
||||
GrTexture* tex = proxy->peekTexture();
|
||||
SkASSERT(fHasMode && textureDomain.mode() == fMode);
|
||||
if (kIgnore_Mode != textureDomain.mode()) {
|
||||
SkScalar wInv, hInv, h;
|
||||
if (proxy->textureType() == GrTextureType::kRectangle) {
|
||||
wInv = hInv = 1.f;
|
||||
h = tex->height();
|
||||
} else {
|
||||
wInv = SK_Scalar1 / tex->width();
|
||||
hInv = SK_Scalar1 / tex->height();
|
||||
h = 1.f;
|
||||
}
|
||||
SkScalar wInv = SK_Scalar1 / tex->width();
|
||||
SkScalar hInv = SK_Scalar1 / tex->height();
|
||||
|
||||
float values[kPrevDomainCount] = {
|
||||
SkScalarToFloat(textureDomain.domain().fLeft * wInv),
|
||||
@ -182,23 +175,15 @@ void GrTextureDomain::GLDomain::setData(const GrGLSLProgramDataManager& pdman,
|
||||
SkScalarToFloat(textureDomain.domain().fBottom * hInv)
|
||||
};
|
||||
|
||||
if (proxy->textureType() == GrTextureType::kRectangle) {
|
||||
SkASSERT(values[0] >= 0.0f && values[0] <= proxy->height());
|
||||
SkASSERT(values[1] >= 0.0f && values[1] <= proxy->height());
|
||||
SkASSERT(values[2] >= 0.0f && values[2] <= proxy->height());
|
||||
SkASSERT(values[3] >= 0.0f && values[3] <= proxy->height());
|
||||
} else {
|
||||
SkASSERT(values[0] >= 0.0f && values[0] <= 1.0f);
|
||||
SkASSERT(values[1] >= 0.0f && values[1] <= 1.0f);
|
||||
SkASSERT(values[2] >= 0.0f && values[2] <= 1.0f);
|
||||
SkASSERT(values[3] >= 0.0f && values[3] <= 1.0f);
|
||||
}
|
||||
SkASSERT(values[0] >= 0.0f && values[0] <= 1.0f);
|
||||
SkASSERT(values[1] >= 0.0f && values[1] <= 1.0f);
|
||||
SkASSERT(values[2] >= 0.0f && values[2] <= 1.0f);
|
||||
SkASSERT(values[3] >= 0.0f && values[3] <= 1.0f);
|
||||
|
||||
// vertical flip if necessary
|
||||
if (kBottomLeft_GrSurfaceOrigin == proxy->origin()) {
|
||||
values[1] = h - values[1];
|
||||
values[3] = h - values[3];
|
||||
|
||||
values[1] = 1.0f - values[1];
|
||||
values[3] = 1.0f - values[3];
|
||||
// The top and bottom were just flipped, so correct the ordering
|
||||
// of elements so that values = (l, t, r, b).
|
||||
using std::swap;
|
||||
|
@ -42,8 +42,7 @@ private:
|
||||
fSamplers[i].reset(std::move(proxies[i]),
|
||||
GrSamplerState(GrSamplerState::WrapMode::kClamp, filterModes[i]));
|
||||
fSamplerTransforms[i] = SkMatrix::MakeScale(scales[i].width(), scales[i].height());
|
||||
fSamplerCoordTransforms[i] =
|
||||
GrCoordTransform(fSamplerTransforms[i], fSamplers[i].proxy());
|
||||
fSamplerCoordTransforms[i].reset(fSamplerTransforms[i], fSamplers[i].proxy(), true);
|
||||
}
|
||||
|
||||
this->setTextureSamplerCnt(numPlanes);
|
||||
|
@ -227,7 +227,11 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
if (version >= GR_GL_VER(3, 1) || ctxInfo.hasExtension("GL_ARB_texture_rectangle") ||
|
||||
ctxInfo.hasExtension("GL_ANGLE_texture_rectangle")) {
|
||||
fRectangleTextureSupport = true;
|
||||
// We also require textureSize() support for rectangle 2D samplers which was added in
|
||||
// GLSL 1.40.
|
||||
if (ctxInfo.glslGeneration() >= k140_GrGLSLGeneration) {
|
||||
fRectangleTextureSupport = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Command buffer exposes this in GL ES context for Chromium reasons,
|
||||
|
@ -3741,13 +3741,11 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
|
||||
sy0 = sh - sy0;
|
||||
sy1 = sh - sy1;
|
||||
}
|
||||
if (srcTex->texturePriv().textureType() != GrTextureType::kRectangle) {
|
||||
// src rect edges in normalized texture space (0 to 1)
|
||||
sx0 /= sw;
|
||||
sx1 /= sw;
|
||||
sy0 /= sh;
|
||||
sy1 /= sh;
|
||||
}
|
||||
// src rect edges in normalized texture space (0 to 1)
|
||||
sx0 /= sw;
|
||||
sx1 /= sw;
|
||||
sy0 /= sh;
|
||||
sy1 /= sh;
|
||||
|
||||
GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
|
||||
GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform,
|
||||
|
@ -24,26 +24,14 @@ SkMatrix GrGLSLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatri
|
||||
}
|
||||
|
||||
if (coordTransform.reverseY()) {
|
||||
if (coordTransform.normalize()) {
|
||||
// combined.postScale(1,-1);
|
||||
// combined.postTranslate(0,1);
|
||||
combined.set(SkMatrix::kMSkewY,
|
||||
combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
|
||||
combined.set(SkMatrix::kMScaleY,
|
||||
combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
|
||||
combined.set(SkMatrix::kMTransY,
|
||||
combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
|
||||
} else {
|
||||
// combined.postScale(1, -1);
|
||||
// combined.postTranslate(0,1);
|
||||
SkScalar h = coordTransform.peekTexture()->height();
|
||||
combined.set(SkMatrix::kMSkewY,
|
||||
h * combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
|
||||
combined.set(SkMatrix::kMScaleY,
|
||||
h * combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
|
||||
combined.set(SkMatrix::kMTransY,
|
||||
h * combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
|
||||
}
|
||||
// combined.postScale(1,-1);
|
||||
// combined.postTranslate(0,1);
|
||||
combined.set(SkMatrix::kMSkewY,
|
||||
combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
|
||||
combined.set(SkMatrix::kMScaleY,
|
||||
combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
|
||||
combined.set(SkMatrix::kMTransY,
|
||||
combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
|
||||
}
|
||||
return combined;
|
||||
}
|
||||
|
@ -54,11 +54,9 @@ static bool filter_has_effect_for_rect_stays_rect(const GrPerspQuad& quad, const
|
||||
SkScalarFraction(qt) != SkScalarFraction(srcRect.fTop);
|
||||
}
|
||||
|
||||
// if normalizing the domain then pass 1/width, 1/height, 1 for iw, ih, h. Otherwise pass
|
||||
// 1, 1, and height.
|
||||
static SkRect compute_domain(Domain domain, GrSamplerState::Filter filter, GrSurfaceOrigin origin,
|
||||
const SkRect& srcRect, float iw, float ih, float h) {
|
||||
static constexpr SkRect kLargeRect = {-100000, -100000, 1000000, 1000000};
|
||||
static SkRect compute_domain(Domain domain, GrSamplerState::Filter filter,
|
||||
GrSurfaceOrigin origin, const SkRect& srcRect, float iw, float ih) {
|
||||
static constexpr SkRect kLargeRect = {-2, -2, 2, 2};
|
||||
if (domain == Domain::kNo) {
|
||||
// Either the quad has no domain constraint and is batched with a domain constrained op
|
||||
// (in which case we want a domain that doesn't restrict normalized tex coords), or the
|
||||
@ -77,7 +75,7 @@ static SkRect compute_domain(Domain domain, GrSamplerState::Filter filter, GrSur
|
||||
ltrb *= Sk4f(iw, ih, iw, ih);
|
||||
if (origin == kBottomLeft_GrSurfaceOrigin) {
|
||||
static const Sk4f kMul = {1.f, -1.f, 1.f, -1.f};
|
||||
static const Sk4f kAdd = {0.f, h, 0.f, h};
|
||||
static const Sk4f kAdd = {0.f, 1.f, 0.f, 1.f};
|
||||
ltrb = SkNx_shuffle<0, 3, 2, 1>(kMul * ltrb + kAdd);
|
||||
}
|
||||
|
||||
@ -86,10 +84,8 @@ static SkRect compute_domain(Domain domain, GrSamplerState::Filter filter, GrSur
|
||||
return domainRect;
|
||||
}
|
||||
|
||||
// If normalizing the src quad then pass 1/width, 1/height, 1 for iw, ih, h. Otherwise pass
|
||||
// 1, 1, and height.
|
||||
static GrPerspQuad compute_src_quad(GrSurfaceOrigin origin, const SkRect& srcRect, float iw,
|
||||
float ih, float h) {
|
||||
static GrPerspQuad compute_src_quad(GrSurfaceOrigin origin, const SkRect& srcRect,
|
||||
float iw, float ih) {
|
||||
// Convert the pixel-space src rectangle into normalized texture coordinates
|
||||
SkRect texRect = {
|
||||
iw * srcRect.fLeft,
|
||||
@ -98,8 +94,8 @@ static GrPerspQuad compute_src_quad(GrSurfaceOrigin origin, const SkRect& srcRec
|
||||
ih * srcRect.fBottom
|
||||
};
|
||||
if (origin == kBottomLeft_GrSurfaceOrigin) {
|
||||
texRect.fTop = h - texRect.fTop;
|
||||
texRect.fBottom = h - texRect.fBottom;
|
||||
texRect.fTop = 1.f - texRect.fTop;
|
||||
texRect.fBottom = 1.f - texRect.fBottom;
|
||||
}
|
||||
return GrPerspQuad(texRect, SkMatrix::I());
|
||||
}
|
||||
@ -309,21 +305,13 @@ private:
|
||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||
auto origin = proxy->origin();
|
||||
const auto* texture = proxy->peekTexture();
|
||||
float iw, ih, h;
|
||||
if (proxy->textureType() == GrTextureType::kRectangle) {
|
||||
iw = ih = 1.f;
|
||||
h = texture->height();
|
||||
} else {
|
||||
iw = 1.f / texture->width();
|
||||
ih = 1.f / texture->height();
|
||||
h = 1.f;
|
||||
}
|
||||
float iw = 1.f / texture->width();
|
||||
float ih = 1.f / texture->height();
|
||||
|
||||
for (int i = start; i < start + cnt; ++i) {
|
||||
const auto q = fQuads[i];
|
||||
GrPerspQuad srcQuad = compute_src_quad(origin, q.srcRect(), iw, ih, h);
|
||||
SkRect domain =
|
||||
compute_domain(q.domain(), this->filter(), origin, q.srcRect(), iw, ih, h);
|
||||
GrPerspQuad srcQuad = compute_src_quad(origin, q.srcRect(), iw, ih);
|
||||
SkRect domain = compute_domain(q.domain(), this->filter(), origin, q.srcRect(), iw, ih);
|
||||
v = GrQuadPerEdgeAA::Tessellate(v, spec, q.quad(), q.color(), srcQuad, domain,
|
||||
q.aaFlags());
|
||||
}
|
||||
|
@ -768,7 +768,7 @@ private:
|
||||
, fNoiseSampler(std::move(noiseProxy))
|
||||
, fPaintingData(std::move(paintingData)) {
|
||||
this->setTextureSamplerCnt(2);
|
||||
fCoordTransform = GrCoordTransform(matrix);
|
||||
fCoordTransform.reset(matrix);
|
||||
this->addCoordTransform(&fCoordTransform);
|
||||
}
|
||||
|
||||
@ -1191,7 +1191,7 @@ private:
|
||||
, fGradientSampler(std::move(gradientProxy))
|
||||
, fPaintingData(std::move(paintingData)) {
|
||||
this->setTextureSamplerCnt(2);
|
||||
fCoordTransform = GrCoordTransform(matrix);
|
||||
fCoordTransform.reset(matrix);
|
||||
this->addCoordTransform(&fCoordTransform);
|
||||
}
|
||||
|
||||
|
@ -1549,6 +1549,37 @@ std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(
|
||||
std::move(ifFalse)));
|
||||
}
|
||||
|
||||
// scales the texture coordinates by the texture size for sampling rectangle textures.
|
||||
// For float2coordinates, implements the transformation:
|
||||
// texture(sampler, coord) -> texture(sampler, textureSize(sampler) * coord)
|
||||
// For float3coordinates, implements the transformation:
|
||||
// texture(sampler, coord) -> texture(sampler, float3textureSize(sampler), 1.0) * coord))
|
||||
void IRGenerator::fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments) {
|
||||
SkASSERT(arguments.size() == 2);
|
||||
SkASSERT(arguments[0]->fType == *fContext.fSampler2DRect_Type);
|
||||
SkASSERT(arguments[0]->fKind == Expression::kVariableReference_Kind);
|
||||
const Variable& sampler = ((VariableReference&) *arguments[0]).fVariable;
|
||||
const Symbol* textureSizeSymbol = (*fSymbolTable)["textureSize"];
|
||||
SkASSERT(textureSizeSymbol->fKind == Symbol::kFunctionDeclaration_Kind);
|
||||
const FunctionDeclaration& textureSize = (FunctionDeclaration&) *textureSizeSymbol;
|
||||
std::vector<std::unique_ptr<Expression>> sizeArguments;
|
||||
sizeArguments.emplace_back(new VariableReference(-1, sampler));
|
||||
std::unique_ptr<Expression> float2ize = call(-1, textureSize, std::move(sizeArguments));
|
||||
const Type& type = arguments[1]->fType;
|
||||
std::unique_ptr<Expression> scale;
|
||||
if (type == *fContext.fFloat2_Type) {
|
||||
scale = std::move(float2ize);
|
||||
} else {
|
||||
SkASSERT(type == *fContext.fFloat3_Type);
|
||||
std::vector<std::unique_ptr<Expression>> float3rguments;
|
||||
float3rguments.push_back(std::move(float2ize));
|
||||
float3rguments.emplace_back(new FloatLiteral(fContext, -1, 1.0));
|
||||
scale.reset(new Constructor(-1, *fContext.fFloat3_Type, std::move(float3rguments)));
|
||||
}
|
||||
arguments[1].reset(new BinaryExpression(-1, std::move(scale), Token::STAR,
|
||||
std::move(arguments[1]), type));
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::call(int offset,
|
||||
const FunctionDeclaration& function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments) {
|
||||
@ -1589,6 +1620,10 @@ std::unique_ptr<Expression> IRGenerator::call(int offset,
|
||||
VariableReference::kPointer_RefKind);
|
||||
}
|
||||
}
|
||||
if (function.fBuiltin && function.fName == "texture" &&
|
||||
arguments[0]->fType == *fContext.fSampler2DRect_Type) {
|
||||
this->fixRectSampling(arguments);
|
||||
}
|
||||
return std::unique_ptr<FunctionCall>(new FunctionCall(offset, *returnType, function,
|
||||
std::move(arguments)));
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ private:
|
||||
// returns a statement which converts sk_Position from device to normalized coordinates
|
||||
std::unique_ptr<Statement> getNormalizeSkPositionCode();
|
||||
|
||||
void fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments);
|
||||
void checkValid(const Expression& expr);
|
||||
void setRefKind(const Expression& expr, VariableReference::RefKind kind);
|
||||
void getConstantInt(const Expression& value, int64_t* out);
|
||||
|
@ -1562,7 +1562,7 @@ DEF_TEST(SkSLRectangleTexture, r) {
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"uniform sampler2DRect test;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor = texture(test, vec2(0.5));\n"
|
||||
" sk_FragColor = texture(test, textureSize(test) * vec2(0.5));\n"
|
||||
"}\n");
|
||||
test(r,
|
||||
"uniform sampler2DRect test;"
|
||||
@ -1574,7 +1574,7 @@ DEF_TEST(SkSLRectangleTexture, r) {
|
||||
"out vec4 sk_FragColor;\n"
|
||||
"uniform sampler2DRect test;\n"
|
||||
"void main() {\n"
|
||||
" sk_FragColor = texture(test, vec3(0.5));\n"
|
||||
" sk_FragColor = texture(test, vec3(textureSize(test), 1.0) * vec3(0.5));\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user