aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2016-07-28 13:37:31 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-28 13:37:31 -0700
commit4d516a6903d83414b5615ca9388b52064da6990c (patch)
tree99a1743be3465948d3e5086ea28d7b15fbc08814
parent03f704a343d7a82974f977eda8789a8c721c93e5 (diff)
Serialize SkColorSpace into DeferredTextureImage
This fixes a memory leak that occurs when DeferredTextureImage is deallocated without being destroyed. It is intended to be stored in discarable memory and thus this has to be safe. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2184823010 Review-Url: https://codereview.chromium.org/2184823010
-rw-r--r--src/image/SkImage_Gpu.cpp96
1 files changed, 60 insertions, 36 deletions
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 740963a824..6cce96c1f7 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -357,31 +357,31 @@ sk_sp<SkImage> SkImage::MakeTextureFromPixmap(GrContext* ctx, const SkPixmap& pi
///////////////////////////////////////////////////////////////////////////////////////////////////
-class DeferredTextureImage {
-public:
- SkImage* newImage(GrContext* context, SkBudgeted) const;
-
-private:
- uint32_t fContextUniqueID;
- struct MipMapLevelData {
- void* fPixelData;
- size_t fRowBytes;
- };
- struct Data {
- SkImageInfo fInfo;
- int fColorTableCnt;
- uint32_t* fColorTableData;
- int fMipMapLevelCount;
- // The fMipMapLevelData array may contain more than 1 element.
- // It contains fMipMapLevelCount elements.
- // That means this struct's size is not known at compile-time.
- MipMapLevelData fMipMapLevelData[1];
- };
- Data fData;
-
- friend class SkImage;
+namespace {
+struct MipMapLevelData {
+ void* fPixelData;
+ size_t fRowBytes;
};
+struct DeferredTextureImage {
+ uint32_t fContextUniqueID;
+ // We don't store a SkImageInfo because it contains a ref-counted SkColorSpace.
+ int fWidth;
+ int fHeight;
+ SkColorType fColorType;
+ SkAlphaType fAlphaType;
+ void* fColorSpace;
+ size_t fColorSpaceSize;
+ int fColorTableCnt;
+ uint32_t* fColorTableData;
+ int fMipMapLevelCount;
+ // The fMipMapLevelData array may contain more than 1 element.
+ // It contains fMipMapLevelCount elements.
+ // That means this struct's size is not known at compile-time.
+ MipMapLevelData fMipMapLevelData[1];
+};
+} // anonymous namespace
+
size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& proxy,
const DeferredTextureImageUsageParams params[],
int paramCnt, void* buffer) const {
@@ -466,11 +466,18 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
size_t size = 0;
size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage));
size += dtiSize;
- size += mipMapLevelCount * sizeof(DeferredTextureImage::MipMapLevelData);
+ size += mipMapLevelCount * sizeof(MipMapLevelData);
size_t pixelOffset = size;
size += pixelSize;
size_t ctOffset = size;
size += ctSize;
+ size_t colorSpaceOffset = 0;
+ size_t colorSpaceSize = 0;
+ if (info.colorSpace()) {
+ colorSpaceOffset = size;
+ colorSpaceSize = info.colorSpace()->writeToMemory(nullptr);
+ size += colorSpaceSize;
+ }
if (!fillMode) {
return size;
}
@@ -490,12 +497,23 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
size_t rowBytes = pixmap.rowBytes();
DeferredTextureImage* dti = new (buffer) DeferredTextureImage();
dti->fContextUniqueID = proxy.fContextUniqueID;
- dti->fData.fInfo = info;
- dti->fData.fColorTableCnt = ctCount;
- dti->fData.fColorTableData = ct;
- dti->fData.fMipMapLevelCount = mipMapLevelCount;
- dti->fData.fMipMapLevelData[0].fPixelData = pixels;
- dti->fData.fMipMapLevelData[0].fRowBytes = rowBytes;
+ dti->fWidth = info.width();
+ dti->fHeight = info.height();
+ dti->fColorType = info.colorType();
+ dti->fAlphaType = info.alphaType();
+ dti->fColorTableCnt = ctCount;
+ dti->fColorTableData = ct;
+ dti->fMipMapLevelCount = mipMapLevelCount;
+ dti->fMipMapLevelData[0].fPixelData = pixels;
+ dti->fMipMapLevelData[0].fRowBytes = rowBytes;
+ if (colorSpaceSize) {
+ dti->fColorSpace = reinterpret_cast<void*>(bufferAsInt + colorSpaceOffset);
+ dti->fColorSpaceSize = colorSpaceSize;
+ info.colorSpace()->writeToMemory(dti->fColorSpace);
+ } else {
+ dti->fColorSpace = nullptr;
+ dti->fColorSpaceSize = 0;
+ }
return size;
}
@@ -510,14 +528,20 @@ sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con
return nullptr;
}
SkAutoTUnref<SkColorTable> colorTable;
- if (dti->fData.fColorTableCnt) {
- SkASSERT(dti->fData.fColorTableData);
- colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData.fColorTableCnt));
+ if (dti->fColorTableCnt) {
+ SkASSERT(dti->fColorTableData);
+ colorTable.reset(new SkColorTable(dti->fColorTableData, dti->fColorTableCnt));
+ }
+ SkASSERT(dti->fMipMapLevelCount == 1);
+ sk_sp<SkColorSpace> colorSpace;
+ if (dti->fColorSpaceSize) {
+ colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpaceSize);
}
- SkASSERT(dti->fData.fMipMapLevelCount == 1);
+ SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight,
+ dti->fColorType, dti->fAlphaType, colorSpace);
SkPixmap pixmap;
- pixmap.reset(dti->fData.fInfo, dti->fData.fMipMapLevelData[0].fPixelData,
- dti->fData.fMipMapLevelData[0].fRowBytes, colorTable.get());
+ pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData,
+ dti->fMipMapLevelData[0].fRowBytes, colorTable.get());
return SkImage::MakeTextureFromPixmap(context, pixmap, budgeted);
}