Chromium Code Reviews| Index: src/image/SkImage_Gpu.cpp |
| diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp |
| index b87e50ba0ae932960422a39ce6f91a7b49c5322f..177f53982fb6a0e096cbfd0e018877b3e8713583 100644 |
| --- a/src/image/SkImage_Gpu.cpp |
| +++ b/src/image/SkImage_Gpu.cpp |
| @@ -325,6 +325,121 @@ SkImage* SkImage::NewTextureFromPixmap(GrContext* ctx, const SkPixmap& pixmap, |
| /////////////////////////////////////////////////////////////////////////////////////////////////// |
| +class DeferredTextureImage { |
| +public: |
| + SkImage* newImage(GrContext* context, SkBudgeted) const; |
| + |
| +private: |
| + uint32_t fContextUniqueID; |
|
robertphillips
2016/03/09 18:54:16
What do we do with fImageUniqueID ?
bsalomon
2016/03/10 15:30:07
Currently, nothing. I wasn't sure whether the new
|
| + uint32_t fImageUniqueID; |
| + struct Data { |
| + SkImageInfo fInfo; |
| + void* fPixelData; |
| + size_t fRowBytes; |
| + int fColorTableCnt; |
| + uint32_t* fColorTableData; |
| + }; |
| + Data fData; |
| + |
| + friend class SkImage; |
| +}; |
| + |
| +size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& proxy, |
| + const DeferredTextureImageUsageParams[], |
| + int paramCnt, void* buffer) const { |
| + const bool fillMode = SkToBool(buffer); |
| + if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { |
| + return 0; |
| + } |
| + |
| + SkAutoPixmapStorage pixmap; |
| + SkImageInfo info; |
| + size_t pixelSize = 0; |
| + size_t ctSize = 0; |
| + int ctCount = 0; |
| + if (this->peekPixels(&pixmap)) { |
| + info = pixmap.info(); |
| + pixelSize = SkAlign8(pixmap.getSafeSize()); |
| + if (pixmap.ctable()) { |
| + ctCount = pixmap.ctable()->count(); |
| + ctSize = SkAlign8(pixmap.ctable()->count() * 4); |
| + } |
| + } else { |
| + // Here we're just using presence of data to know whether there is a codec behind the image. |
| + // In the future we will access the cacherator and get the exact data that we want to (e.g. |
| + // yuv planes) upload. |
| + SkAutoTUnref<SkData> data(this->refEncoded()); |
| + if (!data) { |
| + return 0; |
| + } |
| + SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
| + info = SkImageInfo::MakeN32(this->width(), this->height(), at); |
| + pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); |
| + if (fillMode) { |
| + pixmap.alloc(info); |
| + if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) { |
| + return 0; |
| + } |
| + SkASSERT(!pixmap.ctable()); |
| + } |
| + } |
| + size_t size = 0; |
| + size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); |
| + size += dtiSize; |
| + size_t pixelOffset = size; |
| + size += pixelSize; |
| + size_t ctOffset = size; |
| + size += ctSize; |
| + if (!fillMode) { |
| + return size; |
| + } |
| + intptr_t bufferAsInt = reinterpret_cast<intptr_t>(buffer); |
| + void* pixels = reinterpret_cast<void*>(bufferAsInt + pixelOffset); |
| + SkPMColor* ct = nullptr; |
| + if (ctSize) { |
| + ct = reinterpret_cast<SkPMColor*>(bufferAsInt + ctOffset); |
| + } |
| + |
| + memcpy(pixels, pixmap.addr(), pixmap.getSafeSize()); |
| + if (ctSize) { |
| + memcpy(ct, pixmap.ctable()->readColors(), ctSize); |
| + } |
| + |
| + SkASSERT(info == pixmap.info()); |
| + size_t rowBytes = pixmap.rowBytes(); |
| + DeferredTextureImage* dti = new (buffer) DeferredTextureImage(); |
| + dti->fContextUniqueID = proxy.fContextUniqueID; |
| + dti->fImageUniqueID = this->uniqueID(); |
| + dti->fData.fInfo = info; |
| + dti->fData.fPixelData = pixels; |
| + dti->fData.fRowBytes = rowBytes; |
| + dti->fData.fColorTableCnt = ctCount; |
| + dti->fData.fColorTableData = ct; |
| + return size; |
| +} |
| + |
| +SkImage* SkImage::NewFromDeferredTextureImageData(GrContext* context, const void* data, |
| + SkBudgeted budgeted) { |
| + if (!data) { |
| + return nullptr; |
| + } |
| + const DeferredTextureImage* dti = reinterpret_cast<const DeferredTextureImage*>(data); |
| + |
| + if (!context || context->uniqueID() != dti->fContextUniqueID) { |
| + return nullptr; |
| + } |
| + SkAutoTUnref<SkColorTable> colorTable; |
| + if (dti->fData.fColorTableCnt) { |
| + SkASSERT(dti->fData.fColorTableData); |
| + colorTable.reset(new SkColorTable(dti->fData.fColorTableData, dti->fData.fColorTableCnt)); |
| + } |
| + SkPixmap pixmap; |
| + pixmap.reset(dti->fData.fInfo, dti->fData.fPixelData, dti->fData.fRowBytes, colorTable.get()); |
| + return SkImage::NewTextureFromPixmap(context, pixmap, budgeted); |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| GrTexture* GrDeepCopyTexture(GrTexture* src, SkBudgeted budgeted) { |
| GrContext* ctx = src->getContext(); |