Beef up GrContext::AutoMatrix to handle doing GrPaint matrix adjustments.
R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6656047
git-svn-id: http://skia.googlecode.com/svn/trunk@5918 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index d94a8dd..50cc12b 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -26,13 +26,13 @@
#if 0
extern bool (*gShouldDrawProc)();
- #define CHECK_SHOULD_DRAW(draw) \
+ #define CHECK_SHOULD_DRAW(draw, forceI) \
do { \
if (gShouldDrawProc && !gShouldDrawProc()) return; \
- this->prepareDraw(draw); \
+ this->prepareDraw(draw, forceI); \
} while (0)
#else
- #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
+ #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI)
#endif
// we use the same texture slot on GrPaint for bitmaps and shaders
@@ -407,14 +407,18 @@
// call this every draw call, to ensure that the context reflects our state,
// and not the state from some other canvas/device
-void SkGpuDevice::prepareDraw(const SkDraw& draw) {
+void SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) {
GrAssert(NULL != fClipData.fClipStack);
fContext->setRenderTarget(fRenderTarget);
SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack);
- fContext->setMatrix(*draw.fMatrix);
+ if (forceIdentity) {
+ fContext->setIdentityMatrix();
+ } else {
+ fContext->setMatrix(*draw.fMatrix);
+ }
fClipData.fOrigin = this->getOrigin();
#ifdef SK_DEBUG
@@ -625,7 +629,7 @@
}
void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
GrPaint grPaint;
SkAutoCachedTexture textures[GrPaint::kMaxColorStages];
@@ -649,7 +653,7 @@
void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
size_t count, const SkPoint pts[], const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
SkScalar width = paint.getStrokeWidth();
if (width < 0) {
@@ -688,7 +692,7 @@
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
const SkPaint& paint) {
CHECK_FOR_NODRAW_ANNOTATION(paint);
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
bool doStroke = paint.getStyle() != SkPaint::kFill_Style;
SkScalar width = paint.getStrokeWidth();
@@ -837,21 +841,12 @@
SkAutoTUnref<GrTexture> blurTexture;
- GrMatrix origMatrix = context->getMatrix();
-
- // We pass kPreserve here. We will replace the current matrix below.
- GrContext::AutoMatrix avm(context, GrContext::AutoMatrix::kPreserve_InitialMatrix);
-
{
GrContext::AutoRenderTarget art(context, pathTexture->asRenderTarget());
GrContext::AutoClip ac(context, srcRect);
context->clear(NULL, 0);
- // Draw hard shadow to pathTexture with path top-left at origin 0,0.
- GrMatrix translate;
- translate.setTranslate(offset.fX, offset.fY);
-
GrPaint tempPaint;
if (grp->isAntiAlias()) {
tempPaint.setAntiAlias(true);
@@ -860,14 +855,17 @@
// to properly blend partially covered pixels. This means the AA
// code path may not be taken. So we use a dst blend coeff of ISA. We
// could special case AA draws to a dst surface with known alpha=0 to
- // use a zero dst coeff when dual source blending isn't available.
+ // use a zero dst coeff when dual source blending isn't available.f
tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
}
- context->setMatrix(translate);
- context->drawPath(tempPaint, devPath, pathFillType);
- // switch to device coord drawing when going back to the main RT.
- context->setIdentityMatrix();
+ GrContext::AutoMatrix am;
+
+ // Draw hard shadow to pathTexture with path top-left at origin using tempPaint.
+ GrMatrix translate;
+ translate.setTranslate(offset.fX, offset.fY);
+ am.set(context, translate);
+ context->drawPath(tempPaint, devPath, pathFillType);
// If we're doing a normal blur, we can clobber the pathTexture in the
// gaussianBlur. Otherwise, we need to save it for later compositing.
@@ -876,6 +874,7 @@
srcRect, sigma, sigma));
if (!isNormalBlur) {
+ context->setIdentityMatrix();
GrPaint paint;
paint.reset();
paint.colorSampler(0)->matrix()->setIDiv(pathTexture->width(),
@@ -900,10 +899,11 @@
}
}
- if (!grp->preConcatSamplerMatricesWithInverse(origMatrix)) {
+ 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));
@@ -943,13 +943,9 @@
}
// we now have a device-aligned 8bit mask in dstM, ready to be drawn using
- // the current clip (and identity matrix) and grpaint settings
-
- if (!grp->preConcatSamplerMatricesWithInverse(context->getMatrix())) {
- return false;
- }
-
- GrContext::AutoMatrix avm(context, GrMatrix::I());
+ // the current clip (and identity matrix) and GrPaint settings
+ GrContext::AutoMatrix am;
+ am.setIdentity(context, grp);
GrTextureDesc desc;
desc.fWidth = dstM.fBounds.width();
@@ -993,7 +989,7 @@
const SkPaint& paint, const SkMatrix* prePathMatrix,
bool pathIsMutable) {
CHECK_FOR_NODRAW_ANNOTATION(paint);
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
bool doFill = true;
@@ -1202,7 +1198,7 @@
const SkRect* srcRectPtr,
const SkMatrix& m,
const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
SkRect srcRect;
if (NULL == srcRectPtr) {
@@ -1465,7 +1461,8 @@
const GrRect& rect,
GrCustomStage* stage) {
SkASSERT(srcTexture && srcTexture->getContext() == context);
- GrContext::AutoMatrix avm(context, GrMatrix::I());
+ GrContext::AutoMatrix am;
+ am.setIdentity(context);
GrContext::AutoRenderTarget art(context, dstTexture->asRenderTarget());
GrContext::AutoClip acs(context, rect);
@@ -1504,8 +1501,9 @@
}
void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
- int left, int top, const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ int left, int top, const SkPaint& paint) {
+ // drawSprite is defined to be in device coords.
+ CHECK_SHOULD_DRAW(draw, true);
SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
@@ -1521,8 +1519,6 @@
return;
}
- GrContext::AutoMatrix avm(fContext, GrMatrix::I());
-
GrSamplerState* sampler = grPaint.colorSampler(kBitmapTextureIdx);
GrTexture* texture;
@@ -1584,7 +1580,7 @@
}
void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device,
- int x, int y, const SkPaint& paint) {
+ int x, int y, const SkPaint& paint) {
// clear of the source device must occur before CHECK_SHOULD_DRAW
SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
if (dev->fNeedClear) {
@@ -1592,7 +1588,8 @@
dev->clear(0x0);
}
- CHECK_SHOULD_DRAW(draw);
+ // drawDevice is defined to be in device coords.
+ CHECK_SHOULD_DRAW(draw, true);
GrPaint grPaint;
SkAutoCachedTexture colorLutTexture;
@@ -1622,7 +1619,6 @@
int w = bm.width();
int h = bm.height();
- GrContext::AutoMatrix avm(fContext, GrMatrix::I());
GrRect dstRect = GrRect::MakeXYWH(GrIntToScalar(x),
GrIntToScalar(y),
GrIntToScalar(w),
@@ -1691,7 +1687,7 @@
SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
GrPaint grPaint;
SkAutoCachedTexture textures[GrPaint::kMaxColorStages];
@@ -1800,7 +1796,7 @@
void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
size_t byteLength, SkScalar x, SkScalar y,
const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
if (fContext->getMatrix().hasPerspective()) {
// this guy will just call our drawPath()
@@ -1827,7 +1823,7 @@
size_t byteLength, const SkScalar pos[],
SkScalar constY, int scalarsPerPos,
const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
if (fContext->getMatrix().hasPerspective()) {
// this guy will just call our drawPath()
@@ -1855,7 +1851,7 @@
void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
size_t len, const SkPath& path,
const SkMatrix* m, const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
+ CHECK_SHOULD_DRAW(draw, false);
SkASSERT(draw.fDevice == this);
draw.drawTextOnPath((const char*)text, len, path, m, paint);