skia2/tests/PipeTest.cpp
Mike Reed 8240750718 Change SkCanvas to *not* inherit from SkRefCnt
Definitely tricky for classes like SkNWayCanvas, where the caller (today)
need not pay attention to ownership of the canvases it gave the NWay
(after this CL, the caller *must* managed ownership)

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4441

DOCS_PREVIEW= https://skia.org/?cl=4441

Change-Id: Ib1ac07a3cdf0686d78e7aaa4735d45cc90bea081
Reviewed-on: https://skia-review.googlesource.com/4441
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Robert Phillips <robertphillips@google.com>
2016-11-09 19:40:06 +00:00

188 lines
6.5 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Resources.h"
#include "SkCanvas.h"
#include "SkPipe.h"
#include "SkPaint.h"
#include "SkStream.h"
#include "SkSurface.h"
#include "Test.h"
#include "SkNullCanvas.h"
#include "SkAutoPixmapStorage.h"
#include "SkPictureRecorder.h"
static void drain(SkPipeDeserializer* deserial, SkDynamicMemoryWStream* stream) {
std::unique_ptr<SkCanvas> canvas = SkMakeNullCanvas();
sk_sp<SkData> data = stream->detachAsData();
deserial->playback(data->data(), data->size(), canvas.get());
}
static bool deep_equal(SkImage* a, SkImage* b) {
if (a->width() != b->width() || a->height() != b->height()) {
return false;
}
const SkImageInfo info = SkImageInfo::MakeN32Premul(a->width(), a->height());
SkAutoPixmapStorage pmapA, pmapB;
pmapA.alloc(info);
pmapB.alloc(info);
if (!a->readPixels(pmapA, 0, 0) || !b->readPixels(pmapB, 0, 0)) {
return false;
}
for (int y = 0; y < info.height(); ++y) {
if (memcmp(pmapA.addr32(0, y), pmapB.addr32(0, y), info.width() * sizeof(SkPMColor))) {
return false;
}
}
return true;
}
DEF_TEST(Pipe_image_draw_first, reporter) {
sk_sp<SkImage> img = GetResourceAsImage("mandrill_128.png");
SkASSERT(img.get());
SkPipeSerializer serializer;
SkPipeDeserializer deserializer;
SkDynamicMemoryWStream stream;
SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
wc->drawImage(img, 0, 0, nullptr);
serializer.endWrite();
size_t offset0 = stream.bytesWritten();
REPORTER_ASSERT(reporter, offset0 > 100); // the raw image must be sorta big
drain(&deserializer, &stream);
// try drawing the same image again -- it should be much smaller
wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
wc->drawImage(img, 0, 0, nullptr);
size_t offset1 = stream.bytesWritten();
serializer.endWrite();
REPORTER_ASSERT(reporter, offset1 <= 32);
drain(&deserializer, &stream);
// try serializing the same image directly, again it should be small
sk_sp<SkData> data = serializer.writeImage(img.get());
size_t offset2 = data->size();
REPORTER_ASSERT(reporter, offset2 <= 32);
auto img1 = deserializer.readImage(data.get());
REPORTER_ASSERT(reporter, deep_equal(img.get(), img1.get()));
// try serializing the same image directly (again), check that it is the same!
data = serializer.writeImage(img.get());
size_t offset3 = data->size();
REPORTER_ASSERT(reporter, offset3 <= 32);
auto img2 = deserializer.readImage(data.get());
REPORTER_ASSERT(reporter, img1.get() == img2.get());
}
DEF_TEST(Pipe_image_draw_second, reporter) {
sk_sp<SkImage> img = GetResourceAsImage("mandrill_128.png");
SkASSERT(img.get());
SkPipeSerializer serializer;
SkPipeDeserializer deserializer;
SkDynamicMemoryWStream stream;
sk_sp<SkData> data = serializer.writeImage(img.get());
size_t offset0 = data->size();
REPORTER_ASSERT(reporter, offset0 > 100); // the raw image must be sorta big
auto img1 = deserializer.readImage(data.get());
// The 2nd image should be nice and small
data = serializer.writeImage(img.get());
size_t offset1 = data->size();
REPORTER_ASSERT(reporter, offset1 <= 16);
auto img2 = deserializer.readImage(data.get());
REPORTER_ASSERT(reporter, img1.get() == img2.get());
// Now try drawing the image, it should also be small
SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
wc->drawImage(img, 0, 0, nullptr);
serializer.endWrite();
size_t offset2 = stream.bytesWritten();
REPORTER_ASSERT(reporter, offset2 <= 16);
}
DEF_TEST(Pipe_picture_draw_first, reporter) {
sk_sp<SkPicture> picture = []() {
SkPictureRecorder rec;
SkCanvas* c = rec.beginRecording(SkRect::MakeWH(100, 100));
for (int i = 0; i < 100; ++i) {
c->drawColor(i);
}
return rec.finishRecordingAsPicture();
}();
SkPipeSerializer serializer;
SkPipeDeserializer deserializer;
SkDynamicMemoryWStream stream;
SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
wc->drawPicture(picture);
serializer.endWrite();
size_t offset0 = stream.bytesWritten();
REPORTER_ASSERT(reporter, offset0 > 100); // the raw picture must be sorta big
drain(&deserializer, &stream);
// try drawing the same picture again -- it should be much smaller
wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
wc->drawPicture(picture);
size_t offset1 = stream.bytesWritten();
serializer.endWrite();
REPORTER_ASSERT(reporter, offset1 <= 16);
drain(&deserializer, &stream);
// try writing the picture directly, it should also be small
sk_sp<SkData> data = serializer.writePicture(picture.get());
size_t offset2 = data->size();
REPORTER_ASSERT(reporter, offset2 <= 16);
auto pic1 = deserializer.readPicture(data.get());
// try writing the picture directly, it should also be small
data = serializer.writePicture(picture.get());
size_t offset3 = data->size();
REPORTER_ASSERT(reporter, offset3 == offset2);
auto pic2 = deserializer.readPicture(data.get());
REPORTER_ASSERT(reporter, pic1.get() == pic2.get());
}
DEF_TEST(Pipe_picture_draw_second, reporter) {
sk_sp<SkPicture> picture = []() {
SkPictureRecorder rec;
SkCanvas* c = rec.beginRecording(SkRect::MakeWH(100, 100));
for (int i = 0; i < 100; ++i) {
c->drawColor(i);
}
return rec.finishRecordingAsPicture();
}();
SkPipeSerializer serializer;
SkPipeDeserializer deserializer;
SkDynamicMemoryWStream stream;
sk_sp<SkData> data = serializer.writePicture(picture.get());
size_t offset0 = data->size();
REPORTER_ASSERT(reporter, offset0 > 100); // the raw picture must be sorta big
auto pic1 = deserializer.readPicture(data.get());
// The 2nd picture should be nice and small
data = serializer.writePicture(picture.get());
size_t offset1 = data->size();
REPORTER_ASSERT(reporter, offset1 <= 16);
auto pic2 = deserializer.readPicture(data.get());
SkASSERT(pic1.get() == pic2.get());
// Now try drawing the image, it should also be small
SkCanvas* wc = serializer.beginWrite(SkRect::MakeWH(100, 100), &stream);
wc->drawPicture(picture);
serializer.endWrite();
size_t offset2 = stream.bytesWritten();
REPORTER_ASSERT(reporter, offset2 <= 16);
}