Fix GrContext::writePixels bug
Bug: 769760
Change-Id: I63603c036a8eef5eec66afb6ac4e937f556bbb63
Reviewed-on: https://skia-review.googlesource.com/59681
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index 92390ae..364cf1a 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -447,4 +447,95 @@
}
}
}
+
+static sk_sp<SkSurface> create_surf(GrContext* context, int width, int height) {
+ const SkImageInfo ii = SkImageInfo::Make(width, height,
+ kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+
+ sk_sp<SkSurface> surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii);
+ surf->flush();
+ return surf;
+}
+
+static sk_sp<SkImage> upload(const sk_sp<SkSurface>& surf, SkColor color) {
+ const SkImageInfo smII = SkImageInfo::Make(16, 16, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ SkBitmap bm;
+ bm.allocPixels(smII);
+ bm.eraseColor(color);
+
+ surf->getCanvas()->writePixels(bm, 0, 0);
+
+ return surf->makeImageSnapshot();
+}
+
+// This is tests whether the first writePixels is completed before the
+// second writePixels takes effect (i.e., that writePixels correctly flushes
+// in between uses of the shared backing resource).
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WritePixelsPendingIO, reporter, ctxInfo) {
+ GrContext* context = ctxInfo.grContext();
+
+ static const int kFullSize = 62;
+ static const int kHalfSize = 31;
+
+ static const uint32_t kLeftColor = 0xFF222222;
+ static const uint32_t kRightColor = 0xFFAAAAAA;
+
+ const SkImageInfo fullII = SkImageInfo::Make(kFullSize, kFullSize,
+ kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ const SkImageInfo halfII = SkImageInfo::Make(kHalfSize, kFullSize,
+ kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+
+ sk_sp<SkSurface> dest = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, fullII);
+
+ {
+ // Seed the resource cached with a scratch texture that will be
+ // reused by writeSurfacePixels
+ GrSurfaceDesc desc;
+ desc.fFlags = kNone_GrSurfaceFlags;
+ desc.fWidth = 32;
+ desc.fHeight = 64;
+ desc.fConfig = kRGBA_8888_GrPixelConfig;
+
+ sk_sp<GrTextureProxy> temp = GrSurfaceProxy::MakeDeferred(context->resourceProvider(), desc,
+ SkBackingFit::kApprox,
+ SkBudgeted::kYes);
+ temp->instantiate(context->resourceProvider());
+ }
+
+ // Create the surfaces and flush them to ensure there is no lingering pendingIO
+ sk_sp<SkSurface> leftSurf = create_surf(context, kHalfSize, kFullSize);
+ sk_sp<SkSurface> rightSurf = create_surf(context, kHalfSize, kFullSize);
+
+ sk_sp<SkImage> leftImg = upload(std::move(leftSurf), kLeftColor);
+ dest->getCanvas()->drawImage(std::move(leftImg), 0, 0);
+
+ sk_sp<SkImage> rightImg = upload(std::move(rightSurf), kRightColor);
+ dest->getCanvas()->drawImage(std::move(rightImg), kHalfSize, 0);
+
+ SkBitmap bm;
+ bm.allocPixels(fullII);
+ SkAssertResult(dest->readPixels(bm, 0, 0));
+
+ bool isCorrect = true;
+ for (int y = 0; isCorrect && y < 16; ++y) {
+ const uint32_t* sl = bm.getAddr32(0, y);
+
+ for (int x = 0; x < 16; ++x) {
+ if (kLeftColor != sl[x]) {
+ isCorrect = false;
+ break;
+ }
+ }
+ for (int x = kHalfSize; x < kHalfSize+16; ++x) {
+ if (kRightColor != sl[x]) {
+ isCorrect = false;
+ break;
+ }
+ }
+ }
+
+ REPORTER_ASSERT(reporter, isCorrect);
+}
+
+
#endif