Index: src/gpu/GrContext.cpp |
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp |
index 081bc0ac3819ffcc58be372a8bec9fbc32df65af..6b3c7fa3edfc0e53463922cee4a6b95da320686d 100644 |
--- a/src/gpu/GrContext.cpp |
+++ b/src/gpu/GrContext.cpp |
@@ -1,4 +1,3 @@ |
- |
/* |
* Copyright 2011 Google Inc. |
* |
@@ -19,6 +18,7 @@ |
#include "SkConfig8888.h" |
#include "SkGrPriv.h" |
+#include "SkTypes.h" |
#include "effects/GrConfigConversionEffect.h" |
@@ -224,20 +224,42 @@ 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; |
+ for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; currentMipLevel--) { |
+ // make sure the texelmap's size range is within int range |
+ if (texelsCopy[currentMipLevel].fWidth > SK_MaxS32 |
+ || texelsCopy[currentMipLevel].fHeight > SK_MaxS32) { |
bsalomon
2015/10/28 16:40:44
|| on prev line
Does SkMipMapLevel need to use ui
cblume
2015/10/28 22:49:40
Okay, I'll make them ints and remove the range che
|
+ return false; |
+ } |
+ int currentMipWidth = texelsCopy[currentMipLevel].fWidth; |
+ int currentMipHeight = texelsCopy[currentMipLevel].fHeight; |
+ |
+ SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; |
+ if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(), |
+ GrBytesPerPixel(srcConfig), &left, &top, |
+ ¤tMipWidth, ¤tMipHeight, |
+ ¤tMipMap.fTexels, |
+ ¤tMipMap.fRowBytes)) { |
+ return false; |
+ } |
+ |
+ // make sure the size range is within the texelmap's size range |
+ if (currentMipWidth < 0 || currentMipHeight < 0) { |
+ return false; |
+ } |
+ texelsCopy[currentMipLevel].fWidth = currentMipWidth; |
+ texelsCopy[currentMipLevel].fHeight = currentMipHeight; |
} |
bool applyPremulToSrc = false; |
@@ -256,7 +278,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; |
} |
@@ -312,19 +334,26 @@ 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; |
+ for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; |
+ currentMipLevel--) { |
+ SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; |
+ int currentWidth = currentMipMap.fWidth; |
+ int currentHeight = currentMipMap.fHeight; |
+ size_t tmpRowBytes = 4 * currentWidth; |
+ tmpPixels.reset(currentWidth * currentHeight); |
+ if (!sw_convert_to_premul(srcConfig, currentWidth, currentHeight, |
+ currentMipMap.fRowBytes, |
+ currentMipMap.fTexels, tmpRowBytes, |
+ tmpPixels.get())) { |
+ return false; |
+ } |
+ currentMipMap.fRowBytes = tmpRowBytes; |
+ currentMipMap.fTexels = tmpPixels.get(); |
} |
- 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; |
@@ -344,21 +373,47 @@ 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; |
+ for (int currentMipLevel = texelsCopy.count() - 1; currentMipLevel >= 0; |
+ currentMipLevel--) { |
+ SkMipMapLevel& currentMipMap = texelsCopy[currentMipLevel]; |
+ int currentMipWidth = currentMipMap.fWidth; |
+ int currentMipHeight = currentMipMap.fHeight; |
+ size_t tmpRowBytes = 4 * currentMipWidth; |
+ tmpPixels.reset(currentMipWidth * currentMipHeight); |
+ if (!sw_convert_to_premul(srcConfig, currentMipWidth, currentMipHeight, |
+ currentMipMap.fRowBytes, currentMipMap.fTexels, |
+ tmpRowBytes, tmpPixels.get())) { |
+ return false; |
+ } |
+ currentMipMap.fRowBytes = tmpRowBytes; |
+ currentMipMap.fTexels = tmpPixels.get(); |
} |
- 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) { |
+ 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, |