Chromium Code Reviews| Index: src/gpu/vk/GrVkGpu.cpp |
| diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp |
| index 33b53b1bcd76b257ffa28f6e5cfa6ec5fb216560..dc8e4289aaaa1086f8215f725205dbc26297d502 100644 |
| --- a/src/gpu/vk/GrVkGpu.cpp |
| +++ b/src/gpu/vk/GrVkGpu.cpp |
| @@ -283,9 +283,10 @@ bool GrVkGpu::onWritePixels(GrSurface* surface, |
| success = this->uploadTexDataLinear(vkTex, left, top, width, height, config, |
| texels.begin()->fPixels, texels.begin()->fRowBytes); |
| } else { |
| - int mipLevels = texels.count(); |
| - if (vkTex->texturePriv().maxMipMapLevel() != mipLevels) { |
| - if (!vkTex->reallocForMipmap(this, mipLevels)) { |
| + int newMipLevels = texels.count(); |
| + int currentMipLevels = vkTex->texturePriv().maxMipMapLevel(); |
| + if ((currentMipLevels || newMipLevels != 1) && newMipLevels != currentMipLevels) { |
| + if (!vkTex->reallocForMipmap(this, newMipLevels)) { |
| return false; |
| } |
| } |
| @@ -389,36 +390,45 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, |
| size_t bpp = GrBytesPerPixel(dataConfig); |
| // texels is const. |
| - // But we may need to adjust the fPixels ptr based on the copyRect. |
| - // In this case we need to make a non-const shallow copy of texels. |
| - const SkTArray<GrMipLevel>* texelsPtr = &texels; |
| - SkTArray<GrMipLevel> texelsCopy; |
| - if (0 != left || 0 != top || width != tex->width() || height != tex->height()) { |
| - texelsCopy = texels; |
| + // But we may need to adjust the fPixels ptr based on the copyRect, or fRowBytes. |
| + // Because of this we need to make a non-const shallow copy of texels. |
| + SkTArray<GrMipLevel> texelsShallowCopy(texels); |
| - SkASSERT(1 == texels.count()); |
| - SkASSERT(texelsCopy[0].fPixels); |
| - |
| - if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, |
| - &width, &height, &texelsCopy[0].fPixels, |
| - &texelsCopy[0].fRowBytes)) { |
| - return false; |
| - } |
| - |
| - texelsPtr = &texelsCopy; |
| + for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0; |
| + currentMipLevel--) { |
| + SkASSERT(texelsShallowCopy[currentMipLevel].fPixels); |
| } |
| // Determine whether we need to flip when we copy into the buffer |
| - bool flipY = (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsPtr->empty()); |
| + bool flipY = (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty()); |
| + // adjust any params (left, top, currentWidth, currentHeight |
| // find the combined size of all the mip levels and the relative offset of |
| // each into the collective buffer |
| - size_t combinedBufferSize = 0; |
| - SkTArray<size_t> individualMipOffsets(texelsPtr->count()); |
| - for (int currentMipLevel = 0; currentMipLevel < texelsPtr->count(); currentMipLevel++) { |
| - int twoToTheMipLevel = 1 << currentMipLevel; |
| - int currentWidth = SkTMax(1, width / twoToTheMipLevel); |
| - int currentHeight = SkTMax(1, height / twoToTheMipLevel); |
| + // Do the first level separately because we may need to adjust width and height |
| + // (for the non-mipped case). |
| + if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, |
| + &width, |
| + &height, |
| + &texelsShallowCopy[0].fPixels, |
| + &texelsShallowCopy[0].fRowBytes)) { |
| + return false; |
| + } |
| + SkTArray<size_t> individualMipOffsets(texelsShallowCopy.count()); |
| + individualMipOffsets.push_back(0); |
| + size_t combinedBufferSize = width * bpp * height; |
| + int currentWidth = width; |
| + int currentHeight = height; |
| + for (int currentMipLevel = 1; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { |
|
egdaniel
2016/05/02 17:38:23
In this loop I notice you removed the SkTMax to ke
jvanverth1
2016/05/02 17:46:08
Whoops, fixed.
|
| + currentWidth /= 2; |
| + currentHeight /= 2; |
| + if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bpp, &left, &top, |
| + ¤tWidth, |
| + ¤tHeight, |
| + &texelsShallowCopy[currentMipLevel].fPixels, |
| + &texelsShallowCopy[currentMipLevel].fRowBytes)) { |
| + return false; |
| + } |
| const size_t trimmedSize = currentWidth * bpp * currentHeight; |
| individualMipOffsets.push_back(combinedBufferSize); |
| combinedBufferSize += trimmedSize; |
| @@ -429,18 +439,17 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, |
| GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuffer::kCopyRead_Type); |
| char* buffer = (char*) transferBuffer->map(); |
| - SkTArray<VkBufferImageCopy> regions(texelsPtr->count()); |
| + SkTArray<VkBufferImageCopy> regions(texelsShallowCopy.count()); |
| - for (int currentMipLevel = 0; currentMipLevel < texelsPtr->count(); currentMipLevel++) { |
| - int twoToTheMipLevel = 1 << currentMipLevel; |
| - int currentWidth = SkTMax(1, width / twoToTheMipLevel); |
| - int currentHeight = SkTMax(1, height / twoToTheMipLevel); |
| + currentWidth = width; |
| + currentHeight = height; |
| + for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); currentMipLevel++) { |
| const size_t trimRowBytes = currentWidth * bpp; |
| - const size_t rowBytes = (*texelsPtr)[currentMipLevel].fRowBytes; |
| + const size_t rowBytes = texelsShallowCopy[currentMipLevel].fRowBytes; |
| // copy data into the buffer, skipping the trailing bytes |
| char* dst = buffer + individualMipOffsets[currentMipLevel]; |
| - const char* src = (const char*)(*texelsPtr)[currentMipLevel].fPixels; |
| + const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels; |
| if (flipY) { |
| src += (currentHeight - 1) * rowBytes; |
| for (int y = 0; y < currentHeight; y++) { |
| @@ -460,8 +469,11 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, |
| region.bufferRowLength = currentWidth; |
| region.bufferImageHeight = currentHeight; |
| region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, SkToU32(currentMipLevel), 0, 1 }; |
| - region.imageOffset = { left, top, 0 }; |
| + region.imageOffset = { left, flipY ? tex->height() - top - currentHeight : top, 0 }; |
| region.imageExtent = { (uint32_t)currentWidth, (uint32_t)currentHeight, 1 }; |
| + |
| + currentWidth /= 2; |
| + currentHeight /= 2; |
| } |
| transferBuffer->unmap(); |