aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-02-15 13:18:21 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-15 19:15:20 +0000
commite14d3053f329c97e1bd0519e9b358a887988dcb8 (patch)
tree4914ce59d6b9bc514c81df80932ea5cde6fc45eb
parent5cd467f3a0ab6863ecdf10a63978f661bc1bbb17 (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.h3
-rw-r--r--src/core/SkSpecialImage.cpp22
-rw-r--r--src/gpu/SkGpuDevice.cpp65
-rw-r--r--src/gpu/SkGr.cpp36
-rw-r--r--src/gpu/SkGrPriv.h18
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);