commit-bot@chromium.org 2013-10-24 01:46:11 +00:00
parent e9821871ec
commit bbfe4541ef
5 changed files with 109 additions and 25 deletions

View File

@ -31,3 +31,5 @@
# ('Poppler random failures'): ignore any Poppler failures, for now
pdf-poppler
# Added by bsalomon, test case added in https://codereview.chromium.org/30593003
imagefiltersgraph

View File

@ -7,22 +7,88 @@
#include "gm.h"
#include "SkArithmeticMode.h"
#include "SkBitmapSource.h"
#include "SkBlurImageFilter.h"
#include "SkColorFilter.h"
#include "SkColorMatrixFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkFlattenableBuffers.h"
#include "SkMergeImageFilter.h"
#include "SkMorphologyImageFilter.h"
#include "SkOnce.h"
#include "SkXfermodeImageFilter.h"
#include "SkTestImageFilters.h"
///////////////////////////////////////////////////////////////////////////////
namespace {
// More closely models how Blink's OffsetFilter works as of 10/23/13. SkOffsetImageFilter doesn't
// perform a draw and this one does.
class SimpleOffsetFilter : public SkImageFilter {
public:
SimpleOffsetFilter(SkScalar dx, SkScalar dy, SkImageFilter* input)
: SkImageFilter(input), fDX(dx), fDY(dy) {}
virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
SkBitmap* dst, SkIPoint* offset) SK_OVERRIDE {
SkBitmap source = src;
SkImageFilter* input = getInput(0);
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (NULL != input && !input->filterImage(proxy, src, ctm, &source, &srcOffset)) {
return false;
}
SkIRect bounds;
source.getBounds(&bounds);
if (!this->applyCropRect(&bounds, ctm)) {
return false;
}
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
SkCanvas canvas(device);
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas.drawBitmap(source, fDX - bounds.left(), fDY - bounds.top(), &paint);
*dst = device->accessBitmap(false);
offset->fX += bounds.left();
offset->fY += bounds.top();
return true;
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SimpleOffsetFilter);
protected:
explicit SimpleOffsetFilter(SkFlattenableReadBuffer& buffer)
: SkImageFilter(buffer) {
fDX = buffer.readScalar();
fDY = buffer.readScalar();
}
virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {
this->SkImageFilter::flatten(buffer);
buffer.writeScalar(fDX);
buffer.writeScalar(fDY);
}
private:
SkScalar fDX, fDY;
};
}
static void init_flattenable(int*) {
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SimpleOffsetFilter)
}
class ImageFiltersGraphGM : public skiagm::GM {
public:
ImageFiltersGraphGM() : fInitialized(false) {}
ImageFiltersGraphGM() : fInitialized(false) {
int dummy;
SK_DECLARE_STATIC_ONCE(once);
SkOnce(&once, init_flattenable, &dummy);
}
protected:
virtual SkString onShortName() {
@ -43,7 +109,7 @@ protected:
canvas.drawText(str, strlen(str), SkIntToScalar(20), SkIntToScalar(70), paint);
}
virtual SkISize onISize() { return SkISize::Make(200, 100); }
virtual SkISize onISize() { return SkISize::Make(500, 150); }
virtual void onDraw(SkCanvas* canvas) {
if (!fInitialized) {
@ -81,6 +147,22 @@ protected:
paint.setImageFilter(blendColor);
canvas->drawBitmap(fBitmap, 100, 0, &paint);
}
{
SkScalar matrix[20] = { SK_Scalar1, 0, 0, 0, 0,
0, SK_Scalar1, 0, 0, 0,
0, 0, SK_Scalar1, 0, 0,
0, 0, 0, SkFloatToScalar(0.5f), 0 };
SkColorMatrixFilter matrixCF(matrix);
SkAutoTUnref<SkImageFilter> matrixFilter(SkColorFilterImageFilter::Create(&matrixCF));
SimpleOffsetFilter offsetFilter(SkIntToScalar(10), SkIntToScalar(10), matrixFilter);
SkAutoTUnref<SkXfermode> arith(SkArithmeticMode::Create(0, SK_Scalar1, SK_Scalar1, 0));
SkXfermodeImageFilter arithFilter(arith, matrixFilter, &offsetFilter);
SkPaint paint;
paint.setImageFilter(&arithFilter);
canvas->drawSprite(fBitmap, 200, 0, &paint);
}
}
private:

View File

@ -191,13 +191,11 @@ private:
const SkRect* srcRectPtr) const;
void internalDrawBitmap(const SkBitmap&,
const SkRect&,
const SkMatrix&,
const GrTextureParams& params,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags);
void drawTiledBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
const SkMatrix& m,
const GrTextureParams& params,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags);

