Reland r6233 with fix.
git-svn-id: http://skia.googlecode.com/svn/trunk@6241 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index f7f6b0c..2a39fad 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1307,35 +1307,44 @@
ast.set(this, desc, match);
GrTexture* texture = ast.texture();
if (texture) {
- SkAutoTUnref<GrEffect> effect;
+ GrEffectStage stage;
+ // compute a matrix to perform the draw
+ GrMatrix textureMatrix;
+ if (flipY) {
+ textureMatrix.setTranslate(SK_Scalar1 * left,
+ SK_Scalar1 * (top + height));
+ textureMatrix.set(GrMatrix::kMScaleY, -GR_Scalar1);
+ } else {
+ textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
+ }
+ textureMatrix.postIDiv(src->width(), src->height());
+
+ bool effectInstalled = false;
if (unpremul) {
- effect.reset(this->createPMToUPMEffect(src, swapRAndB));
+ if (this->installPMToUPMEffect(src, swapRAndB, textureMatrix, &stage)) {
+ effectInstalled = true;
+ unpremul = false; // we no longer need to do this on CPU after the readback.
+ }
}
// If we failed to create a PM->UPM effect and have no other conversions to perform then
// there is no longer any point to using the scratch.
- if (NULL != effect || flipY || swapRAndB) {
- if (NULL == effect) {
- effect.reset(GrConfigConversionEffect::Create(src, swapRAndB));
- GrAssert(NULL != effect);
- } else {
- unpremul = false; // we will handle the UPM conversion in the draw
+ if (effectInstalled || flipY || swapRAndB) {
+ if (!effectInstalled) {
+ SkAssertResult(GrConfigConversionEffect::InstallEffect(
+ src,
+ swapRAndB,
+ GrConfigConversionEffect::kNone_PMConversion,
+ textureMatrix,
+ &stage));
}
swapRAndB = false; // we will handle the swap in the draw.
+ flipY = false; // we already incorporated the y flip in the matrix
GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
+ *drawState->stage(0) = stage;
+
drawState->setRenderTarget(texture->asRenderTarget());
- GrMatrix matrix;
- if (flipY) {
- matrix.setTranslate(SK_Scalar1 * left,
- SK_Scalar1 * (top + height));
- matrix.set(GrMatrix::kMScaleY, -GR_Scalar1);
- flipY = false; // the y flip will be handled in the draw
- } else {
- matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
- }
- matrix.postIDiv(src->width(), src->height());
- drawState->stage(0)->setEffect(effect, matrix);
GrRect rect = GrRect::MakeWH(GrIntToScalar(width), GrIntToScalar(height));
fGpu->drawSimpleRect(rect, NULL);
// we want to read back from the scratch's origin
@@ -1350,7 +1359,7 @@
readConfig, buffer, rowBytes, readUpsideDown)) {
return false;
}
- // Perform any conversions we weren't able to perfom using a scratch texture.
+ // Perform any conversions we weren't able to perform using a scratch texture.
if (unpremul || swapRAndB || flipY) {
// These are initialized to suppress a warning
SkCanvas::Config8888 srcC8888 = SkCanvas::kNative_Premul_Config8888;
@@ -1480,7 +1489,7 @@
return;
}
#endif
- SkAutoTUnref<GrEffect> effect;
+
bool swapRAndB = (fGpu->preferredReadPixelsConfig(config) == GrPixelConfigSwapRAndB(config));
GrPixelConfig textureConfig;
@@ -1499,15 +1508,24 @@
if (NULL == texture) {
return;
}
+
+ GrEffectStage stage;
+ GrMatrix textureMatrix;
+ textureMatrix.setIDiv(texture->width(), texture->height());
+
// allocate a tmp buffer and sw convert the pixels to premul
SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
+ bool effectInstalled = false;
if (kUnpremul_PixelOpsFlag & flags) {
if (kRGBA_8888_GrPixelConfig != config && kBGRA_8888_GrPixelConfig != config) {
return;
}
- effect.reset(this->createUPMToPMEffect(texture, swapRAndB));
- if (NULL == effect) {
+ effectInstalled = this->installUPMToPMEffect(texture,
+ swapRAndB,
+ textureMatrix,
+ &stage);
+ if (!effectInstalled) {
SkCanvas::Config8888 srcConfig8888, dstConfig8888;
GR_DEBUGCODE(bool success = )
grconfig_to_config8888(config, true, &srcConfig8888);
@@ -1524,9 +1542,13 @@
rowBytes = 4 * width;
}
}
- if (NULL == effect) {
- effect.reset(GrConfigConversionEffect::Create(texture, swapRAndB));
- GrAssert(NULL != effect);
+ if (!effectInstalled) {
+ SkAssertResult(GrConfigConversionEffect::InstallEffect(
+ texture,
+ swapRAndB,
+ GrConfigConversionEffect::kNone_PMConversion,
+ textureMatrix,
+ &stage));
}
this->writeTexturePixels(texture,
@@ -1536,15 +1558,13 @@
GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
+ *drawState->stage(0) = stage;
GrMatrix matrix;
matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
drawState->setViewMatrix(matrix);
drawState->setRenderTarget(target);
- matrix.setIDiv(texture->width(), texture->height());
- drawState->stage(0)->setEffect(effect, matrix);
-
fGpu->drawSimpleRect(GrRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1726,7 +1746,10 @@
}
}
-GrEffect* GrContext::createPMToUPMEffect(GrTexture* texture, bool swapRAndB) {
+bool GrContext::installPMToUPMEffect(GrTexture* texture,
+ bool swapRAndB,
+ const GrMatrix& matrix,
+ GrEffectStage* stage) {
if (!fDidTestPMConversions) {
test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
fDidTestPMConversions = true;
@@ -1734,13 +1757,17 @@
GrConfigConversionEffect::PMConversion pmToUPM =
static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
- return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM);
+ GrConfigConversionEffect::InstallEffect(texture, swapRAndB, pmToUPM, matrix, stage);
+ return true;
} else {
- return NULL;
+ return false;
}
}
-GrEffect* GrContext::createUPMToPMEffect(GrTexture* texture, bool swapRAndB) {
+bool GrContext::installUPMToPMEffect(GrTexture* texture,
+ bool swapRAndB,
+ const GrMatrix& matrix,
+ GrEffectStage* stage) {
if (!fDidTestPMConversions) {
test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
fDidTestPMConversions = true;
@@ -1748,9 +1775,10 @@
GrConfigConversionEffect::PMConversion upmToPM =
static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
- return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM);
+ GrConfigConversionEffect::InstallEffect(texture, swapRAndB, upmToPM, matrix, stage);
+ return true;
} else {
- return NULL;
+ return false;
}
}
@@ -1808,7 +1836,7 @@
i < scaleFactorY ? 0.5f : 1.0f);
paint.colorStage(0)->setEffect(SkNEW_ARGS(GrSingleTextureEffect,
- (srcTexture, true)), matrix)->unref();
+ (srcTexture, matrix, true)))->unref();
this->drawRectToRect(paint, dstRect, srcRect);
srcRect = dstRect;
srcTexture = dstTexture;
@@ -1865,8 +1893,8 @@
// FIXME: This should be mitchell, not bilinear.
matrix.setIDiv(srcTexture->width(), srcTexture->height());
this->setRenderTarget(dstTexture->asRenderTarget());
- paint.colorStage(0)->setEffect(SkNEW_ARGS(GrSingleTextureEffect,(srcTexture, true)),
- matrix)->unref();
+ paint.colorStage(0)->setEffect(SkNEW_ARGS(GrSingleTextureEffect,(srcTexture,
+ matrix, true)))->unref();
SkRect dstRect(srcRect);
scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
this->drawRectToRect(paint, dstRect, srcRect);