Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2017 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 "SkCanvas.h"
      9 #include "SkSurface.h"
     10 #include "SkVertices.h"
     11 #include "sk_pixel_iter.h"
     12 #include "Test.h"
     13 
     14 static bool equal(const SkVertices* v0, const SkVertices* v1) {
     15     if (v0->mode() != v1->mode()) {
     16         return false;
     17     }
     18     if (v0->vertexCount() != v1->vertexCount()) {
     19         return false;
     20     }
     21     if (v0->indexCount() != v1->indexCount()) {
     22         return false;
     23     }
     24 
     25     if (!!v0->texCoords() != !!v1->texCoords()) {
     26         return false;
     27     }
     28     if (!!v0->colors() != !!v1->colors()) {
     29         return false;
     30     }
     31 
     32     for (int i = 0; i < v0->vertexCount(); ++i) {
     33         if (v0->positions()[i] != v1->positions()[i]) {
     34             return false;
     35         }
     36         if (v0->texCoords()) {
     37             if (v0->texCoords()[i] != v1->texCoords()[i]) {
     38                 return false;
     39             }
     40         }
     41         if (v0->colors()) {
     42             if (v0->colors()[i] != v1->colors()[i]) {
     43                 return false;
     44             }
     45         }
     46     }
     47     for (int i = 0; i < v0->indexCount(); ++i) {
     48         if (v0->indices()[i] != v1->indices()[i]) {
     49             return false;
     50         }
     51     }
     52     return true;
     53 }
     54 
     55 DEF_TEST(Vertices, reporter) {
     56     int vCount = 5;
     57     int iCount = 9; // odd value exercises padding logic in encode()
     58 
     59     const uint32_t texFlags[] = { 0, SkVertices::kHasTexCoords_BuilderFlag };
     60     const uint32_t colFlags[] = { 0, SkVertices::kHasColors_BuilderFlag };
     61     for (auto texF : texFlags) {
     62         for (auto colF : colFlags) {
     63             uint32_t flags = texF | colF;
     64 
     65             SkVertices::Builder builder(SkVertices::kTriangles_VertexMode, vCount, iCount, flags);
     66 
     67             for (int i = 0; i < vCount; ++i) {
     68                 float x = (float)i;
     69                 builder.positions()[i].set(x, 1);
     70                 if (builder.texCoords()) {
     71                     builder.texCoords()[i].set(x, 2);
     72                 }
     73                 if (builder.colors()) {
     74                     builder.colors()[i] = SkColorSetARGB(0xFF, i, 0x80, 0);
     75                 }
     76             }
     77             for (int i = 0; i < builder.indexCount(); ++i) {
     78                 builder.indices()[i] = i % vCount;
     79             }
     80 
     81             sk_sp<SkVertices> v0 = builder.detach();
     82             sk_sp<SkData> data = v0->encode();
     83             sk_sp<SkVertices> v1 = SkVertices::Decode(data->data(), data->size());
     84 
     85             REPORTER_ASSERT(reporter, v0->uniqueID() != 0);
     86             REPORTER_ASSERT(reporter, v1->uniqueID() != 0);
     87             REPORTER_ASSERT(reporter, v0->uniqueID() != v1->uniqueID());
     88             REPORTER_ASSERT(reporter, equal(v0.get(), v1.get()));
     89         }
     90     }
     91 }
     92 
     93 static void fill_triangle(SkCanvas* canvas, const SkPoint pts[], SkColor c) {
     94     SkColor colors[] = { c, c, c };
     95     auto verts = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 3, pts, nullptr, colors);
     96     canvas->drawVertices(verts, SkBlendMode::kSrc, SkPaint());
     97 }
     98 
     99 DEF_TEST(Vertices_clipping, reporter) {
    100     // A very large triangle has to be geometrically clipped (since its "fast" clipping is
    101     // normally done in after building SkFixed coordinates). Check that we handle this.
    102     // (and don't assert).
    103     auto surf = SkSurface::MakeRasterN32Premul(3, 3);
    104 
    105     SkPoint pts[] = { { -10, 1 }, { -10, 2 }, { 1e9f, 1.5f } };
    106     fill_triangle(surf->getCanvas(), pts, SK_ColorBLACK);
    107 
    108     sk_tool_utils::PixelIter iter(surf.get());
    109     SkIPoint loc;
    110     while (void* addr = iter.next(&loc)) {
    111         SkPMColor c = *(SkPMColor*)addr;
    112         if (loc.fY == 1) {
    113             REPORTER_ASSERT(reporter, c == 0xFF000000);
    114         } else {
    115             REPORTER_ASSERT(reporter, c == 0);
    116         }
    117     }
    118 }
    119