diff options
-rw-r--r-- | bench/GrResourceCacheBench.cpp | 1 | ||||
-rw-r--r-- | include/core/SkTraceMemoryDump.h | 4 | ||||
-rw-r--r-- | include/gpu/GrGpuResource.h | 26 | ||||
-rw-r--r-- | include/gpu/GrResourceKey.h | 12 | ||||
-rw-r--r-- | include/gpu/GrSurface.h | 2 | ||||
-rw-r--r-- | src/gpu/GrBuffer.h | 1 | ||||
-rw-r--r-- | src/gpu/GrGpuResource.cpp | 31 | ||||
-rw-r--r-- | src/gpu/GrPath.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrPath.h | 1 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrStencilAttachment.h | 1 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrCircleBlurFragmentProcessor.cpp | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrRRectBlurEffect.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrRectBlurEffect.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLRenderTarget.cpp | 13 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTexture.cpp | 15 | ||||
-rw-r--r-- | src/gpu/gl/GrGLTextureRenderTarget.cpp | 7 | ||||
-rw-r--r-- | src/gpu/ops/GrTessellatingPathRenderer.cpp | 2 | ||||
-rw-r--r-- | tests/ResourceCacheTest.cpp | 8 |
20 files changed, 94 insertions, 46 deletions
diff --git a/bench/GrResourceCacheBench.cpp b/bench/GrResourceCacheBench.cpp index a530e628e8..cc185cf04f 100644 --- a/bench/GrResourceCacheBench.cpp +++ b/bench/GrResourceCacheBench.cpp @@ -38,6 +38,7 @@ public: private: size_t onGpuMemorySize() const override { return 100; } + const char* getResourceType() const override { return "bench"; } typedef GrGpuResource INHERITED; }; diff --git a/include/core/SkTraceMemoryDump.h b/include/core/SkTraceMemoryDump.h index 03656b2c37..e9cb5b20e4 100644 --- a/include/core/SkTraceMemoryDump.h +++ b/include/core/SkTraceMemoryDump.h @@ -50,6 +50,10 @@ public: const char* units, uint64_t value) = 0; + virtual void dumpStringValue(const char* /*dumpName*/, + const char* /*valueName*/, + const char* /*value*/) { } + /** * Sets the memory backing for an existing dump. * backingType and backingObjectId are used by the embedder to associate the memory dumped via diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h index 70c94c0e55..2da8085908 100644 --- a/include/gpu/GrGpuResource.h +++ b/include/gpu/GrGpuResource.h @@ -249,6 +249,15 @@ public: **/ virtual void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const; + /** + * Describes the type of gpu resource that is represented by the implementing + * class (e.g. texture, buffer object, stencil). This data is used for diagnostic + * purposes by dumpMemoryStatistics(). + * + * The value returned is expected to be long lived and will not be copied by the caller. + */ + virtual const char* getResourceType() const = 0; + static uint32_t CreateUniqueID(); protected: @@ -280,11 +289,24 @@ protected: void didChangeGpuMemorySize() const; /** - * Allows subclasses to add additional backing information to the SkTraceMemoryDump. Called by - * onMemoryDump. The default implementation adds no backing information. + * Allows subclasses to add additional backing information to the SkTraceMemoryDump. **/ virtual void setMemoryBacking(SkTraceMemoryDump*, const SkString&) const {} + /** + * Returns a string that uniquely identifies this resource. + */ + SkString getResourceName() const; + + /** + * A helper for subclasses that override dumpMemoryStatistics(). This method using a format + * consistent with the default implementation of dumpMemoryStatistics() but allows the caller + * to customize various inputs. + */ + void dumpMemoryStatisticsPriv(SkTraceMemoryDump* traceMemoryDump, const SkString& resourceName, + const char* type, size_t size) const; + + private: /** * Called by the registerWithCache if the resource is available to be used as scratch. diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h index c0a08f8add..ef319ad1fa 100644 --- a/include/gpu/GrResourceKey.h +++ b/include/gpu/GrResourceKey.h @@ -241,7 +241,7 @@ public: GrUniqueKey& operator=(const GrUniqueKey& that) { this->INHERITED::operator=(that); this->setCustomData(sk_ref_sp(that.getCustomData())); - SkDEBUGCODE(fTag = that.fTag;) + fTag = that.fTag; return *this; } @@ -257,14 +257,13 @@ public: return fData.get(); } - SkDEBUGCODE(const char* tag() const { return fTag.c_str(); }) + const char* tag() const { return fTag; } class Builder : public INHERITED::Builder { public: Builder(GrUniqueKey* key, Domain type, int data32Count, const char* tag = nullptr) : INHERITED::Builder(key, type, data32Count) { - SkDEBUGCODE(key->fTag = tag;) - (void) tag; // suppress unused named param warning. + key->fTag = tag; } /** Used to build a key that wraps another key and adds additional data. */ @@ -277,8 +276,7 @@ public: const uint32_t* srcData = innerKey.data(); (*innerKeyData++) = innerKey.domain(); memcpy(innerKeyData, srcData, innerKey.dataSize()); - SkDEBUGCODE(key->fTag = tag;) - (void) tag; // suppress unused named param warning. + key->fTag = tag; } private: @@ -290,7 +288,7 @@ public: private: sk_sp<SkData> fData; - SkDEBUGCODE(SkString fTag;) + const char* fTag; }; /** diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h index 5fc365b562..46d3945de4 100644 --- a/include/gpu/GrSurface.h +++ b/include/gpu/GrSurface.h @@ -114,6 +114,8 @@ protected: void onAbandon() override; private: + const char* getResourceType() const override { return "Surface"; } + GrPixelConfig fConfig; int fWidth; int fHeight; diff --git a/src/gpu/GrBuffer.h b/src/gpu/GrBuffer.h index b2201a140f..33a7f354fa 100644 --- a/src/gpu/GrBuffer.h +++ b/src/gpu/GrBuffer.h @@ -123,6 +123,7 @@ private: virtual bool onUpdateData(const void* src, size_t srcSizeInBytes); size_t onGpuMemorySize() const override { return fSizeInBytes; } // TODO: zero for cpu backed? + const char* getResourceType() const override { return "Buffer Object"; } void computeScratchKey(GrScratchKey* key) const override; size_t fSizeInBytes; diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp index d90498d6f4..ec7113562b 100644 --- a/src/gpu/GrGpuResource.cpp +++ b/src/gpu/GrGpuResource.cpp @@ -73,20 +73,33 @@ void GrGpuResource::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) con return; } - // Dump resource as "skia/gpu_resources/resource_#". - SkString dumpName("skia/gpu_resources/resource_"); - dumpName.appendU32(this->uniqueID().asUInt()); + this->dumpMemoryStatisticsPriv(traceMemoryDump, this->getResourceName(), + this->getResourceType(), this->gpuMemorySize()); +} - traceMemoryDump->dumpNumericValue(dumpName.c_str(), "size", "bytes", this->gpuMemorySize()); +void GrGpuResource::dumpMemoryStatisticsPriv(SkTraceMemoryDump* traceMemoryDump, + const SkString& resourceName, + const char* type, size_t size) const { + const char* tag = "Scratch"; + if (fUniqueKey.isValid()) { + tag = (fUniqueKey.tag() != nullptr) ? fUniqueKey.tag() : "Other"; + } + traceMemoryDump->dumpNumericValue(resourceName.c_str(), "size", "bytes", size); + traceMemoryDump->dumpStringValue(resourceName.c_str(), "type", type); + traceMemoryDump->dumpStringValue(resourceName.c_str(), "category", tag); if (this->isPurgeable()) { - traceMemoryDump->dumpNumericValue(dumpName.c_str(), "purgeable_size", "bytes", - this->gpuMemorySize()); + traceMemoryDump->dumpNumericValue(resourceName.c_str(), "purgeable_size", "bytes", size); } - // Call setMemoryBacking to allow sub-classes with implementation specific backings (such as GL - // objects) to provide additional information. - this->setMemoryBacking(traceMemoryDump, dumpName); + this->setMemoryBacking(traceMemoryDump, resourceName); +} + +SkString GrGpuResource::getResourceName() const { + // Dump resource as "skia/gpu_resources/resource_#". + SkString resourceName("skia/gpu_resources/resource_"); + resourceName.appendU32(this->uniqueID().asUInt()); + return resourceName; } const GrContext* GrGpuResource::getContext() const { diff --git a/src/gpu/GrPath.cpp b/src/gpu/GrPath.cpp index 836cc5ed55..c0c56430a6 100644 --- a/src/gpu/GrPath.cpp +++ b/src/gpu/GrPath.cpp @@ -25,7 +25,7 @@ void GrPath::ComputeKey(const GrShape& shape, GrUniqueKey* key, bool* outIsVolat return; } static const GrUniqueKey::Domain kGeneralPathDomain = GrUniqueKey::GenerateDomain(); - GrUniqueKey::Builder builder(key, kGeneralPathDomain, geoCnt + styleCnt); + GrUniqueKey::Builder builder(key, kGeneralPathDomain, geoCnt + styleCnt, "Path"); shape.writeUnstyledKey(&builder[0]); if (styleCnt) { write_style_key(&builder[geoCnt], shape.style()); diff --git a/src/gpu/GrPath.h b/src/gpu/GrPath.h index 19538370d5..cf4a11d4fd 100644 --- a/src/gpu/GrPath.h +++ b/src/gpu/GrPath.h @@ -51,6 +51,7 @@ protected: #endif private: + const char* getResourceType() const override { return "Path Data"; } typedef GrGpuResource INHERITED; }; diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 228625f4fb..15ea55d4f2 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -290,14 +290,16 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { // Fractional translate does not affect caching on Android. This is done for better cache // hit ratio and speed, but it is matching HWUI behavior, which doesn't consider the matrix // at all when caching paths. - GrUniqueKey::Builder builder(&maskKey, kDomain, 4 + args.fShape->unstyledKeySize()); + GrUniqueKey::Builder builder(&maskKey, kDomain, 4 + args.fShape->unstyledKeySize(), + "SW Path Mask"); #else SkScalar tx = args.fViewMatrix->get(SkMatrix::kMTransX); SkScalar ty = args.fViewMatrix->get(SkMatrix::kMTransY); // Allow 8 bits each in x and y of subpixel positioning. SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00; SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00; - GrUniqueKey::Builder builder(&maskKey, kDomain, 5 + args.fShape->unstyledKeySize()); + GrUniqueKey::Builder builder(&maskKey, kDomain, 5 + args.fShape->unstyledKeySize(), + "SW Path Mask"); #endif builder[0] = SkFloat2Bits(sx); builder[1] = SkFloat2Bits(sy); diff --git a/src/gpu/GrStencilAttachment.h b/src/gpu/GrStencilAttachment.h index df5677d163..e8c56cca4d 100644 --- a/src/gpu/GrStencilAttachment.h +++ b/src/gpu/GrStencilAttachment.h @@ -45,6 +45,7 @@ protected: } private: + const char* getResourceType() const override { return "Stencil"; } int fWidth; int fHeight; diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index ec06561efc..b4cb22bd10 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -57,7 +57,7 @@ void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& ima SkASSERT(imageID); SkASSERT(!imageBounds.isEmpty()); static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomain(); - GrUniqueKey::Builder builder(key, kImageIDDomain, 5); + GrUniqueKey::Builder builder(key, kImageIDDomain, 5, "Image"); builder[0] = imageID; builder[1] = imageBounds.fLeft; builder[2] = imageBounds.fTop; diff --git a/src/gpu/effects/GrCircleBlurFragmentProcessor.cpp b/src/gpu/effects/GrCircleBlurFragmentProcessor.cpp index d44f431dd3..618da34fcc 100644 --- a/src/gpu/effects/GrCircleBlurFragmentProcessor.cpp +++ b/src/gpu/effects/GrCircleBlurFragmentProcessor.cpp @@ -200,7 +200,7 @@ static sk_sp<GrTextureProxy> create_profile_texture(GrProxyProvider* proxyProvid static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; - GrUniqueKey::Builder builder(&key, kDomain, 1); + GrUniqueKey::Builder builder(&key, kDomain, 1, "1-D Circular Blur"); builder[0] = sigmaToCircleRRatioFixed; builder.finish(); diff --git a/src/gpu/effects/GrRRectBlurEffect.h b/src/gpu/effects/GrRRectBlurEffect.h index 1d382a0dfa..b59d1be7d6 100644 --- a/src/gpu/effects/GrRRectBlurEffect.h +++ b/src/gpu/effects/GrRRectBlurEffect.h @@ -34,7 +34,7 @@ public: float xformedSigma) { static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; - GrUniqueKey::Builder builder(&key, kDomain, 9); + GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask"); builder[0] = SkScalarCeilToInt(xformedSigma - 1 / 6.0f); int index = 1; diff --git a/src/gpu/effects/GrRectBlurEffect.h b/src/gpu/effects/GrRectBlurEffect.h index 123c91fba8..e6d777980f 100644 --- a/src/gpu/effects/GrRectBlurEffect.h +++ b/src/gpu/effects/GrRectBlurEffect.h @@ -25,7 +25,7 @@ public: static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; - GrUniqueKey::Builder builder(&key, kDomain, 1); + GrUniqueKey::Builder builder(&key, kDomain, 1, "Rect Blur Mask"); builder[0] = profileSize; builder.finish(); diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 9500e7d6fe..5513e8aaa7 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -216,19 +216,14 @@ void GrGLRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) // Due to this resource having both a texture and a renderbuffer component, dump as // skia/gpu_resources/resource_#/renderbuffer - SkString dumpName("skia/gpu_resources/resource_"); - dumpName.appendU32(this->uniqueID().asUInt()); - dumpName.append("/renderbuffer"); + SkString resourceName = this->getResourceName(); + resourceName.append("/renderbuffer"); - traceMemoryDump->dumpNumericValue(dumpName.c_str(), "size", "bytes", size); - - if (this->isPurgeable()) { - traceMemoryDump->dumpNumericValue(dumpName.c_str(), "purgeable_size", "bytes", size); - } + this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, "RenderTarget", size); SkString renderbuffer_id; renderbuffer_id.appendU32(fMSColorRenderbufferID); - traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_renderbuffer", + traceMemoryDump->setMemoryBacking(resourceName.c_str(), "gl_renderbuffer", renderbuffer_id.c_str()); } } diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp index 61bce35061..69b214de27 100644 --- a/src/gpu/gl/GrGLTexture.cpp +++ b/src/gpu/gl/GrGLTexture.cpp @@ -138,21 +138,16 @@ void GrGLTexture::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const // Dump as skia/gpu_resources/resource_#/texture, to avoid conflicts in the // GrGLTextureRenderTarget case, where multiple things may dump to the same resource. This // has no downside in the normal case. - SkString dumpName("skia/gpu_resources/resource_"); - dumpName.appendU32(this->uniqueID().asUInt()); - dumpName.append("/texture"); + SkString resourceName = this->getResourceName(); + resourceName.append("/texture"); // As we are only dumping our texture memory (not any additional memory tracked by classes // which may inherit from us), specifically call GrGLTexture::gpuMemorySize to avoid // hitting an override. - size_t size = GrGLTexture::gpuMemorySize(); - traceMemoryDump->dumpNumericValue(dumpName.c_str(), "size", "bytes", size); - - if (this->isPurgeable()) { - traceMemoryDump->dumpNumericValue(dumpName.c_str(), "purgeable_size", "bytes", size); - } + this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, "Texture", + GrGLTexture::gpuMemorySize()); SkString texture_id; texture_id.appendU32(this->textureID()); - traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_texture", texture_id.c_str()); + traceMemoryDump->setMemoryBacking(resourceName.c_str(), "gl_texture", texture_id.c_str()); } diff --git a/src/gpu/gl/GrGLTextureRenderTarget.cpp b/src/gpu/gl/GrGLTextureRenderTarget.cpp index e9f224b71b..049cb31a9b 100644 --- a/src/gpu/gl/GrGLTextureRenderTarget.cpp +++ b/src/gpu/gl/GrGLTextureRenderTarget.cpp @@ -37,9 +37,16 @@ GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu, void GrGLTextureRenderTarget::dumpMemoryStatistics( SkTraceMemoryDump* traceMemoryDump) const { +#ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK // Delegate to the base classes GrGLRenderTarget::dumpMemoryStatistics(traceMemoryDump); GrGLTexture::dumpMemoryStatistics(traceMemoryDump); +#else + SkString resourceName = this->getResourceName(); + resourceName.append("/texture_renderbuffer"); + this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, "RenderTarget", + this->gpuMemorySize()); +#endif } bool GrGLTextureRenderTarget::canAttemptStencilAttachment() const { diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp index 8eaadf0ac3..651d34fae7 100644 --- a/src/gpu/ops/GrTessellatingPathRenderer.cpp +++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp @@ -245,7 +245,7 @@ private: static constexpr int kClipBoundsCnt = sizeof(fDevClipBounds) / sizeof(uint32_t); int shapeKeyDataCnt = fShape.unstyledKeySize(); SkASSERT(shapeKeyDataCnt >= 0); - GrUniqueKey::Builder builder(&key, kDomain, shapeKeyDataCnt + kClipBoundsCnt); + GrUniqueKey::Builder builder(&key, kDomain, shapeKeyDataCnt + kClipBoundsCnt, "Path"); fShape.writeUnstyledKey(&builder[0]); // For inverse fills, the tessellation is dependent on clip bounds. if (inverseFill) { diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp index c56bd01564..11dcdd43b6 100644 --- a/tests/ResourceCacheTest.cpp +++ b/tests/ResourceCacheTest.cpp @@ -340,6 +340,7 @@ private: } size_t onGpuMemorySize() const override { return fSize; } + const char* getResourceType() const override { return "Test"; } TestResource* fToDelete; size_t fSize; @@ -1661,19 +1662,24 @@ static void test_tags(skiatest::Reporter* reporter) { GrResourceCache* cache = mock.cache(); GrGpu* gpu = context->contextPriv().getGpu(); + // tag strings are expected to be long lived + std::vector<SkString> tagStrings; + SkString tagStr; int tagIdx = 0; int currTagCnt = 0; for (int i = 0; i < kNumResources; ++i, ++currTagCnt) { + sk_sp<GrGpuResource> resource(new TestResource(gpu)); GrUniqueKey key; if (currTagCnt == tagIdx) { tagIdx += 1; currTagCnt = 0; tagStr.printf("tag%d", tagIdx); + tagStrings.emplace_back(tagStr); } - make_unique_key<1>(&key, i, tagStr.c_str()); + make_unique_key<1>(&key, i, tagStrings.back().c_str()); resource->resourcePriv().setUniqueKey(key); } SkASSERT(kLastTagIdx == tagIdx); |