Tweak SkPictureShader's tile semantics.
Currently, the tile offset is added when drawing the picture. This might have made a tiny bit of sense when the picture was always positioned at origin, but with a picture cull rect offset things looks really strange. For example, to specify a tile == the picture cull rect we have to pass in [-cullrect.x, -cullrect.y, cullrect.width, cullrect.height]. Yikes. (there's also a bug when not passing a tile, as we use a default tile == cullrect but don't compensate for the above oddity) This changes the semantics of the tile offset: it is now subtracted when drawing the picture tile. As a consequence, one can pass in a tile equal to the cull rect and get the expected behavior (same when not passing a tile). This will require a minor Blink change with the roll, as one client works around the current behavior: https://codereview.chromium.org/789503003 R=reed@google.com,robertphillips@google.com BUG=440046 Review URL: https://codereview.chromium.org/733203005
This commit is contained in:
parent
cf56009d90
commit
a2bd24fd15
@ -21,68 +21,43 @@ static const struct {
|
||||
SkScalar offsetX, offsetY;
|
||||
} tiles[] = {
|
||||
{ 0, 0, 1, 1, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1, 1, 0, 0 },
|
||||
{ -0.5f, -0.5f, 1, 1, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1, 1, 0, 0 },
|
||||
|
||||
{ 0, 0, 1.5f, 1.5f, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1.5f, 1.5f, 0, 0 },
|
||||
{ -0.5f, -0.5f, 1.5f, 1.5f, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1.5f, 1.5f, 0, 0 },
|
||||
|
||||
{ 0, 0, 0.5f, 0.5f, 0, 0 },
|
||||
{ -0.25f, -0.25f, 0.5f, 0.5f, 0, 0 },
|
||||
{ 0.25f, 0.25f, 0.5f, 0.5f, 0, 0 },
|
||||
{ -0.25f, -0.25f, 0.5f, 0.5f, 0, 0 },
|
||||
|
||||
{ 0, 0, 1, 1, 0.5f, 0.5f },
|
||||
{ 0.5f, 0.5f, 1, 1, 0.5f, 0.5f },
|
||||
{ -0.5f, -0.5f, 1, 1, 0.5f, 0.5f },
|
||||
{ 0.5f, 0.5f, 1, 1, 0.5f, 0.5f },
|
||||
|
||||
{ 0, 0, 1.5f, 1.5f, 0.5f, 0.5f },
|
||||
{ 0.5f, 0.5f, 1.5f, 1.5f, 0.5f, 0.5f },
|
||||
{ -0.5f, -0.5f, 1.5f, 1.5f, 0.5f, 0.5f },
|
||||
{ 0.5f, 0.5f, 1.5f, 1.5f, 0.5f, 0.5f },
|
||||
|
||||
{ 0, 0, 1.5f, 1, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1.5f, 1, 0, 0 },
|
||||
{ -0.5f, -0.5f, 1.5f, 1, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1.5f, 1, 0, 0 },
|
||||
|
||||
{ 0, 0, 0.5f, 1, 0, 0 },
|
||||
{ -0.25f, -0.25f, 0.5f, 1, 0, 0 },
|
||||
{ 0.25f, 0.25f, 0.5f, 1, 0, 0 },
|
||||
{ -0.25f, -0.25f, 0.5f, 1, 0, 0 },
|
||||
|
||||
{ 0, 0, 1, 1.5f, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1, 1.5f, 0, 0 },
|
||||
{ -0.5f, -0.5f, 1, 1.5f, 0, 0 },
|
||||
{ 0.5f, 0.5f, 1, 1.5f, 0, 0 },
|
||||
|
||||
{ 0, 0, 1, 0.5f, 0, 0 },
|
||||
{ -0.25f, -0.25f, 1, 0.5f, 0, 0 },
|
||||
{ 0.25f, 0.25f, 1, 0.5f, 0, 0 },
|
||||
{ -0.25f, -0.25f, 1, 0.5f, 0, 0 },
|
||||
};
|
||||
|
||||
class PictureShaderTileGM : public skiagm::GM {
|
||||
public:
|
||||
PictureShaderTileGM() {
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* pictureCanvas = recorder.beginRecording(kPictureSize, kPictureSize, NULL, 0);
|
||||
drawScene(pictureCanvas, kPictureSize);
|
||||
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
|
||||
|
||||
for (unsigned i = 0; i < SK_ARRAY_COUNT(tiles); ++i) {
|
||||
SkRect tile = SkRect::MakeXYWH(tiles[i].x * kPictureSize,
|
||||
tiles[i].y * kPictureSize,
|
||||
tiles[i].w * kPictureSize,
|
||||
tiles[i].h * kPictureSize);
|
||||
SkMatrix localMatrix;
|
||||
localMatrix.setTranslate(tiles[i].offsetX * kPictureSize,
|
||||
tiles[i].offsetY * kPictureSize);
|
||||
localMatrix.postScale(kFillSize / (2 * kPictureSize),
|
||||
kFillSize / (2 * kPictureSize));
|
||||
fShaders[i].reset(SkShader::CreatePictureShader(picture,
|
||||
SkShader::kRepeat_TileMode,
|
||||
SkShader::kRepeat_TileMode,
|
||||
&localMatrix,
|
||||
&tile));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual uint32_t onGetFlags() const SK_OVERRIDE {
|
||||
return kSkipTiled_Flag;
|
||||
@ -96,6 +71,47 @@ protected:
|
||||
return SkISize::Make(800, 600);
|
||||
}
|
||||
|
||||
virtual void onOnceBeforeDraw() SK_OVERRIDE {
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* pictureCanvas = recorder.beginRecording(kPictureSize, kPictureSize);
|
||||
drawScene(pictureCanvas, kPictureSize);
|
||||
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
|
||||
|
||||
SkPoint offset = SkPoint::Make(100, 100);
|
||||
pictureCanvas = recorder.beginRecording(SkRect::MakeXYWH(offset.x(), offset.y(),
|
||||
kPictureSize, kPictureSize));
|
||||
pictureCanvas->translate(offset.x(), offset.y());
|
||||
drawScene(pictureCanvas, kPictureSize);
|
||||
SkAutoTUnref<SkPicture> offsetPicture(recorder.endRecording());
|
||||
|
||||
for (unsigned i = 0; i < SK_ARRAY_COUNT(tiles); ++i) {
|
||||
SkRect tile = SkRect::MakeXYWH(tiles[i].x * kPictureSize,
|
||||
tiles[i].y * kPictureSize,
|
||||
tiles[i].w * kPictureSize,
|
||||
tiles[i].h * kPictureSize);
|
||||
SkMatrix localMatrix;
|
||||
localMatrix.setTranslate(tiles[i].offsetX * kPictureSize,
|
||||
tiles[i].offsetY * kPictureSize);
|
||||
localMatrix.postScale(kFillSize / (2 * kPictureSize),
|
||||
kFillSize / (2 * kPictureSize));
|
||||
|
||||
SkPicture* picturePtr = picture.get();
|
||||
SkRect* tilePtr = &tile;
|
||||
|
||||
if (tile == SkRect::MakeWH(kPictureSize, kPictureSize)) {
|
||||
// When the tile == picture bounds, exercise the picture + offset path.
|
||||
picturePtr = offsetPicture.get();
|
||||
tilePtr = NULL;
|
||||
}
|
||||
|
||||
fShaders[i].reset(SkShader::CreatePictureShader(picturePtr,
|
||||
SkShader::kRepeat_TileMode,
|
||||
SkShader::kRepeat_TileMode,
|
||||
&localMatrix,
|
||||
tilePtr));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
||||
canvas->clear(SK_ColorBLACK);
|
||||
|
||||
|
@ -185,7 +185,7 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatri
|
||||
|
||||
SkCanvas canvas(bm);
|
||||
canvas.scale(tileScale.width(), tileScale.height());
|
||||
canvas.translate(fTile.x(), fTile.y());
|
||||
canvas.translate(-fTile.x(), -fTile.y());
|
||||
canvas.drawPicture(fPicture);
|
||||
|
||||
SkMatrix shaderMatrix = this->getLocalMatrix();
|
||||
|
Loading…
Reference in New Issue
Block a user