Index: src/gpu/GrContext.cpp |
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
index 46a5576b113358492361240cf4737d38f9f6a699..d0f3cc56713226f7f432f6dbd4a90c19d6e94526 100755 |
--- a/src/gpu/GrContext.cpp |
+++ b/src/gpu/GrContext.cpp |
@@ -1374,6 +1374,8 @@ bool GrContext::writeTexturePixels(GrTexture* texture, |
return fGpu->writeTexturePixels(texture, left, top, width, height, |
config, buffer, rowBytes); |
+ |
+ // No need to check the kFlushWrites flag here since we issued the write directly to fGpu. |
} |
bool GrContext::readTexturePixels(GrTexture* texture, |
@@ -1403,7 +1405,8 @@ bool GrContext::readTexturePixels(GrTexture* texture, |
ast.set(this, desc, kExact_ScratchTexMatch); |
GrTexture* dst = ast.texture(); |
if (dst && (target = dst->asRenderTarget())) { |
- this->copyTexture(texture, target, NULL); |
+ this->copySurface(target, texture, SkIRect::MakeXYWH(top, left, width, height), |
+ SkIPoint::Make(0,0)); |
return this->readRenderTargetPixels(target, |
left, top, width, height, |
config, buffer, rowBytes, |
@@ -1591,29 +1594,26 @@ void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { |
target->discard(renderTarget); |
} |
-void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) { |
+void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, |
+ const SkIPoint& dstPoint, uint32_t pixelOpsFlags) { |
if (NULL == src || NULL == dst) { |
return; |
} |
ASSERT_OWNED_RESOURCE(src); |
ASSERT_OWNED_RESOURCE(dst); |
- SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); |
- if (topLeft) { |
- srcRect.offset(*topLeft); |
- } |
- SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); |
- if (!srcRect.intersect(srcBounds)) { |
- return; |
- } |
+ // Since we're going to the draw target and not GPU, no need to check kNoFlush |
+ // here. |
GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, NULL, NULL); |
if (NULL == target) { |
return; |
} |
- SkIPoint dstPoint; |
- dstPoint.setZero(); |
target->copySurface(dst, src, srcRect, dstPoint); |
+ |
+ if (kFlushWrites_PixelOp & pixelOpsFlags) { |
+ this->flush(); |
+ } |
} |
bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget, |
@@ -1621,7 +1621,7 @@ bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget, |
GrPixelConfig srcConfig, |
const void* buffer, |
size_t rowBytes, |
- uint32_t flags) { |
+ uint32_t pixelOpsFlags) { |
ASSERT_OWNED_RESOURCE(renderTarget); |
if (NULL == renderTarget) { |
@@ -1646,11 +1646,11 @@ bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget, |
// At least some drivers on the Mac get confused when glTexImage2D is called on a texture |
// attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or |
// HW is affected. |
- if (renderTarget->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && |
+ if (renderTarget->asTexture() && !(kUnpremul_PixelOpsFlag & pixelOpsFlags) && |
fGpu->canWriteTexturePixels(renderTarget->asTexture(), srcConfig)) { |
return this->writeTexturePixels(renderTarget->asTexture(), |
left, top, width, height, |
- srcConfig, buffer, rowBytes, flags); |
+ srcConfig, buffer, rowBytes, pixelOpsFlags); |
} |
#endif |
@@ -1683,7 +1683,7 @@ bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget, |
// allocate a tmp buffer and sw convert the pixels to premul |
SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); |
- if (kUnpremul_PixelOpsFlag & flags) { |
+ if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { |
if (!GrPixelConfigIs8888(srcConfig)) { |
return false; |
} |
@@ -1724,25 +1724,42 @@ bool GrContext::writeRenderTargetPixels(GrRenderTarget* renderTarget, |
if (!this->writeTexturePixels(texture, |
0, 0, width, height, |
writeConfig, buffer, rowBytes, |
- flags & ~kUnpremul_PixelOpsFlag)) { |
+ pixelOpsFlags & ~kUnpremul_PixelOpsFlag)) { |
return false; |
} |
SkMatrix matrix; |
matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); |
+ |
// This function can be called in the midst of drawing another object (e.g., when uploading a |
// SW-rasterized clip while issuing a draw). So we push the current geometry state before |
// drawing a rect to the render target. |
- GrDrawTarget* drawTarget = this->prepareToDraw(NULL, kYes_BufferedDraw, NULL, NULL); |
- GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::kReset_ASRInit, &matrix); |
- GrDrawState* drawState = drawTarget->drawState(); |
- drawState->addColorProcessor(fp); |
- drawState->setRenderTarget(renderTarget); |
- drawState->disableState(GrDrawState::kClip_StateBit); |
- drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height))); |
+ // The bracket ensures we pop the stack if we wind up flushing below. |
+ { |
+ GrDrawTarget* drawTarget = this->prepareToDraw(NULL, kYes_BufferedDraw, NULL, NULL); |
+ GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::kReset_ASRInit, |
+ &matrix); |
+ GrDrawState* drawState = drawTarget->drawState(); |
+ drawState->addColorProcessor(fp); |
+ drawState->setRenderTarget(renderTarget); |
+ drawState->disableState(GrDrawState::kClip_StateBit); |
+ drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height))); |
+ } |
+ |
+ if (kFlushWrites_PixelOp & pixelOpsFlags) { |
+ this->flush(); |
+ } |
+ |
return true; |
} |
+ |
+void GrContext::flushSurfaceWrites(GrSurface* surface) { |
+ if (surface->surfacePriv().hasPendingWrite()) { |
+ this->flush(); |
+ } |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, |