Don't draw if SkShader::asNewFragmentProcessor fails.
BUG=chromium:473156 Review URL: https://codereview.chromium.org/1089063002
This commit is contained in:
parent
bc0273524b
commit
bed83a66f5
62
gm/badpaint.cpp
Normal file
62
gm/badpaint.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
|
||||
/** This GM draws with invalid paints. It should draw nothing other than the background. */
|
||||
class BadPaintGM : public skiagm::GM {
|
||||
public:
|
||||
BadPaintGM() {}
|
||||
|
||||
protected:
|
||||
SkString onShortName() override { return SkString("badpaint"); }
|
||||
|
||||
SkISize onISize() override { return SkISize::Make(100, 100); }
|
||||
|
||||
void onOnceBeforeDraw() override {
|
||||
SkBitmap emptyBmp;
|
||||
|
||||
SkBitmap blueBmp;
|
||||
blueBmp.allocN32Pixels(10, 10);
|
||||
blueBmp.eraseColor(SK_ColorBLUE);
|
||||
|
||||
SkMatrix badMatrix;
|
||||
badMatrix.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
#if 0 // This crashes pipe!
|
||||
// Empty bitmap.
|
||||
fPaints.push_back().setColor(SK_ColorGREEN);
|
||||
fPaints.back().setShader(SkShader::CreateBitmapShader(emptyBmp, SkShader::kClamp_TileMode,
|
||||
SkShader::kClamp_TileMode))->unref();
|
||||
#endif
|
||||
|
||||
// Non-invertible local matrix.
|
||||
fPaints.push_back().setColor(SK_ColorGREEN);
|
||||
fPaints.back().setShader(SkShader::CreateBitmapShader(blueBmp, SkShader::kClamp_TileMode,
|
||||
SkShader::kClamp_TileMode,
|
||||
&badMatrix))->unref();
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
SkRect rect = SkRect::MakeXYWH(10, 10, 80, 80);
|
||||
for (int i = 0; i < fPaints.count(); ++i) {
|
||||
canvas->drawRect(rect, fPaints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SkTArray<SkPaint> fPaints;
|
||||
|
||||
typedef skiagm::GM INHERITED;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_GM( return SkNEW(BadPaintGM); )
|
@ -104,7 +104,8 @@ protected:
|
||||
} else {
|
||||
skPaint.setColor(kPaintColors[paintType]);
|
||||
}
|
||||
SkPaint2GrPaintShader(context, rt, skPaint, viewMatrix, false, &grPaint);
|
||||
SkAssertResult(SkPaint2GrPaint(context, rt, skPaint, viewMatrix, false,
|
||||
&grPaint));
|
||||
|
||||
GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
|
||||
GrColor color = kColors[procColor];
|
||||
|
@ -26,6 +26,7 @@
|
||||
'../gm/arcofzorro.cpp',
|
||||
'../gm/arithmode.cpp',
|
||||
'../gm/astcbitmap.cpp',
|
||||
'../gm/badpaint.cpp',
|
||||
'../gm/beziereffects.cpp',
|
||||
'../gm/beziers.cpp',
|
||||
'../gm/bigblurs.cpp',
|
||||
|
@ -81,14 +81,14 @@ GrTexture* GrRefCachedBitmapTexture(GrContext*, const SkBitmap&, const GrTexture
|
||||
// an optimization where the color filter can be applied to the SkPaint's
|
||||
// color once while converting to GrPaint and then ignored. TODO: Remove this
|
||||
// bool and use the invariant info to automatically apply the color filter.
|
||||
void SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget*, const SkPaint& skPaint,
|
||||
bool SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget*, const SkPaint& skPaint,
|
||||
GrColor paintColor, bool constantColor, GrPaint* grPaint);
|
||||
|
||||
// This function is similar to skPaint2GrPaintNoShader but also converts
|
||||
// skPaint's shader to a GrFragmentProcessor if possible.
|
||||
// constantColor has the same meaning as in skPaint2GrPaintNoShader.
|
||||
void SkPaint2GrPaintShader(GrContext* context, GrRenderTarget*, const SkPaint& skPaint,
|
||||
const SkMatrix& viewM, bool constantColor, GrPaint* grPaint);
|
||||
bool SkPaint2GrPaint(GrContext* context, GrRenderTarget*, const SkPaint& skPaint,
|
||||
const SkMatrix& viewM, bool constantColor, GrPaint* grPaint);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Classes
|
||||
|
@ -247,7 +247,9 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
|
||||
// Though for the time being runs in the textblob can override the paint, they only touch font
|
||||
// info.
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(fContext, rt, skPaint, viewMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cacheBlob) {
|
||||
if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, viewMatrix, x, y)) {
|
||||
|
@ -116,7 +116,9 @@ void GrTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, const S
|
||||
runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint));
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(fContext, fRenderTarget, runPaint, viewMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(fContext, fRenderTarget, runPaint, viewMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (it.positioning()) {
|
||||
case SkTextBlob::kDefault_Positioning:
|
||||
|
@ -365,7 +365,9 @@ void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext);
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fContext->drawPaint(fRenderTarget, fClip, grPaint, *draw.fMatrix);
|
||||
}
|
||||
@ -390,7 +392,10 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mode) {
|
||||
GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style);
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
SkPath path;
|
||||
path.setIsVolatile(true);
|
||||
path.moveTo(pts[0]);
|
||||
@ -407,7 +412,9 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fContext->drawVertices(fRenderTarget,
|
||||
fClip,
|
||||
@ -479,7 +486,9 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fContext->drawRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, rect, &strokeInfo);
|
||||
}
|
||||
@ -493,7 +502,9 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrStrokeInfo strokeInfo(paint);
|
||||
if (paint.getMaskFilter()) {
|
||||
@ -561,7 +572,10 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) {
|
||||
fContext->drawDRRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, outer, inner);
|
||||
@ -609,7 +623,9 @@ void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval,
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, strokeInfo);
|
||||
}
|
||||
@ -804,7 +820,9 @@ void SkGpuDevice::internalDrawPath(const SkPath& origSrcPath, const SkPaint& pai
|
||||
SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, viewMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, viewMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SkRect* cullRect = NULL; // TODO: what is our bounds?
|
||||
SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr();
|
||||
@ -1478,7 +1496,10 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
|
||||
bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType());
|
||||
GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
|
||||
SkColor2GrColor(paint.getColor());
|
||||
SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, paintColor, false, &grPaint);
|
||||
if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, paintColor, false,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRect,
|
||||
paintRect);
|
||||
@ -1551,8 +1572,10 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
GrPaint grPaint;
|
||||
grPaint.addColorTextureProcessor(texture, SkMatrix::I());
|
||||
|
||||
SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
|
||||
SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint);
|
||||
if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
|
||||
SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fContext->drawNonAARectToRect(fRenderTarget,
|
||||
fClip,
|
||||
@ -1665,8 +1688,10 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
|
||||
GrPaint grPaint;
|
||||
grPaint.addColorTextureProcessor(devTex, SkMatrix::I());
|
||||
|
||||
SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
|
||||
SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint);
|
||||
if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
|
||||
SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x),
|
||||
SkIntToScalar(y),
|
||||
@ -1741,8 +1766,10 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
copy.setStrokeWidth(0);
|
||||
|
||||
// we ignore the shader if texs is null.
|
||||
SkPaint2GrPaintNoShader(this->context(), fRenderTarget, copy,
|
||||
SkColor2GrColor(copy.getColor()), NULL == colors, &grPaint);
|
||||
if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, copy,
|
||||
SkColor2GrColor(copy.getColor()), NULL == colors, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
primType = kLines_GrPrimitiveType;
|
||||
int triangleCount = 0;
|
||||
@ -1781,12 +1808,16 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
primType = gVertexMode2PrimitiveType[vmode];
|
||||
|
||||
if (NULL == texs || NULL == paint.getShader()) {
|
||||
SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
|
||||
SkColor2GrColor(paint.getColor()),
|
||||
NULL == colors, &grPaint);
|
||||
if (!SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint,
|
||||
SkColor2GrColor(paint.getColor()),
|
||||
NULL == colors, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
|
||||
NULL == colors, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix,
|
||||
NULL == colors, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1835,7 +1866,9 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext);
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
@ -1850,7 +1883,9 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
GrPaint grPaint;
|
||||
SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
|
||||
if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
|
@ -642,7 +642,7 @@ bool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
|
||||
bool SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
|
||||
GrColor paintColor, bool constantColor, GrPaint* grPaint) {
|
||||
|
||||
grPaint->setDither(skPaint.isDither());
|
||||
@ -652,6 +652,7 @@ void SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPai
|
||||
GrXPFactory* xpFactory = NULL;
|
||||
if (!SkXfermode::AsXPFactory(mode, &xpFactory)) {
|
||||
// Fall back to src-over
|
||||
// return false here?
|
||||
xpFactory = GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode);
|
||||
}
|
||||
SkASSERT(xpFactory);
|
||||
@ -669,6 +670,7 @@ void SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPai
|
||||
grPaint->setColor(SkColor2GrColor(filtered));
|
||||
} else {
|
||||
SkTDArray<GrFragmentProcessor*> array;
|
||||
// return false if failed?
|
||||
if (colorFilter->asFragmentProcessors(context, &array)) {
|
||||
for (int i = 0; i < array.count(); ++i) {
|
||||
grPaint->addColorProcessor(array[i]);
|
||||
@ -699,15 +701,15 @@ void SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPai
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkPaint2GrPaintShader(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
|
||||
const SkMatrix& viewM, bool constantColor, GrPaint* grPaint) {
|
||||
bool SkPaint2GrPaint(GrContext* context, GrRenderTarget* rt, const SkPaint& skPaint,
|
||||
const SkMatrix& viewM, bool constantColor, GrPaint* grPaint) {
|
||||
SkShader* shader = skPaint.getShader();
|
||||
if (NULL == shader) {
|
||||
SkPaint2GrPaintNoShader(context, rt, skPaint, SkColor2GrColor(skPaint.getColor()),
|
||||
constantColor, grPaint);
|
||||
return;
|
||||
return SkPaint2GrPaintNoShader(context, rt, skPaint, SkColor2GrColor(skPaint.getColor()),
|
||||
constantColor, grPaint);
|
||||
}
|
||||
|
||||
GrColor paintColor = SkColor2GrColor(skPaint.getColor());
|
||||
@ -719,7 +721,10 @@ void SkPaint2GrPaintShader(GrContext* context, GrRenderTarget* rt, const SkPaint
|
||||
// Allow the shader to modify paintColor and also create an effect to be installed as
|
||||
// the first color effect on the GrPaint.
|
||||
GrFragmentProcessor* fp = NULL;
|
||||
if (shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintColor, &fp) && fp) {
|
||||
if (!shader->asFragmentProcessor(context, skPaint, viewM, NULL, &paintColor, &fp)) {
|
||||
return false;
|
||||
}
|
||||
if (fp) {
|
||||
grPaint->addColorProcessor(fp)->unref();
|
||||
constantColor = false;
|
||||
}
|
||||
@ -727,5 +732,5 @@ void SkPaint2GrPaintShader(GrContext* context, GrRenderTarget* rt, const SkPaint
|
||||
|
||||
// The grcolor is automatically set when calling asFragmentProcessor.
|
||||
// If the shader can be seen as an effect it returns true and adds its effect to the grpaint.
|
||||
SkPaint2GrPaintNoShader(context, rt, skPaint, paintColor, constantColor, grPaint);
|
||||
return SkPaint2GrPaintNoShader(context, rt, skPaint, paintColor, constantColor, grPaint);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user