Revert of Switch SkBlurImageFilter over to new onFilterImage interface (patchset #15 id:270001 of https://codereview.chromium.org/1785643003/ )

Reason for revert:
serialize-8888 broken for some reason

Original issue's description:
> Switch SkBlurImageFilter over to new onFilterImage interface
>
> This CL relies on:
> https://codereview.chromium.org/1787883002/ (Add SkSpecialImage::extractSubset & NewFromPixmap)
> https://codereview.chromium.org/1808743003/ (Allow SkGpuDevice::drawSprite to handle subset SkBitmaps)
> https://codereview.chromium.org/1813813002/ (Add SkSpecialImage::makeTextureImage entry point)
>
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1785643003
>
> Committed: https://skia.googlesource.com/skia/+/3c935bc87020bfd19a08922f7394db3a801d168b

TBR=senorblanco@google.com,senorblanco@chromium.org,bsalomon@google.com,reed@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review URL: https://codereview.chromium.org/1831603002
This commit is contained in:
robertphillips 2016-03-23 14:03:43 -07:00 committed by Commit bot
parent 22281c13a1
commit 9c79d7ec4e
7 changed files with 128 additions and 153 deletions

View File

@ -378,12 +378,6 @@ protected:
return NULL;
}
/**
* Calls through to drawSprite, processing the imagefilter.
*/
virtual void drawBitmapAsSpriteWithImageFilter(const SkDraw&, const SkBitmap&,
int x, int y, const SkPaint&);
private:
friend class SkCanvas;
friend struct DeviceCM; //for setMatrixClip
@ -394,6 +388,11 @@ private:
friend class SkNoPixelsBitmapDevice;
friend class SkSurface_Raster;
/**
* Calls through to drawSprite, processing imagefilter as needed.
*/
void drawBitmapAsSprite(const SkDraw&, const SkBitmap&, int x, int y, const SkPaint&);
// used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to
// any clip information.

View File

