Chromium Code Reviews| Index: src/image/SkImage_Gpu.cpp |
| diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp |
| index a728c3dae594f41385891352110363be3ded29c2..b7fae2f2d0c56ed7cd1b0d1eba7cb3c1765df952 100644 |
| --- a/src/image/SkImage_Gpu.cpp |
| +++ b/src/image/SkImage_Gpu.cpp |
| @@ -16,6 +16,7 @@ |
| #include "SkGrPixelRef.h" |
| #include "SkGrPriv.h" |
| #include "SkImage_Gpu.h" |
| +#include "SkMipMap.h" |
| #include "SkPixelRef.h" |
| SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrTexture* tex, |
| @@ -348,7 +349,7 @@ private: |
| }; |
| size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& proxy, |
| - const DeferredTextureImageUsageParams[], |
| + const DeferredTextureImageUsageParams params[], |
| int paramCnt, void* buffer) const { |
| const bool fillMode = SkToBool(buffer); |
| if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { |
| @@ -391,7 +392,29 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox |
| SkASSERT(!pixmap.ctable()); |
| } |
| } |
| + bool shouldUseMipMaps = false; |
| int mipMapLevelCount = 1; |
|
ericrk
2016/06/03 18:05:45
This is a bit misleading - if we are using mips, m
cblume
2016/06/03 18:57:31
Hrmmm perhaps I made a mistake.
The way it *should
|
| + for (int currentParamIndex = paramCnt; currentParamIndex > 0; currentParamIndex--) { |
|
ericrk
2016/06/03 18:05:45
I'm going to need to extract things from params (a
cblume
2016/06/03 18:57:31
Good idea. I'll put this at the top and see how it
|
| + const SkMatrix& currentMatrix = params[currentParamIndex].fMatrix; |
|
ericrk
2016/06/03 18:05:45
won't this index out of bounds and skip the 0th pa
cblume
2016/06/03 18:57:31
Hrmm it will indeed skip the 0th. It should be for
|
| + SkScalar minScaleFactor = currentMatrix.getMinScale(); |
| + if (currentMatrix.hasPerspective() || |
|
ericrk
2016/06/03 18:05:45
Can you add a comment explaining the logic here (i
cblume
2016/06/03 18:57:31
I agree 100% on the individual bools. That might a
|
| + ((params[currentParamIndex].fQuality == kMedium_SkFilterQuality || |
| + params[currentParamIndex].fQuality == kHigh_SkFilterQuality) && |
| + minScaleFactor != -1.f && minScaleFactor < 1.f)) { |
| + shouldUseMipMaps = true; |
| + mipMapLevelCount = SkMipMap::ComputeLevelCount(width(), height()); |
| + break; |
| + } |
| + } |
| + SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
| + if (shouldUseMipMaps) { |
| + for (int currentMipMapLevelIndex = mipMapLevelCount; currentMipMapLevelIndex > 0; |
| + currentMipMapLevelIndex--) { |
| + SkISize mipSize = SkMipMap::ComputeLevelSize(width(), height(), currentMipMapLevelIndex); |
| + SkImageInfo mipInfo = SkImageInfo::MakeN32(mipSize.fWidth, mipSize.fHeight, at); |
| + pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullptr)); |
| + } |
| + } |
| size_t size = 0; |
| size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); |
| size += dtiSize; |
| @@ -425,6 +448,27 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox |
| dti->fData.fMipMapLevelCount = mipMapLevelCount; |
| dti->fData.fMipMapLevelData[0].fPixelData = pixels; |
| dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes; |
| + |
| + // Fill in the mipmap levels if they exist |
| + intptr_t mipLevelPtr = bufferAsInt + pixelOffset; |
| + if (shouldUseMipMaps) { |
| + SkAutoTDelete<SkMipMap> mipmaps(SkMipMap::Build(pixmap, nullptr)); |
| + for (int currentMipMapLevelIndex = 1; currentMipMapLevelIndex < mipMapLevelCount; |
|
ericrk
2016/06/03 18:05:45
Wont this skip the last mip level? when computed b
cblume
2016/06/03 18:57:31
Good catch.
|
| + currentMipMapLevelIndex++) { |
| + SkISize prevMipSize = SkMipMap::ComputeLevelSize(width(), height(), currentMipMapLevelIndex); |
| + SkImageInfo prevMipInfo = SkImageInfo::MakeN32(prevMipSize.fWidth, prevMipSize.fHeight, at); |
| + mipLevelPtr += SkAlign8(SkAutoPixmapStorage::AllocSize(prevMipInfo, nullptr)); |
| + |
| + SkMipMap::Level currentMipMapLevel; |
| + mipmaps->getLevel(currentMipMapLevelIndex, ¤tMipMapLevel); |
| + memcpy(reinterpret_cast<void*>(mipLevelPtr), currentMipMapLevel.fPixmap.addr(), |
| + currentMipMapLevel.fPixmap.getSafeSize()); |
| + dti->fData.fMipMapLevelData[currentMipMapLevelIndex].fPixelData = |
| + reinterpret_cast<void*>(mipLevelPtr); |
| + dti->fData.fMipMapLevelData[currentMipMapLevelIndex].fRowBytes = |
| + currentMipMapLevel.fPixmap.rowBytes(); |
| + } |
| + } |
| return size; |
| } |
| @@ -443,11 +487,23 @@ sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con |
| SkASSERT(dti->fData.fColorTableData); |
| colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData.fColorTableCnt)); |
| } |
| - SkASSERT(dti->fData.fMipMapLevelCount == 1); |
| - SkPixmap pixmap; |
| - pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData, |
| - dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()); |
| - return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); |
| + int mipLevelCount = dti->fData.fMipMapLevelCount; |
| + SkASSERT(mipLevelCount >= 1); |
| + if (mipLevelCount == 1) { |
| + SkPixmap pixmap; |
| + pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData, |
| + dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get()); |
| + return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted); |
| + } else { |
| + SkAutoTDeleteArray<GrMipLevel> texels(new GrMipLevel[mipLevelCount]); |
| + for (int i = 0; i < mipLevelCount; i++) { |
| + texels[i].fPixels = dti->fData.fMipMapLevelData[i].fPixelData; |
| + texels[i].fRowBytes = dti->fData.fMipMapLevelData[i].fRowBytes; |
| + } |
| + |
| + return SkImage::MakeTextureFromMipMap(context, dti->fData.fInfo, texels.get(), |
| + mipLevelCount, SkBudgeted::kYes); |
| + } |
| } |
| /////////////////////////////////////////////////////////////////////////////////////////////////// |