diff options
author | Chris Dalton <csmartdalton@google.com> | 2018-02-22 13:41:37 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-22 21:06:05 +0000 |
commit | 2612baecd8c5b8deeaef18057a57562f45150023 (patch) | |
tree | 6dc6d1690d66d1136a51f9847e6f72d8dbc26c08 /src | |
parent | ee77da2c0bb44b92409d5eaf2b7ae7530f650a24 (diff) |
ccpr: Prefer atlas sizes under 4k on ARM
Bug: skia:
Change-Id: Ib5afb84647efe2e64a3ec2f9da422b39228431e9
Reviewed-on: https://skia-review.googlesource.com/108871
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrCaps.cpp | 2 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCAtlas.cpp | 41 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCAtlas.h | 9 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 6 | ||||
-rw-r--r-- | src/gpu/mock/GrMockCaps.h | 1 | ||||
-rw-r--r-- | src/gpu/mtl/GrMtlCaps.mm | 1 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 3 |
8 files changed, 42 insertions, 24 deletions
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp index 08e26bd1b5..8cfbc5faea 100644 --- a/src/gpu/GrCaps.cpp +++ b/src/gpu/GrCaps.cpp @@ -68,6 +68,7 @@ GrCaps::GrCaps(const GrContextOptions& options) { fMaxVertexAttributes = 0; fMaxRenderTargetSize = 1; + fMaxPreferredRenderTargetSize = 1; fMaxTextureSize = 1; fMaxRasterSamples = 0; fMaxWindowRectangles = 0; @@ -179,6 +180,7 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const { writer->appendS32("Max Vertex Attributes", fMaxVertexAttributes); writer->appendS32("Max Texture Size", fMaxTextureSize); writer->appendS32("Max Render Target Size", fMaxRenderTargetSize); + writer->appendS32("Max Preferred Render Target Size", fMaxPreferredRenderTargetSize); writer->appendS32("Max Raster Samples", fMaxRasterSamples); writer->appendS32("Max Window Rectangles", fMaxWindowRectangles); writer->appendS32("Max Clip Analytic Fragment Processors", fMaxClipAnalyticFPs); diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp index 97b28fb480..ce5cddb6d4 100644 --- a/src/gpu/ccpr/GrCCAtlas.cpp +++ b/src/gpu/ccpr/GrCCAtlas.cpp @@ -18,6 +18,9 @@ #include "ccpr/GrCCPathParser.h" #include "ops/GrDrawOp.h" +static constexpr int kAtlasMinSize = 1024; +static constexpr int kPadding = 1; + class GrCCAtlas::Node { public: Node(std::unique_ptr<Node> previous, int l, int t, int r, int b) @@ -25,10 +28,15 @@ public: Node* previous() const { return fPrevious.get(); } - bool addRect(int w, int h, SkIPoint16* loc) { - static constexpr int kPad = 1; - - if (!fRectanizer.addRect(w + kPad, h + kPad, loc)) { + bool addRect(int w, int h, SkIPoint16* loc, int maxAtlasSize) { + // Pad all paths except those that are expected to take up an entire physical texture. + if (w < maxAtlasSize) { + w = SkTMin(w + kPadding, maxAtlasSize); + } + if (h < maxAtlasSize) { + h = SkTMin(h + kPadding, maxAtlasSize); + } + if (!fRectanizer.addRect(w, h, loc)) { return false; } loc->fX += fX; @@ -76,18 +84,20 @@ private: typedef GrDrawOp INHERITED; }; -GrCCAtlas::GrCCAtlas(const GrCaps& caps, int minWidth, int minHeight) - : fMaxAtlasSize(caps.maxRenderTargetSize()), fDrawBounds{0, 0} { - SkASSERT(fMaxAtlasSize <= caps.maxTextureSize()); - SkASSERT(SkTMax(minWidth, minHeight) <= fMaxAtlasSize); - int initialSize = GrNextPow2(SkTMax(minWidth, minHeight)); - initialSize = SkTMax(int(kMinSize), initialSize); +GrCCAtlas::GrCCAtlas(const GrCaps& caps, int minSize) + : fMaxAtlasSize(SkTMax(minSize, caps.maxPreferredRenderTargetSize())) { + // Caller should have cropped any paths to the destination render target instead of asking for + // an atlas larger than maxRenderTargetSize. + SkASSERT(fMaxAtlasSize <= caps.maxRenderTargetSize()); + int initialSize = GrNextPow2(minSize + kPadding); + initialSize = SkTMax(kAtlasMinSize, initialSize); initialSize = SkTMin(initialSize, fMaxAtlasSize); fHeight = fWidth = initialSize; - fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, initialSize, initialSize); + fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, fWidth, fHeight); } -GrCCAtlas::~GrCCAtlas() {} +GrCCAtlas::~GrCCAtlas() { +} bool GrCCAtlas::addRect(int w, int h, SkIPoint16* loc) { // This can't be called anymore once setCoverageCountBatchID() has been called. @@ -104,17 +114,14 @@ bool GrCCAtlas::addRect(int w, int h, SkIPoint16* loc) { } bool GrCCAtlas::internalPlaceRect(int w, int h, SkIPoint16* loc) { - SkASSERT(SkTMax(w, h) < fMaxAtlasSize); - for (Node* node = fTopNode.get(); node; node = node->previous()) { - if (node->addRect(w, h, loc)) { + if (node->addRect(w, h, loc, fMaxAtlasSize)) { return true; } } // The rect didn't fit. Grow the atlas and try again. do { - SkASSERT(SkTMax(fWidth, fHeight) <= fMaxAtlasSize); if (fWidth == fMaxAtlasSize && fHeight == fMaxAtlasSize) { return false; } @@ -127,7 +134,7 @@ bool GrCCAtlas::internalPlaceRect(int w, int h, SkIPoint16* loc) { fWidth = SkTMin(fWidth * 2, fMaxAtlasSize); fTopNode = skstd::make_unique<Node>(std::move(fTopNode), left, 0, fWidth, fHeight); } - } while (!fTopNode->addRect(w, h, loc)); + } while (!fTopNode->addRect(w, h, loc, fMaxAtlasSize)); return true; } diff --git a/src/gpu/ccpr/GrCCAtlas.h b/src/gpu/ccpr/GrCCAtlas.h index cac82af894..184022ee96 100644 --- a/src/gpu/ccpr/GrCCAtlas.h +++ b/src/gpu/ccpr/GrCCAtlas.h @@ -26,11 +26,9 @@ struct SkIPoint16; */ class GrCCAtlas { public: - static constexpr int kMinSize = 1024; - using CoverageCountBatchID = int; - GrCCAtlas(const GrCaps&, int minWidth, int minHeight); + GrCCAtlas(const GrCaps&, int minSize); ~GrCCAtlas(); bool addRect(int devWidth, int devHeight, SkIPoint16* loc); @@ -55,10 +53,9 @@ private: const int fMaxAtlasSize; - int fWidth; - int fHeight; - SkISize fDrawBounds; + int fWidth, fHeight; std::unique_ptr<Node> fTopNode; + SkISize fDrawBounds = {0, 0}; CoverageCountBatchID fCoverageCountBatchID SkDEBUGCODE(= 0); sk_sp<GrTextureProxy> fTextureProxy; diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp index ec3681dfcf..90d89dec60 100644 --- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp @@ -486,7 +486,8 @@ GrCCAtlas* GrCoverageCountingPathRenderer::placeParsedPathInAtlas( auto coverageCountBatchID = fPerFlushPathParser->closeCurrentBatch(); fPerFlushAtlases.back().setCoverageCountBatchID(coverageCountBatchID); } - fPerFlushAtlases.emplace_back(*onFlushRP->caps(), w, h).addRect(w, h, &atlasLocation); + fPerFlushAtlases.emplace_back(*onFlushRP->caps(), SkTMax(w, h)); + SkAssertResult(fPerFlushAtlases.back().addRect(w, h, &atlasLocation)); } *atlasOffsetX = atlasLocation.x() - static_cast<int16_t>(clippedPathIBounds.left()); diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index d71194ed6f..3bdf5d0e60 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -483,6 +483,12 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, // Our render targets are always created with textures as the color // attachment, hence this min: fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize); + fMaxPreferredRenderTargetSize = fMaxRenderTargetSize; + + if (kARM_GrGLVendor == ctxInfo.vendor()) { + // On Mali G71, RT's above 4k have been observed to incur a performance cost. + fMaxPreferredRenderTargetSize = SkTMin(4096, fMaxPreferredRenderTargetSize); + } fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker"); diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h index d96a690b31..e75a2c63ff 100644 --- a/src/gpu/mock/GrMockCaps.h +++ b/src/gpu/mock/GrMockCaps.h @@ -20,6 +20,7 @@ public: fBufferMapThreshold = SK_MaxS32; // Overridable in GrContextOptions. fMaxTextureSize = options.fMaxTextureSize; fMaxRenderTargetSize = SkTMin(options.fMaxRenderTargetSize, fMaxTextureSize); + fMaxPreferredRenderTargetSize = fMaxRenderTargetSize; fMaxVertexAttributes = options.fMaxVertexAttributes; fShaderCaps.reset(new GrShaderCaps(contextOptions)); diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm index 865aa37fe6..93d801fd72 100644 --- a/src/gpu/mtl/GrMtlCaps.mm +++ b/src/gpu/mtl/GrMtlCaps.mm @@ -118,6 +118,7 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) { } } } + fMaxPreferredRenderTargetSize = fMaxRenderTargetSize; fMaxTextureSize = fMaxRenderTargetSize; // Init sample counts. All devices support 1 (i.e. 0 in skia). diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 3fc5a08acb..88d820a62c 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -165,6 +165,9 @@ void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties, fMaxRenderTargetSize = SkTMin(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX); fMaxTextureSize = SkTMin(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX); + // TODO: check if RT's larger than 4k incur a performance cost on ARM. + fMaxPreferredRenderTargetSize = fMaxRenderTargetSize; + // Assuming since we will always map in the end to upload the data we might as well just map // from the get go. There is no hard data to suggest this is faster or slower. fBufferMapThreshold = 0; |