/** * Move the result of the software mask generation back to the gpu */ void GrSWMaskHelper::toTexture(GrTexture *texture) { SkAutoLockPixels alp(fBM); GrTextureDesc desc; desc.fWidth = fBM.width(); desc.fHeight = fBM.height(); desc.fConfig = texture->config(); // First see if we should compress this texture before uploading. if (texture->config() == kLATC_GrPixelConfig) { SkTextureCompressor::Format format = SkTextureCompressor::kLATC_Format; SkAutoDataUnref latcData(SkTextureCompressor::CompressBitmapToFormat(fBM, format)); SkASSERT(NULL != latcData); this->sendTextureData(texture, desc, latcData->data(), 0); } else { // Looks like we have to send a full A8 texture. this->sendTextureData(texture, desc, fBM.getPixels(), fBM.rowBytes()); } }
/** * Make sure that if we pass in a solid color bitmap that we get the appropriate results */ DEF_TEST(CompressLATC, reporter) { const SkTextureCompressor::Format kLATCFormat = SkTextureCompressor::kLATC_Format; static const int kLATCEncodedBlockSize = 8; SkBitmap bitmap; static const int kWidth = 8; static const int kHeight = 8; SkImageInfo info = SkImageInfo::MakeA8(kWidth, kHeight); bool setInfoSuccess = bitmap.setInfo(info); REPORTER_ASSERT(reporter, setInfoSuccess); bool allocPixelsSuccess = bitmap.allocPixels(info); REPORTER_ASSERT(reporter, allocPixelsSuccess); bitmap.unlockPixels(); int latcDimX, latcDimY; SkTextureCompressor::GetBlockDimensions(kLATCFormat, &latcDimX, &latcDimY); REPORTER_ASSERT(reporter, kWidth % latcDimX == 0); REPORTER_ASSERT(reporter, kHeight % latcDimY == 0); const size_t kSizeToBe = SkTextureCompressor::GetCompressedDataSize(kLATCFormat, kWidth, kHeight); REPORTER_ASSERT(reporter, kSizeToBe == ((kWidth*kHeight*kLATCEncodedBlockSize)/16)); REPORTER_ASSERT(reporter, (kSizeToBe % kLATCEncodedBlockSize) == 0); for (int lum = 0; lum < 256; ++lum) { bitmap.lockPixels(); uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels()); REPORTER_ASSERT(reporter, NULL != pixels); if (NULL == pixels) { bitmap.unlockPixels(); continue; } for (int i = 0; i < kWidth*kHeight; ++i) { pixels[i] = lum; } bitmap.unlockPixels(); SkAutoDataUnref latcData( SkTextureCompressor::CompressBitmapToFormat(bitmap, kLATCFormat)); REPORTER_ASSERT(reporter, NULL != latcData); if (NULL == latcData) { continue; } REPORTER_ASSERT(reporter, kSizeToBe == latcData->size()); // Make sure that it all matches a given block encoding. Since we have // COMPRESS_LATC_FAST defined in SkTextureCompressor_LATC.cpp, we are using // an approximation scheme that optimizes for speed against coverage maps. // That means that each palette in the encoded block is exactly the same, // and that the three bits saved per pixel are computed from the top three // bits of the luminance value. const uint64_t kIndexEncodingMap[8] = { 1, 7, 6, 5, 4, 3, 2, 0 }; const uint64_t kIndex = kIndexEncodingMap[lum >> 5]; const uint64_t kConstColorEncoding = SkEndian_SwapLE64( 255 | (kIndex << 16) | (kIndex << 19) | (kIndex << 22) | (kIndex << 25) | (kIndex << 28) | (kIndex << 31) | (kIndex << 34) | (kIndex << 37) | (kIndex << 40) | (kIndex << 43) | (kIndex << 46) | (kIndex << 49) | (kIndex << 52) | (kIndex << 55) | (kIndex << 58) | (kIndex << 61)); const uint64_t* blockPtr = reinterpret_cast<const uint64_t*>(latcData->data()); for (size_t i = 0; i < (kSizeToBe/8); ++i) { REPORTER_ASSERT(reporter, blockPtr[i] == kConstColorEncoding); } } }