1db74f62c7a464c215b95f563ae4f7a991c4fd058reed/*
2db74f62c7a464c215b95f563ae4f7a991c4fd058reed * Copyright 2015 Google Inc.
3db74f62c7a464c215b95f563ae4f7a991c4fd058reed *
4db74f62c7a464c215b95f563ae4f7a991c4fd058reed * Use of this source code is governed by a BSD-style license that can be
5db74f62c7a464c215b95f563ae4f7a991c4fd058reed * found in the LICENSE file.
6db74f62c7a464c215b95f563ae4f7a991c4fd058reed */
7db74f62c7a464c215b95f563ae4f7a991c4fd058reed
850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "Test.h"
950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
1050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMallocPixelRef.h"
118f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkPixelRef.h"
1250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
13db74f62c7a464c215b95f563ae4f7a991c4fd058reedstatic void decrement_counter_proc(void* pixels, void* ctx) {
14db74f62c7a464c215b95f563ae4f7a991c4fd058reed    int* counter = (int*)ctx;
15db74f62c7a464c215b95f563ae4f7a991c4fd058reed    *counter -= 1;
16db74f62c7a464c215b95f563ae4f7a991c4fd058reed}
17db74f62c7a464c215b95f563ae4f7a991c4fd058reed
18db74f62c7a464c215b95f563ae4f7a991c4fd058reedstatic void test_dont_leak_install(skiatest::Reporter* reporter) {
19db74f62c7a464c215b95f563ae4f7a991c4fd058reed    bool success;
20db74f62c7a464c215b95f563ae4f7a991c4fd058reed    int release_counter;
21db74f62c7a464c215b95f563ae4f7a991c4fd058reed    SkImageInfo info;
22db74f62c7a464c215b95f563ae4f7a991c4fd058reed    SkBitmap bm;
23db74f62c7a464c215b95f563ae4f7a991c4fd058reed
24db74f62c7a464c215b95f563ae4f7a991c4fd058reed    info = SkImageInfo::MakeN32Premul(0, 0);
25db74f62c7a464c215b95f563ae4f7a991c4fd058reed    release_counter = 1;
262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    success = bm.installPixels(info, nullptr, 0, nullptr, decrement_counter_proc, &release_counter);
27db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, true == success);
28db74f62c7a464c215b95f563ae4f7a991c4fd058reed    bm.reset();
29db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, 0 == release_counter);
30db74f62c7a464c215b95f563ae4f7a991c4fd058reed
31db74f62c7a464c215b95f563ae4f7a991c4fd058reed    info = SkImageInfo::MakeN32Premul(10, 10);
32db74f62c7a464c215b95f563ae4f7a991c4fd058reed    release_counter = 1;
332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    success = bm.installPixels(info, nullptr, 0, nullptr, decrement_counter_proc, &release_counter);
34db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, true == success);
35db74f62c7a464c215b95f563ae4f7a991c4fd058reed    bm.reset();
36db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, 0 == release_counter);
37db74f62c7a464c215b95f563ae4f7a991c4fd058reed
38db74f62c7a464c215b95f563ae4f7a991c4fd058reed    info = SkImageInfo::MakeN32Premul(-10, -10);
39db74f62c7a464c215b95f563ae4f7a991c4fd058reed    release_counter = 1;
402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    success = bm.installPixels(info, nullptr, 0, nullptr, decrement_counter_proc, &release_counter);
41db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, false == success);
42db74f62c7a464c215b95f563ae4f7a991c4fd058reed    bm.reset();
43db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, 0 == release_counter);
44db74f62c7a464c215b95f563ae4f7a991c4fd058reed}
45db74f62c7a464c215b95f563ae4f7a991c4fd058reed
46db74f62c7a464c215b95f563ae4f7a991c4fd058reedstatic void test_install(skiatest::Reporter* reporter) {
47db74f62c7a464c215b95f563ae4f7a991c4fd058reed    bool success;
48db74f62c7a464c215b95f563ae4f7a991c4fd058reed    SkImageInfo info = SkImageInfo::MakeN32Premul(0, 0);
49db74f62c7a464c215b95f563ae4f7a991c4fd058reed    SkBitmap bm;
50db74f62c7a464c215b95f563ae4f7a991c4fd058reed    // make sure we don't assert on an empty install
512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    success = bm.installPixels(info, nullptr, 0);
52db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, success);
53db74f62c7a464c215b95f563ae4f7a991c4fd058reed
54db74f62c7a464c215b95f563ae4f7a991c4fd058reed    // no pixels should be the same as setInfo()
55db74f62c7a464c215b95f563ae4f7a991c4fd058reed    info = SkImageInfo::MakeN32Premul(10, 10);
562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    success = bm.installPixels(info, nullptr, 0);
57db74f62c7a464c215b95f563ae4f7a991c4fd058reed    REPORTER_ASSERT(reporter, success);
58db74f62c7a464c215b95f563ae4f7a991c4fd058reed
59db74f62c7a464c215b95f563ae4f7a991c4fd058reed}
60db74f62c7a464c215b95f563ae4f7a991c4fd058reed
6150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgclass TestListener : public SkPixelRef::GenIDChangeListener {
6250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgpublic:
6350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    explicit TestListener(int* ptr) : fPtr(ptr) {}
6436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onChange() override { (*fPtr)++; }
6550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgprivate:
6650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    int* fPtr;
6750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org};
6850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
6950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgDEF_TEST(PixelRef_GenIDChange, r) {
7032678d9a453e2c9fd26e92be429cdd84250b4d85commit-bot@chromium.org    SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
71bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com
722880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkAutoTUnref<SkPixelRef> pixelRef(SkMallocPixelRef::NewAllocate(info, 0, nullptr));
7350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
7450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // Register a listener.
7550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    int count = 0;
762880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    pixelRef->addGenIDChangeListener(new TestListener(&count));
7750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    REPORTER_ASSERT(r, 0 == count);
7850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
7950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // No one has looked at our pixelRef's generation ID, so invalidating it doesn't make sense.
8050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // (An SkPixelRef tree falls in the forest but there's nobody around to hear it.  Do we care?)
81bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    pixelRef->notifyPixelsChanged();
8250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    REPORTER_ASSERT(r, 0 == count);
8350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
8450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // Force the generation ID to be calculated.
85bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    REPORTER_ASSERT(r, 0 != pixelRef->getGenerationID());
8650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
8750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // Our listener was dropped in the first call to notifyPixelsChanged().  This is a no-op.
88bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    pixelRef->notifyPixelsChanged();
8950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    REPORTER_ASSERT(r, 0 == count);
9050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
9150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // Force the generation ID to be recalculated, then add a listener.
92bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    REPORTER_ASSERT(r, 0 != pixelRef->getGenerationID());
932880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    pixelRef->addGenIDChangeListener(new TestListener(&count));
94bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    pixelRef->notifyPixelsChanged();
9550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    REPORTER_ASSERT(r, 1 == count);
9650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
972880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    // Quick check that nullptr is safe.
98bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    REPORTER_ASSERT(r, 0 != pixelRef->getGenerationID());
992880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    pixelRef->addGenIDChangeListener(nullptr);
100bf790232f6d94b54239dbc210d8beee7411ca458reed@google.com    pixelRef->notifyPixelsChanged();
101db74f62c7a464c215b95f563ae4f7a991c4fd058reed
102db74f62c7a464c215b95f563ae4f7a991c4fd058reed    test_install(r);
103db74f62c7a464c215b95f563ae4f7a991c4fd058reed    test_dont_leak_install(r);
10450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}
105