SwizzlerTest.cpp revision 7ecc59610de72043e9b7ebaf1ef45c43425e54fc
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 "SkSwizzle.h" 9#include "SkSwizzler.h" 10#include "Test.h" 11#include "SkOpts.h" 12 13// These are the values that we will look for to indicate that the fill was successful 14static const uint8_t kFillIndex = 0x11; 15static const uint8_t kFillGray = 0x22; 16static const uint16_t kFill565 = 0x3344; 17static const uint32_t kFillColor = 0x55667788; 18 19static void check_fill(skiatest::Reporter* r, 20 const SkImageInfo& imageInfo, 21 uint32_t startRow, 22 uint32_t endRow, 23 size_t rowBytes, 24 uint32_t offset, 25 uint32_t colorOrIndex) { 26 27 // Calculate the total size of the image in bytes. Use the smallest possible size. 28 // The offset value tells us to adjust the pointer from the memory we allocate in order 29 // to test on different memory alignments. If offset is nonzero, we need to increase the 30 // size of the memory we allocate in order to make sure that we have enough. We are 31 // still allocating the smallest possible size. 32 const size_t totalBytes = imageInfo.getSafeSize(rowBytes) + offset; 33 34 // Create fake image data where every byte has a value of 0 35 std::unique_ptr<uint8_t[]> storage(new uint8_t[totalBytes]); 36 memset(storage.get(), 0, totalBytes); 37 // Adjust the pointer in order to test on different memory alignments 38 uint8_t* imageData = storage.get() + offset; 39 uint8_t* imageStart = imageData + rowBytes * startRow; 40 const SkImageInfo fillInfo = imageInfo.makeWH(imageInfo.width(), endRow - startRow + 1); 41 SkSampler::Fill(fillInfo, imageStart, rowBytes, colorOrIndex, SkCodec::kNo_ZeroInitialized); 42 43 // Ensure that the pixels are filled properly 44 // The bots should catch any memory corruption 45 uint8_t* indexPtr = imageData + startRow * rowBytes; 46 uint8_t* grayPtr = indexPtr; 47 uint32_t* colorPtr = (uint32_t*) indexPtr; 48 uint16_t* color565Ptr = (uint16_t*) indexPtr; 49 for (uint32_t y = startRow; y <= endRow; y++) { 50 for (int32_t x = 0; x < imageInfo.width(); x++) { 51 switch (imageInfo.colorType()) { 52 case kIndex_8_SkColorType: 53 REPORTER_ASSERT(r, kFillIndex == indexPtr[x]); 54 break; 55 case kN32_SkColorType: 56 REPORTER_ASSERT(r, kFillColor == colorPtr[x]); 57 break; 58 case kGray_8_SkColorType: 59 REPORTER_ASSERT(r, kFillGray == grayPtr[x]); 60 break; 61 case kRGB_565_SkColorType: 62 REPORTER_ASSERT(r, kFill565 == color565Ptr[x]); 63 break; 64 default: 65 REPORTER_ASSERT(r, false); 66 break; 67 } 68 } 69 indexPtr += rowBytes; 70 colorPtr = (uint32_t*) indexPtr; 71 } 72} 73 74// Test Fill() with different combinations of dimensions, alignment, and padding 75DEF_TEST(SwizzlerFill, r) { 76 // Test on an invalid width and representative widths 77 const uint32_t widths[] = { 0, 10, 50 }; 78 79 // In order to call Fill(), there must be at least one row to fill 80 // Test on the smallest possible height and representative heights 81 const uint32_t heights[] = { 1, 5, 10 }; 82 83 // Test on interesting possibilities for row padding 84 const uint32_t paddings[] = { 0, 4 }; 85 86 // Iterate over test dimensions 87 for (uint32_t width : widths) { 88 for (uint32_t height : heights) { 89 90 // Create image info objects 91 const SkImageInfo colorInfo = SkImageInfo::MakeN32(width, height, kUnknown_SkAlphaType); 92 const SkImageInfo grayInfo = colorInfo.makeColorType(kGray_8_SkColorType); 93 const SkImageInfo indexInfo = colorInfo.makeColorType(kIndex_8_SkColorType); 94 const SkImageInfo color565Info = colorInfo.makeColorType(kRGB_565_SkColorType); 95 96 for (uint32_t padding : paddings) { 97 98 // Calculate row bytes 99 const size_t colorRowBytes = SkColorTypeBytesPerPixel(kN32_SkColorType) * width 100 + padding; 101 const size_t indexRowBytes = width + padding; 102 const size_t grayRowBytes = indexRowBytes; 103 const size_t color565RowBytes = 104 SkColorTypeBytesPerPixel(kRGB_565_SkColorType) * width + padding; 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 += 4) { 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 // Test fill with each color type 114 check_fill(r, colorInfo, startRow, endRow, colorRowBytes, offset, 115 kFillColor); 116 check_fill(r, indexInfo, startRow, endRow, indexRowBytes, offset, 117 kFillIndex); 118 check_fill(r, grayInfo, startRow, endRow, grayRowBytes, offset, 119 kFillGray); 120 check_fill(r, color565Info, startRow, endRow, color565RowBytes, offset, 121 kFill565); 122 } 123 } 124 } 125 } 126 } 127 } 128} 129 130DEF_TEST(SwizzleOpts, r) { 131 uint32_t dst, src; 132 133 // forall c, c*255 == c, c*0 == 0 134 for (int c = 0; c <= 255; c++) { 135 src = (255<<24) | c; 136 SkOpts::RGBA_to_rgbA(&dst, &src, 1); 137 REPORTER_ASSERT(r, dst == src); 138 SkOpts::RGBA_to_bgrA(&dst, &src, 1); 139 REPORTER_ASSERT(r, dst == (uint32_t)((255<<24) | (c<<16))); 140 141 src = (0<<24) | c; 142 SkOpts::RGBA_to_rgbA(&dst, &src, 1); 143 REPORTER_ASSERT(r, dst == 0); 144 SkOpts::RGBA_to_bgrA(&dst, &src, 1); 145 REPORTER_ASSERT(r, dst == 0); 146 } 147 148 // check a totally arbitrary color 149 src = 0xFACEB004; 150 SkOpts::RGBA_to_rgbA(&dst, &src, 1); 151 REPORTER_ASSERT(r, dst == 0xFACAAD04); 152 153 // swap red and blue 154 SkOpts::RGBA_to_BGRA(&dst, &src, 1); 155 REPORTER_ASSERT(r, dst == 0xFA04B0CE); 156 157 // all together now 158 SkOpts::RGBA_to_bgrA(&dst, &src, 1); 159 REPORTER_ASSERT(r, dst == 0xFA04ADCA); 160} 161 162DEF_TEST(PublicSwizzleOpts, r) { 163 uint32_t dst, src; 164 165 // check a totally arbitrary color 166 src = 0xFACEB004; 167 SkSwapRB(&dst, &src, 1); 168 REPORTER_ASSERT(r, dst == 0xFA04B0CE); 169} 170