本文整理汇总了C++中GrPaint::setPorterDuffXPFactory方法的典型用法代码示例。如果您正苦于以下问题:C++ GrPaint::setPorterDuffXPFactory方法的具体用法?C++ GrPaint::setPorterDuffXPFactory怎么用?C++ GrPaint::setPorterDuffXPFactory使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrPaint
的用法示例。
在下文中一共展示了GrPaint::setPorterDuffXPFactory方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: convert_texture
static bool convert_texture(GrTexture* src, GrDrawContext* dst, int dstW, int dstH,
SkYUVColorSpace colorSpace, MakeFPProc proc) {
SkScalar xScale = SkIntToScalar(src->width()) / dstW / src->width();
SkScalar yScale = SkIntToScalar(src->height()) / dstH / src->height();
GrTextureParams::FilterMode filter;
if (dstW == src->width() && dstW == src->height()) {
filter = GrTextureParams::kNone_FilterMode;
} else {
filter = GrTextureParams::kBilerp_FilterMode;
}
sk_sp<GrFragmentProcessor> fp(
GrSimpleTextureEffect::Make(src, SkMatrix::MakeScale(xScale, yScale), filter));
if (!fp) {
return false;
}
fp = proc(std::move(fp), colorSpace);
if (!fp) {
return false;
}
GrPaint paint;
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
paint.addColorFragmentProcessor(std::move(fp));
dst->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH));
return true;
}
示例2: sk_ref_sp
sk_sp<SkImage> SkImage_Gpu::onMakeColorSpace(sk_sp<SkColorSpace> colorSpace) const {
sk_sp<SkColorSpace> srcSpace = fColorSpace ? fColorSpace : SkColorSpace::MakeSRGB();
auto xform = GrNonlinearColorSpaceXformEffect::Make(srcSpace.get(), colorSpace.get());
if (!xform) {
return sk_ref_sp(const_cast<SkImage_Gpu*>(this));
}
sk_sp<GrRenderTargetContext> renderTargetContext(fContext->makeRenderTargetContext(
SkBackingFit::kExact, this->width(), this->height(), kRGBA_8888_GrPixelConfig, nullptr));
if (!renderTargetContext) {
return nullptr;
}
GrPaint paint;
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
paint.addColorTextureProcessor(fContext->resourceProvider(), fProxy, nullptr, SkMatrix::I());
paint.addColorFragmentProcessor(std::move(xform));
const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
if (!renderTargetContext->asTextureProxy()) {
return nullptr;
}
// MDB: this call is okay bc we know 'renderTargetContext' was exact
return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID,
fAlphaType, renderTargetContext->asTextureProxyRef(),
std::move(colorSpace), fBudgeted);
}
示例3: conv
static void convolve_gaussian_2d(GrDrawContext* drawContext,
const GrClip& clip,
const SkIRect& dstRect,
const SkIPoint& srcOffset,
GrTexture* texture,
int radiusX,
int radiusY,
SkScalar sigmaX,
SkScalar sigmaY,
const SkIRect* srcBounds) {
SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()),
-SkIntToScalar(srcOffset.y()));
SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
GrPaint paint;
paint.setGammaCorrect(drawContext->isGammaCorrect());
SkIRect bounds = srcBounds ? *srcBounds : SkIRect::EmptyIRect();
sk_sp<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::MakeGaussian(
texture, bounds, size, 1.0, 0.0, kernelOffset,
srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_Mode,
true, sigmaX, sigmaY));
paint.addColorFragmentProcessor(std::move(conv));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(),
SkRect::Make(dstRect), localMatrix);
}
示例4: clip
sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context,
sk_sp<GrFragmentProcessor> fp,
const SkIRect& bounds) {
GrPaint paint;
paint.addColorFragmentProcessor(fp.get());
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kRGBA_8888_GrPixelConfig;
sk_sp<GrTexture> dst(context->textureProvider()->createApproxTexture(desc));
if (!dst) {
return nullptr;
}
sk_sp<GrDrawContext> drawContext(context->drawContext(sk_ref_sp(dst->asRenderTarget())));
if (!drawContext) {
return nullptr;
}
SkRect srcRect = SkRect::Make(bounds);
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
GrClip clip(dstRect);
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
std::move(dst));
}
示例5: conv
static void convolve_gaussian_2d(GrDrawContext* drawContext,
const GrClip& clip,
const SkRect& dstRect,
const SkPoint& srcOffset,
GrTexture* texture,
int radiusX,
int radiusY,
SkScalar sigmaX,
SkScalar sigmaY,
const SkRect* srcBounds) {
SkMatrix localMatrix = SkMatrix::MakeTrans(-srcOffset.x(), -srcOffset.y());
SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1);
SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
GrPaint paint;
SkIRect bounds;
if (srcBounds) {
srcBounds->roundOut(&bounds);
} else {
bounds.setEmpty();
}
SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaussian(
texture, bounds, size, 1.0, 0.0, kernelOffset,
srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_Mode,
true, sigmaX, sigmaY));
paint.addColorFragmentProcessor(conv);
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, localMatrix);
}
示例6: clip
sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context,
sk_sp<GrFragmentProcessor> fp,
const SkIRect& bounds,
sk_sp<SkColorSpace> colorSpace) {
GrPaint paint;
paint.addColorFragmentProcessor(std::move(fp));
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
sk_sp<GrDrawContext> drawContext(context->makeDrawContext(SkBackingFit::kApprox,
bounds.width(), bounds.height(),
kRGBA_8888_GrPixelConfig,
std::move(colorSpace)));
if (!drawContext) {
return nullptr;
}
SkIRect dstIRect = SkIRect::MakeWH(bounds.width(), bounds.height());
SkRect srcRect = SkRect::Make(bounds);
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
GrFixedClip clip(dstIRect);
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
return SkSpecialImage::MakeFromGpu(dstIRect, kNeedNewImageUniqueID_SpecialImage,
drawContext->asTexture(),
sk_ref_sp(drawContext->getColorSpace()));
}
示例7: filterImageGPU
bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
SkBitmap* result, SkIPoint* offset) const {
#if SK_SUPPORT_GPU
SkBitmap input = src;
SkASSERT(fInputCount == 1);
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!this->filterInputGPU(0, proxy, src, ctx, &input, &srcOffset)) {
return false;
}
GrTexture* srcTexture = input.getTexture();
SkIRect bounds;
if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) {
return false;
}
SkRect srcRect = SkRect::Make(bounds);
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
GrContext* context = srcTexture->getContext();
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag,
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kRGBA_8888_GrPixelConfig;
SkAutoTUnref<GrTexture> dst(context->textureProvider()->createTexture(desc,
GrTextureProvider::FromImageFilter(ctx.sizeConstraint())));
if (!dst) {
return false;
}
// setup new clip
GrClip clip(dstRect);
GrFragmentProcessor* fp;
offset->fX = bounds.left();
offset->fY = bounds.top();
bounds.offset(-srcOffset);
SkMatrix matrix(ctx.ctm());
matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
GrPaint paint;
if (this->asFragmentProcessor(&fp, srcTexture, matrix, bounds)) {
SkASSERT(fp);
paint.addColorFragmentProcessor(fp)->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
if (drawContext) {
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
WrapTexture(dst, bounds.width(), bounds.height(), result);
return true;
}
}
#endif
return false;
}
示例8: samplerState
sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context,
sk_sp<GrTextureProxy> inputProxy,
const CopyParams& copyParams,
bool dstWillRequireMipMaps) {
SkASSERT(context);
const SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight);
GrMipMapped mipMapped = dstWillRequireMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
SkRect localRect = SkRect::MakeWH(inputProxy->width(), inputProxy->height());
bool needsDomain = false;
bool resizing = false;
if (copyParams.fFilter != GrSamplerState::Filter::kNearest) {
bool resizing = localRect.width() != dstRect.width() ||
localRect.height() != dstRect.height();
needsDomain = resizing && !GrProxyProvider::IsFunctionallyExact(inputProxy.get());
}
if (copyParams.fFilter == GrSamplerState::Filter::kNearest && !needsDomain && !resizing &&
dstWillRequireMipMaps) {
sk_sp<GrTextureProxy> proxy = GrCopyBaseMipMapToTextureProxy(context, inputProxy.get());
if (proxy) {
return proxy;
}
}
sk_sp<GrRenderTargetContext> copyRTC =
context->contextPriv().makeDeferredRenderTargetContextWithFallback(
SkBackingFit::kExact, dstRect.width(), dstRect.height(), inputProxy->config(),
nullptr, 1, mipMapped, inputProxy->origin());
if (!copyRTC) {
return nullptr;
}
GrPaint paint;
if (needsDomain) {
const SkRect domain = localRect.makeInset(0.5f, 0.5f);
// This would cause us to read values from outside the subset. Surely, the caller knows
// better!
SkASSERT(copyParams.fFilter != GrSamplerState::Filter::kMipMap);
paint.addColorFragmentProcessor(
GrTextureDomainEffect::Make(std::move(inputProxy), SkMatrix::I(), domain,
GrTextureDomain::kClamp_Mode, copyParams.fFilter));
} else {
GrSamplerState samplerState(GrSamplerState::WrapMode::kClamp, copyParams.fFilter);
paint.addColorTextureProcessor(std::move(inputProxy), SkMatrix::I(), samplerState);
}
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
copyRTC->fillRectToRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), dstRect,
localRect);
return copyRTC->asTextureProxyRef();
}
示例9: apply_morphology_rect_no_bounds
static void apply_morphology_rect_no_bounds(GrRenderTargetContext* renderTargetContext,
const GrClip& clip,
sk_sp<GrTextureProxy> proxy,
const SkIRect& srcRect,
const SkIRect& dstRect,
int radius,
GrMorphologyEffect::Type morphType,
GrMorphologyEffect::Direction direction) {
GrPaint paint;
paint.addColorFragmentProcessor(GrMorphologyEffect::Make(std::move(proxy),
direction, radius, morphType));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
SkRect::Make(dstRect), SkRect::Make(srcRect));
}
示例10: apply_morphology_rect_no_bounds
static void apply_morphology_rect_no_bounds(GrDrawContext* drawContext,
const GrClip& clip,
GrTexture* texture,
const SkIRect& srcRect,
const SkIRect& dstRect,
int radius,
GrMorphologyEffect::MorphologyType morphType,
Gr1DKernelEffect::Direction direction) {
GrPaint paint;
paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture,
direction,
radius,
morphType))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
SkRect::Make(srcRect));
}
示例11: test_basic_draw_as_src
// skbug.com/5932
static void test_basic_draw_as_src(skiatest::Reporter* reporter, GrContext* context,
sk_sp<GrTextureProxy> rectProxy, uint32_t expectedPixelValues[]) {
sk_sp<GrRenderTargetContext> rtContext(context->contextPriv().makeDeferredRenderTargetContext(
SkBackingFit::kExact, rectProxy->width(),
rectProxy->height(), rectProxy->config(),
nullptr));
for (auto filter : {GrSamplerState::Filter::kNearest,
GrSamplerState::Filter::kBilerp,
GrSamplerState::Filter::kMipMap}) {
rtContext->clear(nullptr, 0xDDCCBBAA, GrRenderTargetContext::CanClearFullscreen::kYes);
auto fp = GrSimpleTextureEffect::Make(rectProxy, SkMatrix::I(), filter);
GrPaint paint;
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
paint.addColorFragmentProcessor(std::move(fp));
rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
test_read_pixels(reporter, rtContext.get(), expectedPixelValues,
"RectangleTexture-basic-draw");
}
}
示例12: clip
sk_sp<SkSpecialImage> SkImageFilter::DrawWithFP(GrContext* context,
sk_sp<GrFragmentProcessor> fp,
const SkIRect& bounds) {
GrPaint paint;
paint.addColorFragmentProcessor(fp.get());
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
bounds.width(), bounds.height(),
kRGBA_8888_GrPixelConfig));
if (!drawContext) {
return nullptr;
}
SkRect srcRect = SkRect::Make(bounds);
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
GrClip clip(dstRect);
drawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
drawContext->asTexture());
}
示例13: drawContext
sk_sp<GrTexture> GrYUVProvider::refAsTexture(GrContext* ctx,
const GrSurfaceDesc& desc,
bool useCache) {
SkYUVPlanesCache::Info yuvInfo;
void* planes[3];
YUVScoper scoper;
if (!scoper.init(this, &yuvInfo, planes, useCache)) {
return nullptr;
}
GrSurfaceDesc yuvDesc;
yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
SkAutoTUnref<GrTexture> yuvTextures[3];
for (int i = 0; i < 3; i++) {
yuvDesc.fWidth = yuvInfo.fSizeInfo.fSizes[i].fWidth;
yuvDesc.fHeight = yuvInfo.fSizeInfo.fSizes[i].fHeight;
// TODO: why do we need this check?
bool needsExactTexture =
(yuvDesc.fWidth != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth) ||
(yuvDesc.fHeight != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
if (needsExactTexture) {
yuvTextures[i].reset(ctx->textureProvider()->createTexture(yuvDesc, SkBudgeted::kYes));
} else {
yuvTextures[i].reset(ctx->textureProvider()->createApproxTexture(yuvDesc));
}
if (!yuvTextures[i] ||
!yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight, yuvDesc.fConfig,
planes[i], yuvInfo.fSizeInfo.fWidthBytes[i])) {
return nullptr;
}
}
sk_sp<GrDrawContext> drawContext(ctx->newDrawContext(SkBackingFit::kExact,
desc.fWidth, desc.fHeight,
desc.fConfig, desc.fSampleCnt));
if (!drawContext) {
return nullptr;
}
GrPaint paint;
sk_sp<GrFragmentProcessor> yuvToRgbProcessor(
GrYUVEffect::MakeYUVToRGB(yuvTextures[0], yuvTextures[1], yuvTextures[2],
yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false));
paint.addColorFragmentProcessor(std::move(yuvToRgbProcessor));
// If we're decoding an sRGB image, the result of our linear math on the YUV planes is already
// in sRGB. (The encoding is just math on bytes, with no concept of color spaces.) So, we need
// to output the results of that math directly to the buffer that we will then consider sRGB.
// If we have sRGB write control, we can just tell the HW not to do the Linear -> sRGB step.
// Otherwise, we do our shader math to go from YUV -> sRGB, manually convert sRGB -> Linear,
// then let the HW convert Linear -> sRGB.
if (GrPixelConfigIsSRGB(desc.fConfig)) {
if (ctx->caps()->srgbWriteControl()) {
paint.setDisableOutputConversionToSRGB(true);
} else {
paint.addColorFragmentProcessor(GrGammaEffect::Make(2.2f));
}
}
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth,
yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
drawContext->drawRect(GrNoClip(), paint, SkMatrix::I(), r);
return drawContext->asTexture();
}
示例14: filterImageGPU
bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
SkBitmap* result, SkIPoint* offset) const {
SkBitmap colorBM = src;
SkIPoint colorOffset = SkIPoint::Make(0, 0);
if (!this->filterInputGPU(1, proxy, src, ctx, &colorBM, &colorOffset)) {
return false;
}
SkBitmap displacementBM = src;
SkIPoint displacementOffset = SkIPoint::Make(0, 0);
if (!this->filterInputGPU(0, proxy, src, ctx, &displacementBM, &displacementOffset)) {
return false;
}
SkIRect bounds;
// Since GrDisplacementMapEffect does bounds checking on color pixel access, we don't need to
// pad the color bitmap to bounds here.
if (!this->applyCropRect(ctx, colorBM, colorOffset, &bounds)) {
return false;
}
SkIRect displBounds;
if (!this->applyCropRect(ctx, proxy, displacementBM,
&displacementOffset, &displBounds, &displacementBM)) {
return false;
}
if (!bounds.intersect(displBounds)) {
return false;
}
GrTexture* color = colorBM.getTexture();
GrTexture* displacement = displacementBM.getTexture();
GrContext* context = color->getContext();
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kSkia8888_GrPixelConfig;
auto constraint = GrTextureProvider::FromImageFilter(ctx.sizeConstraint());
SkAutoTUnref<GrTexture> dst(context->textureProvider()->createTexture(desc, constraint));
if (!dst) {
return false;
}
SkVector scale = SkVector::Make(fScale, fScale);
ctx.ctm().mapVectors(&scale, 1);
GrPaint paint;
SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displacement);
offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displacementOffset.fX),
SkIntToScalar(colorOffset.fY - displacementOffset.fY));
paint.addColorFragmentProcessor(
GrDisplacementMapEffect::Create(fXChannelSelector,
fYChannelSelector,
scale,
displacement,
offsetMatrix,
color,
colorBM.dimensions()))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkIRect colorBounds = bounds;
colorBounds.offset(-colorOffset);
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(colorBounds.x()),
-SkIntToScalar(colorBounds.y()));
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
if (!drawContext) {
return false;
}
drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(colorBounds));
offset->fX = bounds.left();
offset->fY = bounds.top();
WrapTexture(dst, bounds.width(), bounds.height(), result);
return true;
}
示例15: MakeFromGpu
sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint colorOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> color(this->filterInput(1, source, ctx, &colorOffset));
if (!color) {
return nullptr;
}
SkIPoint displOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> displ(this->filterInput(0, source, ctx, &displOffset));
if (!displ) {
return nullptr;
}
const SkIRect srcBounds = SkIRect::MakeXYWH(colorOffset.x(), colorOffset.y(),
color->width(), color->height());
// Both paths do bounds checking on color pixel access, we don't need to
// pad the color bitmap to bounds here.
SkIRect bounds;
if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
return nullptr;
}
SkIRect displBounds;
displ = this->applyCropRect(ctx, displ.get(), &displOffset, &displBounds);
if (!displ) {
return nullptr;
}
if (!bounds.intersect(displBounds)) {
return nullptr;
}
const SkIRect colorBounds = bounds.makeOffset(-colorOffset.x(), -colorOffset.y());
SkVector scale = SkVector::Make(fScale, fScale);
ctx.ctm().mapVectors(&scale, 1);
#if SK_SUPPORT_GPU
if (source->isTextureBacked()) {
GrContext* context = source->getContext();
sk_sp<GrTexture> colorTexture(color->asTextureRef(context));
sk_sp<GrTexture> displTexture(displ->asTextureRef(context));
if (!colorTexture || !displTexture) {
return nullptr;
}
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kSkia8888_GrPixelConfig;
SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc));
if (!dst) {
return nullptr;
}
GrPaint paint;
SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displTexture.get());
offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displOffset.fX),
SkIntToScalar(colorOffset.fY - displOffset.fY));
paint.addColorFragmentProcessor(
GrDisplacementMapEffect::Create(fXChannelSelector,
fYChannelSelector,
scale,
displTexture.get(),
offsetMatrix,
colorTexture.get(),
SkISize::Make(color->width(),
color->height())))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
if (!drawContext) {
return nullptr;
}
drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(colorBounds));
offset->fX = bounds.left();
offset->fY = bounds.top();
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
dst);
}
#endif
SkBitmap colorBM, displBM;
if (!color->getROPixels(&colorBM) || !displ->getROPixels(&displBM)) {
return nullptr;
}
//.........这里部分代码省略.........