YUV scale fix
There was a scaling mistake visible in some JPEG images because the ratio between Y, U and V planes were assumed to be the same ratios as the ratio between texture sizes, which was wrong because texture have a minimum size of 16 and are rounded up to the next POT. Since the ratios between Y and UV planes are generally 1, 2 or 4, rounding up to the next POT would generally preserve this ratio, so that this bug was not very visible, apart from very small jpeg images of 8 or less pixels in either width or height. BUG=457954 Committed: https://skia.googlesource.com/skia/+/e6eddf7dd85add7da41f22f2643bdd573ad1f1cf Review URL: https://codereview.chromium.org/922273002
This commit is contained in:
parent
db0f9516ae
commit
4ccce7ea61
@ -19,6 +19,10 @@
|
||||
#include "SkGr.h"
|
||||
#include "SkGradientShader.h"
|
||||
|
||||
#define YSIZE 8
|
||||
#define USIZE 4
|
||||
#define VSIZE 4
|
||||
|
||||
namespace skiagm {
|
||||
/**
|
||||
* This GM directly exercises GrYUVtoRGBEffect.
|
||||
@ -35,14 +39,16 @@ protected:
|
||||
}
|
||||
|
||||
SkISize onISize() SK_OVERRIDE {
|
||||
return SkISize::Make(334, 128);
|
||||
return SkISize::Make(238, 84);
|
||||
}
|
||||
|
||||
void onOnceBeforeDraw() SK_OVERRIDE {
|
||||
SkImageInfo info = SkImageInfo::MakeA8(24, 24);
|
||||
fBmp[0].allocPixels(info);
|
||||
fBmp[1].allocPixels(info);
|
||||
fBmp[2].allocPixels(info);
|
||||
SkImageInfo yinfo = SkImageInfo::MakeA8(YSIZE, YSIZE);
|
||||
fBmp[0].allocPixels(yinfo);
|
||||
SkImageInfo uinfo = SkImageInfo::MakeA8(USIZE, USIZE);
|
||||
fBmp[1].allocPixels(uinfo);
|
||||
SkImageInfo vinfo = SkImageInfo::MakeA8(VSIZE, VSIZE);
|
||||
fBmp[2].allocPixels(vinfo);
|
||||
unsigned char* pixels[3];
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pixels[i] = (unsigned char*)fBmp[i].getPixels();
|
||||
@ -51,8 +57,9 @@ protected:
|
||||
const int limit[] = {255, 0, 255};
|
||||
const int invl[] = {0, 255, 0};
|
||||
const int inc[] = {1, -1, 1};
|
||||
for (int j = 0; j < 576; ++j) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const size_t nbBytes = fBmp[i].rowBytes() * fBmp[i].height();
|
||||
for (size_t j = 0; j < nbBytes; ++j) {
|
||||
pixels[i][j] = (unsigned char)color[i];
|
||||
color[i] = (color[i] == limit[i]) ? invl[i] : color[i] + inc[i];
|
||||
}
|
||||
@ -88,7 +95,8 @@ protected:
|
||||
|
||||
static const SkScalar kDrawPad = 10.f;
|
||||
static const SkScalar kTestPad = 10.f;
|
||||
static const SkScalar kColorSpaceOffset = 64.f;
|
||||
static const SkScalar kColorSpaceOffset = 36.f;
|
||||
SkISize sizes[3] = {{YSIZE, YSIZE}, {USIZE, USIZE}, {VSIZE, VSIZE}};
|
||||
|
||||
for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace;
|
||||
++space) {
|
||||
@ -105,9 +113,10 @@ protected:
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
SkAutoTUnref<GrFragmentProcessor> fp(
|
||||
GrYUVtoRGBEffect::Create(texture[indices[i][0]],
|
||||
texture[indices[i][1]],
|
||||
texture[indices[i][2]],
|
||||
static_cast<SkYUVColorSpace>(space)));
|
||||
texture[indices[i][1]],
|
||||
texture[indices[i][2]],
|
||||
sizes,
|
||||
static_cast<SkYUVColorSpace>(space)));
|
||||
if (fp) {
|
||||
SkMatrix viewMatrix;
|
||||
viewMatrix.setTranslate(x, y);
|
||||
|
@ -391,7 +391,7 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrContentKey& optionalK
|
||||
|
||||
SkAutoTUnref<GrFragmentProcessor>
|
||||
yuvToRgbProcessor(GrYUVtoRGBEffect::Create(yuvTextures[0], yuvTextures[1], yuvTextures[2],
|
||||
yuvInfo.fColorSpace));
|
||||
yuvInfo.fSize, yuvInfo.fColorSpace));
|
||||
GrPaint paint;
|
||||
paint.addColorProcessor(yuvToRgbProcessor);
|
||||
SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth),
|
||||
|
@ -18,8 +18,22 @@ namespace {
|
||||
class YUVtoRGBEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
static GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture,
|
||||
GrTexture* vTexture, SkYUVColorSpace colorSpace) {
|
||||
return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, colorSpace));
|
||||
GrTexture* vTexture, SkISize sizes[3],
|
||||
SkYUVColorSpace colorSpace) {
|
||||
SkScalar w[3], h[3];
|
||||
w[0] = SkIntToScalar(sizes[0].fWidth) / SkIntToScalar(yTexture->width());
|
||||
h[0] = SkIntToScalar(sizes[0].fHeight) / SkIntToScalar(yTexture->height());
|
||||
w[1] = SkIntToScalar(sizes[1].fWidth) / SkIntToScalar(uTexture->width());
|
||||
h[1] = SkIntToScalar(sizes[1].fHeight) / SkIntToScalar(uTexture->height());
|
||||
w[2] = SkIntToScalar(sizes[2].fWidth) / SkIntToScalar(vTexture->width());
|
||||
h[2] = SkIntToScalar(sizes[2].fHeight) / SkIntToScalar(vTexture->height());
|
||||
SkMatrix yuvMatrix[3];
|
||||
yuvMatrix[0] = GrCoordTransform::MakeDivByTextureWHMatrix(yTexture);
|
||||
yuvMatrix[1] = yuvMatrix[0];
|
||||
yuvMatrix[1].preScale(w[1] / w[0], h[1] / h[0]);
|
||||
yuvMatrix[2] = yuvMatrix[0];
|
||||
yuvMatrix[2].preScale(w[2] / w[0], h[2] / h[0]);
|
||||
return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture, yuvMatrix, colorSpace));
|
||||
}
|
||||
|
||||
const char* name() const SK_OVERRIDE { return "YUV to RGB"; }
|
||||
@ -53,9 +67,9 @@ public:
|
||||
fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", outputColor);
|
||||
fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
|
||||
fsBuilder->codeAppend(".r,\n\t\t");
|
||||
fsBuilder->appendTextureLookup(samplers[1], coords[0].c_str(), coords[0].getType());
|
||||
fsBuilder->appendTextureLookup(samplers[1], coords[1].c_str(), coords[1].getType());
|
||||
fsBuilder->codeAppend(".r,\n\t\t");
|
||||
fsBuilder->appendTextureLookup(samplers[2], coords[0].c_str(), coords[0].getType());
|
||||
fsBuilder->appendTextureLookup(samplers[2], coords[2].c_str(), coords[2].getType());
|
||||
fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
|
||||
}
|
||||
|
||||
@ -89,18 +103,20 @@ public:
|
||||
|
||||
private:
|
||||
YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
|
||||
SkYUVColorSpace colorSpace)
|
||||
: fCoordTransform(kLocal_GrCoordSet,
|
||||
GrCoordTransform::MakeDivByTextureWHMatrix(yTexture),
|
||||
yTexture, GrTextureParams::kNone_FilterMode)
|
||||
SkMatrix yuvMatrix[3], SkYUVColorSpace colorSpace)
|
||||
: fYTransform(kLocal_GrCoordSet, yuvMatrix[0], yTexture, GrTextureParams::kNone_FilterMode)
|
||||
, fYAccess(yTexture)
|
||||
, fUTransform(kLocal_GrCoordSet, yuvMatrix[1], uTexture, GrTextureParams::kNone_FilterMode)
|
||||
, fUAccess(uTexture)
|
||||
, fVTransform(kLocal_GrCoordSet, yuvMatrix[2], vTexture, GrTextureParams::kNone_FilterMode)
|
||||
, fVAccess(vTexture)
|
||||
, fColorSpace(colorSpace) {
|
||||
this->initClassID<YUVtoRGBEffect>();
|
||||
this->addCoordTransform(&fCoordTransform);
|
||||
this->addCoordTransform(&fYTransform);
|
||||
this->addTextureAccess(&fYAccess);
|
||||
this->addCoordTransform(&fUTransform);
|
||||
this->addTextureAccess(&fUAccess);
|
||||
this->addCoordTransform(&fVTransform);
|
||||
this->addTextureAccess(&fVAccess);
|
||||
}
|
||||
|
||||
@ -115,9 +131,11 @@ private:
|
||||
GrInvariantOutput::kWillNot_ReadInput);
|
||||
}
|
||||
|
||||
GrCoordTransform fCoordTransform;
|
||||
GrCoordTransform fYTransform;
|
||||
GrTextureAccess fYAccess;
|
||||
GrCoordTransform fUTransform;
|
||||
GrTextureAccess fUAccess;
|
||||
GrCoordTransform fVTransform;
|
||||
GrTextureAccess fVAccess;
|
||||
SkYUVColorSpace fColorSpace;
|
||||
|
||||
@ -140,6 +158,7 @@ const GrGLfloat YUVtoRGBEffect::GLProcessor::kRec601ConversionMatrix[16] = {
|
||||
|
||||
GrFragmentProcessor*
|
||||
GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
|
||||
SkYUVColorSpace colorSpace) {
|
||||
return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, colorSpace);
|
||||
SkISize sizes[3], SkYUVColorSpace colorSpace) {
|
||||
SkASSERT(yTexture && uTexture && vTexture && sizes);
|
||||
return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture, sizes, colorSpace);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace GrYUVtoRGBEffect {
|
||||
* Creates an effect that performs color conversion from YUV to RGB
|
||||
*/
|
||||
GrFragmentProcessor* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture,
|
||||
SkYUVColorSpace colorSpace);
|
||||
SkISize sizes[3], SkYUVColorSpace colorSpace);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user