diff options
author | Robert Phillips <robertphillips@google.com> | 2017-02-15 13:18:21 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-15 19:15:20 +0000 |
commit | e14d3053f329c97e1bd0519e9b358a887988dcb8 (patch) | |
tree | 4914ce59d6b9bc514c81df80932ea5cde6fc45eb | |
parent | 5cd467f3a0ab6863ecdf10a63978f661bc1bbb17 (diff) |
Add GrMakeCachedBitmapProxy
This is split out of https://skia-review.googlesource.com/c/7889/ (Remove SkSpecialImage's GrTexture-based ctors) to allow focusing on the caching/subsetting changes.
Change-Id: Ic2af7a0d03e88941ab5b6cdfcecbbdefe3578eda
Reviewed-on: https://skia-review.googlesource.com/8456
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | include/gpu/SkGr.h | 3 | ||||
-rw-r--r-- | src/core/SkSpecialImage.cpp | 22 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 65 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 36 | ||||
-rw-r--r-- | src/gpu/SkGrPriv.h | 18 |
5 files changed, 92 insertions, 52 deletions
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h index 3f72fa134d..f7ca0c8e4d 100644 --- a/include/gpu/SkGr.h +++ b/include/gpu/SkGr.h @@ -86,9 +86,6 @@ static inline GrColor SkPMColorToGrColor(SkPMColor c) { GrTexture* GrRefCachedBitmapTexture(GrContext*, const SkBitmap&, const GrSamplerParams&, SkScalar scaleAdjust[2]); -sk_sp<GrTexture> GrMakeCachedBitmapTexture(GrContext*, const SkBitmap&, - const GrSamplerParams&, SkScalar scaleAdjust[2]); - // TODO: Move SkImageInfo2GrPixelConfig to SkGrPriv.h (requires cleanup to SkWindow its subclasses). GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps); diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp index 0ec5459127..f44d011c05 100644 --- a/src/core/SkSpecialImage.cpp +++ b/src/core/SkSpecialImage.cpp @@ -103,16 +103,24 @@ sk_sp<SkSpecialImage> SkSpecialImage::makeTextureImage(GrContext* context) { return SkSpecialImage::MakeFromRaster(SkIRect::MakeEmpty(), bmp, &this->props()); } - sk_sp<GrTexture> resultTex( - GrRefCachedBitmapTexture(context, bmp, GrSamplerParams::ClampNoFilter(), nullptr)); - if (!resultTex) { + // TODO: this is a tight copy of 'bmp' but it doesn't have to be (given SkSpecialImage's + // semantics). Since this is cached though we would have to bake the fit into the cache key. + sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(context, bmp); + if (!proxy) { return nullptr; } - return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(resultTex->width(), resultTex->height()), - this->uniqueID(), - resultTex, sk_ref_sp(this->getColorSpace()), &this->props(), - this->alphaType()); + const SkIRect rect = SkIRect::MakeWH(proxy->width(), proxy->height()); + + // GrMakeCachedBitmapProxy has uploaded only the specified subset of 'bmp' so we need not + // bother with SkBitmap::getSubset + return SkSpecialImage::MakeDeferredFromGpu(context, + rect, + this->uniqueID(), + std::move(proxy), + sk_ref_sp(this->getColorSpace()), + &this->props(), + this->alphaType()); #else return nullptr; #endif diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index f30057d315..4314b450fd 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1021,14 +1021,13 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, if (bitmap.extractSubset(&tmpB, iTileR)) { // now offset it to make it "local" to our tmp bitmap tileR.offset(-offset.fX, -offset.fY); - GrSamplerParams paramsTemp = params; // de-optimized this determination bool needsTextureDomain = true; this->drawBitmapTile(tmpB, viewMatrix, rectToDraw, tileR, - paramsTemp, + params, *paint, constraint, bicubic, @@ -1054,9 +1053,11 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap, SkASSERT(bitmap.width() <= fContext->caps()->maxTileSize() && bitmap.height() <= fContext->caps()->maxTileSize()); - SkScalar scaleAdjust[2] = { 1.0f, 1.0f }; + SkASSERT(SkShader::kClamp_TileMode == params.getTileModeX() && + SkShader::kClamp_TileMode == params.getTileModeY()); + sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext.get(), bitmap, - params, scaleAdjust); + params, nullptr); if (nullptr == texture) { return; } @@ -1064,8 +1065,8 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap, GrColorSpaceXform::Make(bitmap.colorSpace(), fRenderTargetContext->getColorSpace()); // Compute a matrix that maps the rect we will draw to the src rect. - SkMatrix texMatrix = SkMatrix::MakeRectToRect(dstRect, srcRect, SkMatrix::kFill_ScaleToFit); - texMatrix.postScale(scaleAdjust[0], scaleAdjust[1]); + const SkMatrix texMatrix = SkMatrix::MakeRectToRect(dstRect, srcRect, + SkMatrix::kFill_ScaleToFit); // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring // the rest from the SkPaint. @@ -1125,32 +1126,11 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, return; } - sk_sp<GrTexture> texture; - { - SkAutoLockPixels alp(bitmap, true); - if (!bitmap.readyToDraw()) { - return; - } - - // draw sprite neither filters nor tiles. - texture.reset(GrRefCachedBitmapTexture(fContext.get(), bitmap, - GrSamplerParams::ClampNoFilter(), nullptr)); - if (!texture) { - return; - } + sk_sp<SkSpecialImage> srcImg = this->makeSpecial(bitmap); + if (!srcImg) { + return; } - SkIRect srcRect = SkIRect::MakeXYWH(bitmap.pixelRefOrigin().fX, - bitmap.pixelRefOrigin().fY, - bitmap.width(), - bitmap.height()); - - sk_sp<SkSpecialImage> srcImg(SkSpecialImage::MakeFromGpu(srcRect, - bitmap.getGenerationID(), - std::move(texture), - bitmap.refColorSpace(), - &this->surfaceProps())); - this->drawSpecial(draw, srcImg.get(), left, top, paint); } @@ -1294,22 +1274,23 @@ void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, } sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) { - SkAutoLockPixels alp(bitmap, true); - if (!bitmap.readyToDraw()) { + // TODO: this makes a tight copy of 'bitmap' but it doesn't have to be (given SkSpecialImage's + // semantics). Since this is cached we would have to bake the fit into the cache key though. + sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(fContext.get(), bitmap); + if (!proxy) { return nullptr; } - sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext.get(), bitmap, - GrSamplerParams::ClampNoFilter(), nullptr); - if (!texture) { - return nullptr; - } + const SkIRect rect = SkIRect::MakeWH(proxy->width(), proxy->height()); - return SkSpecialImage::MakeFromGpu(bitmap.bounds(), - bitmap.getGenerationID(), - texture, - bitmap.refColorSpace(), - &this->surfaceProps()); + // GrMakeCachedBitmapProxy creates a tight copy of 'bitmap' so we don't have to subset + // the special image + return SkSpecialImage::MakeDeferredFromGpu(fContext.get(), + rect, + bitmap.getGenerationID(), + std::move(proxy), + bitmap.refColorSpace(), + &this->surfaceProps()); } sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) { diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index bf04927ab1..45f6e6eb92 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -269,6 +269,42 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, nullptr, scaleAdjust); } +// For better or for worse, this method currently sidesteps the issue of caching an uninstantiated +// proxy via a key. +sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrContext* context, const SkBitmap& bitmap) { + GrUniqueKey originalKey; + + if (!bitmap.isVolatile()) { + SkIPoint origin = bitmap.pixelRefOrigin(); + SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), bitmap.height()); + GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset); + } + + sk_sp<GrTexture> tex; + + if (originalKey.isValid()) { + tex.reset(context->textureProvider()->findAndRefTextureByUniqueKey(originalKey)); + } + if (!tex) { + tex.reset(GrUploadBitmapToTexture(context, bitmap)); + if (tex && originalKey.isValid()) { + tex->resourcePriv().setUniqueKey(originalKey); + GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef()); + } + } + + if (!tex) { + return nullptr; + } + + sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex)); + if (!proxy) { + return nullptr; + } + + return sk_ref_sp(proxy->asTextureProxy()); +} + sk_sp<GrTexture> GrMakeCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, const GrSamplerParams& params, SkScalar scaleAdjust[2]) { // Caller doesn't care about the texture's color space (they can always get it from the bitmap) diff --git a/src/gpu/SkGrPriv.h b/src/gpu/SkGrPriv.h index 5437d4a07c..7f52ee8596 100644 --- a/src/gpu/SkGrPriv.h +++ b/src/gpu/SkGrPriv.h @@ -9,6 +9,7 @@ #define SkGrPriv_DEFINED #include "GrBlend.h" +#include "GrSamplerParams.h" #include "GrTypes.h" #include "SkCanvas.h" #include "SkImageInfo.h" @@ -22,6 +23,7 @@ class GrRenderTargetContext; class GrFragmentProcessor; class GrPaint; class GrTexture; +class GrTextureProxy; class GrUniqueKey; class SkBitmap; class SkData; @@ -178,6 +180,22 @@ GrTexture* GrUploadPixmapToTexture(GrContext*, const SkPixmap&, SkBudgeted budge GrTexture* GrUploadMipMapToTexture(GrContext*, const SkImageInfo&, const GrMipLevel* texels, int mipLevelCount); +sk_sp<GrTexture> GrMakeCachedBitmapTexture(GrContext*, const SkBitmap&, + const GrSamplerParams&, SkScalar scaleAdjust[2]); + +// This is intended to replace: +// SkAutoLockPixels alp(bitmap, true); +// if (!bitmap.readyToDraw()) { +// return nullptr; +// } +// sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext.get(), bitmap, +// GrSamplerParams::ClampNoFilter(), +// nullptr); +// if (!texture) { +// return nullptr; +// } +sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrContext* context, const SkBitmap& bitmap); + ////////////////////////////////////////////////////////////////////////////// GR_STATIC_ASSERT((int)kZero_GrBlendCoeff == (int)SkXfermode::kZero_Coeff); |