Chromium Code Reviews| Index: src/gpu/GrContext.cpp |
| diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
| index 4d6b6b8d0c3e6427c680d471586f6664578f2785..ee658d7ee6e216f98b3af3a6639c98b28400f4e5 100644 |
| --- a/src/gpu/GrContext.cpp |
| +++ b/src/gpu/GrContext.cpp |
| @@ -6,6 +6,8 @@ |
| * found in the LICENSE file. |
| */ |
| +#include <algorithm> |
| + |
| #include "GrContext.h" |
| #include "GrBatchFontCache.h" |
| @@ -320,20 +322,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); |
| + |
| 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; |
| + int currentMipWidth = width; |
| + int currentMipHeight = height; |
| + for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; currentMipLevel--) { |
| + SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; |
| + if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(), |
| + GrBytesPerPixel(srcConfig), &left, &top, |
| + ¤tMipWidth, ¤tMipHeight, |
| + ¤tMipMap.fTexels, |
| + ¤tMipMap.fRowBytes)) { |
| + return false; |
| + } |
| + currentMipWidth = std::max(1, currentMipWidth / 2); |
|
bsalomon
2015/09/30 18:01:29
SkTMax
cblume
2015/10/08 09:27:56
Noted. Although, I think my better option at this
bsalomon
2015/10/08 17:01:34
Does that mean that SkMipMap and OpenGL will disag
|
| + currentMipHeight = std::max(1, currentMipHeight / 2); |
|
bsalomon
2015/09/30 18:01:29
SkTMax
|
| } |
| bool applyPremulToSrc = false; |
| @@ -352,7 +365,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 +417,28 @@ 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; |
| + int currentWidth = width; |
| + int currentHeight = height; |
| + for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; |
| + currentMipLevel--) { |
| + size_t tmpRowBytes = 4 * currentWidth; |
| + tmpPixels.reset(currentWidth * currentHeight); |
| + SkMipMapLevel& 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 = std::max(1, currentWidth / 2); |
|
bsalomon
2015/09/30 18:01:29
SkTMax
cblume
2015/10/08 09:27:56
Done.
|
| + currentHeight = std::max(1, currentHeight / 2); |
|
bsalomon
2015/09/30 18:01:29
SkTMax
cblume
2015/10/08 09:27:56
Done.
|
| } |
| - 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 +458,49 @@ 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; |
| + int currentMipWidth = width; |
| + int currentMipHeight = height; |
| + for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; |
| + currentMipLevel--) { |
| + size_t tmpRowBytes = 4 * currentMipWidth; |
| + tmpPixels.reset(currentMipWidth * currentMipHeight); |
| + SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; |
| + if (!sw_convert_to_premul(srcConfig, currentMipWidth, currentMipHeight, |
| + currentMipMap.fRowBytes, currentMipMap.fTexels, |
| + tmpRowBytes, tmpPixels.get())) { |
| + return false; |
| + } |
| + currentMipMap.fRowBytes = tmpRowBytes; |
| + currentMipMap.fTexels = tmpPixels.get(); |
| + currentMipWidth = std::max(1, currentMipWidth / 2); |
|
bsalomon
2015/09/30 18:01:29
SkTMax
cblume
2015/10/08 09:27:56
Done.
|
| + currentMipHeight = std::max(1, currentMipHeight / 2); |
|
bsalomon
2015/09/30 18:01:29
SkTMax
cblume
2015/10/08 09:27:56
Done.
|
| } |
| - 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) { |
| + if (width < 0 || height < 0) { |
|
bsalomon
2015/09/30 18:01:29
Why not <=?
cblume
2015/10/08 09:27:56
Done.
|
| + return false; |
| + } |
| + const uint32_t baseLevelWidth = width; |
| + const uint32_t baseLevelHeight = height; |
| + |
| + SkMipMapLevel level(buffer, rowBytes, baseLevelWidth, baseLevelHeight); |
| + 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, |