Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Unified Diff: src/gpu/GrContext.cpp

Issue 1260293004: Revert of Move draw on upload decision in GrGpu (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/gpu/GrGpu.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrContext.cpp
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index adbde946c55adbc4303af55e95fd12d9058adc47..ba02d60b11ece81231086a890d33214dc03e3601 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -329,96 +329,76 @@
GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
uint32_t pixelOpsFlags) {
RETURN_FALSE_IF_ABANDONED
+ {
+ GrTexture* texture = NULL;
+ if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) &&
+ fGpu->canWriteTexturePixels(texture, srcConfig) &&
+ (!fCaps->useDrawInsteadOfPartialRenderTargetWrite() || !surface->asRenderTarget() ||
+ (width == texture->width() && height == texture->height()))) {
+
+ if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) &&
+ surface->surfacePriv().hasPendingIO()) {
+ this->flush();
+ }
+ return fGpu->writeTexturePixels(texture, left, top, width, height,
+ srcConfig, buffer, rowBytes);
+ // Don't need to check kFlushWrites_PixelOp here, we just did a direct write so the
+ // upload is already flushed.
+ }
+ }
// Trim the params here so that if we wind up making a temporary surface it can be as small as
- // necessary and because GrGpu::getWritePixelsInfo requires it.
+ // necessary.
if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(),
GrBytesPerPixel(srcConfig), &left, &top, &width,
&height, &buffer, &rowBytes)) {
return false;
}
- bool applyPremulToSrc = false;
+ // If we didn't do a direct texture write then we upload the pixels to a texture and draw.
+ GrRenderTarget* renderTarget = surface->asRenderTarget();
+ if (!renderTarget) {
+ return false;
+ }
+
+ // We ignore the preferred config unless it is a R/B swap of the src config. In that case
+ // we will upload the original src data to a scratch texture but we will spoof it as the swapped
+ // config. This scratch will then have R and B swapped. We correct for this by swapping again
+ // when drawing the scratch to the dst using a conversion effect.
+ bool swapRAndB = false;
+ GrPixelConfig writeConfig = srcConfig;
+ if (GrPixelConfigSwapRAndB(srcConfig) ==
+ fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) {
+ writeConfig = GrPixelConfigSwapRAndB(srcConfig);
+ swapRAndB = true;
+ }
+
+ GrSurfaceDesc desc;
+ desc.fWidth = width;
+ desc.fHeight = height;
+ desc.fConfig = writeConfig;
+ SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(desc,
+ GrTextureProvider::kApprox_ScratchTexMatch));
+ if (!texture) {
+ return false;
+ }
+
+ SkAutoTUnref<const GrFragmentProcessor> fp;
+ SkMatrix 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);
+
+ GrPaint paint;
if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
if (!GrPixelConfigIs8888(srcConfig)) {
return false;
}
- applyPremulToSrc = true;
- }
- GrGpu::DrawPreference drawPreference = applyPremulToSrc ?
- GrGpu::kCallerPrefersDraw_DrawPreference :
- GrGpu::kNoDraw_DrawPreference;
- GrGpu::WritePixelTempDrawInfo tempDrawInfo;
- if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, &drawPreference,
- &tempDrawInfo)) {
- return false;
- }
-
- if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().hasPendingIO()) {
- this->flush();
- }
-
- SkAutoTUnref<GrTexture> tempTexture;
- if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
- tempTexture.reset(this->textureProvider()->refScratchTexture(
- tempDrawInfo.fTempSurfaceDesc, GrTextureProvider::kApprox_ScratchTexMatch));
- if (!tempTexture && GrGpu::kRequireDraw_DrawPreference == drawPreference) {
- return false;
- }
- }
-
- if (tempTexture) {
- SkAutoTUnref<const GrFragmentProcessor> fp;
- SkMatrix textureMatrix;
- textureMatrix.setIDiv(tempTexture->width(), tempTexture->height());
- GrPaint paint;
- if (applyPremulToSrc) {
- fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), tempTexture,
- tempDrawInfo.fSwapRAndB, textureMatrix));
- // If premultiplying was the only reason for the draw, fall back to a straight write.
- if (!fp && GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
- tempTexture.reset(NULL);
- }
- }
- if (tempTexture) {
- if (!fp) {
- fp.reset(GrConfigConversionEffect::Create(
- paint.getProcessorDataManager(), tempTexture, tempDrawInfo.fSwapRAndB,
- GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
- if (!fp) {
- return false;
- }
- }
- GrRenderTarget* renderTarget = surface->asRenderTarget();
- SkASSERT(renderTarget);
- if (tempTexture->surfacePriv().hasPendingIO()) {
- this->flush();
- }
- if (!fGpu->writeTexturePixels(tempTexture, 0, 0, width, height,
- tempDrawInfo.fTempSurfaceDesc.fConfig, buffer,
- rowBytes)) {
- return false;
- }
- SkMatrix matrix;
- matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
- GrDrawContext* drawContext = this->drawContext();
- if (!drawContext) {
- return false;
- }
- paint.addColorProcessor(fp);
- SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
- drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL);
-
- if (kFlushWrites_PixelOp & pixelOpsFlags) {
- this->flushSurfaceWrites(surface);
- }
- }
- }
- if (!tempTexture) {
- SkASSERT(surface->asTexture());
- // allocate a tmp buffer and sw convert the pixels to premul
- SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
- if (applyPremulToSrc) {
+ fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), texture, swapRAndB,
+ textureMatrix));
+ // handle the unpremul step on the CPU if we couldn't create an effect to do it.
+ if (!fp) {
size_t tmpRowBytes = 4 * width;
tmpPixels.reset(width * height);
if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
@@ -428,9 +408,45 @@
rowBytes = tmpRowBytes;
buffer = tmpPixels.get();
}
- return fGpu->writeTexturePixels(surface->asTexture(), left, top, width, height, srcConfig,
- buffer, rowBytes);
- }
+ }
+
+ if (!fp) {
+ fp.reset(GrConfigConversionEffect::Create(paint.getProcessorDataManager(),
+ texture,
+ swapRAndB,
+ GrConfigConversionEffect::kNone_PMConversion,
+ textureMatrix));
+ }
+
+ // Even if the client told us not to flush, we still flush here. The client may have known that
+ // writes to the original surface caused no data hazards, but they can't know that the scratch
+ // we just got is safe.
+ if (texture->surfacePriv().hasPendingIO()) {
+ this->flush();
+ }
+ if (!fGpu->writeTexturePixels(texture, 0, 0, width, height,
+ writeConfig, buffer, rowBytes)) {
+ return false;
+ }
+
+ SkMatrix matrix;
+ matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
+
+ GrDrawContext* drawContext = this->drawContext();
+ if (!drawContext) {
+ return false;
+ }
+
+ paint.addColorProcessor(fp);
+
+ SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
+
+ drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL);
+
+ if (kFlushWrites_PixelOp & pixelOpsFlags) {
+ this->flushSurfaceWrites(surface);
+ }
+
return true;
}
« no previous file with comments | « no previous file | src/gpu/GrGpu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698