Adding an option for pixelated rendering in SkPictureImageFilter

BUG=skia:3209

Review URL: https://codereview.chromium.org/787073003
This commit is contained in:
junov 2014-12-09 13:07:22 -08:00 committed by Commit bot
parent 4beac74324
commit f3c78ccf56
5 changed files with 46 additions and 19 deletions

View File

@ -36,7 +36,7 @@ protected:
fPicture.reset(recorder.endRecording());
}
virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(400, 300); }
virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(600, 300); }
virtual void onOnceBeforeDraw() SK_OVERRIDE {
this->makePicture();
@ -64,7 +64,11 @@ protected:
SkAutoTUnref<SkPictureImageFilter> pictureSourceEmptyRect(
SkPictureImageFilter::Create(fPicture, emptyRect));
SkAutoTUnref<SkPictureImageFilter> pictureSourceResampled(
SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect()));
SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect(),
SkPaint::kLow_FilterLevel));
SkAutoTUnref<SkPictureImageFilter> pictureSourcePixelated(
SkPictureImageFilter::CreateForLocalSpace(fPicture, fPicture->cullRect(),
SkPaint::kNone_FilterLevel));
canvas->save();
// Draw the picture unscaled.
@ -90,6 +94,10 @@ protected:
// Draw the picture scaled, but rasterized at original resolution
canvas->translate(srcRect.width(), 0);
fillRectFiltered(canvas, srcRect, pictureSourceResampled);
// Draw the picture scaled, pixelated
canvas->translate(srcRect.width(), 0);
fillRectFiltered(canvas, srcRect, pictureSourcePixelated);
}
}

View File

@ -246,14 +246,15 @@ private:
// V35: Store SkRect (rather then width & height) in header
// V36: Remove (obsolete) alphatype from SkColorTable
// V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR)
// V37: Added PictureResolution and FilterLevel options to SkPictureImageFilter
// V38: Added PictureResolution option to SkPictureImageFilter
// V39: Added FilterLevel option to SkPictureImageFilter
// Note: If the picture version needs to be increased then please follow the
// steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39.
static const uint32_t CURRENT_PICTURE_VERSION = 38;
static const uint32_t CURRENT_PICTURE_VERSION = 39;
void createHeader(SkPictInfo* info) const;
static bool IsValidPictInfo(const SkPictInfo& info);

View File

@ -27,7 +27,8 @@ public:
static SkPictureImageFilter* Create(const SkPicture* picture, const SkRect& cropRect,
uint32_t uniqueID = 0) {
return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect, uniqueID,
kDeviceSpace_PictureResolution));
kDeviceSpace_PictureResolution,
SkPaint::kLow_FilterLevel));
}
/**
@ -39,9 +40,10 @@ public:
*/
static SkPictureImageFilter* CreateForLocalSpace(const SkPicture* picture,
const SkRect& cropRect,
SkPaint::FilterLevel filterLevel,
uint32_t uniqueID = 0) {
return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect, uniqueID,
kLocalSpace_PictureResolution));
kLocalSpace_PictureResolution, filterLevel));
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
@ -54,7 +56,7 @@ protected:
explicit SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID);
SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect, uint32_t uniqueID,
PictureResolution);
PictureResolution, SkPaint::FilterLevel);
virtual ~SkPictureImageFilter();
/* Constructs an SkPictureImageFilter object from an SkReadBuffer.
* Note: If the SkPictureImageFilter object construction requires bitmap
@ -77,6 +79,7 @@ private:
const SkPicture* fPicture;
SkRect fCropRect;
PictureResolution fPictureResolution;
SkPaint::FilterLevel fFilterLevel;
typedef SkImageFilter INHERITED;
};

View File

@ -54,6 +54,7 @@ public:
kRemoveColorTableAlpha_Version = 36,
kDropShadowMode_Version = 37,
kPictureImageFilterResolution_Version = 38,
kPictureImageFilterLevel_Version = 39,
};
/**

View File

@ -17,15 +17,18 @@ SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, uint32_t un
: INHERITED(0, 0, NULL, uniqueID)
, fPicture(SkSafeRef(picture))
, fCropRect(picture ? picture->cullRect() : SkRect::MakeEmpty())
, fPictureResolution(kDeviceSpace_PictureResolution) {
, fPictureResolution(kDeviceSpace_PictureResolution)
, fFilterLevel(SkPaint::kLow_FilterLevel) {
}
SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect,
uint32_t uniqueID, PictureResolution pictureResolution)
uint32_t uniqueID, PictureResolution pictureResolution,
SkPaint::FilterLevel filterLevel)
: INHERITED(0, 0, NULL, uniqueID)
, fPicture(SkSafeRef(picture))
, fCropRect(cropRect)
, fPictureResolution(pictureResolution) {
, fPictureResolution(pictureResolution)
, fFilterLevel(filterLevel) {
}
SkPictureImageFilter::~SkPictureImageFilter() {
@ -49,10 +52,17 @@ SkFlattenable* SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) {
pictureResolution = kDeviceSpace_PictureResolution;
} else {
pictureResolution = (PictureResolution)buffer.readInt();
}
}
if (pictureResolution == kLocalSpace_PictureResolution) {
return CreateForLocalSpace(picture, cropRect);
if (kLocalSpace_PictureResolution == pictureResolution) {
//filterLevel is only serialized if pictureResolution is LocalSpace
SkPaint::FilterLevel filterLevel;
if (buffer.isVersionLT(SkReadBuffer::kPictureImageFilterLevel_Version)) {
filterLevel = SkPaint::kLow_FilterLevel;
} else {
filterLevel = (SkPaint::FilterLevel)buffer.readInt();
}
return CreateForLocalSpace(picture, cropRect, filterLevel);
}
return Create(picture, cropRect);
}
@ -69,6 +79,9 @@ void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const {
}
buffer.writeRect(fCropRect);
buffer.writeInt(fPictureResolution);
if (kLocalSpace_PictureResolution == fPictureResolution) {
buffer.writeInt(fFilterLevel);
}
}
bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx,
@ -95,11 +108,11 @@ bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Co
return false;
}
if (kLocalSpace_PictureResolution == fPictureResolution &&
(ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) {
drawPictureAtLocalResolution(proxy, device.get(), bounds, ctx);
if (kDeviceSpace_PictureResolution == fPictureResolution ||
0 == (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) {
drawPictureAtDeviceResolution(proxy, device.get(), bounds, ctx);
} else {
drawPictureAtDeviceResolution(proxy, device.get(), bounds, ctx);
drawPictureAtLocalResolution(proxy, device.get(), bounds, ctx);
}
*result = device.get()->accessBitmap(false);
@ -149,7 +162,8 @@ void SkPictureImageFilter::drawPictureAtLocalResolution(Proxy* proxy, SkBaseDevi
canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBounds.fTop));
canvas.concat(ctx.ctm());
SkPaint paint;
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
canvas.drawBitmap(localDevice.get()->accessBitmap(false), SkIntToScalar(localIBounds.fLeft), SkIntToScalar(localIBounds.fTop), &paint);
paint.setFilterLevel(fFilterLevel);
canvas.drawBitmap(localDevice.get()->accessBitmap(false), SkIntToScalar(localIBounds.fLeft),
SkIntToScalar(localIBounds.fTop), &paint);
//canvas.drawPicture(fPicture);
}