View File

@ -23,6 +23,11 @@ bool SkImageFilterUtils::WrapTexture(GrTexture* texture, int width, int height,
bool SkImageFilterUtils::GetInputResultGPU(SkImageFilter* filter, SkImageFilter::Proxy* proxy,
const SkBitmap& src, const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset) {
// Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity
// matrix with no clip and that the matrix, clip, and render target set before this function was
// called are restored before we return to the caller.
GrContext* context = src.getTexture()->getContext();
GrContext::AutoWideOpenIdentityDraw awoid(context, NULL);
if (!filter) {
*result = src;
return true;
@ -31,9 +36,7 @@ bool SkImageFilterUtils::GetInputResultGPU(SkImageFilter* filter, SkImageFilter:
} else {
if (filter->filterImage(proxy, src, ctm, result, offset)) {
if (!result->getTexture()) {
GrContext* context = ((GrTexture *) src.getTexture())->getContext();
GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context,
*result, NULL);
GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context, *result, NULL);
result->setPixelRef(new SkGrPixelRef(resultTex))->unref();
GrUnlockAndUnrefCachedBitmapTexture(resultTex);
}

View File

@ -1164,6 +1164,8 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
return;
}
fContext->concatMatrix(m);
GrTextureParams params;
SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
GrTextureParams::FilterMode textureFilterMode;
@ -1195,9 +1197,9 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) {
// take the simple case
this->internalDrawBitmap(bitmap, srcRect, m, params, paint, flags);
this->internalDrawBitmap(bitmap, srcRect, params, paint, flags);
} else {
this->drawTiledBitmap(bitmap, srcRect, m, params, paint, flags);
this->drawTiledBitmap(bitmap, srcRect, params, paint, flags);
}
}
@ -1205,7 +1207,6 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
// been determined to be too large to fit in VRAM
void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
const SkMatrix& m,
const GrTextureParams& params,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags) {
@ -1226,9 +1227,8 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) {
return;
}
SkMatrix matrix, inverse;
matrix.setConcat(fContext->getMatrix(), m);
if (!matrix.invert(&inverse)) {
SkMatrix inverse;
if (!fContext->getMatrix().invert(&inverse)) {
return;
}
inverse.mapRect(&clipRect);
@ -1278,10 +1278,11 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
if (bitmap.extractSubset(&tmpB, iTileR)) {
// now offset it to make it "local" to our tmp bitmap
tileR.offset(-offset.fX, -offset.fY);
SkMatrix tmpM(m);
tmpM.preTranslate(offset.fX, offset.fY);
this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint, flags);
SkMatrix tmpM;
tmpM.setTranslate(offset.fX, offset.fY);
GrContext::AutoMatrix am;
am.setPreConcat(fContext, tmpM);
this->internalDrawBitmap(tmpB, tileR, params, paint, flags);
}
}
}
@ -1338,7 +1339,6 @@ static bool may_color_bleed(const SkRect& srcRect,
*/
void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
const SkMatrix& m,
const GrTextureParams& params,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags) {
@ -1366,19 +1366,18 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
// Need texture domain if drawing a sub rect.
needsTextureDomain = srcRect.width() < bitmap.width() ||
srcRect.height() < bitmap.height();
if (needsTextureDomain && m.rectStaysRect() && fContext->getMatrix().rectStaysRect()) {
if (needsTextureDomain && fContext->getMatrix().rectStaysRect()) {
const SkMatrix& matrix = fContext->getMatrix();
// sampling is axis-aligned
SkRect transformedRect;
SkMatrix srcToDeviceMatrix(m);
srcToDeviceMatrix.postConcat(fContext->getMatrix());
srcToDeviceMatrix.mapRect(&transformedRect, srcRect);
matrix.mapRect(&transformedRect, srcRect);
if (has_aligned_samples(srcRect, transformedRect)) {
// We could also turn off filtering here (but we already did a cache lookup with
// params).
needsTextureDomain = false;
} else {
needsTextureDomain = may_color_bleed(srcRect, transformedRect, m);
needsTextureDomain = may_color_bleed(srcRect, transformedRect, matrix);
}
}
}
@ -1421,7 +1420,7 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
return;
}
fContext->drawRectToRect(grPaint, dstRect, paintRect, &m);
fContext->drawRectToRect(grPaint, dstRect, paintRect, NULL);
}
static bool filter_texture(SkBaseDevice* device, GrContext* context,