Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2015 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 "SkSwizzler.h"
      9 #include "Test.h"
     10 
     11 // These are the values that we will look for to indicate that the fill was successful
     12 static const uint8_t kFillIndex = 0x1;
     13 static const uint32_t kFillColor = 0x22334455;
     14 
     15 static void check_fill(skiatest::Reporter* r,
     16                        const SkImageInfo& imageInfo,
     17                        uint32_t startRow,
     18                        uint32_t endRow,
     19                        size_t rowBytes,
     20                        uint32_t offset,
     21                        uint32_t colorOrIndex,
     22                        SkPMColor* colorTable) {
     23 
     24     // Calculate the total size of the image in bytes.  Use the smallest possible size.
     25     // The offset value tells us to adjust the pointer from the memory we allocate in order
     26     // to test on different memory alignments.  If offset is nonzero, we need to increase the
     27     // size of the memory we allocate in order to make sure that we have enough.  We are
     28     // still allocating the smallest possible size.
     29     const size_t totalBytes = imageInfo.getSafeSize(rowBytes) + offset;
     30 
     31     // Create fake image data where every byte has a value of 0
     32     SkAutoTDeleteArray<uint8_t> storage(SkNEW_ARRAY(uint8_t, totalBytes));
     33     memset(storage.get(), 0, totalBytes);
     34     // Adjust the pointer in order to test on different memory alignments
     35     uint8_t* imageData = storage.get() + offset;
     36     uint8_t* imageStart = imageData + rowBytes * startRow;
     37 
     38     // Fill image with the fill value starting at the indicated row
     39     SkSwizzler::Fill(imageStart, imageInfo, rowBytes, endRow - startRow + 1, colorOrIndex,
     40             colorTable);
     41 
     42     // Ensure that the pixels are filled properly
     43     // The bots should catch any memory corruption
     44     uint8_t* indexPtr = imageData + startRow * rowBytes;
     45     uint8_t* grayPtr = indexPtr;
     46     uint32_t* colorPtr = (uint32_t*) indexPtr;
     47     for (uint32_t y = startRow; y <= endRow; y++) {
     48         for (int32_t x = 0; x < imageInfo.width(); x++) {
     49             switch (imageInfo.colorType()) {
     50                 case kIndex_8_SkColorType:
     51                     REPORTER_ASSERT(r, kFillIndex == indexPtr[x]);
     52                     break;
     53                 case kN32_SkColorType:
     54                     REPORTER_ASSERT(r, kFillColor == colorPtr[x]);
     55                     break;
     56                 case kGray_8_SkColorType:
     57                     // We always fill kGray with black
     58                     REPORTER_ASSERT(r, (uint8_t) kFillColor == grayPtr[x]);
     59                     break;
     60                 default:
     61                     REPORTER_ASSERT(r, false);
     62                     break;
     63             }
     64         }
     65         indexPtr += rowBytes;
     66         colorPtr = (uint32_t*) indexPtr;
     67     }
     68 }
     69 
     70 // Test Fill() with different combinations of dimensions, alignment, and padding
     71 DEF_TEST(SwizzlerFill, r) {
     72     // Set up a color table
     73     SkPMColor colorTable[kFillIndex + 1];
     74     colorTable[kFillIndex] = kFillColor;
     75     // Apart from the fill index, we will leave the other colors in the color table uninitialized.
     76     // If we incorrectly try to fill with this uninitialized memory, the bots will catch it.
     77 
     78     // Test on an invalid width and representative widths
     79     const uint32_t widths[] = { 0, 10, 50 };
     80 
     81     // In order to call Fill(), there must be at least one row to fill
     82     // Test on the smallest possible height and representative heights
     83     const uint32_t heights[] = { 1, 5, 10 };
     84 
     85     // Test on interesting possibilities for row padding
     86     const uint32_t paddings[] = { 0, 1, 2, 3, 4 };
     87 
     88     // Iterate over test dimensions
     89     for (uint32_t width : widths) {
     90         for (uint32_t height : heights) {
     91 
     92             // Create image info objects
     93             const SkImageInfo colorInfo = SkImageInfo::MakeN32(width, height,
     94                 kUnknown_SkAlphaType);
     95             const SkImageInfo indexInfo = colorInfo.makeColorType(kIndex_8_SkColorType);
     96             const SkImageInfo grayInfo = colorInfo.makeColorType(kGray_8_SkColorType);
     97 
     98             for (uint32_t padding : paddings) {
     99 
    100                 // Calculate row bytes
    101                 size_t colorRowBytes = SkColorTypeBytesPerPixel(kN32_SkColorType) * width +
    102                         padding;
    103                 size_t indexRowBytes = width + padding;
    104                 size_t grayRowBytes = indexRowBytes;
    105 
    106                 // If there is padding, we can invent an offset to change the memory alignment
    107                 for (uint32_t offset = 0; offset <= padding; offset++) {
    108 
    109                     // Test all possible start rows with all possible end rows
    110                     for (uint32_t startRow = 0; startRow < height; startRow++) {
    111                         for (uint32_t endRow = startRow; endRow < height; endRow++) {
    112 
    113                             // Fill with an index that we use to look up a color
    114                             check_fill(r, colorInfo, startRow, endRow, colorRowBytes, offset,
    115                                     kFillIndex, colorTable);
    116 
    117                             // Fill with a color
    118                             check_fill(r, colorInfo, startRow, endRow, colorRowBytes, offset,
    119                                     kFillColor, NULL);
    120 
    121                             // Fill with an index
    122                             check_fill(r, indexInfo, startRow, endRow, indexRowBytes, offset,
    123                                     kFillIndex, NULL);
    124 
    125                             // Fill a grayscale image
    126                             check_fill(r, grayInfo, startRow, endRow, grayRowBytes, offset,
    127                                     kFillColor, NULL);
    128                         }
    129                     }
    130                 }
    131             }
    132         }
    133     }
    134 }
    135