incorporate r,g,b,a into shaderHash
Today's shader hash changes if the unordered set of {r,g,b,a} values we produce changes, but is not sensitive to simple order changes like sampling RGBA vs BGRA. Folding in a hash of each value's ID in order will fix this. This has been difficult to track down (thread-local caches), so I've added a GM that reliably reproduces the bug. Live demo: https://fiddle.skia.org/c/30f2e5b731c2e53a6f092424c585ca41 Bug: skia:9819 Change-Id: Iceb09d89eb036735028ae97dc79c576787199ac5 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/267119 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
162e04b9a9
commit
d352529216
64
gm/skbug_9819.cpp
Normal file
64
gm/skbug_9819.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm/gm.h"
|
||||
#include "include/core/SkBitmap.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
|
||||
// This GM should draw two yellow boxes; the bug drew one in cyan.
|
||||
|
||||
DEF_SIMPLE_GM(skbug_9819, c, 256, 256) {
|
||||
auto info = SkImageInfo::Make(1,1, kUnknown_SkColorType, kPremul_SkAlphaType);
|
||||
SkBitmap rgba,
|
||||
bgra;
|
||||
rgba.allocPixels(info.makeColorType(kRGBA_8888_SkColorType));
|
||||
bgra.allocPixels(info.makeColorType(kBGRA_8888_SkColorType));
|
||||
|
||||
SkColor yellow = 0xffffff00;
|
||||
rgba.eraseColor(yellow);
|
||||
bgra.eraseColor(yellow);
|
||||
|
||||
c->save();
|
||||
c->scale(128,128);
|
||||
c->drawBitmap(rgba, 0,0);
|
||||
c->drawBitmap(bgra, 0,1);
|
||||
c->restore();
|
||||
|
||||
auto grade = [&](int x, int y){
|
||||
SkBitmap bm;
|
||||
bm.allocPixels(SkImageInfo::Make(1,1,
|
||||
kBGRA_8888_SkColorType,
|
||||
kUnpremul_SkAlphaType,
|
||||
SkColorSpace::MakeSRGB()));
|
||||
if (!c->readPixels(bm, x,y)) {
|
||||
// Picture-backed canvases, that sort of thing. Just assume they're good.
|
||||
MarkGMGood(c, x+128, y);
|
||||
return;
|
||||
}
|
||||
|
||||
SkColor pixel;
|
||||
memcpy(&pixel, bm.getAddr(0,0), sizeof(pixel));
|
||||
|
||||
auto close = [](int x, int y) {
|
||||
return x-y < 2
|
||||
&& y-x < 2;
|
||||
};
|
||||
|
||||
if (close(SkColorGetR(pixel), SkColorGetR(yellow)) &&
|
||||
close(SkColorGetG(pixel), SkColorGetG(yellow)) &&
|
||||
close(SkColorGetB(pixel), SkColorGetB(yellow)) &&
|
||||
close(SkColorGetA(pixel), SkColorGetA(yellow))) {
|
||||
|
||||
MarkGMGood(c, x+128,y);
|
||||
} else {
|
||||
MarkGMBad(c, x+128,y);
|
||||
}
|
||||
};
|
||||
|
||||
grade(64, 64);
|
||||
grade(64, 192);
|
||||
}
|
@ -327,6 +327,7 @@ gm_sources = [
|
||||
"$_gm/skbug_8664.cpp",
|
||||
"$_gm/skbug_8955.cpp",
|
||||
"$_gm/skbug_9319.cpp",
|
||||
"$_gm/skbug_9819.cpp",
|
||||
"$_gm/skinning.cpp",
|
||||
"$_gm/smallarc.cpp",
|
||||
"$_gm/smallpaths.cpp",
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/core/SkColorSpaceXformSteps.h"
|
||||
#include "src/core/SkCoreBlitters.h"
|
||||
#include "src/core/SkLRUCache.h"
|
||||
#include "src/core/SkOpts.h"
|
||||
#include "src/core/SkVM.h"
|
||||
#include "src/core/SkVMBlitter.h"
|
||||
#include "src/shaders/SkColorFilterShader.h"
|
||||
@ -132,6 +133,11 @@ namespace {
|
||||
uniforms,alloc,
|
||||
x,y, &r,&g,&b,&a)) {
|
||||
shaderHash = p.hash();
|
||||
// p.hash() folds in all instructions to produce r,g,b,a but does not know
|
||||
// precisely which value we'll treat as which channel. Imagine the shader
|
||||
// called std::swap(*r,*b)... it draws differently, but p.hash() is unchanged.
|
||||
const int outputs[] = { r.id, g.id, b.id, a.id };
|
||||
shaderHash ^= SkOpts::hash(outputs, sizeof(outputs));
|
||||
} else {
|
||||
*ok = false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user