Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2016 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 "Resources.h"
      9 #include "SkCanvas.h"
     10 #include "SkPipe.h"
     11 #include "SkPaint.h"
     12 #include "SkStream.h"
     13 #include "SkSurface.h"
     14 #include "Test.h"
     15 
     16 #include "SkNullCanvas.h"
     17 #include "SkAutoPixmapStorage.h"
     18 #include "SkPictureRecorder.h"
     19 
     20 static void drain(SkPipeDeserializer* deserial, SkDynamicMemoryWStream* stream) {
     21     std::unique_ptr<SkCanvas> canvas = SkMakeNullCanvas();
     22     sk_sp<SkData> data = stream->detachAsData();
     23     deserial->playback(data->data(), data->size(), canvas.get());
     24 }
     25 
     26 static bool deep_equal(SkImage* a, SkImage* b) {
     27     if (a->width() != b->width() || a->height() != b->height()) {
     28         return false;
     29     }
     30 
     31     const SkImageInfo info = SkImageInfo::MakeN32Premul(a->width(), a->height());
     32     SkAutoPixmapStorage pmapA, pmapB;
     33     pmapA.alloc(info);
     34     pmapB.alloc(info);
     35 
     36     if (!a->readPixels(pmapA, 0, 0) || !b->readPixels(pmapB, 0, 0)) {
     37         return false;
     38     }
     39 
     40     for (int y = 0; y < info.height(); ++y) {
     41         if (memcmp(pmapA.addr32(0, y), pmapB.addr32(0, y), info.width() * sizeof(SkPMColor))) {
     42             return false;
     43         }
     44     }
     45     return true;
     46 }
     47 
     48 DEF_TEST(Pipe_image_draw_first, reporter) {
     49     sk_sp<SkImage> img = GetResourceAsImage("images/mandrill_128.png");
     50     SkASSERT(img.get());
     51 
     52     SkPipeSerializer serializer;
     53     SkPipeDeserializer deserializer;
     54 
     55     SkDynamicMemoryWStream stream;
     56     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
     57     wc->drawImage(img, 0, 0, nullptr);
     58     serializer.endWrite();
     59     size_t offset0 = stream.bytesWritten();
     60     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw image must be sorta big
     61     drain(&deserializer, &stream);
     62 
     63     // try drawing the same image again -- it should be much smaller
     64     wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
     65     wc->drawImage(img, 0, 0, nullptr);
     66     size_t offset1 = stream.bytesWritten();
     67     serializer.endWrite();
     68     REPORTER_ASSERT(reporter, offset1 <= 32);
     69     drain(&deserializer, &stream);
     70 
     71     // try serializing the same image directly, again it should be small
     72     sk_sp<SkData> data = serializer.writeImage(img.get());
     73     size_t offset2 = data->size();
     74     REPORTER_ASSERT(reporter, offset2 <= 32);
     75     auto img1 = deserializer.readImage(data.get());
     76     REPORTER_ASSERT(reporter, deep_equal(img.get(), img1.get()));
     77 
     78     // try serializing the same image directly (again), check that it is the same!
     79     data = serializer.writeImage(img.get());
     80     size_t offset3 = data->size();
     81     REPORTER_ASSERT(reporter, offset3 <= 32);
     82     auto img2 = deserializer.readImage(data.get());
     83     REPORTER_ASSERT(reporter, img1.get() == img2.get());
     84 }
     85 
     86 DEF_TEST(Pipe_image_draw_second, reporter) {
     87     sk_sp<SkImage> img = GetResourceAsImage("images/mandrill_128.png");
     88     SkASSERT(img.get());
     89 
     90     SkPipeSerializer serializer;
     91     SkPipeDeserializer deserializer;
     92     SkDynamicMemoryWStream stream;
     93 
     94     sk_sp<SkData> data = serializer.writeImage(img.get());
     95     size_t offset0 = data->size();
     96     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw image must be sorta big
     97     auto img1 = deserializer.readImage(data.get());
     98 
     99     // The 2nd image should be nice and small
    100     data = serializer.writeImage(img.get());
    101     size_t offset1 = data->size();
    102     REPORTER_ASSERT(reporter, offset1 <= 16);
    103     auto img2 = deserializer.readImage(data.get());
    104     REPORTER_ASSERT(reporter, img1.get() == img2.get());
    105 
    106     // Now try drawing the image, it should also be small
    107     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
    108     wc->drawImage(img, 0, 0, nullptr);
    109     serializer.endWrite();
    110     size_t offset2 = stream.bytesWritten();
    111     REPORTER_ASSERT(reporter, offset2 <= 16);
    112 }
    113 
    114 DEF_TEST(Pipe_picture_draw_first, reporter) {
    115     sk_sp<SkPicture> picture = []() {
    116         SkPictureRecorder rec;
    117         SkCanvas* c = rec.beginRecording(SkRect::MakeWH(100, 100));
    118         for (int i = 0; i < 100; ++i) {
    119             c->drawColor(i);
    120         }
    121         return rec.finishRecordingAsPicture();
    122     }();
    123     SkPipeSerializer serializer;
    124     SkPipeDeserializer deserializer;
    125 
    126     SkDynamicMemoryWStream stream;
    127     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
    128     wc->drawPicture(picture);
    129     serializer.endWrite();
    130     size_t offset0 = stream.bytesWritten();
    131     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw picture must be sorta big
    132     drain(&deserializer, &stream);
    133 
    134     // try drawing the same picture again -- it should be much smaller
    135     wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
    136     wc->drawPicture(picture);
    137     size_t offset1 = stream.bytesWritten();
    138     serializer.endWrite();
    139     REPORTER_ASSERT(reporter, offset1 <= 16);
    140     drain(&deserializer, &stream);
    141 
    142     // try writing the picture directly, it should also be small
    143     sk_sp<SkData> data = serializer.writePicture(picture.get());
    144     size_t offset2 = data->size();
    145     REPORTER_ASSERT(reporter, offset2 <= 16);
    146     auto pic1 = deserializer.readPicture(data.get());
    147 
    148     // try writing the picture directly, it should also be small
    149     data = serializer.writePicture(picture.get());
    150     size_t offset3 = data->size();
    151     REPORTER_ASSERT(reporter, offset3 == offset2);
    152     auto pic2 = deserializer.readPicture(data.get());
    153     REPORTER_ASSERT(reporter, pic1.get() == pic2.get());
    154 }
    155 
    156 DEF_TEST(Pipe_picture_draw_second, reporter) {
    157     sk_sp<SkPicture> picture = []() {
    158         SkPictureRecorder rec;
    159         SkCanvas* c = rec.beginRecording(SkRect::MakeWH(100, 100));
    160         for (int i = 0; i < 100; ++i) {
    161             c->drawColor(i);
    162         }
    163         return rec.finishRecordingAsPicture();
    164     }();
    165     SkPipeSerializer serializer;
    166     SkPipeDeserializer deserializer;
    167     SkDynamicMemoryWStream stream;
    168 
    169     sk_sp<SkData> data = serializer.writePicture(picture.get());
    170     size_t offset0 = data->size();
    171     REPORTER_ASSERT(reporter, offset0 > 100);   // the raw picture must be sorta big
    172     auto pic1 = deserializer.readPicture(data.get());
    173 
    174     // The 2nd picture should be nice and small
    175     data = serializer.writePicture(picture.get());
    176     size_t offset1 = data->size();
    177     REPORTER_ASSERT(reporter, offset1 <= 16);
    178     auto pic2 = deserializer.readPicture(data.get());
    179     SkASSERT(pic1.get() == pic2.get());
    180 
    181     // Now try drawing the image, it should also be small
    182     SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
    183     wc->drawPicture(picture);
    184     serializer.endWrite();
    185     size_t offset2 = stream.bytesWritten();
    186     REPORTER_ASSERT(reporter, offset2 <= 16);
    187 }
    188