Chromium Code Reviews| Index: src/gpu/GrContext.cpp |
| diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
| index c7e6ca949a7d22db30661449b7e05916f8c873c9..e6c29e03f26d038a370b09dd60bd25105d2faa83 100644 |
| --- a/src/gpu/GrContext.cpp |
| +++ b/src/gpu/GrContext.cpp |
| @@ -105,7 +105,7 @@ void GrContext::DrawingMgr::flush() { |
| } |
| } |
| -GrDrawContext* GrContext::DrawingMgr::drawContext(const SkSurfaceProps* surfaceProps) { |
| +GrDrawContext* GrContext::DrawingMgr::drawContext(const SkSurfaceProps* surfaceProps) { |
| if (this->abandoned()) { |
| return nullptr; |
| } |
| @@ -320,20 +320,31 @@ bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t |
| bool GrContext::writeSurfacePixels(GrSurface* surface, |
| int left, int top, int width, int height, |
| - GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, |
| + GrPixelConfig srcConfig, const SkTArray<SkMipMapLevel>& texels, |
| uint32_t pixelOpsFlags) { |
| RETURN_FALSE_IF_ABANDONED |
| ASSERT_OWNED_RESOURCE(surface); |
| SkASSERT(surface); |
| + SkTArray<SkMipMapLevel> texelsCopy(texels); |
|
bsalomon
2015/09/15 13:14:11
Why do we need to copy the mip array?
cblume
2015/09/16 18:40:46
Further down there is a call to GrSurfacePriv::Adj
|
| + |
| this->testPMConversionsIfNecessary(pixelOpsFlags); |
| // 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. |
| - if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(), |
| - GrBytesPerPixel(srcConfig), &left, &top, &width, |
| - &height, &buffer, &rowBytes)) { |
| - return false; |
| + auto currentMipHeight = height; |
| + auto currentMipWidth = width; |
| + for (auto currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; currentMipLevel--) { |
| + auto& currentMipMap = texelsCopy[currentMipLevel]; |
| + if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(), |
| + GrBytesPerPixel(srcConfig), &left, &top, |
| + ¤tMipWidth, ¤tMipHeight, |
| + ¤tMipMap.fTexels, |
| + ¤tMipMap.fRowBytes)) { |
| + return false; |
| + } |
| + currentMipHeight /= 2; |
| + currentMipWidth /= 2; |
| } |
| bool applyPremulToSrc = false; |
| @@ -352,7 +363,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, |
| } |
| GrGpu::WritePixelTempDrawInfo tempDrawInfo; |
| - if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, &drawPreference, |
| + if (!fGpu->getWritePixelsInfo(surface, width, height, srcConfig, &drawPreference, |
| &tempDrawInfo)) { |
| return false; |
| } |
| @@ -404,19 +415,27 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, |
| this->flush(); |
| } |
| if (applyPremulToSrc) { |
| - size_t tmpRowBytes = 4 * width; |
| - tmpPixels.reset(width * height); |
| - if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes, |
| - tmpPixels.get())) { |
| - return false; |
| + auto currentWidth = width; |
| + auto currentHeight = height; |
| + for (auto currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; currentMipLevel--) { |
| + size_t tmpRowBytes = 4 * currentWidth; |
| + tmpPixels.reset(currentWidth * currentHeight); |
| + auto& currentMipMap = texelsCopy[currentMipLevel]; |
| + if (!sw_convert_to_premul(srcConfig, currentWidth, currentHeight, |
| + currentMipMap.fRowBytes, |
| + currentMipMap.fTexels, tmpRowBytes, |
| + tmpPixels.get())) { |
| + return false; |
| + } |
| + currentMipMap.fRowBytes = tmpRowBytes; |
| + currentMipMap.fTexels = tmpPixels.get(); |
| + currentWidth /= 2; |
| + currentHeight /= 2; |
| } |
| - rowBytes = tmpRowBytes; |
| - buffer = tmpPixels.get(); |
| applyPremulToSrc = false; |
| } |
| if (!fGpu->writePixels(tempTexture, 0, 0, width, height, |
| - tempDrawInfo.fTempSurfaceDesc.fConfig, buffer, |
| - rowBytes)) { |
| + tempDrawInfo.fTempSurfaceDesc.fConfig, texelsCopy)) { |
| return false; |
| } |
| SkMatrix matrix; |
| @@ -436,21 +455,42 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, |
| } |
| if (!tempTexture) { |
| if (applyPremulToSrc) { |
| - size_t tmpRowBytes = 4 * width; |
| - tmpPixels.reset(width * height); |
| - if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes, |
| - tmpPixels.get())) { |
| - return false; |
| + auto currentWidth = width; |
| + auto currentHeight = height; |
| + for (auto currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; currentMipLevel--) { |
| + size_t tmpRowBytes = 4 * currentWidth; |
| + tmpPixels.reset(currentWidth * currentHeight); |
| + auto& currentMipMap = texelsCopy[currentMipLevel]; |
| + if (!sw_convert_to_premul(srcConfig, currentWidth, currentHeight, |
| + currentMipMap.fRowBytes, currentMipMap.fTexels, |
| + tmpRowBytes, tmpPixels.get())) { |
| + return false; |
| + } |
| + currentMipMap.fRowBytes = tmpRowBytes; |
| + currentMipMap.fTexels = tmpPixels.get(); |
| + currentWidth /= 2; |
| + currentHeight /= 2; |
| } |
| - rowBytes = tmpRowBytes; |
| - buffer = tmpPixels.get(); |
| applyPremulToSrc = false; |
| } |
| - return fGpu->writePixels(surface, left, top, width, height, srcConfig, buffer, rowBytes); |
| + return fGpu->writePixels(surface, left, top, width, height, srcConfig, texelsCopy); |
| } |
| return true; |
| } |
| +bool GrContext::writeSurfacePixels(GrSurface* surface, |
| + int left, int top, int width, int height, |
| + GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, |
| + uint32_t pixelOpsFlags) { |
| + SkMipMapLevel level(buffer, rowBytes); |
| + const int mipLevelCount = 1; |
| + SkTArray<SkMipMapLevel> texels(mipLevelCount); |
| + texels.push_back(level); |
| + |
| + return this->writeSurfacePixels(surface, left, top, width, height, srcConfig, texels, |
| + pixelOpsFlags); |
| +} |
| + |
| bool GrContext::readSurfacePixels(GrSurface* src, |
| int left, int top, int width, int height, |
| GrPixelConfig dstConfig, void* buffer, size_t rowBytes, |