diff options
-rw-r--r-- | bench/ETCBitmapBench.cpp | 238 | ||||
-rw-r--r-- | src/images/SkImageDecoder_ktx.cpp | 98 | ||||
-rw-r--r-- | tests/KtxTest.cpp | 37 |
3 files changed, 0 insertions, 373 deletions
diff --git a/bench/ETCBitmapBench.cpp b/bench/ETCBitmapBench.cpp deleted file mode 100644 index 305f492108..0000000000 --- a/bench/ETCBitmapBench.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "Benchmark.h" -#include "Resources.h" -#include "SkCanvas.h" -#include "SkData.h" -#include "SkImageGenerator.h" -#include "SkImageDecoder.h" -#include "SkOSFile.h" -#include "SkPixelRef.h" - -#ifndef SK_IGNORE_ETC1_SUPPORT - -#include "etc1.h" - -// This takes the etc1 data pointed to by orig, and copies it `factor` times in each -// dimension. The return value is the new data or nullptr on error. -static etc1_byte* create_expanded_etc1_bitmap(const uint8_t* orig, int factor) { - SkASSERT(orig); - SkASSERT(factor > 1); - - const etc1_byte* origData = reinterpret_cast<const etc1_byte*>(orig); - if (!etc1_pkm_is_valid(orig)) { - return nullptr; - } - - etc1_uint32 origWidth = etc1_pkm_get_width(origData); - etc1_uint32 origHeight = etc1_pkm_get_height(origData); - - // The width and height must be aligned along block boundaries - static const etc1_uint32 kETC1BlockWidth = 4; - static const etc1_uint32 kETC1BlockHeight = 4; - if ((origWidth % kETC1BlockWidth) != 0 || - (origHeight % kETC1BlockHeight) != 0) { - return nullptr; - } - - // The picture must be at least as large as a block. - if (origWidth <= kETC1BlockWidth || origHeight <= kETC1BlockHeight) { - return nullptr; - } - - etc1_uint32 newWidth = origWidth * factor; - etc1_uint32 newHeight = origHeight * factor; - - etc1_uint32 newDataSz = etc1_get_encoded_data_size(newWidth, newHeight); - etc1_byte* newData = reinterpret_cast<etc1_byte *>( - sk_malloc_throw(newDataSz + ETC_PKM_HEADER_SIZE)); - etc1_pkm_format_header(newData, newWidth, newHeight); - - etc1_byte* copyInto = newData; - - copyInto += ETC_PKM_HEADER_SIZE; - origData += ETC_PKM_HEADER_SIZE; - - etc1_uint32 origBlocksX = (origWidth >> 2); - etc1_uint32 origBlocksY = (origHeight >> 2); - etc1_uint32 newBlocksY = (newHeight >> 2); - etc1_uint32 origRowSzInBytes = origBlocksX * ETC1_ENCODED_BLOCK_SIZE; - - for (etc1_uint32 j = 0; j < newBlocksY; ++j) { - const etc1_byte* rowStart = origData + ((j % origBlocksY) * origRowSzInBytes); - for(etc1_uint32 i = 0; i < newWidth; i += origWidth) { - memcpy(copyInto, rowStart, origRowSzInBytes); - copyInto += origRowSzInBytes; - } - } - return newData; -} - -// Defined in SkImageDecoder_ktx.cpp -extern SkImageGenerator* decoder_image_generator(SkData*); - -// This is the base class for all of the benches in this file. In general -// the ETC1 benches should all be working on the same data. Due to the -// simplicity of the PKM file, that data is the 128x128 mandrill etc1 -// compressed texture repeated by some factor (currently 8 -> 1024x1024) -class ETCBitmapBenchBase : public Benchmark { -public: - ETCBitmapBenchBase() : fPKMData(loadPKM()) { - if (nullptr == fPKMData) { - SkDebugf("Could not load PKM data!\n"); - } - } - -protected: - SkAutoDataUnref fPKMData; - -private: - SkData* loadPKM() { - SkString pkmFilename = GetResourcePath("mandrill_128.pkm"); - // Expand the data - SkAutoDataUnref fileData(SkData::NewFromFileName(pkmFilename.c_str())); - if (nullptr == fileData) { - SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n"); - return nullptr; - } - - const etc1_uint32 kExpansionFactor = 8; - etc1_byte* expandedETC1 = - create_expanded_etc1_bitmap(fileData->bytes(), kExpansionFactor); - if (nullptr == expandedETC1) { - SkDebugf("Error expanding ETC1 data by factor of %d\n", kExpansionFactor); - return nullptr; - } - - etc1_uint32 width = etc1_pkm_get_width(expandedETC1); - etc1_uint32 height = etc1_pkm_get_width(expandedETC1); - etc1_uint32 dataSz = ETC_PKM_HEADER_SIZE + etc1_get_encoded_data_size(width, height); - return SkData::NewFromMalloc(expandedETC1, dataSz); - } - - typedef Benchmark INHERITED; -}; - -// This is the rendering benchmark. Prior to rendering the data, create a -// bitmap using the etc1 data. -class ETCBitmapBench : public ETCBitmapBenchBase { -public: - ETCBitmapBench(bool decompress, Backend backend) - : fDecompress(decompress), fBackend(backend) { } - - bool isSuitableFor(Backend backend) override { - return SkToBool(fImage) && backend == this->fBackend; - } - -protected: - const char* onGetName() override { - if (kGPU_Backend == this->fBackend) { - if (this->fDecompress) { - return "etc1bitmap_render_gpu_decompressed"; - } else { - return "etc1bitmap_render_gpu_compressed"; - } - } else { - SkASSERT(kRaster_Backend == this->fBackend); - if (this->fDecompress) { - return "etc1bitmap_render_raster_decompressed"; - } else { - return "etc1bitmap_render_raster_compressed"; - } - } - } - - void onDelayedSetup() override { - if (nullptr == fPKMData) { - SkDebugf("Failed to load PKM data!\n"); - return; - } - - if (fDecompress) { - SkAutoTDelete<SkImageGenerator> gen(decoder_image_generator(fPKMData)); - gen->generateBitmap(&fBitmap); - } else { - fImage.reset(SkImage::NewFromGenerator(decoder_image_generator(fPKMData))); - } - } - - void onDraw(int loops, SkCanvas* canvas) override { - for (int i = 0; i < loops; ++i) { - if (fDecompress) { - canvas->drawBitmap(this->fBitmap, 0, 0, nullptr); - } else { - canvas->drawImage(fImage, 0, 0, nullptr); - } - } - } - -protected: - SkBitmap fBitmap; - SkAutoTUnref<SkImage> fImage; - - bool decompress() const { return fDecompress; } - Backend backend() const { return fBackend; } -private: - const bool fDecompress; - const Backend fBackend; - typedef ETCBitmapBenchBase INHERITED; -}; - -// This benchmark is identical to the previous benchmark, but it explicitly forces -// an upload to the GPU before each draw call. We do this by notifying the bitmap -// that the pixels have changed (even though they haven't). -class ETCBitmapUploadBench : public ETCBitmapBench { -public: - ETCBitmapUploadBench(bool decompress, Backend backend) - : ETCBitmapBench(decompress, backend) { } - -protected: - const char* onGetName() override { - if (kGPU_Backend == this->backend()) { - if (this->decompress()) { - return "etc1bitmap_upload_gpu_decompressed"; - } else { - return "etc1bitmap_upload_gpu_compressed"; - } - } else { - SkASSERT(kRaster_Backend == this->backend()); - if (this->decompress()) { - return "etc1bitmap_upload_raster_decompressed"; - } else { - return "etc1bitmap_upload_raster_compressed"; - } - } - } - - void onDraw(int loops, SkCanvas* canvas) override { - SkPixelRef* pr = fBitmap.pixelRef(); - for (int i = 0; i < loops; ++i) { - if (pr) { - pr->notifyPixelsChanged(); - } - canvas->drawBitmap(this->fBitmap, 0, 0, nullptr); - } - } - -private: - typedef ETCBitmapBench INHERITED; -}; - -DEF_BENCH(return new ETCBitmapBench(false, Benchmark::kRaster_Backend);) -DEF_BENCH(return new ETCBitmapBench(true, Benchmark::kRaster_Backend);) - -DEF_BENCH(return new ETCBitmapBench(false, Benchmark::kGPU_Backend);) -DEF_BENCH(return new ETCBitmapBench(true, Benchmark::kGPU_Backend);) - -DEF_BENCH(return new ETCBitmapUploadBench(false, Benchmark::kRaster_Backend);) -DEF_BENCH(return new ETCBitmapUploadBench(true, Benchmark::kRaster_Backend);) - -DEF_BENCH(return new ETCBitmapUploadBench(false, Benchmark::kGPU_Backend);) -DEF_BENCH(return new ETCBitmapUploadBench(true, Benchmark::kGPU_Backend);) - -#endif // SK_IGNORE_ETC1_SUPPORT diff --git a/src/images/SkImageDecoder_ktx.cpp b/src/images/SkImageDecoder_ktx.cpp index 019fa97678..539795ad9b 100644 --- a/src/images/SkImageDecoder_ktx.cpp +++ b/src/images/SkImageDecoder_ktx.cpp @@ -329,101 +329,3 @@ SkImageEncoder* sk_libktx_efactory(SkImageEncoder::Type t) { static SkImageDecoder_DecodeReg gReg(sk_libktx_dfactory); static SkImageDecoder_FormatReg gFormatReg(get_format_ktx); static SkImageEncoder_EncodeReg gEReg(sk_libktx_efactory); - -///////////////////////////////////////////////////////////////////////////////////////// -// Old implementation of SkImageGenerator::NewFromEncoded which uses SkImageDecoder. -// Here because it is only needed by DM and tests for Ktx. -class BareMemoryAllocator : public SkBitmap::Allocator { - const SkImageInfo fInfo; - void* const fMemory; - const size_t fRowBytes; - -public: - BareMemoryAllocator(const SkImageInfo& info, void* memory, size_t rowBytes) - : fInfo(info), fMemory(memory), fRowBytes(rowBytes) - {} - -protected: - bool allocPixelRef(SkBitmap* bm, SkColorTable* ctable) override { - const SkImageInfo bmi = bm->info(); - if (bmi.width() != fInfo.width() || bmi.height() != fInfo.height() || - bmi.colorType() != fInfo.colorType()) - { - return false; - } - return bm->installPixels(bmi, fMemory, fRowBytes, ctable, nullptr, nullptr); - } -}; - -class SkImageDecoderGenerator : public SkImageGenerator { - const SkImageInfo fInfo; - SkAutoTDelete<SkImageDecoder> fDecoder; - SkAutoTUnref<SkData> fData; - -public: - SkImageDecoderGenerator(const SkImageInfo& info, SkImageDecoder* decoder, SkData* data) - : INHERITED(info), fInfo(info), fDecoder(decoder), fData(SkRef(data)) - {} - -protected: - SkData* onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM) override { - return SkRef(fData.get()); - } - bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, - SkPMColor ctableEntries[], int* ctableCount) override { - SkMemoryStream stream(fData->data(), fData->size(), false); - SkAutoTUnref<BareMemoryAllocator> allocator( - new BareMemoryAllocator(info, pixels, rowBytes)); - fDecoder->setAllocator(allocator); - fDecoder->setRequireUnpremultipliedColors(kUnpremul_SkAlphaType == info.alphaType()); - - SkBitmap bm; - const SkImageDecoder::Result result = fDecoder->decode(&stream, &bm, info.colorType(), - SkImageDecoder::kDecodePixels_Mode); - if (SkImageDecoder::kFailure == result) { - return false; - } - - SkASSERT(info.colorType() == bm.info().colorType()); - - if (kIndex_8_SkColorType == info.colorType()) { - SkASSERT(ctableEntries); - - SkColorTable* ctable = bm.getColorTable(); - if (nullptr == ctable) { - return false; - } - const int count = ctable->count(); - memcpy(ctableEntries, ctable->readColors(), count * sizeof(SkPMColor)); - *ctableCount = count; - } - return true; - } - - bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], - SkYUVColorSpace* colorSpace) override { - SkMemoryStream stream(fData->data(), fData->size(), false); - return fDecoder->decodeYUV8Planes(&stream, sizes, planes, rowBytes, colorSpace); - } - -private: - typedef SkImageGenerator INHERITED; -}; - -SkImageGenerator* decoder_image_generator(SkData* data) { - SkMemoryStream stream(data->data(), data->size(), false); - SkImageDecoder* decoder = SkImageDecoder::Factory(&stream); - if (nullptr == decoder) { - return nullptr; - } - - SkBitmap bm; - stream.rewind(); - if (!decoder->decode(&stream, &bm, kUnknown_SkColorType, SkImageDecoder::kDecodeBounds_Mode)) { - delete decoder; - return nullptr; - } - - return new SkImageDecoderGenerator(bm.info(), decoder, data); -} - diff --git a/tests/KtxTest.cpp b/tests/KtxTest.cpp index 99bae83329..7220cbf32e 100644 --- a/tests/KtxTest.cpp +++ b/tests/KtxTest.cpp @@ -142,40 +142,3 @@ DEF_TEST(KtxReadUnpremul, reporter) { row += decodedBitmap.rowBytes(); } } - -// For KtxReexportPKM, below. Defined in SkImageDecoder_ktx.cpp -extern SkImageGenerator* decoder_image_generator(SkData*); - -/** - * Finally, make sure that if we get ETC1 data from a PKM file that we can then - * accurately write it out into a KTX file (i.e. transferring the ETC1 data from - * the PKM to the KTX should produce an identical KTX to the one we have on file) - */ -DEF_TEST(KtxReexportPKM, reporter) { - SkString pkmFilename = GetResourcePath("mandrill_128.pkm"); - - // Load PKM file into a bitmap - SkBitmap etcBitmap; - SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(pkmFilename.c_str())); - if (nullptr == fileData) { - SkDebugf("KtxReexportPKM: can't load test file %s\n", pkmFilename.c_str()); - return; - } - - bool installDiscardablePixelRefSuccess = - SkDEPRECATED_InstallDiscardablePixelRef(decoder_image_generator(fileData), &etcBitmap); - if (!installDiscardablePixelRefSuccess) { - ERRORF(reporter, "failed to create discardable pixelRef from KTX file"); - return; - } - - // Write the bitmap out to a KTX file. - SkData *ktxDataPtr = SkImageEncoder::EncodeData(etcBitmap, SkImageEncoder::kKTX_Type, 0); - SkAutoDataUnref newKtxData(ktxDataPtr); - REPORTER_ASSERT(reporter, ktxDataPtr); - - // See is this data is identical to data in existing ktx file. - SkString ktxFilename = GetResourcePath("mandrill_128.ktx"); - SkAutoDataUnref oldKtxData(SkData::NewFromFileName(ktxFilename.c_str())); - REPORTER_ASSERT(reporter, oldKtxData->equals(newKtxData)); -} |