diff options
author | Brian Salomon <bsalomon@google.com> | 2018-02-09 08:50:22 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-09 14:19:51 +0000 |
commit | 67f8584b6f899876ca4187dba4f449ce5489f9c8 (patch) | |
tree | ef23d8ccb9430be5ed954ff4cc0eb345baeafc98 /src | |
parent | c4616804bb407506c6ac1046c7e25e2016911449 (diff) |
Revert "Revert "Remove SkImage deferred texture image data APIs.""
This reverts commit aae533e418f37d788cdb1a1177e882d0f8868b62.
Change-Id: I0434892d8946490a75e17620c49c594eaa18158e
Reviewed-on: https://skia-review.googlesource.com/100603
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/image/SkImage.cpp | 20 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 379 |
2 files changed, 0 insertions, 399 deletions
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 4d54a1c838..ad70af7451 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -355,26 +355,6 @@ sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx, return nullptr; } -size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy&, - const DeferredTextureImageUsageParams[], - int paramCnt, void* buffer, - SkColorSpace* dstColorSpace, - SkColorType dstColorType) const { - return 0; -} - -sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, const void*, - SkBudgeted) { - return nullptr; -} - -sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx, - const GrBackendTexture& tex, GrSurfaceOrigin origin, - SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs, - TextureReleaseProc releaseP, ReleaseContext releaseC) { - return nullptr; -} - bool SkImage::MakeBackendTextureFromSkImage(GrContext*, sk_sp<SkImage>, GrBackendTexture*, diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index b0311d5b55..d14f001caf 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -669,385 +669,6 @@ sk_sp<SkImage> SkImage::MakeFromAHardwareBuffer(AHardwareBuffer* graphicBuffer, /////////////////////////////////////////////////////////////////////////////////////////////////// -namespace { -struct MipMapLevelData { - void* fPixelData; - size_t fRowBytes; -}; - -struct DeferredTextureImage { - uint32_t fContextUniqueID; - // Right now, the destination color mode is only considered when generating mipmaps - SkDestinationSurfaceColorMode fColorMode; - // 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 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 - -static bool should_use_mip_maps(const SkImage::DeferredTextureImageUsageParams & param) { - // There is a bug in the mipmap pre-generation logic in use in getDeferredTextureImageData. - // This can cause runaway memory leaks, so we are disabling this path until we can - // investigate further. crbug.com/669775 - return false; -} - -namespace { - -class DTIBufferFiller -{ -public: - explicit DTIBufferFiller(char* bufferAsCharPtr) - : bufferAsCharPtr_(bufferAsCharPtr) {} - - void fillMember(const void* source, size_t memberOffset, size_t size) { - memcpy(bufferAsCharPtr_ + memberOffset, source, size); - } - -private: - - char* bufferAsCharPtr_; -}; -} - -#define FILL_MEMBER(bufferFiller, member, source) \ - bufferFiller.fillMember(source, \ - offsetof(DeferredTextureImage, member), \ - sizeof(DeferredTextureImage::member)); - -static bool SupportsColorSpace(SkColorType colorType) { - switch (colorType) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - case kRGBA_F16_SkColorType: - return true; - default: - return false; - } -} - -size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& proxy, - const DeferredTextureImageUsageParams params[], - int paramCnt, void* buffer, - SkColorSpace* dstColorSpace, - SkColorType dstColorType) const { - // Some quick-rejects where is makes no sense to return CPU data - // e.g. - // - texture backed - // - picture backed - // - if (this->isTextureBacked()) { - return 0; - } - if (as_IB(this)->onCanLazyGenerateOnGPU()) { - return 0; - } - - bool supportsColorSpace = SupportsColorSpace(dstColorType); - // Quick reject if the caller requests a color space with an unsupported color type. - if (SkToBool(dstColorSpace) && !supportsColorSpace) { - return 0; - } - - // Extract relevant min/max values from the params array. - int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel; - SkFilterQuality highestFilterQuality = params[0].fQuality; - bool useMipMaps = should_use_mip_maps(params[0]); - for (int i = 1; i < paramCnt; ++i) { - if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel) - lowestPreScaleMipLevel = params[i].fPreScaleMipLevel; - if (highestFilterQuality < params[i].fQuality) - highestFilterQuality = params[i].fQuality; - useMipMaps |= should_use_mip_maps(params[i]); - } - - const bool fillMode = SkToBool(buffer); - if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { - return 0; - } - - // Calculate scaling parameters. - bool isScaled = lowestPreScaleMipLevel != 0; - - SkISize scaledSize; - if (isScaled) { - // SkMipMap::ComputeLevelSize takes an index into an SkMipMap. SkMipMaps don't contain the - // base level, so to get an SkMipMap index we must subtract one from the GL MipMap level. - scaledSize = SkMipMap::ComputeLevelSize(this->width(), this->height(), - lowestPreScaleMipLevel - 1); - } else { - scaledSize = SkISize::Make(this->width(), this->height()); - } - - // We never want to scale at higher than SW medium quality, as SW medium matches GPU high. - SkFilterQuality scaleFilterQuality = highestFilterQuality; - if (scaleFilterQuality > kMedium_SkFilterQuality) { - scaleFilterQuality = kMedium_SkFilterQuality; - } - - const int maxTextureSize = proxy.fCaps->maxTextureSize(); - if (scaledSize.width() > maxTextureSize || scaledSize.height() > maxTextureSize) { - return 0; - } - - SkAutoPixmapStorage pixmap; - SkImageInfo info; - size_t pixelSize = 0; - if (!isScaled && this->peekPixels(&pixmap) && pixmap.info().colorType() == dstColorType) { - info = pixmap.info(); - pixelSize = SkAlign8(pixmap.computeByteSize()); - if (!dstColorSpace) { - pixmap.setColorSpace(nullptr); - info = info.makeColorSpace(nullptr); - } - } else { - if (!this->isLazyGenerated() && !this->peekPixels(nullptr)) { - return 0; - } - if (SkImageCacherator* cacher = as_IB(this)->peekCacherator()) { - // Generator backed image. Tweak info to trigger correct kind of decode. - SkImageCacherator::CachedFormat cacheFormat = cacher->chooseCacheFormat( - dstColorSpace, proxy.fCaps.get()); - info = cacher->buildCacheInfo(cacheFormat).makeWH(scaledSize.width(), - scaledSize.height()); - } else { - info = as_IB(this)->onImageInfo().makeWH(scaledSize.width(), scaledSize.height()); - if (!dstColorSpace) { - info = info.makeColorSpace(nullptr); - } - } - // Force color type to be the requested type. - info = info.makeColorType(dstColorType); - pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); - if (fillMode) { - // Always decode to N32 and convert to the requested type if necessary. - SkImageInfo decodeInfo = info.makeColorType(kN32_SkColorType); - SkAutoPixmapStorage decodePixmap; - decodePixmap.alloc(decodeInfo); - - if (isScaled) { - if (!this->scalePixels(decodePixmap, scaleFilterQuality, - SkImage::kDisallow_CachingHint)) { - return 0; - } - } else { - if (!this->readPixels(decodePixmap, 0, 0, SkImage::kDisallow_CachingHint)) { - return 0; - } - } - - if (decodeInfo.colorType() != info.colorType()) { - pixmap.alloc(info); - // Convert and copy the decoded pixmap to the target pixmap. - decodePixmap.readPixels(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes(), 0, - 0); - } else { - pixmap = std::move(decodePixmap); - } - } - } - int mipMapLevelCount = 1; - if (useMipMaps) { - // SkMipMap only deals with the mipmap levels it generates, which does - // not include the base level. - // That means it generates and holds levels 1-x instead of 0-x. - // So the total mipmap level count is 1 more than what - // SkMipMap::ComputeLevelCount returns. - mipMapLevelCount = SkMipMap::ComputeLevelCount(scaledSize.width(), scaledSize.height()) + 1; - - // We already initialized pixelSize to the size of the base level. - // SkMipMap will generate the extra mipmap levels. Their sizes need to - // be added to the total. - // Index 0 here does not refer to the base mipmap level -- it is - // SkMipMap's first generated mipmap level (level 1). - for (int currentMipMapLevelIndex = mipMapLevelCount - 2; currentMipMapLevelIndex >= 0; - currentMipMapLevelIndex--) { - SkISize mipSize = SkMipMap::ComputeLevelSize(scaledSize.width(), scaledSize.height(), - currentMipMapLevelIndex); - SkImageInfo mipInfo = info.makeWH(mipSize.fWidth, mipSize.fHeight); - pixelSize += SkAlign8(SkAutoPixmapStorage::AllocSize(mipInfo, nullptr)); - } - } - size_t size = 0; - size_t dtiSize = SkAlign8(sizeof(DeferredTextureImage)); - size += dtiSize; - size += (mipMapLevelCount - 1) * sizeof(MipMapLevelData); - // We subtract 1 because DeferredTextureImage already includes the base - // level in its size - size_t pixelOffset = size; - size += pixelSize; - size_t colorSpaceOffset = 0; - size_t colorSpaceSize = 0; - SkColorSpaceTransferFn fn; - if (info.colorSpace()) { - SkASSERT(dstColorSpace); - SkASSERT(supportsColorSpace); - colorSpaceOffset = size; - colorSpaceSize = info.colorSpace()->writeToMemory(nullptr); - size += colorSpaceSize; - } else if (supportsColorSpace && this->colorSpace() && this->colorSpace()->isNumericalTransferFn(&fn)) { - // In legacy mode, preserve the color space tag on the SkImage. This is only - // supported if the color space has a parametric transfer function. - SkASSERT(!dstColorSpace); - colorSpaceOffset = size; - colorSpaceSize = this->colorSpace()->writeToMemory(nullptr); - size += colorSpaceSize; - } - if (!fillMode) { - return size; - } - char* bufferAsCharPtr = reinterpret_cast<char*>(buffer); - char* pixelsAsCharPtr = bufferAsCharPtr + pixelOffset; - void* pixels = pixelsAsCharPtr; - - memcpy(reinterpret_cast<void*>(SkAlign8(reinterpret_cast<uintptr_t>(pixelsAsCharPtr))), - pixmap.addr(), pixmap.computeByteSize()); - - // If the context has sRGB support, and we're intending to render to a surface with an attached - // color space, and the image has an sRGB-like color space attached, then use our gamma (sRGB) - // aware mip-mapping. - SkDestinationSurfaceColorMode colorMode = SkDestinationSurfaceColorMode::kLegacy; - if (proxy.fCaps->srgbSupport() && SkToBool(dstColorSpace) && - info.colorSpace() && info.colorSpace()->gammaCloseToSRGB()) { - SkASSERT(supportsColorSpace); - colorMode = SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware; - } - - SkASSERT(info == pixmap.info()); - size_t rowBytes = pixmap.rowBytes(); - static_assert(std::is_standard_layout<DeferredTextureImage>::value, - "offsetof, which we use below, requires the type have standard layout"); - auto dtiBufferFiller = DTIBufferFiller{bufferAsCharPtr}; - FILL_MEMBER(dtiBufferFiller, fColorMode, &colorMode); - FILL_MEMBER(dtiBufferFiller, fContextUniqueID, &proxy.fContextUniqueID); - int width = info.width(); - FILL_MEMBER(dtiBufferFiller, fWidth, &width); - int height = info.height(); - FILL_MEMBER(dtiBufferFiller, fHeight, &height); - SkColorType colorType = info.colorType(); - FILL_MEMBER(dtiBufferFiller, fColorType, &colorType); - SkAlphaType alphaType = info.alphaType(); - FILL_MEMBER(dtiBufferFiller, fAlphaType, &alphaType); - FILL_MEMBER(dtiBufferFiller, fMipMapLevelCount, &mipMapLevelCount); - memcpy(bufferAsCharPtr + offsetof(DeferredTextureImage, fMipMapLevelData[0].fPixelData), - &pixels, sizeof(pixels)); - memcpy(bufferAsCharPtr + offsetof(DeferredTextureImage, fMipMapLevelData[0].fRowBytes), - &rowBytes, sizeof(rowBytes)); - if (colorSpaceSize) { - void* colorSpace = bufferAsCharPtr + colorSpaceOffset; - FILL_MEMBER(dtiBufferFiller, fColorSpace, &colorSpace); - FILL_MEMBER(dtiBufferFiller, fColorSpaceSize, &colorSpaceSize); - if (info.colorSpace()) { - info.colorSpace()->writeToMemory(bufferAsCharPtr + colorSpaceOffset); - } else { - SkASSERT(this->colorSpace() && this->colorSpace()->isNumericalTransferFn(&fn)); - SkASSERT(!dstColorSpace); - this->colorSpace()->writeToMemory(bufferAsCharPtr + colorSpaceOffset); - } - } else { - memset(bufferAsCharPtr + offsetof(DeferredTextureImage, fColorSpace), - 0, sizeof(DeferredTextureImage::fColorSpace)); - memset(bufferAsCharPtr + offsetof(DeferredTextureImage, fColorSpaceSize), - 0, sizeof(DeferredTextureImage::fColorSpaceSize)); - } - - // Fill in the mipmap levels if they exist - char* mipLevelPtr = pixelsAsCharPtr + SkAlign8(pixmap.computeByteSize()); - - if (useMipMaps) { - static_assert(std::is_standard_layout<MipMapLevelData>::value, - "offsetof, which we use below, requires the type have a standard layout"); - - std::unique_ptr<SkMipMap> mipmaps(SkMipMap::Build(pixmap, colorMode, nullptr)); - // SkMipMap holds only the mipmap levels it generates. - // A programmer can use the data they provided to SkMipMap::Build as level 0. - // So the SkMipMap provides levels 1-x but it stores them in its own - // range 0-(x-1). - for (int generatedMipLevelIndex = 0; generatedMipLevelIndex < mipMapLevelCount - 1; - generatedMipLevelIndex++) { - SkMipMap::Level mipLevel; - mipmaps->getLevel(generatedMipLevelIndex, &mipLevel); - - // Make sure the mipmap data is after the start of the buffer - SkASSERT(mipLevelPtr > bufferAsCharPtr); - // Make sure the mipmap data starts before the end of the buffer - SkASSERT(mipLevelPtr < bufferAsCharPtr + pixelOffset + pixelSize); - // Make sure the mipmap data ends before the end of the buffer - SkASSERT(mipLevelPtr + mipLevel.fPixmap.computeByteSize() <= - bufferAsCharPtr + pixelOffset + pixelSize); - - memcpy(mipLevelPtr, mipLevel.fPixmap.addr(), mipLevel.fPixmap.computeByteSize()); - - memcpy(bufferAsCharPtr + offsetof(DeferredTextureImage, fMipMapLevelData) + - sizeof(MipMapLevelData) * (generatedMipLevelIndex + 1) + - offsetof(MipMapLevelData, fPixelData), &mipLevelPtr, sizeof(void*)); - size_t rowBytes = mipLevel.fPixmap.rowBytes(); - memcpy(bufferAsCharPtr + offsetof(DeferredTextureImage, fMipMapLevelData) + - sizeof(MipMapLevelData) * (generatedMipLevelIndex + 1) + - offsetof(MipMapLevelData, fRowBytes), &rowBytes, sizeof(rowBytes)); - - mipLevelPtr += SkAlign8(mipLevel.fPixmap.computeByteSize()); - } - } - return size; -} - -sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(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 || context->abandoned()) { - return nullptr; - } - int mipLevelCount = dti->fMipMapLevelCount; - SkASSERT(mipLevelCount >= 1); - sk_sp<SkColorSpace> colorSpace; - if (dti->fColorSpaceSize) { - colorSpace = SkColorSpace::Deserialize(dti->fColorSpace, dti->fColorSpaceSize); - } - SkImageInfo info = SkImageInfo::Make(dti->fWidth, dti->fHeight, - dti->fColorType, dti->fAlphaType, colorSpace); - if (mipLevelCount == 1) { - SkPixmap pixmap; - pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, dti->fMipMapLevelData[0].fRowBytes); - - // Pass nullptr for the |dstColorSpace|. This opts in to more lenient color space - // verification. This is ok because we've already verified the color space in - // getDeferredTextureImageData(). - sk_sp<GrTextureProxy> proxy(GrUploadPixmapToTextureProxy( - context->contextPriv().proxyProvider(), pixmap, budgeted, nullptr)); - if (!proxy) { - return nullptr; - } - return sk_make_sp<SkImage_Gpu>(context, kNeedNewImageUniqueID, pixmap.alphaType(), - std::move(proxy), std::move(colorSpace), budgeted); - } else { - std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]); - for (int i = 0; i < mipLevelCount; i++) { - texels[i].fPixels = dti->fMipMapLevelData[i].fPixelData; - texels[i].fRowBytes = dti->fMipMapLevelData[i].fRowBytes; - } - - return SkImage::MakeTextureFromMipMap(context, info, texels.get(), - mipLevelCount, SkBudgeted::kYes, - dti->fColorMode); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - bool SkImage::MakeBackendTextureFromSkImage(GrContext* ctx, sk_sp<SkImage> image, GrBackendTexture* backendTexture, |