Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include <functional>
      9 #include <initializer_list>
     10 #include <vector>
     11 
     12 #include "SkAutoPixmapStorage.h"
     13 #include "SkBitmap.h"
     14 #include "SkCanvas.h"
     15 #include "SkColorSpacePriv.h"
     16 #include "SkData.h"
     17 #include "SkImageEncoder.h"
     18 #include "SkImageGenerator.h"
     19 #include "SkImage_Base.h"
     20 #include "SkImagePriv.h"
     21 #include "SkMakeUnique.h"
     22 #include "SkPicture.h"
     23 #include "SkPictureRecorder.h"
     24 #include "SkPixelSerializer.h"
     25 #include "SkRRect.h"
     26 #include "SkStream.h"
     27 #include "SkSurface.h"
     28 #include "SkUtils.h"
     29 #include "Test.h"
     30 
     31 #include "Resources.h"
     32 #include "sk_tool_utils.h"
     33 
     34 #if SK_SUPPORT_GPU
     35 #include "GrGpu.h"
     36 #endif
     37 
     38 using namespace sk_gpu_test;
     39 
     40 SkImageInfo read_pixels_info(SkImage* image) {
     41     if (as_IB(image)->onImageInfo().colorSpace()) {
     42         return SkImageInfo::MakeS32(image->width(), image->height(), image->alphaType());
     43     }
     44 
     45     return SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType());
     46 }
     47 
     48 static void assert_equal(skiatest::Reporter* reporter, SkImage* a, const SkIRect* subsetA,
     49                          SkImage* b) {
     50     const int widthA = subsetA ? subsetA->width() : a->width();
     51     const int heightA = subsetA ? subsetA->height() : a->height();
     52 
     53     REPORTER_ASSERT(reporter, widthA == b->width());
     54     REPORTER_ASSERT(reporter, heightA == b->height());
     55 
     56     // see https://bug.skia.org/3965
     57     //REPORTER_ASSERT(reporter, a->isOpaque() == b->isOpaque());
     58 
     59     SkAutoPixmapStorage pmapA, pmapB;
     60     pmapA.alloc(read_pixels_info(a));
     61     pmapB.alloc(read_pixels_info(b));
     62 
     63     const int srcX = subsetA ? subsetA->x() : 0;
     64     const int srcY = subsetA ? subsetA->y() : 0;
     65 
     66     REPORTER_ASSERT(reporter, a->readPixels(pmapA, srcX, srcY));
     67     REPORTER_ASSERT(reporter, b->readPixels(pmapB, 0, 0));
     68 
     69     const size_t widthBytes = widthA * 4;
     70     for (int y = 0; y < heightA; ++y) {
     71         REPORTER_ASSERT(reporter, !memcmp(pmapA.addr32(0, y), pmapB.addr32(0, y), widthBytes));
     72     }
     73 }
     74 static void draw_image_test_pattern(SkCanvas* canvas) {
     75     canvas->clear(SK_ColorWHITE);
     76     SkPaint paint;
     77     paint.setColor(SK_ColorBLACK);
     78     canvas->drawRect(SkRect::MakeXYWH(5, 5, 10, 10), paint);
     79 }
     80 static sk_sp<SkImage> create_image() {
     81     const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
     82     auto surface(SkSurface::MakeRaster(info));
     83     draw_image_test_pattern(surface->getCanvas());
     84     return surface->makeImageSnapshot();
     85 }
     86 static sk_sp<SkData> create_image_data(SkImageInfo* info) {
     87     *info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
     88     const size_t rowBytes = info->minRowBytes();
     89     sk_sp<SkData> data(SkData::MakeUninitialized(rowBytes * info->height()));
     90     {
     91         SkBitmap bm;
     92         bm.installPixels(*info, data->writable_data(), rowBytes);
     93         SkCanvas canvas(bm);
     94         draw_image_test_pattern(&canvas);
     95     }
     96     return data;
     97 }
     98 static sk_sp<SkImage> create_data_image() {
     99     SkImageInfo info;
    100     sk_sp<SkData> data(create_image_data(&info));
    101     return SkImage::MakeRasterData(info, std::move(data), info.minRowBytes());
    102 }
    103 #if SK_SUPPORT_GPU // not gpu-specific but currently only used in GPU tests
    104 static sk_sp<SkImage> create_image_large(int maxTextureSize) {
    105     const SkImageInfo info = SkImageInfo::MakeN32(maxTextureSize + 1, 32, kOpaque_SkAlphaType);
    106     auto surface(SkSurface::MakeRaster(info));
    107     surface->getCanvas()->clear(SK_ColorWHITE);
    108     SkPaint paint;
    109     paint.setColor(SK_ColorBLACK);
    110     surface->getCanvas()->drawRect(SkRect::MakeXYWH(4000, 2, 28000, 30), paint);
    111     return surface->makeImageSnapshot();
    112 }
    113 static sk_sp<SkImage> create_picture_image() {
    114     SkPictureRecorder recorder;
    115     SkCanvas* canvas = recorder.beginRecording(10, 10);
    116     canvas->clear(SK_ColorCYAN);
    117     return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), SkISize::Make(10, 10),
    118                                     nullptr, nullptr, SkImage::BitDepth::kU8,
    119                                     SkColorSpace::MakeSRGB());
    120 };
    121 #endif
    122 // Want to ensure that our Release is called when the owning image is destroyed
    123 struct RasterDataHolder {
    124     RasterDataHolder() : fReleaseCount(0) {}
    125     sk_sp<SkData> fData;
    126     int fReleaseCount;
    127     static void Release(const void* pixels, void* context) {
    128         RasterDataHolder* self = static_cast<RasterDataHolder*>(context);
    129         self->fReleaseCount++;
    130         self->fData.reset();
    131     }
    132 };
    133 static sk_sp<SkImage> create_rasterproc_image(RasterDataHolder* dataHolder) {
    134     SkASSERT(dataHolder);
    135     SkImageInfo info;
    136     dataHolder->fData = create_image_data(&info);
    137     return SkImage::MakeFromRaster(SkPixmap(info, dataHolder->fData->data(), info.minRowBytes()),
    138                                    RasterDataHolder::Release, dataHolder);
    139 }
    140 static sk_sp<SkImage> create_codec_image() {
    141     SkImageInfo info;
    142     sk_sp<SkData> data(create_image_data(&info));
    143     SkBitmap bitmap;
    144     bitmap.installPixels(info, data->writable_data(), info.minRowBytes());
    145     sk_sp<SkData> src(sk_tool_utils::EncodeImageToData(bitmap, SkEncodedImageFormat::kPNG, 100));
    146     return SkImage::MakeFromEncoded(std::move(src));
    147 }
    148 #if SK_SUPPORT_GPU
    149 static sk_sp<SkImage> create_gpu_image(GrContext* context) {
    150     const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
    151     auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
    152     draw_image_test_pattern(surface->getCanvas());
    153     return surface->makeImageSnapshot();
    154 }
    155 #endif
    156 
    157 static void test_encode(skiatest::Reporter* reporter, SkImage* image) {
    158     const SkIRect ir = SkIRect::MakeXYWH(5, 5, 10, 10);
    159     sk_sp<SkData> origEncoded(image->encode());
    160     REPORTER_ASSERT(reporter, origEncoded);
    161     REPORTER_ASSERT(reporter, origEncoded->size() > 0);
    162 
    163     sk_sp<SkImage> decoded(SkImage::MakeFromEncoded(origEncoded));
    164     if (!decoded) {
    165         ERRORF(reporter, "failed to decode image!");
    166         return;
    167     }
    168     REPORTER_ASSERT(reporter, decoded);
    169     assert_equal(reporter, image, nullptr, decoded.get());
    170 
    171     // Now see if we can instantiate an image from a subset of the surface/origEncoded
    172 
    173     decoded = SkImage::MakeFromEncoded(origEncoded, &ir);
    174     REPORTER_ASSERT(reporter, decoded);
    175     assert_equal(reporter, image, &ir, decoded.get());
    176 }
    177 
    178 DEF_TEST(ImageEncode, reporter) {
    179     test_encode(reporter, create_image().get());
    180 }
    181 
    182 #if SK_SUPPORT_GPU
    183 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageEncode_Gpu, reporter, ctxInfo) {
    184     test_encode(reporter, create_gpu_image(ctxInfo.grContext()).get());
    185 }
    186 #endif
    187 
    188 DEF_TEST(Image_MakeFromRasterBitmap, reporter) {
    189     const struct {
    190         SkCopyPixelsMode fCPM;
    191         bool            fExpectSameAsMutable;
    192         bool            fExpectSameAsImmutable;
    193     } recs[] = {
    194         { kIfMutable_SkCopyPixelsMode,  false,  true },
    195         { kAlways_SkCopyPixelsMode,     false,  false },
    196         { kNever_SkCopyPixelsMode,      true,   true },
    197     };
    198     for (auto rec : recs) {
    199         SkPixmap pm;
    200         SkBitmap bm;
    201         bm.allocN32Pixels(100, 100);
    202 
    203         auto img = SkMakeImageFromRasterBitmap(bm, rec.fCPM);
    204         REPORTER_ASSERT(reporter, img->peekPixels(&pm));
    205         const bool sameMutable = pm.addr32(0, 0) == bm.getAddr32(0, 0);
    206         REPORTER_ASSERT(reporter, rec.fExpectSameAsMutable == sameMutable);
    207         REPORTER_ASSERT(reporter, (bm.getGenerationID() == img->uniqueID()) == sameMutable);
    208 
    209         bm.notifyPixelsChanged();   // force a new generation ID
    210 
    211         bm.setImmutable();
    212         img = SkMakeImageFromRasterBitmap(bm, rec.fCPM);
    213         REPORTER_ASSERT(reporter, img->peekPixels(&pm));
    214         const bool sameImmutable = pm.addr32(0, 0) == bm.getAddr32(0, 0);
    215         REPORTER_ASSERT(reporter, rec.fExpectSameAsImmutable == sameImmutable);
    216         REPORTER_ASSERT(reporter, (bm.getGenerationID() == img->uniqueID()) == sameImmutable);
    217     }
    218 }
    219 
    220 namespace {
    221 
    222 const char* kSerializedData = "serialized";
    223 
    224 class MockSerializer : public SkPixelSerializer {
    225 public:
    226     MockSerializer(sk_sp<SkData> (*func)()) : fFunc(func), fDidEncode(false) { }
    227 
    228     bool didEncode() const { return fDidEncode; }
    229 
    230 protected:
    231     bool onUseEncodedData(const void*, size_t) override {
    232         return false;
    233     }
    234 
    235     SkData* onEncode(const SkPixmap&) override {
    236         fDidEncode = true;
    237         return fFunc().release();
    238     }
    239 
    240 private:
    241     sk_sp<SkData> (*fFunc)();
    242     bool fDidEncode;
    243 
    244     typedef SkPixelSerializer INHERITED;
    245 };
    246 
    247 } // anonymous namespace
    248 
    249 // Test that SkImage encoding observes custom pixel serializers.
    250 DEF_TEST(Image_Encode_Serializer, reporter) {
    251     MockSerializer serializer([]() -> sk_sp<SkData> {
    252         return SkData::MakeWithCString(kSerializedData);
    253     });
    254     sk_sp<SkImage> image(create_image());
    255     sk_sp<SkData> encoded(image->encode(&serializer));
    256     sk_sp<SkData> reference(SkData::MakeWithCString(kSerializedData));
    257 
    258     REPORTER_ASSERT(reporter, serializer.didEncode());
    259     REPORTER_ASSERT(reporter, encoded);
    260     REPORTER_ASSERT(reporter, encoded->size() > 0);
    261     REPORTER_ASSERT(reporter, encoded->equals(reference.get()));
    262 }
    263 
    264 // Test that image encoding failures do not break picture serialization/deserialization.
    265 DEF_TEST(Image_Serialize_Encoding_Failure, reporter) {
    266     auto surface(SkSurface::MakeRasterN32Premul(100, 100));
    267     surface->getCanvas()->clear(SK_ColorGREEN);
    268     sk_sp<SkImage> image(surface->makeImageSnapshot());
    269     REPORTER_ASSERT(reporter, image);
    270 
    271     SkPictureRecorder recorder;
    272     SkCanvas* canvas = recorder.beginRecording(100, 100);
    273     canvas->drawImage(image, 0, 0);
    274     sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
    275     REPORTER_ASSERT(reporter, picture);
    276     REPORTER_ASSERT(reporter, picture->approximateOpCount() > 0);
    277 
    278     MockSerializer emptySerializer([]() -> sk_sp<SkData> { return SkData::MakeEmpty(); });
    279     MockSerializer nullSerializer([]() -> sk_sp<SkData> { return nullptr; });
    280     MockSerializer* serializers[] = { &emptySerializer, &nullSerializer };
    281 
    282     for (size_t i = 0; i < SK_ARRAY_COUNT(serializers); ++i) {
    283         SkDynamicMemoryWStream wstream;
    284         REPORTER_ASSERT(reporter, !serializers[i]->didEncode());
    285         picture->serialize(&wstream, serializers[i]);
    286         REPORTER_ASSERT(reporter, serializers[i]->didEncode());
    287 
    288         std::unique_ptr<SkStream> rstream(wstream.detachAsStream());
    289         sk_sp<SkPicture> deserialized(SkPicture::MakeFromStream(rstream.get()));
    290         REPORTER_ASSERT(reporter, deserialized);
    291         REPORTER_ASSERT(reporter, deserialized->approximateOpCount() > 0);
    292     }
    293 }
    294 
    295 DEF_TEST(Image_NewRasterCopy, reporter) {
    296     const SkPMColor red =   SkPackARGB32(0xFF, 0xFF, 0, 0);
    297     const SkPMColor green = SkPackARGB32(0xFF, 0, 0xFF, 0);
    298     const SkPMColor blue =  SkPackARGB32(0xFF, 0, 0, 0xFF);
    299     SkPMColor colors[] = { red, green, blue, 0 };
    300     sk_sp<SkColorTable> ctable(new SkColorTable(colors, SK_ARRAY_COUNT(colors)));
    301     // The colortable made a copy, so we can trash the original colors
    302     memset(colors, 0xFF, sizeof(colors));
    303 
    304     const SkImageInfo srcInfo = SkImageInfo::Make(2, 2, kIndex_8_SkColorType, kPremul_SkAlphaType);
    305     const size_t srcRowBytes = 2 * sizeof(uint8_t);
    306     uint8_t indices[] = { 0, 1, 2, 3 };
    307     auto image = SkImage::MakeRasterCopy(SkPixmap(srcInfo, indices, srcRowBytes, ctable.get()));
    308     // The image made a copy, so we can trash the original indices
    309     memset(indices, 0xFF, sizeof(indices));
    310 
    311     const SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(2, 2);
    312     const size_t dstRowBytes = 2 * sizeof(SkPMColor);
    313     SkPMColor pixels[4];
    314     memset(pixels, 0xFF, sizeof(pixels));   // init with values we don't expect
    315     image->readPixels(dstInfo, pixels, dstRowBytes, 0, 0);
    316     REPORTER_ASSERT(reporter, red == pixels[0]);
    317     REPORTER_ASSERT(reporter, green == pixels[1]);
    318     REPORTER_ASSERT(reporter, blue == pixels[2]);
    319     REPORTER_ASSERT(reporter, 0 == pixels[3]);
    320 }
    321 
    322 // Test that a draw that only partially covers the drawing surface isn't
    323 // interpreted as covering the entire drawing surface (i.e., exercise one of the
    324 // conditions of SkCanvas::wouldOverwriteEntireSurface()).
    325 DEF_TEST(Image_RetainSnapshot, reporter) {
    326     const SkPMColor red   = SkPackARGB32(0xFF, 0xFF, 0, 0);
    327     const SkPMColor green = SkPackARGB32(0xFF, 0, 0xFF, 0);
    328     SkImageInfo info = SkImageInfo::MakeN32Premul(2, 2);
    329     auto surface(SkSurface::MakeRaster(info));
    330     surface->getCanvas()->clear(0xFF00FF00);
    331 
    332     SkPMColor pixels[4];
    333     memset(pixels, 0xFF, sizeof(pixels));   // init with values we don't expect
    334     const SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(2, 2);
    335     const size_t dstRowBytes = 2 * sizeof(SkPMColor);
    336 
    337     sk_sp<SkImage> image1(surface->makeImageSnapshot());
    338     REPORTER_ASSERT(reporter, image1->readPixels(dstInfo, pixels, dstRowBytes, 0, 0));
    339     for (size_t i = 0; i < SK_ARRAY_COUNT(pixels); ++i) {
    340         REPORTER_ASSERT(reporter, pixels[i] == green);
    341     }
    342 
    343     SkPaint paint;
    344     paint.setBlendMode(SkBlendMode::kSrc);
    345     paint.setColor(SK_ColorRED);
    346 
    347     surface->getCanvas()->drawRect(SkRect::MakeXYWH(1, 1, 1, 1), paint);
    348 
    349     sk_sp<SkImage> image2(surface->makeImageSnapshot());
    350     REPORTER_ASSERT(reporter, image2->readPixels(dstInfo, pixels, dstRowBytes, 0, 0));
    351     REPORTER_ASSERT(reporter, pixels[0] == green);
    352     REPORTER_ASSERT(reporter, pixels[1] == green);
    353     REPORTER_ASSERT(reporter, pixels[2] == green);
    354     REPORTER_ASSERT(reporter, pixels[3] == red);
    355 }
    356 
    357 /////////////////////////////////////////////////////////////////////////////////////////////////
    358 
    359 static void make_bitmap_mutable(SkBitmap* bm) {
    360     bm->allocN32Pixels(10, 10);
    361 }
    362 
    363 static void make_bitmap_immutable(SkBitmap* bm) {
    364     bm->allocN32Pixels(10, 10);
    365     bm->setImmutable();
    366 }
    367 
    368 DEF_TEST(image_newfrombitmap, reporter) {
    369     const struct {
    370         void (*fMakeProc)(SkBitmap*);
    371         bool fExpectPeekSuccess;
    372         bool fExpectSharedID;
    373         bool fExpectLazy;
    374     } rec[] = {
    375         { make_bitmap_mutable,      true,   false, false },
    376         { make_bitmap_immutable,    true,   true,  false },
    377     };
    378 
    379     for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
    380         SkBitmap bm;
    381         rec[i].fMakeProc(&bm);
    382 
    383         sk_sp<SkImage> image(SkImage::MakeFromBitmap(bm));
    384         SkPixmap pmap;
    385 
    386         const bool sharedID = (image->uniqueID() == bm.getGenerationID());
    387         REPORTER_ASSERT(reporter, sharedID == rec[i].fExpectSharedID);
    388 
    389         const bool peekSuccess = image->peekPixels(&pmap);
    390         REPORTER_ASSERT(reporter, peekSuccess == rec[i].fExpectPeekSuccess);
    391 
    392         const bool lazy = image->isLazyGenerated();
    393         REPORTER_ASSERT(reporter, lazy == rec[i].fExpectLazy);
    394     }
    395 }
    396 
    397 ///////////////////////////////////////////////////////////////////////////////////////////////////
    398 #if SK_SUPPORT_GPU
    399 
    400 #include "SkBitmapCache.h"
    401 
    402 /*
    403  *  This tests the caching (and preemptive purge) of the raster equivalent of a gpu-image.
    404  *  We cache it for performance when drawing into a raster surface.
    405  *
    406  *  A cleaner test would know if each drawImage call triggered a read-back from the gpu,
    407  *  but we don't have that facility (at the moment) so we use a little internal knowledge
    408  *  of *how* the raster version is cached, and look for that.
    409  */
    410 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(c, reporter, ctxInfo) {
    411     SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
    412     sk_sp<SkImage> image(create_gpu_image(ctxInfo.grContext()));
    413     const uint32_t uniqueID = image->uniqueID();
    414     const auto desc = SkBitmapCacheDesc::Make(image.get());
    415 
    416     auto surface(SkSurface::MakeRaster(info));
    417 
    418     // now we can test drawing a gpu-backed image into a cpu-backed surface
    419 
    420     {
    421         SkBitmap cachedBitmap;
    422         REPORTER_ASSERT(reporter, !SkBitmapCache::Find(desc, &cachedBitmap));
    423     }
    424 
    425     surface->getCanvas()->drawImage(image, 0, 0);
    426     {
    427         SkBitmap cachedBitmap;
    428         if (SkBitmapCache::Find(desc, &cachedBitmap)) {
    429             REPORTER_ASSERT(reporter, cachedBitmap.getGenerationID() == uniqueID);
    430             REPORTER_ASSERT(reporter, cachedBitmap.isImmutable());
    431             REPORTER_ASSERT(reporter, cachedBitmap.getPixels());
    432         } else {
    433             // unexpected, but not really a bug, since the cache is global and this test may be
    434             // run w/ other threads competing for its budget.
    435             SkDebugf("SkImage_Gpu2Cpu : cachedBitmap was already purged\n");
    436         }
    437     }
    438 
    439     image.reset(nullptr);
    440     {
    441         SkBitmap cachedBitmap;
    442         REPORTER_ASSERT(reporter, !SkBitmapCache::Find(desc, &cachedBitmap));
    443     }
    444 }
    445 
    446 GrContextFactory::ContextType pick_second_context_type(const sk_gpu_test::ContextInfo& info) {
    447     switch (info.backend()) {
    448         case kOpenGL_GrBackend:
    449 #if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_UNIX) || defined (SK_BUILD_FOR_MAC)
    450             return GrContextFactory::kGL_ContextType;
    451 #else
    452             return GrContextFactory::kGLES_ContextType;
    453 #endif
    454         case kVulkan_GrBackend:
    455             return GrContextFactory::kVulkan_ContextType;
    456     }
    457     SkFAIL("Unknown backend type.");
    458     return GrContextFactory::kGL_ContextType;
    459 }
    460 
    461 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkImage_makeTextureImage, reporter, contextInfo) {
    462     GrContext* context = contextInfo.grContext();
    463     sk_gpu_test::TestContext* testContext = contextInfo.testContext();
    464     GrContextFactory otherFactory;
    465     GrContextFactory::ContextType otherContextType = pick_second_context_type(contextInfo);
    466     ContextInfo otherContextInfo = otherFactory.getContextInfo(otherContextType);
    467     testContext->makeCurrent();
    468 
    469     std::function<sk_sp<SkImage>()> imageFactories[] = {
    470         create_image,
    471         create_codec_image,
    472         create_data_image,
    473         // Create an image from a picture.
    474         create_picture_image,
    475         // Create a texture image.
    476         [context] { return create_gpu_image(context); },
    477         // Create a texture image in a another GrContext.
    478         [testContext, otherContextInfo] {
    479             otherContextInfo.testContext()->makeCurrent();
    480             sk_sp<SkImage> otherContextImage = create_gpu_image(otherContextInfo.grContext());
    481             testContext->makeCurrent();
    482             return otherContextImage;
    483         }
    484     };
    485 
    486     sk_sp<SkColorSpace> dstColorSpaces[] ={
    487         nullptr,
    488         SkColorSpace::MakeSRGB(),
    489     };
    490 
    491     for (auto& dstColorSpace : dstColorSpaces) {
    492         for (auto factory : imageFactories) {
    493             sk_sp<SkImage> image(factory());
    494             if (!image) {
    495                 ERRORF(reporter, "Error creating image.");
    496                 continue;
    497             }
    498             GrTexture* origTexture = as_IB(image)->peekTexture();
    499 
    500             sk_sp<SkImage> texImage(image->makeTextureImage(context, dstColorSpace.get()));
    501             if (!texImage) {
    502                 // We expect to fail if image comes from a different GrContext.
    503                 if (!origTexture || origTexture->getContext() == context) {
    504                     ERRORF(reporter, "makeTextureImage failed.");
    505                 }
    506                 continue;
    507             }
    508             GrTexture* copyTexture = as_IB(texImage)->peekTexture();
    509             if (!copyTexture) {
    510                 ERRORF(reporter, "makeTextureImage returned non-texture image.");
    511                 continue;
    512             }
    513             if (origTexture) {
    514                 if (origTexture != copyTexture) {
    515                     ERRORF(reporter, "makeTextureImage made unnecessary texture copy.");
    516                 }
    517             }
    518             if (image->width() != texImage->width() || image->height() != texImage->height()) {
    519                 ERRORF(reporter, "makeTextureImage changed the image size.");
    520             }
    521             if (image->alphaType() != texImage->alphaType()) {
    522                 ERRORF(reporter, "makeTextureImage changed image alpha type.");
    523             }
    524         }
    525     }
    526 }
    527 
    528 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkImage_makeNonTextureImage, reporter, contextInfo) {
    529     GrContext* context = contextInfo.grContext();
    530 
    531     std::function<sk_sp<SkImage>()> imageFactories[] = {
    532         create_image,
    533         create_codec_image,
    534         create_data_image,
    535         create_picture_image,
    536         [context] { return create_gpu_image(context); },
    537     };
    538     SkColorSpace* legacyColorSpace = nullptr;
    539     for (auto factory : imageFactories) {
    540         sk_sp<SkImage> image = factory();
    541         if (!image->isTextureBacked()) {
    542             REPORTER_ASSERT(reporter, image->makeNonTextureImage().get() == image.get());
    543             if (!(image = image->makeTextureImage(context, legacyColorSpace))) {
    544                 continue;
    545             }
    546         }
    547         auto rasterImage = image->makeNonTextureImage();
    548         if (!rasterImage) {
    549             ERRORF(reporter, "makeNonTextureImage failed for texture-backed image.");
    550         }
    551         REPORTER_ASSERT(reporter, !rasterImage->isTextureBacked());
    552         assert_equal(reporter, image.get(), nullptr, rasterImage.get());
    553     }
    554 }
    555 
    556 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkImage_drawAbandonedGpuImage, reporter, contextInfo) {
    557     auto context = contextInfo.grContext();
    558     auto image = create_gpu_image(context);
    559     auto info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
    560     auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
    561     as_IB(image)->peekTexture()->abandon();
    562     surface->getCanvas()->drawImage(image, 0, 0);
    563 }
    564 
    565 #endif
    566 
    567 // https://bug.skia.org/4390
    568 DEF_TEST(ImageFromIndex8Bitmap, r) {
    569     SkPMColor pmColors[1] = {SkPreMultiplyColor(SK_ColorWHITE)};
    570     SkBitmap bm;
    571     sk_sp<SkColorTable> ctable( new SkColorTable(pmColors, SK_ARRAY_COUNT(pmColors)));
    572     SkImageInfo info = SkImageInfo::Make(1, 1, kIndex_8_SkColorType, kPremul_SkAlphaType);
    573     bm.allocPixels(info, nullptr, ctable.get());
    574     SkAutoLockPixels autoLockPixels(bm);
    575     *bm.getAddr8(0, 0) = 0;
    576     sk_sp<SkImage> img(SkImage::MakeFromBitmap(bm));
    577     REPORTER_ASSERT(r, img != nullptr);
    578 }
    579 
    580 class EmptyGenerator : public SkImageGenerator {
    581 public:
    582     EmptyGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {}
    583 };
    584 
    585 DEF_TEST(ImageEmpty, reporter) {
    586     const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_SkAlphaType);
    587     SkPixmap pmap(info, nullptr, 0);
    588     REPORTER_ASSERT(reporter, nullptr == SkImage::MakeRasterCopy(pmap));
    589     REPORTER_ASSERT(reporter, nullptr == SkImage::MakeRasterData(info, nullptr, 0));
    590     REPORTER_ASSERT(reporter, nullptr == SkImage::MakeFromRaster(pmap, nullptr, nullptr));
    591     REPORTER_ASSERT(reporter, nullptr == SkImage::MakeFromGenerator(
    592                                                             skstd::make_unique<EmptyGenerator>()));
    593 }
    594 
    595 DEF_TEST(ImageDataRef, reporter) {
    596     SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
    597     size_t rowBytes = info.minRowBytes();
    598     size_t size = info.getSafeSize(rowBytes);
    599     sk_sp<SkData> data = SkData::MakeUninitialized(size);
    600     REPORTER_ASSERT(reporter, data->unique());
    601     sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, rowBytes);
    602     REPORTER_ASSERT(reporter, !data->unique());
    603     image.reset();
    604     REPORTER_ASSERT(reporter, data->unique());
    605 }
    606 
    607 static bool has_pixels(const SkPMColor pixels[], int count, SkPMColor expected) {
    608     for (int i = 0; i < count; ++i) {
    609         if (pixels[i] != expected) {
    610             return false;
    611         }
    612     }
    613     return true;
    614 }
    615 
    616 static void image_test_read_pixels(skiatest::Reporter* reporter, SkImage* image) {
    617     if (!image) {
    618         ERRORF(reporter, "Failed to create image!");
    619         return;
    620     }
    621     const SkPMColor expected = SkPreMultiplyColor(SK_ColorWHITE);
    622     const SkPMColor notExpected = ~expected;
    623 
    624     const int w = 2, h = 2;
    625     const size_t rowBytes = w * sizeof(SkPMColor);
    626     SkPMColor pixels[w*h];
    627 
    628     SkImageInfo info;
    629 
    630     info = SkImageInfo::MakeUnknown(w, h);
    631     REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0));
    632 
    633     // out-of-bounds should fail
    634     info = SkImageInfo::MakeN32Premul(w, h);
    635     REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0));
    636     REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h));
    637     REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->width(), 0));
    638     REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, image->height()));
    639 
    640     // top-left should succeed
    641     sk_memset32(pixels, notExpected, w*h);
    642     REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0));
    643     REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
    644 
    645     // bottom-right should succeed
    646     sk_memset32(pixels, notExpected, w*h);
    647     REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
    648                                                 image->width() - w, image->height() - h));
    649     REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));
    650 
    651     // partial top-left should succeed
    652     sk_memset32(pixels, notExpected, w*h);
    653     REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1));
    654     REPORTER_ASSERT(reporter, pixels[3] == expected);
    655     REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));
    656 
    657     // partial bottom-right should succeed
    658     sk_memset32(pixels, notExpected, w*h);
    659     REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
    660                                                 image->width() - 1, image->height() - 1));
    661     REPORTER_ASSERT(reporter, pixels[0] == expected);
    662     REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
    663 }
    664 DEF_TEST(ImageReadPixels, reporter) {
    665     sk_sp<SkImage> image(create_image());
    666     image_test_read_pixels(reporter, image.get());
    667 
    668     image = create_data_image();
    669     image_test_read_pixels(reporter, image.get());
    670 
    671     RasterDataHolder dataHolder;
    672     image = create_rasterproc_image(&dataHolder);
    673     image_test_read_pixels(reporter, image.get());
    674     image.reset();
    675     REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
    676 
    677     image = create_codec_image();
    678     image_test_read_pixels(reporter, image.get());
    679 }
    680 #if SK_SUPPORT_GPU
    681 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageReadPixels_Gpu, reporter, ctxInfo) {
    682     image_test_read_pixels(reporter, create_gpu_image(ctxInfo.grContext()).get());
    683 }
    684 #endif
    685 
    686 static void check_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image,
    687                                 const SkBitmap& bitmap, SkImage::LegacyBitmapMode mode) {
    688     REPORTER_ASSERT(reporter, image->width() == bitmap.width());
    689     REPORTER_ASSERT(reporter, image->height() == bitmap.height());
    690     REPORTER_ASSERT(reporter, image->alphaType() == bitmap.alphaType());
    691 
    692     if (SkImage::kRO_LegacyBitmapMode == mode) {
    693         REPORTER_ASSERT(reporter, bitmap.isImmutable());
    694     }
    695 
    696     SkAutoLockPixels alp(bitmap);
    697     REPORTER_ASSERT(reporter, bitmap.getPixels());
    698 
    699     const SkImageInfo info = SkImageInfo::MakeN32(1, 1, bitmap.alphaType());
    700     SkPMColor imageColor;
    701     REPORTER_ASSERT(reporter, image->readPixels(info, &imageColor, sizeof(SkPMColor), 0, 0));
    702     REPORTER_ASSERT(reporter, imageColor == *bitmap.getAddr32(0, 0));
    703 }
    704 
    705 static void test_legacy_bitmap(skiatest::Reporter* reporter, const SkImage* image, SkImage::LegacyBitmapMode mode) {
    706     if (!image) {
    707         ERRORF(reporter, "Failed to create image.");
    708         return;
    709     }
    710     SkBitmap bitmap;
    711     REPORTER_ASSERT(reporter, image->asLegacyBitmap(&bitmap, mode));
    712     check_legacy_bitmap(reporter, image, bitmap, mode);
    713 
    714     // Test subsetting to exercise the rowBytes logic.
    715     SkBitmap tmp;
    716     REPORTER_ASSERT(reporter, bitmap.extractSubset(&tmp, SkIRect::MakeWH(image->width() / 2,
    717                                                                          image->height() / 2)));
    718     sk_sp<SkImage> subsetImage(SkImage::MakeFromBitmap(tmp));
    719     REPORTER_ASSERT(reporter, subsetImage.get());
    720 
    721     SkBitmap subsetBitmap;
    722     REPORTER_ASSERT(reporter, subsetImage->asLegacyBitmap(&subsetBitmap, mode));
    723     check_legacy_bitmap(reporter, subsetImage.get(), subsetBitmap, mode);
    724 }
    725 DEF_TEST(ImageLegacyBitmap, reporter) {
    726     const SkImage::LegacyBitmapMode modes[] = {
    727         SkImage::kRO_LegacyBitmapMode,
    728         SkImage::kRW_LegacyBitmapMode,
    729     };
    730     for (auto& mode : modes) {
    731         sk_sp<SkImage> image(create_image());
    732         test_legacy_bitmap(reporter, image.get(), mode);
    733 
    734         image = create_data_image();
    735         test_legacy_bitmap(reporter, image.get(), mode);
    736 
    737         RasterDataHolder dataHolder;
    738         image = create_rasterproc_image(&dataHolder);
    739         test_legacy_bitmap(reporter, image.get(), mode);
    740         image.reset();
    741         REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
    742 
    743         image = create_codec_image();
    744         test_legacy_bitmap(reporter, image.get(), mode);
    745     }
    746 }
    747 #if SK_SUPPORT_GPU
    748 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageLegacyBitmap_Gpu, reporter, ctxInfo) {
    749     const SkImage::LegacyBitmapMode modes[] = {
    750         SkImage::kRO_LegacyBitmapMode,
    751         SkImage::kRW_LegacyBitmapMode,
    752     };
    753     for (auto& mode : modes) {
    754         sk_sp<SkImage> image(create_gpu_image(ctxInfo.grContext()));
    755         test_legacy_bitmap(reporter, image.get(), mode);
    756     }
    757 }
    758 #endif
    759 
    760 static void test_peek(skiatest::Reporter* reporter, SkImage* image, bool expectPeekSuccess) {
    761     if (!image) {
    762         ERRORF(reporter, "Failed to create image!");
    763         return;
    764     }
    765     SkPixmap pm;
    766     bool success = image->peekPixels(&pm);
    767     REPORTER_ASSERT(reporter, expectPeekSuccess == success);
    768     if (success) {
    769         const SkImageInfo& info = pm.info();
    770         REPORTER_ASSERT(reporter, 20 == info.width());
    771         REPORTER_ASSERT(reporter, 20 == info.height());
    772         REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
    773         REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
    774                         kOpaque_SkAlphaType == info.alphaType());
    775         REPORTER_ASSERT(reporter, info.minRowBytes() <= pm.rowBytes());
    776         REPORTER_ASSERT(reporter, SkPreMultiplyColor(SK_ColorWHITE) == *pm.addr32(0, 0));
    777     }
    778 }
    779 DEF_TEST(ImagePeek, reporter) {
    780     sk_sp<SkImage> image(create_image());
    781     test_peek(reporter, image.get(), true);
    782 
    783     image = create_data_image();
    784     test_peek(reporter, image.get(), true);
    785 
    786     RasterDataHolder dataHolder;
    787     image = create_rasterproc_image(&dataHolder);
    788     test_peek(reporter, image.get(), true);
    789     image.reset();
    790     REPORTER_ASSERT(reporter, 1 == dataHolder.fReleaseCount);
    791 
    792     image = create_codec_image();
    793     test_peek(reporter, image.get(), false);
    794 }
    795 #if SK_SUPPORT_GPU
    796 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImagePeek_Gpu, reporter, ctxInfo) {
    797     sk_sp<SkImage> image(create_gpu_image(ctxInfo.grContext()));
    798     test_peek(reporter, image.get(), false);
    799 }
    800 #endif
    801 
    802 #if SK_SUPPORT_GPU
    803 struct TextureReleaseChecker {
    804     TextureReleaseChecker() : fReleaseCount(0) {}
    805     int fReleaseCount;
    806     static void Release(void* self) {
    807         static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
    808     }
    809 };
    810 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkImage_NewFromTextureRelease, reporter, ctxInfo) {
    811     const int kWidth = 10;
    812     const int kHeight = 10;
    813     std::unique_ptr<uint32_t[]> pixels(new uint32_t[kWidth * kHeight]);
    814     GrBackendTextureDesc backendDesc;
    815     backendDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
    816     backendDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
    817     backendDesc.fConfig = kRGBA_8888_GrPixelConfig;
    818     backendDesc.fWidth = kWidth;
    819     backendDesc.fHeight = kHeight;
    820     backendDesc.fSampleCnt = 0;
    821     backendDesc.fTextureHandle = ctxInfo.grContext()->getGpu()->createTestingOnlyBackendTexture(
    822         pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig, true);
    823 
    824     TextureReleaseChecker releaseChecker;
    825     sk_sp<SkImage> refImg(
    826         SkImage::MakeFromTexture(ctxInfo.grContext(), backendDesc, kPremul_SkAlphaType,
    827                                  TextureReleaseChecker::Release, &releaseChecker));
    828 
    829     GrSurfaceOrigin readBackOrigin;
    830     GrBackendObject readBackHandle = refImg->getTextureHandle(false, &readBackOrigin);
    831     // TODO: Make it so we can check this (see skbug.com/5019)
    832 #if 0
    833     if (*readBackHandle != *(backendDesc.fTextureHandle)) {
    834         ERRORF(reporter, "backend mismatch %d %d\n",
    835                        (int)readBackHandle, (int)backendDesc.fTextureHandle);
    836     }
    837     REPORTER_ASSERT(reporter, readBackHandle == backendDesc.fTextureHandle);
    838 #else
    839     REPORTER_ASSERT(reporter, SkToBool(readBackHandle));
    840 #endif
    841     if (readBackOrigin != backendDesc.fOrigin) {
    842         ERRORF(reporter, "origin mismatch %d %d\n", readBackOrigin, backendDesc.fOrigin);
    843     }
    844     REPORTER_ASSERT(reporter, readBackOrigin == backendDesc.fOrigin);
    845 
    846     // Now exercise the release proc
    847     REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
    848     refImg.reset(nullptr); // force a release of the image
    849     REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
    850 
    851     ctxInfo.grContext()->getGpu()->deleteTestingOnlyBackendTexture(backendDesc.fTextureHandle);
    852 }
    853 
    854 static void check_images_same(skiatest::Reporter* reporter, const SkImage* a, const SkImage* b) {
    855     if (a->width() != b->width() || a->height() != b->height()) {
    856         ERRORF(reporter, "Images must have the same size");
    857         return;
    858     }
    859     if (a->alphaType() != b->alphaType()) {
    860         ERRORF(reporter, "Images must have the same alpha type");
    861         return;
    862     }
    863 
    864     SkImageInfo info = SkImageInfo::MakeN32Premul(a->width(), a->height());
    865     SkAutoPixmapStorage apm;
    866     SkAutoPixmapStorage bpm;
    867 
    868     apm.alloc(info);
    869     bpm.alloc(info);
    870 
    871     if (!a->readPixels(apm, 0, 0)) {
    872         ERRORF(reporter, "Could not read image a's pixels");
    873         return;
    874     }
    875     if (!b->readPixels(bpm, 0, 0)) {
    876         ERRORF(reporter, "Could not read image b's pixels");
    877         return;
    878     }
    879 
    880     for (auto y = 0; y < info.height(); ++y) {
    881         for (auto x = 0; x < info.width(); ++x) {
    882             uint32_t pixelA = *apm.addr32(x, y);
    883             uint32_t pixelB = *bpm.addr32(x, y);
    884             if (pixelA != pixelB) {
    885                 ERRORF(reporter, "Expected image pixels to be the same. At %d,%d 0x%08x != 0x%08x",
    886                        x, y, pixelA, pixelB);
    887                 return;
    888             }
    889         }
    890     }
    891 }
    892 
    893 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredTextureImage, reporter, ctxInfo) {
    894     GrContext* context = ctxInfo.grContext();
    895     sk_gpu_test::TestContext* testContext = ctxInfo.testContext();
    896     sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy();
    897 
    898     GrContextFactory otherFactory;
    899     ContextInfo otherContextInfo =
    900         otherFactory.getContextInfo(pick_second_context_type(ctxInfo));
    901 
    902     testContext->makeCurrent();
    903     REPORTER_ASSERT(reporter, proxy);
    904     auto createLarge = [context] {
    905         return create_image_large(context->caps()->maxTextureSize());
    906     };
    907     struct {
    908         std::function<sk_sp<SkImage> ()>                      fImageFactory;
    909         std::vector<SkImage::DeferredTextureImageUsageParams> fParams;
    910         SkFilterQuality                                       fExpectedQuality;
    911         int                                                   fExpectedScaleFactor;
    912         bool                                                  fExpectation;
    913     } testCases[] = {
    914         { create_image,          {{SkMatrix::I(), kNone_SkFilterQuality, 0}},
    915           kNone_SkFilterQuality, 1, true },
    916         { create_codec_image,    {{SkMatrix::I(), kNone_SkFilterQuality, 0}},
    917           kNone_SkFilterQuality, 1, true },
    918         { create_data_image,     {{SkMatrix::I(), kNone_SkFilterQuality, 0}},
    919           kNone_SkFilterQuality, 1, true },
    920         { create_picture_image,  {{SkMatrix::I(), kNone_SkFilterQuality, 0}},
    921           kNone_SkFilterQuality, 1, false },
    922         { [context] { return create_gpu_image(context); },
    923           {{SkMatrix::I(), kNone_SkFilterQuality, 0}},
    924           kNone_SkFilterQuality, 1, false },
    925         // Create a texture image in a another GrContext.
    926         { [testContext, otherContextInfo] {
    927             otherContextInfo.testContext()->makeCurrent();
    928             sk_sp<SkImage> otherContextImage = create_gpu_image(otherContextInfo.grContext());
    929             testContext->makeCurrent();
    930             return otherContextImage;
    931           }, {{SkMatrix::I(), kNone_SkFilterQuality, 0}},
    932           kNone_SkFilterQuality, 1, false },
    933         // Create an image that is too large to upload.
    934         { createLarge, {{SkMatrix::I(), kNone_SkFilterQuality, 0}},
    935           kNone_SkFilterQuality, 1, false },
    936         // Create an image that is too large, but is scaled to an acceptable size.
    937         { createLarge, {{SkMatrix::I(), kMedium_SkFilterQuality, 4}},
    938           kMedium_SkFilterQuality, 16, true},
    939         // Create an image with multiple low filter qualities, make sure we round up.
    940         { createLarge, {{SkMatrix::I(), kNone_SkFilterQuality, 4},
    941                         {SkMatrix::I(), kMedium_SkFilterQuality, 4}},
    942           kMedium_SkFilterQuality, 16, true},
    943         // Create an image with multiple prescale levels, make sure we chose the minimum scale.
    944         { createLarge, {{SkMatrix::I(), kMedium_SkFilterQuality, 5},
    945                         {SkMatrix::I(), kMedium_SkFilterQuality, 4}},
    946           kMedium_SkFilterQuality, 16, true},
    947     };
    948 
    949 
    950     for (auto testCase : testCases) {
    951         sk_sp<SkImage> image(testCase.fImageFactory());
    952         if (!image) {
    953             ERRORF(reporter, "Failed to create image!");
    954             continue;
    955         }
    956 
    957         size_t size = image->getDeferredTextureImageData(*proxy, testCase.fParams.data(),
    958                                                          static_cast<int>(testCase.fParams.size()),
    959                                                          nullptr, nullptr);
    960         static const char *const kFS[] = { "fail", "succeed" };
    961         if (SkToBool(size) != testCase.fExpectation) {
    962             ERRORF(reporter,  "This image was expected to %s but did not.",
    963                    kFS[testCase.fExpectation]);
    964         }
    965         if (size) {
    966             void* buffer = sk_malloc_throw(size);
    967             void* misaligned = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(buffer) + 3);
    968             if (image->getDeferredTextureImageData(*proxy, testCase.fParams.data(),
    969                                                    static_cast<int>(testCase.fParams.size()),
    970                                                    misaligned, nullptr)) {
    971                 ERRORF(reporter, "Should fail when buffer is misaligned.");
    972             }
    973             if (!image->getDeferredTextureImageData(*proxy, testCase.fParams.data(),
    974                                                     static_cast<int>(testCase.fParams.size()),
    975                                                     buffer, nullptr)) {
    976                 ERRORF(reporter, "deferred image size succeeded but creation failed.");
    977             } else {
    978                 for (auto budgeted : { SkBudgeted::kNo, SkBudgeted::kYes }) {
    979                     sk_sp<SkImage> newImage(
    980                         SkImage::MakeFromDeferredTextureImageData(context, buffer, budgeted));
    981                     REPORTER_ASSERT(reporter, newImage != nullptr);
    982                     if (newImage) {
    983                         // Scale the image in software for comparison.
    984                         SkImageInfo scaled_info = SkImageInfo::MakeN32(
    985                                                     image->width() / testCase.fExpectedScaleFactor,
    986                                                     image->height() / testCase.fExpectedScaleFactor,
    987                                                     image->alphaType());
    988                         SkAutoPixmapStorage scaled;
    989                         scaled.alloc(scaled_info);
    990                         image->scalePixels(scaled, testCase.fExpectedQuality);
    991                         sk_sp<SkImage> scaledImage = SkImage::MakeRasterCopy(scaled);
    992                         check_images_same(reporter, scaledImage.get(), newImage.get());
    993                     }
    994                     // The other context should not be able to create images from texture data
    995                     // created by the original context.
    996                     sk_sp<SkImage> newImage2(SkImage::MakeFromDeferredTextureImageData(
    997                         otherContextInfo.grContext(), buffer, budgeted));
    998                     REPORTER_ASSERT(reporter, !newImage2);
    999                     testContext->makeCurrent();
   1000                 }
   1001             }
   1002             sk_free(buffer);
   1003         }
   1004     }
   1005 }
   1006 #endif
   1007 
   1008 ///////////////////////////////////////////////////////////////////////////////////////////////////
   1009 
   1010 static sk_sp<SkImage> create_picture_image(sk_sp<SkColorSpace> space) {
   1011     SkPictureRecorder recorder;
   1012     SkCanvas* canvas = recorder.beginRecording(10, 10);
   1013     canvas->clear(SK_ColorCYAN);
   1014     return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(), SkISize::Make(10, 10),
   1015                                     nullptr, nullptr, SkImage::BitDepth::kU8, std::move(space));
   1016 };
   1017 
   1018 static inline bool almost_equal(int a, int b) {
   1019     return SkTAbs(a - b) <= 1;
   1020 }
   1021 
   1022 DEF_TEST(Image_ColorSpace, r) {
   1023     sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
   1024     sk_sp<SkImage> image = GetResourceAsImage("mandrill_512_q075.jpg");
   1025     REPORTER_ASSERT(r, srgb.get() == image->colorSpace());
   1026 
   1027     image = GetResourceAsImage("webp-color-profile-lossy.webp");
   1028     SkColorSpaceTransferFn fn;
   1029     bool success = image->colorSpace()->isNumericalTransferFn(&fn);
   1030     REPORTER_ASSERT(r, success);
   1031     REPORTER_ASSERT(r, color_space_almost_equal(1.8f, fn.fG));
   1032 
   1033     sk_sp<SkColorSpace> rec2020 = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
   1034                                                         SkColorSpace::kRec2020_Gamut);
   1035     image = create_picture_image(rec2020);
   1036     REPORTER_ASSERT(r, SkColorSpace::Equals(rec2020.get(), image->colorSpace()));
   1037 
   1038     SkBitmap bitmap;
   1039     SkImageInfo info = SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, rec2020);
   1040     bitmap.allocPixels(info);
   1041     image = SkImage::MakeFromBitmap(bitmap);
   1042     REPORTER_ASSERT(r, SkColorSpace::Equals(rec2020.get(), image->colorSpace()));
   1043 
   1044     sk_sp<SkSurface> surface = SkSurface::MakeRaster(
   1045             SkImageInfo::MakeN32Premul(SkISize::Make(10, 10)));
   1046     image = surface->makeImageSnapshot();
   1047     REPORTER_ASSERT(r, nullptr == image->colorSpace());
   1048 
   1049     surface = SkSurface::MakeRaster(info);
   1050     image = surface->makeImageSnapshot();
   1051     REPORTER_ASSERT(r, SkColorSpace::Equals(rec2020.get(), image->colorSpace()));
   1052 }
   1053 
   1054 DEF_TEST(Image_makeColorSpace, r) {
   1055     sk_sp<SkColorSpace> p3 = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
   1056                                                    SkColorSpace::kDCIP3_D65_Gamut);
   1057     SkColorSpaceTransferFn fn;
   1058     fn.fA = 1.f; fn.fB = 0.f; fn.fC = 0.f; fn.fD = 0.f; fn.fE = 0.f; fn.fF = 0.f; fn.fG = 1.8f;
   1059     sk_sp<SkColorSpace> adobeGamut = SkColorSpace::MakeRGB(fn, SkColorSpace::kAdobeRGB_Gamut);
   1060 
   1061     SkBitmap srgbBitmap;
   1062     srgbBitmap.allocPixels(SkImageInfo::MakeS32(1, 1, kOpaque_SkAlphaType));
   1063     *srgbBitmap.getAddr32(0, 0) = SkSwizzle_RGBA_to_PMColor(0xFF604020);
   1064     srgbBitmap.setImmutable();
   1065     sk_sp<SkImage> srgbImage = SkImage::MakeFromBitmap(srgbBitmap);
   1066     sk_sp<SkImage> p3Image = as_IB(srgbImage)->makeColorSpace(p3);
   1067     SkBitmap p3Bitmap;
   1068     bool success = p3Image->asLegacyBitmap(&p3Bitmap, SkImage::kRO_LegacyBitmapMode);
   1069     REPORTER_ASSERT(r, success);
   1070     p3Bitmap.lockPixels();
   1071     REPORTER_ASSERT(r, almost_equal(0x28, SkGetPackedR32(*p3Bitmap.getAddr32(0, 0))));
   1072     REPORTER_ASSERT(r, almost_equal(0x40, SkGetPackedG32(*p3Bitmap.getAddr32(0, 0))));
   1073     REPORTER_ASSERT(r, almost_equal(0x5E, SkGetPackedB32(*p3Bitmap.getAddr32(0, 0))));
   1074 
   1075     sk_sp<SkImage> adobeImage = as_IB(srgbImage)->makeColorSpace(adobeGamut);
   1076     SkBitmap adobeBitmap;
   1077     success = adobeImage->asLegacyBitmap(&adobeBitmap, SkImage::kRO_LegacyBitmapMode);
   1078     REPORTER_ASSERT(r, success);
   1079     adobeBitmap.lockPixels();
   1080     REPORTER_ASSERT(r, almost_equal(0x21, SkGetPackedR32(*adobeBitmap.getAddr32(0, 0))));
   1081     REPORTER_ASSERT(r, almost_equal(0x31, SkGetPackedG32(*adobeBitmap.getAddr32(0, 0))));
   1082     REPORTER_ASSERT(r, almost_equal(0x4C, SkGetPackedB32(*adobeBitmap.getAddr32(0, 0))));
   1083 
   1084     srgbImage = GetResourceAsImage("1x1.png");
   1085     p3Image = as_IB(srgbImage)->makeColorSpace(p3);
   1086     success = p3Image->asLegacyBitmap(&p3Bitmap, SkImage::kRO_LegacyBitmapMode);
   1087     REPORTER_ASSERT(r, success);
   1088     p3Bitmap.lockPixels();
   1089     REPORTER_ASSERT(r, almost_equal(0x8B, SkGetPackedR32(*p3Bitmap.getAddr32(0, 0))));
   1090     REPORTER_ASSERT(r, almost_equal(0x82, SkGetPackedG32(*p3Bitmap.getAddr32(0, 0))));
   1091     REPORTER_ASSERT(r, almost_equal(0x77, SkGetPackedB32(*p3Bitmap.getAddr32(0, 0))));
   1092 }
   1093 
   1094 ///////////////////////////////////////////////////////////////////////////////////////////////////
   1095 
   1096 static void make_all_premul(SkBitmap* bm) {
   1097     bm->allocPixels(SkImageInfo::MakeN32(256, 256, kPremul_SkAlphaType));
   1098     for (int a = 0; a < 256; ++a) {
   1099         for (int r = 0; r < 256; ++r) {
   1100             // make all valid premul combinations
   1101             int c = SkTMin(a, r);
   1102             *bm->getAddr32(a, r) = SkPackARGB32(a, c, c, c);
   1103         }
   1104     }
   1105 }
   1106 
   1107 static bool equal(const SkBitmap& a, const SkBitmap& b) {
   1108     SkASSERT(a.width() == b.width());
   1109     SkASSERT(a.height() == b.height());
   1110     for (int y = 0; y < a.height(); ++y) {
   1111         for (int x = 0; x < a.width(); ++x) {
   1112             SkPMColor pa = *a.getAddr32(x, y);
   1113             SkPMColor pb = *b.getAddr32(x, y);
   1114             if (pa != pb) {
   1115                 return false;
   1116             }
   1117         }
   1118     }
   1119     return true;
   1120 }
   1121 
   1122 DEF_TEST(image_roundtrip_encode, reporter) {
   1123     SkBitmap bm0;
   1124     make_all_premul(&bm0);
   1125 
   1126     auto img0 = SkImage::MakeFromBitmap(bm0);
   1127     sk_sp<SkData> data(img0->encode(SkEncodedImageFormat::kPNG, 100));
   1128     auto img1 = SkImage::MakeFromEncoded(data);
   1129 
   1130     SkBitmap bm1;
   1131     bm1.allocPixels(SkImageInfo::MakeN32(256, 256, kPremul_SkAlphaType));
   1132     img1->readPixels(bm1.info(), bm1.getPixels(), bm1.rowBytes(), 0, 0);
   1133 
   1134     REPORTER_ASSERT(reporter, equal(bm0, bm1));
   1135 }
   1136 
   1137 DEF_TEST(image_roundtrip_premul, reporter) {
   1138     SkBitmap bm0;
   1139     make_all_premul(&bm0);
   1140 
   1141     SkBitmap bm1;
   1142     bm1.allocPixels(SkImageInfo::MakeN32(256, 256, kUnpremul_SkAlphaType));
   1143     bm0.readPixels(bm1.info(), bm1.getPixels(), bm1.rowBytes(), 0, 0);
   1144 
   1145     SkBitmap bm2;
   1146     bm2.allocPixels(SkImageInfo::MakeN32(256, 256, kPremul_SkAlphaType));
   1147     bm1.readPixels(bm2.info(), bm2.getPixels(), bm2.rowBytes(), 0, 0);
   1148 
   1149     REPORTER_ASSERT(reporter, equal(bm0, bm2));
   1150 }
   1151