Index: src/gpu/SkGpuDevice.cpp |
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp |
index 3b0d143c5b5397ac1c4381404f7c7376aef74fd7..ab7693c7f1c0d1e276a9701fefa5cfebf50c04cb 100644 |
--- a/src/gpu/SkGpuDevice.cpp |
+++ b/src/gpu/SkGpuDevice.cpp |
@@ -38,15 +38,6 @@ |
#define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI) |
#endif |
-// we use the same effect slot on GrPaint for bitmaps and shaders (since drawBitmap, drawSprite, |
-// and drawDevice ignore SkShader) |
-enum { |
- kShaderEffectIdx = 0, |
- kBitmapEffectIdx = 0, |
- kColorFilterEffectIdx = 1, |
- kXfermodeEffectIdx = 2, |
-}; |
- |
// This constant represents the screen alignment criterion in texels for |
// requiring texture domain clamping to prevent color bleeding when drawing |
// a sub region of a larger source image. |
@@ -442,16 +433,6 @@ GrRenderTarget* SkGpuDevice::accessRenderTarget() { |
return fRenderTarget; |
} |
-bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) { |
- GrTexture* texture = fRenderTarget->asTexture(); |
- if (NULL != texture) { |
- paint->colorStage(kBitmapEffectIdx)->setEffect( |
- GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); |
- return true; |
- } |
- return false; |
-} |
- |
/////////////////////////////////////////////////////////////////////////////// |
SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); |
@@ -489,7 +470,7 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev, |
GrEffectRef* xferEffect = NULL; |
if (SkXfermode::AsNewEffectOrCoeff(mode, dev->context(), &xferEffect, &sm, &dm)) { |
if (NULL != xferEffect) { |
- grPaint->colorStage(kXfermodeEffectIdx)->setEffect(xferEffect)->unref(); |
+ grPaint->addColorEffect(xferEffect)->unref(); |
sm = SkXfermode::kOne_Coeff; |
dm = SkXfermode::kZero_Coeff; |
} |
@@ -513,7 +494,6 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev, |
GrAssert(!constantColor); |
} else { |
grPaint->setColor(SkColor2GrColor(skPaint.getColor())); |
- GrAssert(!grPaint->isColorStageEnabled(kShaderEffectIdx)); |
} |
SkColorFilter* colorFilter = skPaint.getColorFilter(); |
@@ -526,7 +506,7 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev, |
} else { |
SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(dev->context())); |
if (NULL != effect.get()) { |
- grPaint->colorStage(kColorFilterEffectIdx)->setEffect(effect); |
+ grPaint->addColorEffect(effect); |
} else { |
// TODO: rewrite this using asNewEffect() |
SkColor color; |
@@ -552,32 +532,33 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev, |
SkShader* shader = skPaint.getShader(); |
if (NULL == shader) { |
return skPaint2GrPaintNoShader(dev, skPaint, false, constantColor, grPaint); |
- } else if (!skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint)) { |
- return false; |
} |
+ // setup the shader as the first color effect on the paint |
SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(dev->context(), skPaint)); |
if (NULL != effect.get()) { |
- grPaint->colorStage(kShaderEffectIdx)->setEffect(effect); |
- return true; |
- } |
- |
- // We still don't have SkColorShader::asNewEffect() implemented. |
- SkShader::GradientInfo info; |
- SkColor color; |
- |
- info.fColors = &color; |
- info.fColorOffsets = NULL; |
- info.fColorCount = 1; |
- if (SkShader::kColor_GradientType == shader->asAGradient(&info)) { |
- SkPaint copy(skPaint); |
- copy.setShader(NULL); |
- // modulate the paint alpha by the shader's solid color alpha |
- U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha()); |
- copy.setColor(SkColorSetA(color, newA)); |
- return skPaint2GrPaintNoShader(dev, copy, false, constantColor, grPaint); |
+ grPaint->addColorEffect(effect); |
+ // Now setup the rest of the paint. |
+ return skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint); |
+ } else { |
+ // We still don't have SkColorShader::asNewEffect() implemented. |
+ SkShader::GradientInfo info; |
+ SkColor color; |
+ |
+ info.fColors = &color; |
+ info.fColorOffsets = NULL; |
+ info.fColorCount = 1; |
+ if (SkShader::kColor_GradientType == shader->asAGradient(&info)) { |
+ SkPaint copy(skPaint); |
+ copy.setShader(NULL); |
+ // modulate the paint alpha by the shader's solid color alpha |
+ U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha()); |
+ copy.setColor(SkColorSetA(color, newA)); |
+ return skPaint2GrPaintNoShader(dev, copy, false, constantColor, grPaint); |
+ } else { |
+ return false; |
+ } |
} |
- return false; |
} |
} |
@@ -769,22 +750,16 @@ namespace { |
// Return true if the mask was successfully drawn. |
bool draw_mask(GrContext* context, const SkRect& maskRect, |
GrPaint* grp, GrTexture* mask) { |
- |
GrContext::AutoMatrix am; |
if (!am.setIdentity(context, grp)) { |
return false; |
} |
- static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; |
- // we assume the last mask index is available for use |
- GrAssert(!grp->isCoverageStageEnabled(MASK_IDX)); |
- |
SkMatrix matrix; |
matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); |
matrix.postIDiv(mask->width(), mask->height()); |
- grp->coverageStage(MASK_IDX)->reset(); |
- grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref(); |
+ grp->addCoverageEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref(); |
context->drawRect(*grp, maskRect); |
return true; |
} |
@@ -1169,20 +1144,14 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
return; |
} |
- GrPaint grPaint; |
- |
- bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config()); |
- if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) { |
- return; |
- } |
GrTextureParams params; |
params.setBilerp(paint.isFilterBitmap()); |
if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { |
// take the simple case |
- this->internalDrawBitmap(bitmap, srcRect, m, params, &grPaint); |
+ this->internalDrawBitmap(bitmap, srcRect, m, params, paint); |
} else { |
- this->drawTiledBitmap(bitmap, srcRect, m, params, &grPaint); |
+ this->drawTiledBitmap(bitmap, srcRect, m, params, paint); |
} |
} |
@@ -1192,7 +1161,7 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
const SkRect& srcRect, |
const SkMatrix& m, |
const GrTextureParams& params, |
- GrPaint* grPaint) { |
+ const SkPaint& paint) { |
const int maxTextureSize = fContext->getMaxTextureSize(); |
int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); |
@@ -1241,7 +1210,7 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), |
SkIntToScalar(iTileR.fTop)); |
- this->internalDrawBitmap(tmpB, tileR, tmpM, params, grPaint); |
+ this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint); |
} |
} |
} |
@@ -1301,7 +1270,7 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, |
const SkRect& srcRect, |
const SkMatrix& m, |
const GrTextureParams& params, |
- GrPaint* grPaint) { |
+ const SkPaint& paint) { |
SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && |
bitmap.height() <= fContext->getMaxTextureSize()); |
@@ -1371,8 +1340,17 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, |
} else { |
effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params)); |
} |
- grPaint->colorStage(kBitmapEffectIdx)->setEffect(effect); |
- fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); |
+ |
+ // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring |
+ // the rest from the SkPaint. |
+ GrPaint grPaint; |
+ grPaint.addColorEffect(effect); |
+ bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config()); |
+ if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) { |
+ return; |
+ } |
+ |
+ fContext->drawRectToRect(grPaint, dstRect, paintRect, &m); |
} |
static bool filter_texture(SkDevice* device, GrContext* context, |
@@ -1404,33 +1382,28 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, |
int w = bitmap.width(); |
int h = bitmap.height(); |
- GrPaint grPaint; |
- if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
- return; |
- } |
- |
- GrEffectStage* stage = grPaint.colorStage(kBitmapEffectIdx); |
- |
GrTexture* texture; |
- stage->reset(); |
// draw sprite uses the default texture params |
SkAutoCachedTexture act(this, bitmap, NULL, &texture); |
- grPaint.colorStage(kBitmapEffectIdx)->setEffect( |
- GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); |
SkImageFilter* filter = paint.getImageFilter(); |
SkIPoint offset = SkIPoint::Make(0, 0); |
if (NULL != filter) { |
SkBitmap filterBitmap; |
if (filter_texture(this, fContext, texture, filter, w, h, &filterBitmap, &offset)) { |
- grPaint.colorStage(kBitmapEffectIdx)->setEffect( |
- GrSimpleTextureEffect::Create(filterBitmap.getTexture(), SkMatrix::I()))->unref(); |
- texture = filterBitmap.getTexture(); |
+ texture = (GrTexture*) filterBitmap.getTexture(); |
w = filterBitmap.width(); |
h = filterBitmap.height(); |
} |
} |
+ GrPaint grPaint; |
+ grPaint.addColorTextureEffect(texture, SkMatrix::I()); |
+ |
+ if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
+ return; |
+ } |
+ |
fContext->drawRectToRect(grPaint, |
GrRect::MakeXYWH(SkIntToScalar(left), |
SkIntToScalar(top), |
@@ -1484,27 +1457,22 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, |
// drawDevice is defined to be in device coords. |
CHECK_SHOULD_DRAW(draw, true); |
- GrPaint grPaint; |
- grPaint.colorStage(kBitmapEffectIdx)->reset(); |
- if (!dev->bindDeviceAsTexture(&grPaint) || |
- !skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
+ GrRenderTarget* devRT = device->accessRenderTarget(); |
+ GrTexture* devTex; |
+ if (NULL == (devTex = devRT->asTexture())) { |
return; |
} |
- GrTexture* devTex = (*grPaint.getColorStage(kBitmapEffectIdx).getEffect())->texture(0); |
- SkASSERT(NULL != devTex); |
- |
const SkBitmap& bm = dev->accessBitmap(false); |
int w = bm.width(); |
int h = bm.height(); |
SkImageFilter* filter = paint.getImageFilter(); |
+ |
if (NULL != filter) { |
SkBitmap filterBitmap; |
SkIPoint offset = SkIPoint::Make(0, 0); |
if (filter_texture(this, fContext, devTex, filter, w, h, &filterBitmap, &offset)) { |
- grPaint.colorStage(kBitmapEffectIdx)->setEffect( |
- GrSimpleTextureEffect::Create(filterBitmap.getTexture(), SkMatrix::I()))->unref(); |
devTex = filterBitmap.getTexture(); |
w = filterBitmap.width(); |
h = filterBitmap.height(); |
@@ -1513,13 +1481,20 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device, |
} |
} |
+ GrPaint grPaint; |
+ grPaint.addColorTextureEffect(devTex, SkMatrix::I()); |
+ |
+ if (!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
+ return; |
+ } |
+ |
GrRect dstRect = GrRect::MakeXYWH(SkIntToScalar(x), |
SkIntToScalar(y), |
SkIntToScalar(w), |
SkIntToScalar(h)); |
- // The device being drawn may not fill up its texture (saveLayer uses |
- // the approximate ). |
+ // The device being drawn may not fill up its texture (e.g. saveLayer uses approximate |
+ // scratch texture). |
GrRect srcRect = GrRect::MakeWH(SK_Scalar1 * w / devTex->width(), |
SK_Scalar1 * h / devTex->height()); |