This is a staging CL to position the writePixels in sw_draw_with_mask_filter to be moved to GrSurfaceContext
Change-Id: I808372d30ad4aca4a56125ea75d071f7a3747146
Reviewed-on: https://skia-review.googlesource.com/5926
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
class GrFragmentProcessor;
class GrRenderTarget;
class GrTexture;
+class GrTextureProxy;
class GrTextureProvider;
class SkBitmap;
class SkBlitter;
* Implementations are free to get the GrContext from the src texture in order to create
* additional textures and perform multiple passes.
*/
- virtual bool filterMaskGPU(GrTexture* src,
- const SkMatrix& ctm,
- const SkIRect& maskRect,
- GrTexture** result) const;
+ virtual sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
+ sk_sp<GrTextureProxy> srcProxy,
+ const SkMatrix& ctm,
+ const SkIRect& maskRect) const;
#endif
/**
#if SK_SUPPORT_GPU
#include "GrTexture.h"
+#include "GrTextureProxy.h"
#include "SkGr.h"
#endif
return false;
}
-bool SkMaskFilter::filterMaskGPU(GrTexture* src,
- const SkMatrix& ctm,
- const SkIRect& maskRect,
- GrTexture** result) const {
- return false;
+sk_sp<GrTextureProxy> SkMaskFilter::filterMaskGPU(GrContext*,
+ sk_sp<GrTextureProxy> srcProxy,
+ const SkMatrix& ctm,
+ const SkIRect& maskRect) const {
+ return nullptr;
}
#endif
#include "GrInvariantOutput.h"
#include "GrShaderCaps.h"
#include "GrStyle.h"
+#include "GrTextureProxy.h"
#include "effects/GrSimpleTextureEffect.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
const SkStrokeRec& strokeRec,
const SkRRect& rrect,
const SkRRect& devRRect) const override;
- bool filterMaskGPU(GrTexture* src,
- const SkMatrix& ctm,
- const SkIRect& maskRect,
- GrTexture** result) const override;
+ sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
+ sk_sp<GrTextureProxy> srcProxy,
+ const SkMatrix& ctm,
+ const SkIRect& maskRect) const override;
#endif
void computeFastBounds(const SkRect&, SkRect*) const override;
return true;
}
-bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
- const SkMatrix& ctm,
- const SkIRect& maskRect,
- GrTexture** result) const {
+sk_sp<GrTextureProxy> SkBlurMaskFilterImpl::filterMaskGPU(GrContext* context,
+ sk_sp<GrTextureProxy> srcProxy,
+ const SkMatrix& ctm,
+ const SkIRect& maskRect) const {
// 'maskRect' isn't snapped to the UL corner but the mask in 'src' is.
const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height());
- GrContext* context = src->getContext();
-
SkScalar xformedSigma = this->computeXformedSigma(ctm);
SkASSERT(xformedSigma > 0);
+ // TODO: defer this further (i.e., push the proxy into GaussianBlur)
+ GrTexture* src = srcProxy->instantiate(context->textureProvider());
+ if (!src) {
+ return nullptr;
+ }
+
// 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 = (kNormal_SkBlurStyle == fBlurStyle);
xformedSigma,
xformedSigma));
if (!renderTargetContext) {
- return false;
+ return nullptr;
}
if (!isNormalBlur) {
SkRect::Make(clipRect));
}
- *result = renderTargetContext->asTexture().release();
- return SkToBool(*result);
+ return sk_ref_sp(renderTargetContext->asDeferredTexture());
}
#endif // SK_SUPPORT_GPU
#include "GrInvariantOutput.h"
#include "GrStyle.h"
#include "GrTexture.h"
+#include "GrTextureProxy.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
const SkStrokeRec& strokeRec,
const SkRRect& rrect,
const SkRRect& devRRect) const override;
- bool filterMaskGPU(GrTexture* src,
- const SkMatrix& ctm,
- const SkIRect& maskRect,
- GrTexture** result) const override;
+ sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
+ sk_sp<GrTextureProxy> srcProxy,
+ const SkMatrix& ctm,
+ const SkIRect& maskRect) const override;
#endif
void computeFastBounds(const SkRect&, SkRect*) const override;
return true;
}
-bool SkShadowMaskFilterImpl::filterMaskGPU(GrTexture* src,
- const SkMatrix& ctm,
- const SkIRect& maskRect,
- GrTexture** result) const {
- // TODO
- return false;
+sk_sp<GrTextureProxy> SkShadowMaskFilterImpl::filterMaskGPU(GrContext*,
+ sk_sp<GrTextureProxy> srcProxy,
+ const SkMatrix& ctm,
+ const SkIRect& maskRect) const {
+ // This filter it generative and doesn't operate on pre-existing masks
+ return nullptr;
}
#endif
// is already burnt into the mask this boils down to a rect draw.
// Return true if the mask was successfully drawn.
static bool draw_mask(GrRenderTargetContext* renderTargetContext,
+ GrTextureProvider* textureProvider,
const GrClip& clip,
const SkMatrix& viewMatrix,
const SkIRect& maskRect,
GrPaint* grp,
- GrTexture* mask) {
+ sk_sp<GrTextureProxy> mask) {
+
+ // TODO: defer this instantiation
+ GrTexture* maskTex = mask->instantiate(textureProvider);
+ if (!maskTex) {
+ return false;
+ }
+
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
- matrix.postIDiv(mask->width(), mask->height());
+ // TODO: this divide relies on the instantiated texture's size!
+ matrix.postIDiv(maskTex->width(), maskTex->height());
matrix.preConcat(viewMatrix);
- grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr, matrix));
+ grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(maskTex, nullptr, matrix));
SkMatrix inverse;
if (!viewMatrix.invert(&inverse)) {
return true;
}
-static bool sw_draw_with_mask_filter(GrRenderTargetContext* renderTargetContext,
- GrTextureProvider* textureProvider,
+static bool sw_draw_with_mask_filter(GrContext* context,
+ GrRenderTargetContext* renderTargetContext,
const GrClip& clipData,
const SkMatrix& viewMatrix,
const SkPath& devPath,
desc.fHeight = dstM.fBounds.height();
desc.fConfig = kAlpha_8_GrPixelConfig;
- sk_sp<GrTexture> texture(textureProvider->createApproxTexture(desc));
+ sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeDeferred(*context->caps(), desc,
+ SkBackingFit::kApprox,
+ SkBudgeted::kYes));
+ if (!proxy || !proxy->asTextureProxy()) {
+ return false;
+ }
+
+ // This is a bit goofy but, until writePixels is moved to GrSurfaceContext, we're stuck
+ // instantiating here to do the writePixels
+ GrTexture* texture = proxy->asTextureProxy()->instantiate(context->textureProvider());
if (!texture) {
return false;
}
+
texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
- dstM.fImage, dstM.fRowBytes);
+ dstM.fImage, dstM.fRowBytes);
- return draw_mask(renderTargetContext, clipData, viewMatrix, dstM.fBounds, grp, texture.get());
+ return draw_mask(renderTargetContext, context->textureProvider(),
+ clipData, viewMatrix, dstM.fBounds, grp, sk_ref_sp(proxy->asTextureProxy()));
}
// Create a mask of 'devPath' and place the result in 'mask'.
aa,
renderTargetContext->numColorSamples()));
if (maskProxy) {
- GrTexture* filtered;
-
- GrTexture* mask = maskProxy->instantiate(context->textureProvider());
- if (!mask) {
- return;
- }
-
- if (maskFilter->filterMaskGPU(mask, viewMatrix, finalIRect, &filtered)) {
- // filterMaskGPU gives us ownership of a ref to the result
- sk_sp<GrTexture> atu(filtered);
- if (draw_mask(renderTargetContext, clip, viewMatrix, finalIRect, paint, filtered)) {
+ sk_sp<GrTextureProxy> filtered = maskFilter->filterMaskGPU(context,
+ std::move(maskProxy),
+ viewMatrix,
+ finalIRect);
+ if (filtered) {
+ if (draw_mask(renderTargetContext, context->textureProvider(),
+ clip, viewMatrix, finalIRect, paint, std::move(filtered))) {
// This path is completely drawn
return;
}
}
}
- sw_draw_with_mask_filter(renderTargetContext, context->textureProvider(),
- clip, viewMatrix, *path,
+ sw_draw_with_mask_filter(context, renderTargetContext, clip, viewMatrix, *path,
maskFilter, clipBounds, paint, fillOrHairline);
}