1 /* 2 * Copyright 2014 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 "SkBitmap.h" 9 #include "SkData.h" 10 #include "SkEndian.h" 11 #include "SkImageInfo.h" 12 #include "SkTextureCompressor.h" 13 #include "Test.h" 14 15 static const int kLATCBlockDimension = 4; 16 static const int kLATCEncodedBlockSize = 8; 17 18 /** 19 * Make sure that we properly fail when we don't have multiple of four image dimensions. 20 */ 21 DEF_TEST(CompressLATCFailDimensions, reporter) { 22 SkBitmap bitmap; 23 static const int kWidth = 63; 24 static const int kHeight = 63; 25 SkImageInfo info = SkImageInfo::MakeA8(kWidth, kHeight); 26 REPORTER_ASSERT(reporter, kWidth % kLATCBlockDimension != 0); 27 REPORTER_ASSERT(reporter, kHeight % kLATCBlockDimension != 0); 28 29 bool setInfoSuccess = bitmap.setInfo(info); 30 REPORTER_ASSERT(reporter, setInfoSuccess); 31 32 bool allocPixelsSuccess = bitmap.allocPixels(info); 33 REPORTER_ASSERT(reporter, allocPixelsSuccess); 34 bitmap.unlockPixels(); 35 36 const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format; 37 SkAutoDataUnref latcData(SkTextureCompressor::CompressBitmapToFormat(bitmap, kLATCFormat)); 38 REPORTER_ASSERT(reporter, NULL == latcData); 39 } 40 41 /** 42 * Make sure that we properly fail when we don't have the correct bitmap type. 43 * LATC compressed textures can only be created from A8 bitmaps. 44 */ 45 DEF_TEST(CompressLATCFailColorType, reporter) { 46 SkBitmap bitmap; 47 static const int kWidth = 64; 48 static const int kHeight = 64; 49 SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight); 50 REPORTER_ASSERT(reporter, kWidth % kLATCBlockDimension == 0); 51 REPORTER_ASSERT(reporter, kHeight % kLATCBlockDimension == 0); 52 53 bool setInfoSuccess = bitmap.setInfo(info); 54 REPORTER_ASSERT(reporter, setInfoSuccess); 55 56 bool allocPixelsSuccess = bitmap.allocPixels(info); 57 REPORTER_ASSERT(reporter, allocPixelsSuccess); 58 bitmap.unlockPixels(); 59 60 const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format; 61 SkAutoDataUnref latcData(SkTextureCompressor::CompressBitmapToFormat(bitmap, kLATCFormat)); 62 REPORTER_ASSERT(reporter, NULL == latcData); 63 } 64 65 /** 66 * Make sure that if we pass in a solid color bitmap that we get the appropriate results 67 */ 68 DEF_TEST(CompressLATC, reporter) { 69 SkBitmap bitmap; 70 static const int kWidth = 8; 71 static const int kHeight = 8; 72 SkImageInfo info = SkImageInfo::MakeA8(kWidth, kHeight); 73 74 bool setInfoSuccess = bitmap.setInfo(info); 75 REPORTER_ASSERT(reporter, setInfoSuccess); 76 77 bool allocPixelsSuccess = bitmap.allocPixels(info); 78 REPORTER_ASSERT(reporter, allocPixelsSuccess); 79 bitmap.unlockPixels(); 80 81 REPORTER_ASSERT(reporter, kWidth % kLATCBlockDimension == 0); 82 REPORTER_ASSERT(reporter, kHeight % kLATCBlockDimension == 0); 83 const int numBlocks = (kWidth / kLATCBlockDimension) * (kHeight / kLATCBlockDimension); 84 const size_t kSizeToBe = static_cast<size_t>(kLATCEncodedBlockSize * numBlocks); 85 86 for (int lum = 0; lum < 256; ++lum) { 87 bitmap.lockPixels(); 88 uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels()); 89 REPORTER_ASSERT(reporter, NULL != pixels); 90 91 for (int i = 0; i < kWidth*kHeight; ++i) { 92 pixels[i] = lum; 93 } 94 bitmap.unlockPixels(); 95 96 const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format; 97 SkAutoDataUnref latcData( 98 SkTextureCompressor::CompressBitmapToFormat(bitmap, kLATCFormat)); 99 REPORTER_ASSERT(reporter, NULL != latcData); 100 REPORTER_ASSERT(reporter, kSizeToBe == latcData->size()); 101 102 // Make sure that it all matches a given block encoding. If the entire bitmap 103 // is a single value, then the lower two bytes of the encoded data should be that 104 // value. The remaining indices can be any value, and since we try to match the pixels 105 // in the chosen palette in increasing index order, each one should be zero. Hence, 106 // the correct encoding should be just the two luminance values in the bottom two 107 // bytes of the block encoding. 108 const uint64_t kConstColorEncoding = SkEndian_SwapLE64(lum | (lum << 8)); 109 const uint64_t* blockPtr = reinterpret_cast<const uint64_t*>(latcData->data()); 110 for (int i = 0; i < numBlocks; ++i) { 111 REPORTER_ASSERT(reporter, blockPtr[i] == kConstColorEncoding); 112 } 113 } 114 } 115