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 <string>
      9 #include <tuple>
     10 #include <vector>
     11 #include "Resources.h"
     12 #include "SkCpu.h"
     13 #include "SkImage.h"
     14 #include "SkImage_Base.h"
     15 #include "SkOpts.h"
     16 #include "SkPM4fPriv.h"
     17 #include "SkNx.h"
     18 #include "Test.h"
     19 
     20 typedef void (*Blender)(uint32_t* dst, const uint32_t* const srcStart, int ndst, const int nsrc);
     21 
     22 static inline void srcover_srgb_srgb_1(uint32_t* dst, uint32_t src) {
     23     auto d = Sk4f_fromS32(*dst),
     24          s = Sk4f_fromS32( src);
     25     *dst = Sk4f_toS32(s + d * (1.0f - s[3]));
     26 }
     27 
     28 static void brute_force_srcover_srgb_srgb(
     29     uint32_t* dst, const uint32_t* const src, int ndst, const int nsrc) {
     30     while (ndst > 0) {
     31         int n = SkTMin(ndst, nsrc);
     32 
     33         for (int i = 0; i < n; i++) {
     34             srcover_srgb_srgb_1(dst++, src[i]);
     35         }
     36         ndst -= n;
     37     }
     38 }
     39 
     40 static SkString mismatch_message(std::string resourceName, int x, int y,
     41                                   uint32_t src, uint32_t good, uint32_t bad) {
     42     return SkStringPrintf(
     43         "%s - missmatch at %d, %d src: %08x good: %08x bad: %08x",
     44         resourceName.c_str(), x, y, src, good, bad);
     45 }
     46 
     47 static void test_blender(std::string resourceName, skiatest::Reporter* reporter) {
     48     std::string fileName = resourceName + ".png";
     49     sk_sp<SkImage> image = GetResourceAsImage(fileName.c_str());
     50     if (image == nullptr) {
     51         ERRORF(reporter, "image is NULL");
     52         return;
     53     }
     54     SkBitmap bm;
     55     sk_sp<SkColorSpace> srgbColorSpace = SkColorSpace::MakeSRGB();
     56     if (!as_IB(image)->getROPixels(&bm, srgbColorSpace.get())) {
     57         ERRORF(reporter, "Could not read resource");
     58         return;
     59     }
     60 
     61     SkPixmap pixmap;
     62     bm.peekPixels(&pixmap);
     63     SkASSERTF(pixmap.colorType() == kN32_SkColorType, "colorType: %d", pixmap.colorType());
     64     SkASSERT(pixmap.alphaType() != kUnpremul_SkAlphaType);
     65     const uint32_t* src = pixmap.addr32();
     66     const int width = pixmap.rowBytesAsPixels();
     67     SkASSERT(width > 0);
     68     SkASSERT(width < 4000);
     69     SkAutoTArray<uint32_t> correctDst(width);
     70     SkAutoTArray<uint32_t> testDst(width);
     71 
     72     for (int y = 0; y < pixmap.height(); y++) {
     73         // TODO: zero is not the most interesting dst to test srcover...
     74         sk_bzero(correctDst.get(), width * sizeof(uint32_t));
     75         sk_bzero(testDst.get(), width * sizeof(uint32_t));
     76         brute_force_srcover_srgb_srgb(correctDst.get(), src, width, width);
     77         SkOpts::    srcover_srgb_srgb(   testDst.get(), src, width, width);
     78         for (int x = 0; x < width; x++) {
     79             REPORTER_ASSERT_MESSAGE(
     80                 reporter, correctDst[x] == testDst[x],
     81                 mismatch_message(resourceName, x, y, src[x], correctDst[x], testDst[x]));
     82             if (correctDst[x] != testDst[x]) break;
     83         }
     84         src += width;
     85     }
     86 }
     87 
     88 DEF_TEST(SkBlend_optsCheck, reporter) {
     89     std::vector<std::string> testResources = {
     90         "yellow_rose", "baby_tux", "plane", "mandrill_512", "iconstrip"
     91     };
     92 
     93     for (auto& resourceName : testResources) {
     94         test_blender(resourceName, reporter);
     95     }
     96 }
     97 
     98 DEF_TEST(SkBlend_optsSqrtCheck, reporter) {
     99     for (int c = 0; c < 256; c++) {
    100         Sk4f i{(float)c};
    101         Sk4f ii = i * i;
    102         Sk4f s = ii.sqrt() + 0.5f;
    103         Sk4f sf = s.floor();
    104         REPORTER_ASSERT_MESSAGE(
    105             reporter, i[0] == sf[0], SkStringPrintf("i: %f, s: %f", i[0], sf[0]));
    106     }
    107 }
    108