aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/DrawOpAtlasTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/DrawOpAtlasTest.cpp')
-rw-r--r--tests/DrawOpAtlasTest.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/tests/DrawOpAtlasTest.cpp b/tests/DrawOpAtlasTest.cpp
new file mode 100644
index 0000000000..a34618e38f
--- /dev/null
+++ b/tests/DrawOpAtlasTest.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTypes.h"
+
+#if SK_SUPPORT_GPU
+
+#include "GrContextPriv.h"
+#include "Test.h"
+#include "text/GrAtlasGlyphCache.h"
+
+static const int kNumPlots = 2;
+static const int kPlotSize = 32;
+static const int kAtlasSize = kNumPlots * kPlotSize;
+
+int GrDrawOpAtlas::numAllocated_TestingOnly() const {
+ int count = 0;
+ for (uint32_t i = 0; i < this->maxPages(); ++i) {
+ if (fProxies[i]->priv().isInstantiated()) {
+ ++count;
+ }
+ }
+
+ return count;
+}
+
+void EvictionFunc(GrDrawOpAtlas::AtlasID atlasID, void*) {
+ SkASSERT(0); // The unit test shouldn't exercise this code path
+}
+
+static void check(skiatest::Reporter* r, GrDrawOpAtlas* atlas,
+ uint32_t expectedActive, uint32_t expectedMax, int expectedAlloced) {
+ REPORTER_ASSERT(r, expectedActive == atlas->numActivePages());
+ REPORTER_ASSERT(r, expectedMax == atlas->maxPages());
+ REPORTER_ASSERT(r, expectedAlloced == atlas->numAllocated_TestingOnly());
+}
+
+class TestingUploadTarget : public GrDeferredUploadTarget {
+public:
+ TestingUploadTarget() { }
+
+ const GrTokenTracker* tokenTracker() final {
+ return &fTokenTracker;
+ }
+
+ GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) final {
+ SkASSERT(0); // this test shouldn't invoke this code path
+ return fTokenTracker.nextDrawToken();
+ }
+
+ virtual GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&& upload) final {
+ return fTokenTracker.nextTokenToFlush();
+ }
+
+ void issueDrawToken() { fTokenTracker.issueDrawToken(); }
+ void flushToken() { fTokenTracker.flushToken(); }
+
+private:
+ GrTokenTracker fTokenTracker;
+
+ typedef GrDeferredUploadTarget INHERITED;
+};
+
+static bool fill_plot(GrDrawOpAtlas* atlas,
+ GrResourceProvider* resourceProvider,
+ GrDeferredUploadTarget* target,
+ GrDrawOpAtlas::AtlasID* atlasID,
+ int alpha) {
+ SkImageInfo ii = SkImageInfo::MakeA8(kPlotSize, kPlotSize);
+
+ SkBitmap data;
+ data.allocPixels(ii);
+ data.eraseARGB(alpha, 0, 0, 0);
+
+ SkIPoint16 loc;
+ bool result = atlas->addToAtlas(resourceProvider, atlasID, target, kPlotSize, kPlotSize,
+ data.getAddr(0, 0), &loc);
+ return result;
+}
+
+
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DrawOpAtlas, reporter, ctxInfo) {
+ auto context = ctxInfo.grContext();
+ auto proxyProvider = context->contextPriv().proxyProvider();
+ auto resourceProvider = context->contextPriv().resourceProvider();
+ auto drawingManager = context->contextPriv().drawingManager();
+
+ GrOnFlushResourceProvider onFlushResourceProvider(drawingManager);
+ TestingUploadTarget uploadTarget;
+
+ std::unique_ptr<GrDrawOpAtlas> atlas = GrDrawOpAtlas::Make(
+ proxyProvider,
+ kAlpha_8_GrPixelConfig,
+ kAtlasSize, kAtlasSize,
+ kNumPlots, kNumPlots,
+ GrDrawOpAtlas::AllowMultitexturing::kYes,
+ EvictionFunc, nullptr);
+ check(reporter, atlas.get(), 0, 4, 0);
+
+ // Fill up the first level
+ GrDrawOpAtlas::AtlasID atlasIDs[kNumPlots * kNumPlots];
+ for (int i = 0; i < kNumPlots * kNumPlots; ++i) {
+ bool result = fill_plot(atlas.get(), resourceProvider, &uploadTarget, &atlasIDs[i], i*32);
+ REPORTER_ASSERT(reporter, result);
+ check(reporter, atlas.get(), 1, 4, 1);
+ }
+
+ atlas->instantiate(&onFlushResourceProvider);
+ check(reporter, atlas.get(), 1, 4, 1);
+
+ // Force allocation of a second level
+ GrDrawOpAtlas::AtlasID atlasID;
+ bool result = fill_plot(atlas.get(), resourceProvider, &uploadTarget, &atlasID, 4*32);
+ REPORTER_ASSERT(reporter, result);
+ check(reporter, atlas.get(), 2, 4, 2);
+
+ // Simulate a lot of draws using only the first plot. The last texture should be compacted.
+ for (int i = 0; i < 512; ++i) {
+ atlas->setLastUseToken(atlasIDs[0], uploadTarget.tokenTracker()->nextDrawToken());
+ uploadTarget.issueDrawToken();
+ uploadTarget.flushToken();
+ atlas->compact(uploadTarget.tokenTracker()->nextTokenToFlush());
+ }
+
+ check(reporter, atlas.get(), 1, 4, 1);
+}
+
+#endif