Index: src/gpu/vk/GrVkGpu.cpp |
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp |
index f5c6c3eb3b2af2e650073411a68a4b002f32a00f..d5671d427a76baa425b7e9288865cf8710fe7c97 100644 |
--- a/src/gpu/vk/GrVkGpu.cpp |
+++ b/src/gpu/vk/GrVkGpu.cpp |
@@ -414,8 +414,8 @@ bool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex, |
if (trimRowBytes == rowBytes && trimRowBytes == layout.rowPitch) { |
memcpy(mapPtr, data, trimRowBytes * height); |
} else { |
- SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, |
- trimRowBytes, height); |
+ SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, trimRowBytes, |
+ height); |
} |
} |
@@ -1356,6 +1356,24 @@ void GrVkGpu::onGetMultisampleSpecs(GrRenderTarget* rt, const GrStencilSettings& |
bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, |
GrPixelConfig readConfig, DrawPreference* drawPreference, |
ReadPixelTempDrawInfo* tempDrawInfo) { |
+ // These settings we will always want if a temp draw is performed. |
+ tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag; |
+ tempDrawInfo->fTempSurfaceDesc.fWidth = width; |
+ tempDrawInfo->fTempSurfaceDesc.fHeight = height; |
+ tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; |
+ tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. |
+ tempDrawInfo->fUseExactScratch = false; |
+ |
+ // For now assume no swizzling, we may change that below. |
+ tempDrawInfo->fSwizzle = GrSwizzle::RGBA(); |
+ |
+ // Depends on why we need/want a temp draw. Start off assuming no change, the surface we read |
+ // from will be srcConfig and we will read readConfig pixels from it. |
+ // Not that if we require a draw and return a non-renderable format for the temp surface the |
+ // base class will fail for us. |
+ tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config(); |
+ tempDrawInfo->fReadConfig = readConfig; |
+ |
if (srcSurface->config() == readConfig) { |
return true; |
} |
@@ -1408,7 +1426,7 @@ bool GrVkGpu::onReadPixels(GrSurface* surface, |
VkBufferImageCopy region; |
memset(®ion, 0, sizeof(VkBufferImageCopy)); |
region.bufferOffset = 0; |
- region.bufferRowLength = 0; // Forces RowLength to be imageExtent.width |
+ region.bufferRowLength = 0; // Forces RowLength to be width. We handle the rowBytes below. |
region.bufferImageHeight = 0; // Forces height to be tightly packed. Only useful for 3d images. |
region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
region.imageOffset = offset; |
@@ -1435,29 +1453,26 @@ bool GrVkGpu::onReadPixels(GrSurface* surface, |
void* mappedMemory = transferBuffer->map(); |
- memcpy(buffer, mappedMemory, rowBytes*height); |
- |
- transferBuffer->unmap(); |
- transferBuffer->unref(); |
- |
+ size_t tightRowBytes = GrBytesPerPixel(config) * width; |
if (flipY) { |
- SkAutoSMalloc<32 * sizeof(GrColor)> scratch; |
- size_t tightRowBytes = GrBytesPerPixel(config) * width; |
- scratch.reset(tightRowBytes); |
- void* tmpRow = scratch.get(); |
- // flip y in-place by rows |
- const int halfY = height >> 1; |
- char* top = reinterpret_cast<char*>(buffer); |
- char* bottom = top + (height - 1) * rowBytes; |
- for (int y = 0; y < halfY; y++) { |
- memcpy(tmpRow, top, tightRowBytes); |
- memcpy(top, bottom, tightRowBytes); |
- memcpy(bottom, tmpRow, tightRowBytes); |
- top += rowBytes; |
- bottom -= rowBytes; |
+ const char* srcRow = reinterpret_cast<const char*>(mappedMemory); |
+ char* dstRow = reinterpret_cast<char*>(buffer)+(height - 1) * rowBytes; |
+ for (int y = 0; y < height; y++) { |
+ memcpy(dstRow, srcRow, tightRowBytes); |
+ srcRow += tightRowBytes; |
+ dstRow -= rowBytes; |
+ } |
+ } else { |
+ if (tightRowBytes == rowBytes) { |
+ memcpy(buffer, mappedMemory, rowBytes*height); |
+ } else { |
+ SkRectMemcpy(buffer, rowBytes, mappedMemory, tightRowBytes, tightRowBytes, height); |
} |
} |
+ transferBuffer->unmap(); |
+ transferBuffer->unref(); |
+ |
return true; |
} |