Add color space xform to GrMagnifierEffect
Tag helper image as sRGB in magnifier image filter GM, so we can see
this working.
BUG=skia:
Change-Id: I8057dc332d09e1d508ad8462aaf0749b307f480f
Reviewed-on: https://skia-review.googlesource.com/6347
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/gm/imagemagnifier.cpp b/gm/imagemagnifier.cpp
index 88a6d10..888bb5d 100644
--- a/gm/imagemagnifier.cpp
+++ b/gm/imagemagnifier.cpp
@@ -8,6 +8,7 @@
#include "gm.h"
#include "SkImageSource.h"
#include "SkMagnifierImageFilter.h"
+#include "SkPixelRef.h"
#include "SkRandom.h"
#include "SkSurface.h"
@@ -43,23 +44,25 @@
#define WIDTH_HEIGHT 256
static sk_sp<SkImage> make_img() {
- const SkImageInfo info = SkImageInfo::MakeN32Premul(WIDTH_HEIGHT, WIDTH_HEIGHT);
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(WIDTH_HEIGHT, WIDTH_HEIGHT);
+ SkCanvas canvas(bitmap);
- sk_sp<SkSurface> surf(SkSurface::MakeRaster(info));
-
- SkCanvas* canvas = surf->getCanvas();
-
- canvas->clear(0x0);
+ canvas.clear(0x0);
SkPaint paint;
paint.setColor(SK_ColorBLUE);
for (float pos = 0; pos < WIDTH_HEIGHT; pos += 16) {
- canvas->drawLine(0, pos, SkIntToScalar(WIDTH_HEIGHT), pos, paint);
- canvas->drawLine(pos, 0, pos, SkIntToScalar(WIDTH_HEIGHT), paint);
+ canvas.drawLine(0, pos, SkIntToScalar(WIDTH_HEIGHT), pos, paint);
+ canvas.drawLine(pos, 0, pos, SkIntToScalar(WIDTH_HEIGHT), paint);
}
- return surf->makeImageSnapshot();
+ SkBitmap result;
+ result.setInfo(SkImageInfo::MakeS32(WIDTH_HEIGHT, WIDTH_HEIGHT, kPremul_SkAlphaType));
+ result.setPixelRef(sk_ref_sp(bitmap.pixelRef()), 0, 0);
+
+ return SkImage::MakeFromBitmap(result);
}
DEF_SIMPLE_GM_BG(imagemagnifier_cropped, canvas, WIDTH_HEIGHT, WIDTH_HEIGHT, SK_ColorBLACK) {
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 916bd95..2b04532 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -19,6 +19,7 @@
#include "GrContext.h"
#include "GrInvariantOutput.h"
#include "effects/GrSingleTextureEffect.h"
+#include "glsl/GrGLSLColorSpaceXformHelper.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
@@ -29,6 +30,7 @@
public:
static sk_sp<GrFragmentProcessor> Make(GrTexture* texture,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkRect& bounds,
float xOffset,
float yOffset,
@@ -36,8 +38,8 @@
float yInvZoom,
float xInvInset,
float yInvInset) {
- return sk_sp<GrFragmentProcessor>(new GrMagnifierEffect(texture, bounds,
- xOffset, yOffset,
+ return sk_sp<GrFragmentProcessor>(new GrMagnifierEffect(texture, std::move(colorSpaceXform),
+ bounds, xOffset, yOffset,
xInvZoom, yInvZoom,
xInvInset, yInvInset));
}
@@ -61,6 +63,7 @@
private:
GrMagnifierEffect(GrTexture* texture,
+ sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkRect& bounds,
float xOffset,
float yOffset,
@@ -68,7 +71,8 @@
float yInvZoom,
float xInvInset,
float yInvInset)
- : INHERITED(texture, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
+ : INHERITED(texture, std::move(colorSpaceXform),
+ GrCoordTransform::MakeDivByTextureWHMatrix(texture))
, fBounds(bounds)
, fXOffset(xOffset)
, fYOffset(yOffset)
@@ -107,6 +111,12 @@
public:
void emitCode(EmitArgs&) override;
+ static inline void GenKey(const GrProcessor& effect, const GrShaderCaps&,
+ GrProcessorKeyBuilder* b) {
+ const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>();
+ b->add32(GrColorSpaceXform::XformKey(zoom.colorSpaceXform()));
+ }
+
protected:
void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
@@ -115,6 +125,7 @@
UniformHandle fInvZoomVar;
UniformHandle fInvInsetVar;
UniformHandle fBoundsVar;
+ UniformHandle fColorSpaceXformVar;
typedef GrGLSLFragmentProcessor INHERITED;
};
@@ -134,6 +145,10 @@
kVec4f_GrSLType, kDefault_GrSLPrecision,
"Bounds");
+ const GrMagnifierEffect& zoom = args.fFp.cast<GrMagnifierEffect>();
+ GrGLSLColorSpaceXformHelper colorSpaceHelper(uniformHandler, zoom.colorSpaceXform(),
+ &fColorSpaceXformVar);
+
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
@@ -160,7 +175,8 @@
fragBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
fragBuilder->codeAppend("\t\tvec4 output_color = ");
- fragBuilder->appendTextureLookup(args.fTexSamplers[0], "mix_coord");
+ fragBuilder->appendTextureLookup(args.fTexSamplers[0], "mix_coord", kVec2f_GrSLType,
+ &colorSpaceHelper);
fragBuilder->codeAppend(";\n");
fragBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor);
@@ -177,6 +193,9 @@
pdman.set2f(fInvInsetVar, zoom.xInvInset(), zoom.yInvInset());
pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(),
zoom.bounds().width(), zoom.bounds().height());
+ if (SkToBool(zoom.colorSpaceXform())) {
+ pdman.setSkMatrix44(fColorSpaceXformVar, zoom.colorSpaceXform()->srcToDst());
+ }
}
/////////////////////////////////////////////////////////////////////
@@ -202,9 +221,11 @@
uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width);
uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height);
uint32_t inset = d->fRandom->nextULessThan(kMaxInset);
+ auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
sk_sp<GrFragmentProcessor> effect(GrMagnifierEffect::Make(
texture,
+ std::move(colorSpaceXform),
SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)),
(float) width / texture->width(),
(float) height / texture->height(),
@@ -323,9 +344,13 @@
SkIntToScalar(boundsY) / inputTexture->height(),
SkIntToScalar(inputTexture->width()) / bounds.width(),
SkIntToScalar(inputTexture->height()) / bounds.height());
- // SRGBTODO: Handle sRGB here
+
+ SkColorSpace* dstColorSpace = ctx.outputProperties().colorSpace();
+ sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(input->getColorSpace(),
+ dstColorSpace);
sk_sp<GrFragmentProcessor> fp(GrMagnifierEffect::Make(
inputTexture.get(),
+ std::move(colorSpaceXform),
effectBounds,
fSrcRect.x() / inputTexture->width(),
yOffset / inputTexture->height(),