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