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>
This commit is contained in:
Brian Osman 2016-12-20 15:54:11 -05:00 committed by Skia Commit-Bot
parent 5ec9def2dd
commit b44bb31137
2 changed files with 42 additions and 14 deletions

View File

@ -8,6 +8,7 @@
#include "gm.h" #include "gm.h"
#include "SkImageSource.h" #include "SkImageSource.h"
#include "SkMagnifierImageFilter.h" #include "SkMagnifierImageFilter.h"
#include "SkPixelRef.h"
#include "SkRandom.h" #include "SkRandom.h"
#include "SkSurface.h" #include "SkSurface.h"
@ -43,23 +44,25 @@ DEF_SIMPLE_GM_BG(imagemagnifier, canvas, WIDTH, HEIGHT, SK_ColorBLACK) {
#define WIDTH_HEIGHT 256 #define WIDTH_HEIGHT 256
static sk_sp<SkImage> make_img() { 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)); canvas.clear(0x0);
SkCanvas* canvas = surf->getCanvas();
canvas->clear(0x0);
SkPaint paint; SkPaint paint;
paint.setColor(SK_ColorBLUE); paint.setColor(SK_ColorBLUE);
for (float pos = 0; pos < WIDTH_HEIGHT; pos += 16) { for (float pos = 0; pos < WIDTH_HEIGHT; pos += 16) {
canvas->drawLine(0, pos, SkIntToScalar(WIDTH_HEIGHT), pos, paint); canvas.drawLine(0, pos, SkIntToScalar(WIDTH_HEIGHT), pos, paint);
canvas->drawLine(pos, 0, pos, SkIntToScalar(WIDTH_HEIGHT), 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) { DEF_SIMPLE_GM_BG(imagemagnifier_cropped, canvas, WIDTH_HEIGHT, WIDTH_HEIGHT, SK_ColorBLACK) {

View File

@ -19,6 +19,7 @@
#include "GrContext.h" #include "GrContext.h"
#include "GrInvariantOutput.h" #include "GrInvariantOutput.h"
#include "effects/GrSingleTextureEffect.h" #include "effects/GrSingleTextureEffect.h"
#include "glsl/GrGLSLColorSpaceXformHelper.h"
#include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLProgramDataManager.h"
@ -29,6 +30,7 @@ class GrMagnifierEffect : public GrSingleTextureEffect {
public: public:
static sk_sp<GrFragmentProcessor> Make(GrTexture* texture, static sk_sp<GrFragmentProcessor> Make(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkRect& bounds, const SkRect& bounds,
float xOffset, float xOffset,
float yOffset, float yOffset,
@ -36,8 +38,8 @@ public:
float yInvZoom, float yInvZoom,
float xInvInset, float xInvInset,
float yInvInset) { float yInvInset) {
return sk_sp<GrFragmentProcessor>(new GrMagnifierEffect(texture, bounds, return sk_sp<GrFragmentProcessor>(new GrMagnifierEffect(texture, std::move(colorSpaceXform),
xOffset, yOffset, bounds, xOffset, yOffset,
xInvZoom, yInvZoom, xInvZoom, yInvZoom,
xInvInset, yInvInset)); xInvInset, yInvInset));
} }
@ -61,6 +63,7 @@ public:
private: private:
GrMagnifierEffect(GrTexture* texture, GrMagnifierEffect(GrTexture* texture,
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkRect& bounds, const SkRect& bounds,
float xOffset, float xOffset,
float yOffset, float yOffset,
@ -68,7 +71,8 @@ private:
float yInvZoom, float yInvZoom,
float xInvInset, float xInvInset,
float yInvInset) float yInvInset)
: INHERITED(texture, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) : INHERITED(texture, std::move(colorSpaceXform),
GrCoordTransform::MakeDivByTextureWHMatrix(texture))
, fBounds(bounds) , fBounds(bounds)
, fXOffset(xOffset) , fXOffset(xOffset)
, fYOffset(yOffset) , fYOffset(yOffset)
@ -107,6 +111,12 @@ class GrGLMagnifierEffect : public GrGLSLFragmentProcessor {
public: public:
void emitCode(EmitArgs&) override; 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: protected:
void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
@ -115,6 +125,7 @@ private:
UniformHandle fInvZoomVar; UniformHandle fInvZoomVar;
UniformHandle fInvInsetVar; UniformHandle fInvInsetVar;
UniformHandle fBoundsVar; UniformHandle fBoundsVar;
UniformHandle fColorSpaceXformVar;
typedef GrGLSLFragmentProcessor INHERITED; typedef GrGLSLFragmentProcessor INHERITED;
}; };
@ -134,6 +145,10 @@ void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
kVec4f_GrSLType, kDefault_GrSLPrecision, kVec4f_GrSLType, kDefault_GrSLPrecision,
"Bounds"); "Bounds");
const GrMagnifierEffect& zoom = args.fFp.cast<GrMagnifierEffect>();
GrGLSLColorSpaceXformHelper colorSpaceHelper(uniformHandler, zoom.colorSpaceXform(),
&fColorSpaceXformVar);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
@ -160,7 +175,8 @@ void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
fragBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n"); fragBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
fragBuilder->codeAppend("\t\tvec4 output_color = "); 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->codeAppend(";\n");
fragBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor); fragBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor);
@ -177,6 +193,9 @@ void GrGLMagnifierEffect::onSetData(const GrGLSLProgramDataManager& pdman,
pdman.set2f(fInvInsetVar, zoom.xInvInset(), zoom.yInvInset()); pdman.set2f(fInvInsetVar, zoom.xInvInset(), zoom.yInvInset());
pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(), pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(),
zoom.bounds().width(), zoom.bounds().height()); zoom.bounds().width(), zoom.bounds().height());
if (SkToBool(zoom.colorSpaceXform())) {
pdman.setSkMatrix44(fColorSpaceXformVar, zoom.colorSpaceXform()->srcToDst());
}
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -202,9 +221,11 @@ sk_sp<GrFragmentProcessor> GrMagnifierEffect::TestCreate(GrProcessorTestData* d)
uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width); uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width);
uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height); uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height);
uint32_t inset = d->fRandom->nextULessThan(kMaxInset); uint32_t inset = d->fRandom->nextULessThan(kMaxInset);
auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
sk_sp<GrFragmentProcessor> effect(GrMagnifierEffect::Make( sk_sp<GrFragmentProcessor> effect(GrMagnifierEffect::Make(
texture, texture,
std::move(colorSpaceXform),
SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)), SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)),
(float) width / texture->width(), (float) width / texture->width(),
(float) height / texture->height(), (float) height / texture->height(),
@ -323,9 +344,13 @@ sk_sp<SkSpecialImage> SkMagnifierImageFilter::onFilterImage(SkSpecialImage* sour
SkIntToScalar(boundsY) / inputTexture->height(), SkIntToScalar(boundsY) / inputTexture->height(),
SkIntToScalar(inputTexture->width()) / bounds.width(), SkIntToScalar(inputTexture->width()) / bounds.width(),
SkIntToScalar(inputTexture->height()) / bounds.height()); 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( sk_sp<GrFragmentProcessor> fp(GrMagnifierEffect::Make(
inputTexture.get(), inputTexture.get(),
std::move(colorSpaceXform),
effectBounds, effectBounds,
fSrcRect.x() / inputTexture->width(), fSrcRect.x() / inputTexture->width(),
yOffset / inputTexture->height(), yOffset / inputTexture->height(),