@ -28,9 +28,12 @@ public:
protected:
void flatten(SkWriteBuffer&) const override;
SkSpecialImage* onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
SkIPoint* offset) const override;
SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
bool canFilterImageGPU() const override { return true; }
bool filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
SkBitmap* result, SkIPoint* offset) const override;
private:
SkBlurImageFilter(SkScalar sigmaX,

View File

@ -2265,9 +2265,9 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
if (as_IB(image)->asBitmapForImageFilters(&bitmap)) {
SkPoint pt;
iter.fMatrix->mapXY(x, y, &pt);
iter.fDevice->drawBitmapAsSpriteWithImageFilter(iter, bitmap,
SkScalarRoundToInt(pt.fX),
SkScalarRoundToInt(pt.fY), pnt);
iter.fDevice->drawBitmapAsSprite(iter, bitmap,
SkScalarRoundToInt(pt.fX),
SkScalarRoundToInt(pt.fY), pnt);
}
} else {
iter.fDevice->drawImage(iter, image, x, y, pnt);
@ -2347,9 +2347,9 @@ void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons
if (drawAsSprite && pnt.getImageFilter()) {
SkPoint pt;
iter.fMatrix->mapXY(x, y, &pt);
iter.fDevice->drawBitmapAsSpriteWithImageFilter(iter, bitmap,
SkScalarRoundToInt(pt.fX),
SkScalarRoundToInt(pt.fY), pnt);
iter.fDevice->drawBitmapAsSprite(iter, bitmap,
SkScalarRoundToInt(pt.fX),
SkScalarRoundToInt(pt.fY), pnt);
} else {
iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
}

View File

@ -403,13 +403,10 @@ void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b
//////////////////////////////////////////////////////////////////////////////////////////
void SkBaseDevice::drawBitmapAsSpriteWithImageFilter(const SkDraw& draw, const SkBitmap& bitmap,
int x, int y,
const SkPaint& paint) {
void SkBaseDevice::drawBitmapAsSprite(const SkDraw& draw, const SkBitmap& bitmap, int x, int y,
const SkPaint& paint) {
SkImageFilter* filter = paint.getImageFilter();
SkASSERT(filter);
if (!this->canHandleImageFilter(filter)) {
if (filter && !this->canHandleImageFilter(filter)) {
SkImageFilter::DeviceProxy proxy(this);
SkIPoint offset = SkIPoint::Make(0, 0);
SkMatrix matrix = *draw.fMatrix;

View File

@ -5,16 +5,14 @@
* found in the LICENSE file.
*/
#include "SkBitmap.h"
#include "SkBlurImageFilter.h"
#include "SkAutoPixmapStorage.h"
#include "SkColorPriv.h"
#include "SkDevice.h"
#include "SkGpuBlurUtils.h"
#include "SkOpts.h"
#include "SkReadBuffer.h"
#include "SkSpecialImage.h"
#include "SkWriteBuffer.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "SkGr.h"
@ -55,8 +53,8 @@ void SkBlurImageFilter::flatten(SkWriteBuffer& buffer) const {
buffer.writeScalar(fSigma.fHeight);
}
static void get_box3_params(SkScalar s, int *kernelSize, int* kernelSize3, int *lowOffset,
int *highOffset)
static void getBox3Params(SkScalar s, int *kernelSize, int* kernelSize3, int *lowOffset,
int *highOffset)
{
float pi = SkScalarToFloat(SK_ScalarPI);
int d = static_cast<int>(floorf(SkScalarToFloat(s) * 3.0f * sqrtf(2.0f * pi) / 4.0f + 0.5f));
@ -71,109 +69,77 @@ static void get_box3_params(SkScalar s, int *kernelSize, int* kernelSize3, int *
}
}
SkSpecialImage* SkBlurImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
SkIPoint* offset) const {
SkIPoint inputOffset = SkIPoint::Make(0, 0);
SkAutoTUnref<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
if (!input) {
return nullptr;
bool SkBlurImageFilter::onFilterImageDeprecated(Proxy* proxy,
const SkBitmap& source, const Context& ctx,
SkBitmap* dst, SkIPoint* offset) const {
SkBitmap src = source;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
return false;
}
SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.fX, inputOffset.fY,
input->width(), input->height());
if (src.colorType() != kN32_SkColorType) {
return false;
}
SkIRect srcBounds = src.bounds();
srcBounds.offset(srcOffset);
SkIRect dstBounds;
if (!this->applyCropRect(this->mapContext(ctx), inputBounds, &dstBounds)) {
return nullptr;
if (!this->applyCropRect(this->mapContext(ctx), srcBounds, &dstBounds)) {
return false;
}
if (!inputBounds.intersect(dstBounds)) {
return nullptr;
if (!srcBounds.intersect(dstBounds)) {
return false;
}
const SkVector sigma = map_sigma(fSigma, ctx.ctm());
#if SK_SUPPORT_GPU
if (input->peekTexture()) {
if (0 == sigma.x() && 0 == sigma.y()) {
offset->fX = inputBounds.x();
offset->fY = inputBounds.y();
return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-inputOffset.y())).release();
}
GrTexture* inputTexture = input->peekTexture();
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
inputBounds.offset(-inputOffset);
dstBounds.offset(-inputOffset);
SkRect inputBoundsF(SkRect::Make(inputBounds));
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(),
inputTexture,
false,
SkRect::Make(dstBounds),
&inputBoundsF,
sigma.x(),
sigma.y()));
if (!tex) {
return nullptr;
}
return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
kNeedNewImageUniqueID_SpecialImage,
tex).release();
}
#endif
SkVector sigma = map_sigma(fSigma, ctx.ctm());
int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
get_box3_params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
get_box3_params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
if (kernelSizeX < 0 || kernelSizeY < 0) {
return nullptr;
return false;
}
if (kernelSizeX == 0 && kernelSizeY == 0) {
offset->fX = inputBounds.x();
offset->fY = inputBounds.y();
return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-inputOffset.y())).release();
src.extractSubset(dst, srcBounds.makeOffset(-srcOffset.x(), -srcOffset.y()));
offset->fX = srcBounds.x();
offset->fY = srcBounds.y();
return true;
}
SkPixmap inputPixmap;
if (!input->peekPixels(&inputPixmap)) {
return nullptr;
SkAutoLockPixels alp(src);
if (!src.getPixels()) {
return false;
}
if (inputPixmap.colorType() != kN32_SkColorType) {
return nullptr;
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height()));
if (!device) {
return false;
}
*dst = device->accessBitmap(false);
SkAutoLockPixels alp_dst(*dst);
SkImageInfo info = SkImageInfo::Make(dstBounds.width(), dstBounds.height(),
inputPixmap.colorType(), inputPixmap.alphaType());
SkBitmap tmp, dst;
if (!tmp.tryAllocPixels(info) || !dst.tryAllocPixels(info)) {
return nullptr;
SkAutoTUnref<SkBaseDevice> tempDevice(proxy->createDevice(dst->width(), dst->height()));
if (!tempDevice) {
return false;
}
SkBitmap temp = tempDevice->accessBitmap(false);
SkAutoLockPixels alpTemp(temp);
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
SkPMColor* t = tmp.getAddr32(0, 0);
SkPMColor* d = dst.getAddr32(0, 0);
SkPMColor* t = temp.getAddr32(0, 0);
SkPMColor* d = dst->getAddr32(0, 0);
int w = dstBounds.width(), h = dstBounds.height();
const SkPMColor* s = inputPixmap.addr32(inputBounds.x() - inputOffset.x(),
inputBounds.y() - inputOffset.y());
inputBounds.offset(-dstBounds.x(), -dstBounds.y());
const SkPMColor* s = src.getAddr32(srcBounds.x() - srcOffset.x(), srcBounds.y() - srcOffset.y());
srcBounds.offset(-dstBounds.x(), -dstBounds.y());
dstBounds.offset(-dstBounds.x(), -dstBounds.y());
SkIRect inputBoundsT = SkIRect::MakeLTRB(inputBounds.top(), inputBounds.left(),
inputBounds.bottom(), inputBounds.right());
SkIRect srcBoundsT = SkIRect::MakeLTRB(srcBounds.top(), srcBounds.left(), srcBounds.bottom(), srcBounds.right());
SkIRect dstBoundsT = SkIRect::MakeWH(dstBounds.height(), dstBounds.width());
int sw = int(inputPixmap.rowBytes() >> 2);
int sw = src.rowBytesAsPixels();
/**
*
@ -194,26 +160,22 @@ SkSpecialImage* SkBlurImageFilter::onFilterImage(SkSpecialImage* source, const C
* images, and all memory reads are contiguous.
*/
if (kernelSizeX > 0 && kernelSizeY > 0) {
SkOpts::box_blur_xx(s, sw, inputBounds, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
SkOpts::box_blur_xy(d, w, dstBounds, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, h, dstBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
SkOpts::box_blur_xx(s, sw, srcBounds, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
SkOpts::box_blur_xy(d, w, dstBounds, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, h, dstBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
} else if (kernelSizeX > 0) {
SkOpts::box_blur_xx(s, sw, inputBounds, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(d, w, dstBounds, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(s, sw, srcBounds, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(d, w, dstBounds, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX3, highOffsetX, highOffsetX, w, h);
} else if (kernelSizeY > 0) {
SkOpts::box_blur_yx(s, sw, inputBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
SkOpts::box_blur_yx(s, sw, srcBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
}
return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
SkIRect::MakeWH(dstBounds.width(),
dstBounds.height()),
dst).release();
return true;
}
@ -231,6 +193,55 @@ SkIRect SkBlurImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix
SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
}
bool SkBlurImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
const Context& ctx,
SkBitmap* result, SkIPoint* offset) const {
#if SK_SUPPORT_GPU
SkBitmap input = src;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &input, &srcOffset)) {
return false;
}
SkIRect srcBounds = input.bounds();
srcBounds.offset(srcOffset);
SkIRect dstBounds;
if (!this->applyCropRect(this->mapContext(ctx), srcBounds, &dstBounds)) {
return false;
}
if (!srcBounds.intersect(dstBounds)) {
return false;
}
SkVector sigma = map_sigma(fSigma, ctx.ctm());
if (sigma.x() == 0 && sigma.y() == 0) {
input.extractSubset(result, srcBounds.makeOffset(-srcOffset.x(), -srcOffset.y()));
offset->fX = srcBounds.x();
offset->fY = srcBounds.y();
return true;
}
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
srcBounds.offset(-srcOffset);
dstBounds.offset(-srcOffset);
SkRect srcBoundsF(SkRect::Make(srcBounds));
GrTexture* inputTexture = input.getTexture();
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(),
inputTexture,
false,
SkRect::Make(dstBounds),
&srcBoundsF,
sigma.x(),
sigma.y()));
if (!tex) {
return false;
}
GrWrapTextureInBitmap(tex, dstBounds.width(), dstBounds.height(), false, result);
return true;
#else
SkDEBUGFAIL("Should not call in GPU-less build");
return false;
#endif
}
#ifndef SK_IGNORE_TO_STRING
void SkBlurImageFilter::toString(SkString* str) const {
str->appendf("SkBlurImageFilter: (");

View File

@ -221,38 +221,6 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(
return texture->asRenderTarget();
}
// This method ensures that we always have a texture-backed "bitmap" when we finally
// call through to the base impl so that the image filtering code will take the
// gpu-specific paths. This mirrors SkCanvas::internalDrawDevice (the other
// use of SkImageFilter::filterImage) in that the source and dest will have
// homogenous backing (e.g., raster or gpu).
void SkGpuDevice::drawBitmapAsSpriteWithImageFilter(const SkDraw& draw, const SkBitmap& bitmap,
int x, int y, const SkPaint& paint) {
if (bitmap.getTexture()) {
INHERITED::drawBitmapAsSpriteWithImageFilter(draw, bitmap, x, y, paint);
return;
}
SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
return;
}
GrTexture* texture;
// draw sprite neither filters nor tiles.
AutoBitmapTexture abt(fContext, bitmap, GrTextureParams::ClampNoFilter(), &texture);
if (!texture) {
return;
}
SkBitmap newBitmap;
GrWrapTextureInBitmap(texture, texture->width(), texture->height(),
bitmap.isOpaque(), &newBitmap);
INHERITED::drawBitmapAsSpriteWithImageFilter(draw, newBitmap, x, y, paint);
}
///////////////////////////////////////////////////////////////////////////////
bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,

View File

@ -262,9 +262,6 @@ private:
static GrRenderTarget* CreateRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&,
int sampleCount, GrTextureStorageAllocator);
void drawBitmapAsSpriteWithImageFilter(const SkDraw&, const SkBitmap&, int x, int y,
const SkPaint&) override;
friend class GrAtlasTextContext;
friend class SkSurface_Gpu; // for access to surfaceProps
typedef SkBaseDevice INHERITED;