Move gaussianBlur functionality to src\effects
https://codereview.chromium.org/18771004/ git-svn-id: http://skia.googlecode.com/svn/trunk@10080 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
3dd2784cb7
commit
736dd031f1
@ -31,6 +31,8 @@
|
||||
'<(skia_src_path)/effects/SkEmbossMask.h',
|
||||
'<(skia_src_path)/effects/SkEmbossMask_Table.h',
|
||||
'<(skia_src_path)/effects/SkEmbossMaskFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkGpuBlurUtils.h',
|
||||
'<(skia_src_path)/effects/SkGpuBlurUtils.cpp',
|
||||
'<(skia_src_path)/effects/SkKernel33MaskFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkLayerDrawLooper.cpp',
|
||||
'<(skia_src_path)/effects/SkLayerRasterizer.cpp',
|
||||
|
@ -619,22 +619,6 @@ public:
|
||||
*/
|
||||
void resolveRenderTarget(GrRenderTarget* target);
|
||||
|
||||
/**
|
||||
* Applies a 2D Gaussian blur to a given texture.
|
||||
* @param srcTexture The source texture to be blurred.
|
||||
* @param canClobberSrc If true, srcTexture may be overwritten, and
|
||||
* may be returned as the result.
|
||||
* @param rect The destination rectangle.
|
||||
* @param sigmaX The blur's standard deviation in X.
|
||||
* @param sigmaY The blur's standard deviation in Y.
|
||||
* @return the blurred texture, which may be srcTexture reffed, or a
|
||||
* new texture. It is the caller's responsibility to unref this texture.
|
||||
*/
|
||||
GrTexture* gaussianBlur(GrTexture* srcTexture,
|
||||
bool canClobberSrc,
|
||||
const SkRect& rect,
|
||||
float sigmaX, float sigmaY);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "SkBlurImageFilter.h"
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkFlattenableBuffers.h"
|
||||
#include "SkGpuBlurUtils.h"
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContext.h"
|
||||
#include "SkImageFilterUtils.h"
|
||||
@ -203,8 +204,9 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBitm
|
||||
GrTexture* source = input.getTexture();
|
||||
SkRect rect;
|
||||
src.getBounds(&rect);
|
||||
SkAutoTUnref<GrTexture> tex(source->getContext()->gaussianBlur(source, false, rect,
|
||||
fSigma.width(), fSigma.height()));
|
||||
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(source->getContext(),
|
||||
source, false, rect,
|
||||
fSigma.width(), fSigma.height()));
|
||||
return SkImageFilterUtils::WrapTexture(tex, src.width(), src.height(), result);
|
||||
#else
|
||||
SkDEBUGFAIL("Should not call in GPU-less build");
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "SkBlurMaskFilter.h"
|
||||
#include "SkBlurMask.h"
|
||||
#include "SkGpuBlurUtils.h"
|
||||
#include "SkFlattenableBuffers.h"
|
||||
#include "SkMaskFilter.h"
|
||||
#include "SkRTConf.h"
|
||||
@ -410,8 +411,8 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
|
||||
// If we're doing a normal blur, we can clobber the pathTexture in the
|
||||
// gaussianBlur. Otherwise, we need to save it for later compositing.
|
||||
bool isNormalBlur = (SkBlurMaskFilter::kNormal_BlurStyle == fBlurStyle);
|
||||
*result = context->gaussianBlur(src, isNormalBlur && canOverwriteSrc,
|
||||
clipRect, sigma, sigma);
|
||||
*result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOverwriteSrc,
|
||||
clipRect, sigma, sigma);
|
||||
if (NULL == *result) {
|
||||
return false;
|
||||
}
|
||||
|
187
src/effects/SkGpuBlurUtils.cpp
Normal file
187
src/effects/SkGpuBlurUtils.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkGpuBlurUtils.h"
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "effects/GrConvolutionEffect.h"
|
||||
#include "GrContext.h"
|
||||
#endif
|
||||
|
||||
namespace SkGpuBlurUtils {
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
|
||||
#define MAX_BLUR_SIGMA 4.0f
|
||||
|
||||
static void scale_rect(SkRect* rect, float xScale, float yScale) {
|
||||
rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale));
|
||||
rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale));
|
||||
rect->fRight = SkScalarMul(rect->fRight, SkFloatToScalar(xScale));
|
||||
rect->fBottom = SkScalarMul(rect->fBottom, SkFloatToScalar(yScale));
|
||||
}
|
||||
|
||||
static float adjust_sigma(float sigma, int *scaleFactor, int *radius) {
|
||||
*scaleFactor = 1;
|
||||
while (sigma > MAX_BLUR_SIGMA) {
|
||||
*scaleFactor *= 2;
|
||||
sigma *= 0.5f;
|
||||
}
|
||||
*radius = static_cast<int>(ceilf(sigma * 3.0f));
|
||||
GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius);
|
||||
return sigma;
|
||||
}
|
||||
|
||||
static void convolve_gaussian(GrContext* context,
|
||||
GrTexture* texture,
|
||||
const SkRect& rect,
|
||||
float sigma,
|
||||
int radius,
|
||||
Gr1DKernelEffect::Direction direction) {
|
||||
GrPaint paint;
|
||||
|
||||
SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(texture,
|
||||
direction,
|
||||
radius,
|
||||
sigma));
|
||||
paint.addColorEffect(conv);
|
||||
context->drawRect(paint, rect);
|
||||
}
|
||||
|
||||
GrTexture* GaussianBlur(GrContext* context,
|
||||
GrTexture* srcTexture,
|
||||
bool canClobberSrc,
|
||||
const SkRect& rect,
|
||||
float sigmaX,
|
||||
float sigmaY) {
|
||||
GrAssert(NULL != context);
|
||||
|
||||
GrContext::AutoRenderTarget art(context);
|
||||
|
||||
GrContext::AutoMatrix am;
|
||||
am.setIdentity(context);
|
||||
|
||||
SkIRect clearRect;
|
||||
int scaleFactorX, radiusX;
|
||||
int scaleFactorY, radiusY;
|
||||
sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX);
|
||||
sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY);
|
||||
|
||||
SkRect srcRect(rect);
|
||||
scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
|
||||
srcRect.roundOut();
|
||||
scale_rect(&srcRect, static_cast<float>(scaleFactorX),
|
||||
static_cast<float>(scaleFactorY));
|
||||
|
||||
GrContext::AutoClip acs(context, srcRect);
|
||||
|
||||
GrAssert(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
|
||||
kRGBA_8888_GrPixelConfig == srcTexture->config() ||
|
||||
kAlpha_8_GrPixelConfig == srcTexture->config());
|
||||
|
||||
GrTextureDesc desc;
|
||||
desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
|
||||
desc.fWidth = SkScalarFloorToInt(srcRect.width());
|
||||
desc.fHeight = SkScalarFloorToInt(srcRect.height());
|
||||
desc.fConfig = srcTexture->config();
|
||||
|
||||
GrAutoScratchTexture temp1, temp2;
|
||||
GrTexture* dstTexture = temp1.set(context, desc);
|
||||
GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(context, desc);
|
||||
if (NULL == dstTexture || NULL == tempTexture) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
|
||||
GrPaint paint;
|
||||
SkMatrix matrix;
|
||||
matrix.setIDiv(srcTexture->width(), srcTexture->height());
|
||||
context->setRenderTarget(dstTexture->asRenderTarget());
|
||||
SkRect dstRect(srcRect);
|
||||
scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
|
||||
i < scaleFactorY ? 0.5f : 1.0f);
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, true);
|
||||
paint.addColorTextureEffect(srcTexture, matrix, params);
|
||||
context->drawRectToRect(paint, dstRect, srcRect);
|
||||
srcRect = dstRect;
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
|
||||
SkIRect srcIRect;
|
||||
srcRect.roundOut(&srcIRect);
|
||||
|
||||
if (sigmaX > 0.0f) {
|
||||
if (scaleFactorX > 1) {
|
||||
// Clear out a radius to the right of the srcRect to prevent the
|
||||
// X convolution from reading garbage.
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
|
||||
radiusX, srcIRect.height());
|
||||
context->clear(&clearRect, 0x0);
|
||||
}
|
||||
context->setRenderTarget(dstTexture->asRenderTarget());
|
||||
convolve_gaussian(context, srcTexture, srcRect, sigmaX, radiusX,
|
||||
Gr1DKernelEffect::kX_Direction);
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
|
||||
if (sigmaY > 0.0f) {
|
||||
if (scaleFactorY > 1 || sigmaX > 0.0f) {
|
||||
// Clear out a radius below the srcRect to prevent the Y
|
||||
// convolution from reading garbage.
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
|
||||
srcIRect.width(), radiusY);
|
||||
context->clear(&clearRect, 0x0);
|
||||
}
|
||||
|
||||
context->setRenderTarget(dstTexture->asRenderTarget());
|
||||
convolve_gaussian(context, srcTexture, srcRect, sigmaY, radiusY,
|
||||
Gr1DKernelEffect::kY_Direction);
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
|
||||
if (scaleFactorX > 1 || scaleFactorY > 1) {
|
||||
// Clear one pixel to the right and below, to accommodate bilinear
|
||||
// upsampling.
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
|
||||
srcIRect.width() + 1, 1);
|
||||
context->clear(&clearRect, 0x0);
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
|
||||
1, srcIRect.height());
|
||||
context->clear(&clearRect, 0x0);
|
||||
SkMatrix matrix;
|
||||
matrix.setIDiv(srcTexture->width(), srcTexture->height());
|
||||
context->setRenderTarget(dstTexture->asRenderTarget());
|
||||
|
||||
GrPaint paint;
|
||||
// FIXME: this should be mitchell, not bilinear.
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, true);
|
||||
paint.addColorTextureEffect(srcTexture, matrix, params);
|
||||
|
||||
SkRect dstRect(srcRect);
|
||||
scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
|
||||
context->drawRectToRect(paint, dstRect, srcRect);
|
||||
srcRect = dstRect;
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
if (srcTexture == temp1.texture()) {
|
||||
return temp1.detach();
|
||||
} else if (srcTexture == temp2.texture()) {
|
||||
return temp2.detach();
|
||||
} else {
|
||||
srcTexture->ref();
|
||||
return srcTexture;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
43
src/effects/SkGpuBlurUtils.h
Normal file
43
src/effects/SkGpuBlurUtils.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkGpuBlurUtils_DEFINED
|
||||
#define SkGpuBlurUtils_DEFINED
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
class GrTexture;
|
||||
class GrContext;
|
||||
#endif
|
||||
|
||||
struct SkRect;
|
||||
|
||||
namespace SkGpuBlurUtils {
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
/**
|
||||
* Applies a 2D Gaussian blur to a given texture.
|
||||
* @param context The GPU context
|
||||
* @param srcTexture The source texture to be blurred.
|
||||
* @param canClobberSrc If true, srcTexture may be overwritten, and
|
||||
* may be returned as the result.
|
||||
* @param rect The destination rectangle.
|
||||
* @param sigmaX The blur's standard deviation in X.
|
||||
* @param sigmaY The blur's standard deviation in Y.
|
||||
* @return the blurred texture, which may be srcTexture reffed, or a
|
||||
* new texture. It is the caller's responsibility to unref this texture.
|
||||
*/
|
||||
GrTexture* GaussianBlur(GrContext* context,
|
||||
GrTexture* srcTexture,
|
||||
bool canClobberSrc,
|
||||
const SkRect& rect,
|
||||
float sigmaX,
|
||||
float sigmaY);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "GrContext.h"
|
||||
|
||||
#include "effects/GrConvolutionEffect.h"
|
||||
#include "effects/GrSingleTextureEffect.h"
|
||||
#include "effects/GrConfigConversionEffect.h"
|
||||
|
||||
@ -42,8 +41,6 @@ SK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true,
|
||||
|
||||
#define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw)
|
||||
|
||||
#define MAX_BLUR_SIGMA 4.0f
|
||||
|
||||
// When we're using coverage AA but the blend is incompatible (given gpu
|
||||
// limitations) should we disable AA or draw wrong?
|
||||
#define DISABLE_COVERAGE_AA_FOR_BLEND 1
|
||||
@ -230,48 +227,6 @@ size_t GrContext::getGpuTextureCacheBytes() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
|
||||
void scale_rect(SkRect* rect, float xScale, float yScale) {
|
||||
rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale));
|
||||
rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale));
|
||||
rect->fRight = SkScalarMul(rect->fRight, SkFloatToScalar(xScale));
|
||||
rect->fBottom = SkScalarMul(rect->fBottom, SkFloatToScalar(yScale));
|
||||
}
|
||||
|
||||
float adjust_sigma(float sigma, int *scaleFactor, int *radius) {
|
||||
*scaleFactor = 1;
|
||||
while (sigma > MAX_BLUR_SIGMA) {
|
||||
*scaleFactor *= 2;
|
||||
sigma *= 0.5f;
|
||||
}
|
||||
*radius = static_cast<int>(ceilf(sigma * 3.0f));
|
||||
GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius);
|
||||
return sigma;
|
||||
}
|
||||
|
||||
void convolve_gaussian(GrDrawTarget* target,
|
||||
GrTexture* texture,
|
||||
const SkRect& rect,
|
||||
float sigma,
|
||||
int radius,
|
||||
Gr1DKernelEffect::Direction direction) {
|
||||
GrRenderTarget* rt = target->drawState()->getRenderTarget();
|
||||
GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit);
|
||||
GrDrawState* drawState = target->drawState();
|
||||
drawState->setRenderTarget(rt);
|
||||
SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(texture,
|
||||
direction,
|
||||
radius,
|
||||
sigma));
|
||||
drawState->addColorEffect(conv);
|
||||
target->drawSimpleRect(rect, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc,
|
||||
const GrCacheID& cacheID,
|
||||
const GrTextureParams* params) {
|
||||
@ -1724,139 +1679,6 @@ const GrEffectRef* GrContext::createUPMToPMEffect(GrTexture* texture,
|
||||
}
|
||||
}
|
||||
|
||||
GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
|
||||
bool canClobberSrc,
|
||||
const SkRect& rect,
|
||||
float sigmaX, float sigmaY) {
|
||||
ASSERT_OWNED_RESOURCE(srcTexture);
|
||||
|
||||
AutoRenderTarget art(this);
|
||||
|
||||
AutoMatrix am;
|
||||
am.setIdentity(this);
|
||||
|
||||
SkIRect clearRect;
|
||||
int scaleFactorX, radiusX;
|
||||
int scaleFactorY, radiusY;
|
||||
sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX);
|
||||
sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY);
|
||||
|
||||
SkRect srcRect(rect);
|
||||
scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
|
||||
srcRect.roundOut();
|
||||
scale_rect(&srcRect, static_cast<float>(scaleFactorX),
|
||||
static_cast<float>(scaleFactorY));
|
||||
|
||||
AutoClip acs(this, srcRect);
|
||||
|
||||
GrAssert(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
|
||||
kRGBA_8888_GrPixelConfig == srcTexture->config() ||
|
||||
kAlpha_8_GrPixelConfig == srcTexture->config());
|
||||
|
||||
GrTextureDesc desc;
|
||||
desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
|
||||
desc.fWidth = SkScalarFloorToInt(srcRect.width());
|
||||
desc.fHeight = SkScalarFloorToInt(srcRect.height());
|
||||
desc.fConfig = srcTexture->config();
|
||||
|
||||
GrAutoScratchTexture temp1, temp2;
|
||||
GrTexture* dstTexture = temp1.set(this, desc);
|
||||
GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(this, desc);
|
||||
if (NULL == dstTexture || NULL == tempTexture) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
|
||||
GrPaint paint;
|
||||
SkMatrix matrix;
|
||||
matrix.setIDiv(srcTexture->width(), srcTexture->height());
|
||||
this->setRenderTarget(dstTexture->asRenderTarget());
|
||||
SkRect dstRect(srcRect);
|
||||
scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
|
||||
i < scaleFactorY ? 0.5f : 1.0f);
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, true);
|
||||
paint.addColorTextureEffect(srcTexture, matrix, params);
|
||||
this->drawRectToRect(paint, dstRect, srcRect);
|
||||
srcRect = dstRect;
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
|
||||
SkIRect srcIRect;
|
||||
srcRect.roundOut(&srcIRect);
|
||||
|
||||
if (sigmaX > 0.0f) {
|
||||
if (scaleFactorX > 1) {
|
||||
// Clear out a radius to the right of the srcRect to prevent the
|
||||
// X convolution from reading garbage.
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
|
||||
radiusX, srcIRect.height());
|
||||
this->clear(&clearRect, 0x0);
|
||||
}
|
||||
GrPaint paint;
|
||||
this->setRenderTarget(dstTexture->asRenderTarget());
|
||||
AutoRestoreEffects are;
|
||||
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are);
|
||||
convolve_gaussian(target, srcTexture, srcRect, sigmaX, radiusX,
|
||||
Gr1DKernelEffect::kX_Direction);
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
|
||||
if (sigmaY > 0.0f) {
|
||||
if (scaleFactorY > 1 || sigmaX > 0.0f) {
|
||||
// Clear out a radius below the srcRect to prevent the Y
|
||||
// convolution from reading garbage.
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
|
||||
srcIRect.width(), radiusY);
|
||||
this->clear(&clearRect, 0x0);
|
||||
}
|
||||
|
||||
this->setRenderTarget(dstTexture->asRenderTarget());
|
||||
GrPaint paint;
|
||||
AutoRestoreEffects are;
|
||||
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are);
|
||||
convolve_gaussian(target, srcTexture, srcRect, sigmaY, radiusY,
|
||||
Gr1DKernelEffect::kY_Direction);
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
|
||||
if (scaleFactorX > 1 || scaleFactorY > 1) {
|
||||
// Clear one pixel to the right and below, to accommodate bilinear
|
||||
// upsampling.
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
|
||||
srcIRect.width() + 1, 1);
|
||||
this->clear(&clearRect, 0x0);
|
||||
clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
|
||||
1, srcIRect.height());
|
||||
this->clear(&clearRect, 0x0);
|
||||
SkMatrix matrix;
|
||||
matrix.setIDiv(srcTexture->width(), srcTexture->height());
|
||||
this->setRenderTarget(dstTexture->asRenderTarget());
|
||||
|
||||
GrPaint paint;
|
||||
// FIXME: This should be mitchell, not bilinear.
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, true);
|
||||
paint.addColorTextureEffect(srcTexture, matrix, params);
|
||||
|
||||
SkRect dstRect(srcRect);
|
||||
scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
|
||||
this->drawRectToRect(paint, dstRect, srcRect);
|
||||
srcRect = dstRect;
|
||||
srcTexture = dstTexture;
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
if (srcTexture == temp1.texture()) {
|
||||
return temp1.detach();
|
||||
} else if (srcTexture == temp2.texture()) {
|
||||
return temp2.detach();
|
||||
} else {
|
||||
srcTexture->ref();
|
||||
return srcTexture;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if GR_CACHE_STATS
|
||||
void GrContext::printCacheStats() const {
|
||||
|
Loading…
Reference in New Issue
Block a user