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;
|
SkScalar offsetX, offsetY;
|
||||||
} tiles[] = {
|
} tiles[] = {
|
||||||
{ 0, 0, 1, 1, 0, 0 },
|
{ 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.5f, 0.5f, 1, 1, 0, 0 },
|
||||||
|
|
||||||
{ 0, 0, 1.5f, 1.5f, 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.5f, 0.5f, 1.5f, 1.5f, 0, 0 },
|
||||||
|
|
||||||
{ 0, 0, 0.5f, 0.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.25f, -0.25f, 0.5f, 0.5f, 0, 0 },
|
||||||
|
|
||||||
{ 0, 0, 1, 1, 0.5f, 0.5f },
|
{ 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.5f, 0.5f, 1, 1, 0.5f, 0.5f },
|
||||||
|
|
||||||
{ 0, 0, 1.5f, 1.5f, 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.5f, 0.5f, 1.5f, 1.5f, 0.5f, 0.5f },
|
||||||
|
|
||||||
{ 0, 0, 1.5f, 1, 0, 0 },
|
{ 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.5f, 0.5f, 1.5f, 1, 0, 0 },
|
||||||
|
|
||||||
{ 0, 0, 0.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.25f, -0.25f, 0.5f, 1, 0, 0 },
|
||||||
|
|
||||||
{ 0, 0, 1, 1.5f, 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.5f, 0.5f, 1, 1.5f, 0, 0 },
|
||||||
|
|
||||||
{ 0, 0, 1, 0.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 },
|
||||||
|
{ -0.25f, -0.25f, 1, 0.5f, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
class PictureShaderTileGM : public skiagm::GM {
|
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:
|
protected:
|
||||||
virtual uint32_t onGetFlags() const SK_OVERRIDE {
|
virtual uint32_t onGetFlags() const SK_OVERRIDE {
|
||||||
return kSkipTiled_Flag;
|
return kSkipTiled_Flag;
|
||||||
@ -96,6 +71,47 @@ protected:
|
|||||||
return SkISize::Make(800, 600);
|
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 {
|
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
||||||
canvas->clear(SK_ColorBLACK);
|
canvas->clear(SK_ColorBLACK);
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatri
|
|||||||
|
|
||||||
SkCanvas canvas(bm);
|
SkCanvas canvas(bm);
|
||||||
canvas.scale(tileScale.width(), tileScale.height());
|
canvas.scale(tileScale.width(), tileScale.height());
|
||||||
canvas.translate(fTile.x(), fTile.y());
|
canvas.translate(-fTile.x(), -fTile.y());
|
||||||
canvas.drawPicture(fPicture);
|
canvas.drawPicture(fPicture);
|
||||||
|
|
||||||
SkMatrix shaderMatrix = this->getLocalMatrix();
|
SkMatrix shaderMatrix = this->getLocalMatrix();
|
||||||
|
Loading…
Reference in New Issue
Block a user