Index: tests/ImageTest.cpp |
diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp |
index 2ec1f342b360f8f93649a34458de56165cdf4f36..d8ffa0c9efaf6496664dd98b2fb29fad6b20c7a1 100644 |
--- a/tests/ImageTest.cpp |
+++ b/tests/ImageTest.cpp |
@@ -737,4 +737,103 @@ DEF_GPUTEST_FOR_NATIVE_CONTEXT(SkImage_NewFromTexture, reporter, context) { |
refImg.reset(nullptr); // force a release of the image |
REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount); |
} |
+ |
+static void check_images_same(skiatest::Reporter* reporter, const SkImage* a, const SkImage* b) { |
+ if (a->width() != b->width() || a->height() != b->height()) { |
+ ERRORF(reporter, "Images must have the same size"); |
+ return; |
+ } |
+ if (a->isOpaque() != b->isOpaque()) { |
+ ERRORF(reporter, "Images must have the same opaquness"); |
+ return; |
+ } |
+ |
+ SkImageInfo info = SkImageInfo::MakeN32Premul(a->width(), a->height()); |
+ SkAutoPixmapStorage apm; |
+ SkAutoPixmapStorage bpm; |
+ |
+ apm.alloc(info); |
+ bpm.alloc(info); |
+ |
+ if (!a->readPixels(apm, 0, 0)) { |
+ ERRORF(reporter, "Could not read image a's pixels"); |
+ return; |
+ } |
+ if (!b->readPixels(bpm, 0, 0)) { |
+ ERRORF(reporter, "Could not read image b's pixels"); |
+ return; |
+ } |
+ |
+ for (auto y = 0; y < info.height(); ++y) { |
+ for (auto x = 0; x < info.width(); ++x) { |
+ uint32_t pixelA = *apm.addr32(x, y); |
+ uint32_t pixelB = *bpm.addr32(x, y); |
+ if (pixelA != pixelB) { |
+ ERRORF(reporter, "Expected image pixels to be the same. At %d,%d 0x%08x != 0x%08x", |
+ x, y, pixelA, pixelB); |
+ return; |
+ } |
+ } |
+ } |
+} |
+ |
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageTextureData, reporter, context, glContext) { |
+ SkAutoTUnref<GrContextThreadSafeProxy> proxy(context->threadSafeProxy()); |
+ |
+ GrContextFactory otherFactory; |
+ GrContextFactory::ContextInfo otherContextInfo = |
+ otherFactory.getContextInfo(GrContextFactory::kNative_GLContextType); |
+ |
+ glContext->makeCurrent(); |
+ REPORTER_ASSERT(reporter, proxy); |
+ |
+ std::function<SkImage *()> imageFactories[] = { |
+ create_image, |
+ create_codec_image, |
+ create_data_image, |
+ // Create an image from a picture. |
+ create_picture_image, |
+ // Create a texture image. |
+ [context] { return create_gpu_image(context); }, |
+ // Create a texture image in a another GrContext. |
+ [glContext, otherContextInfo] { |
+ otherContextInfo.fGLContext->makeCurrent(); |
+ SkImage *otherContextImage = create_gpu_image(otherContextInfo.fGrContext); |
+ glContext->makeCurrent(); |
+ return otherContextImage; |
+ } |
+ }; |
+ |
+ |
+ for (auto imageFactory : imageFactories) { |
+ SkAutoTUnref<SkImage> image(imageFactory()); |
+ int allocCnt = 0; |
+ auto allocator = [&allocCnt] (size_t size, const SkImage*) { |
+ ++allocCnt; |
+ return sk_malloc_throw(size); |
+ }; |
+ SkImageTextureData* td = image->newImageTextureData(*proxy, allocator); |
+ |
+ REPORTER_ASSERT_MESSAGE(reporter, SkToBool(td) != SkToBool(as_IB(image)->peekTexture()), |
+ "Texture backed images should not succeed, others should."); |
+ if (td) { |
+ REPORTER_ASSERT_MESSAGE(reporter, 1 == allocCnt, |
+ "Should have made a single allocation."); |
+ for (auto budgeted : { SkBudgeted::kNo, SkBudgeted::kYes }) { |
+ SkAutoTUnref<SkImage> newImage(td->newImage(context, budgeted)); |
+ REPORTER_ASSERT(reporter, SkToBool(newImage)); |
+ if (newImage) { |
+ check_images_same(reporter, image, newImage); |
+ } |
+ // The other context should be able to create images from texture data created by |
+ // the original context. |
+ SkAutoTUnref<SkImage> image1(td->newImage(otherContextInfo.fGrContext, budgeted)); |
+ REPORTER_ASSERT(reporter, !image1); |
+ glContext->makeCurrent(); |
+ } |
+ sk_free(td); |
+ } |
+ } |
+} |
#endif |
+ |