Make SkPicture/SkImageGenerator default to SkCodec

Remove reference to SkImageDecoder from SkPicture. Make the default
InstallPixelRefProc passed to CreateFromStream use
SkImageGenerator::NewFromEncoded instead.

Make SkImageGenerator::NewFromEncoded create an SkCodecImageGenerator.
Remove the old version that used SkImageDecoder.

Remove all versions of lazy_decode_bitmap/LazyDecodeBitmap. The default
now behaves lazily.

Update all clients to use the default.

Move SkImageDecoderGenerator into KtxTest.cpp, and use it directly.

BUG=skia:4691
BUG=skia:4290
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1671193002

Review URL: https://codereview.chromium.org/1671193002
This commit is contained in:
scroggo 2016-02-10 11:15:21 -08:00 committed by Commit bot
parent b5b497423c
commit 026388a018
19 changed files with 173 additions and 211 deletions

View File

@ -73,6 +73,9 @@ static etc1_byte* create_expanded_etc1_bitmap(const uint8_t* orig, int factor) {
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
@ -151,10 +154,10 @@ protected:
}
if (fDecompress) {
SkAutoTDelete<SkImageGenerator> gen(SkImageGenerator::NewFromEncoded(fPKMData));
SkAutoTDelete<SkImageGenerator> gen(decoder_image_generator(fPKMData));
gen->generateBitmap(&fBitmap);
} else {
fImage.reset(SkImage::NewFromEncoded(fPKMData));
fImage.reset(SkImage::NewFromGenerator(decoder_image_generator(fPKMData)));
}
}

View File

@ -40,11 +40,6 @@ DEFINE_bool(multiPage, false, "For document-type backends, render the source"
" into multiple pages");
DEFINE_bool(RAW_threading, true, "Allow RAW decodes to run on multiple threads?");
static bool lazy_decode_bitmap(const void* src, size_t size, SkBitmap* dst) {
SkAutoTUnref<SkData> encoded(SkData::NewWithCopy(src, size));
return encoded && SkDEPRECATED_InstallDiscardablePixelRef(encoded, dst);
}
namespace DM {
GMSrc::GMSrc(skiagm::GMRegistry::Factory factory) : fFactory(factory) {}
@ -804,7 +799,7 @@ Error SKPSrc::draw(SkCanvas* canvas) const {
if (!stream) {
return SkStringPrintf("Couldn't read %s.", fPath.c_str());
}
SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream, &lazy_decode_bitmap));
SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream));
if (!pic) {
return SkStringPrintf("Couldn't decode %s as a picture.", fPath.c_str());
}
@ -1177,7 +1172,7 @@ Error ViaSerialization::draw(
SkDynamicMemoryWStream wStream;
pic->serialize(&wStream);
SkAutoTDelete<SkStream> rStream(wStream.detachAsStream());
SkAutoTUnref<SkPicture> deserialized(SkPicture::CreateFromStream(rStream, &lazy_decode_bitmap));
SkAutoTUnref<SkPicture> deserialized(SkPicture::CreateFromStream(rStream));
return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas) {
canvas->drawPicture(deserialized);

View File

@ -58,6 +58,7 @@
'../src/codec/SkWebpCodec.cpp',
'../src/codec/SkCodecImageGenerator.cpp',
'../src/ports/SkImageGenerator_skia.cpp',
],
'direct_dependent_settings': {
'include_dirs': [

View File

@ -77,8 +77,6 @@
'../src/images/SkScaledBitmapSampler.cpp',
'../src/images/SkScaledBitmapSampler.h',
'../src/ports/SkImageGenerator_skia.cpp',
'../src/ports/SkImageDecoder_CG.cpp',
'../src/ports/SkImageDecoder_WIC.cpp',
],

View File

@ -82,7 +82,6 @@
],
'dependencies': [
'flags.gyp:flags',
'lazy_decode_bitmap',
'skia_lib.gyp:skia_lib',
],
},
@ -265,20 +264,6 @@
'skia_lib.gyp:skia_lib',
],
},
{
'target_name': 'lazy_decode_bitmap',
'type': 'static_library',
'sources': [ '../tools/LazyDecodeBitmap.cpp' ],
'include_dirs': [
'../include/private',
'../src/core',
'../src/lazy',
],
'dependencies': [
'flags.gyp:flags',
'skia_lib.gyp:skia_lib'
],
},
{
'target_name': 'gpuveto',
'type': 'executable',
@ -291,7 +276,6 @@
'../src/images',
],
'dependencies': [
'lazy_decode_bitmap',
'flags.gyp:flags',
'skia_lib.gyp:skia_lib',
],
@ -333,7 +317,6 @@
'../src/core/',
],
'dependencies': [
'lazy_decode_bitmap',
'effects.gyp:effects',
'flags.gyp:flags',
'images.gyp:images',
@ -367,7 +350,6 @@
'../tools/pinspect.cpp',
],
'dependencies': [
'lazy_decode_bitmap',
'flags.gyp:flags',
'skia_lib.gyp:skia_lib',
],

View File

@ -54,8 +54,19 @@ public:
* @return A new SkPicture representing the serialized data, or NULL if the stream is
* invalid.
*/
static SkPicture* CreateFromStream(SkStream*,
InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory);
static SkPicture* CreateFromStream(SkStream*, InstallPixelRefProc proc);
/**
* Recreate a picture that was serialized into a stream.
*
* Any serialized images in the stream will be passed to
* SkImageGenerator::NewFromEncoded.
*
* @param SkStream Serialized picture data. Ownership is unchanged by this call.
* @return A new SkPicture representing the serialized data, or NULL if the stream is
* invalid.
*/
static SkPicture* CreateFromStream(SkStream*);
/**
* Recreate a picture that was serialized into a buffer. If the creation requires bitmap

View File

@ -380,8 +380,6 @@ DM_SRCS_ALL = struct(
"tests/*.h",
"tools/CrashHandler.cpp",
"tools/CrashHandler.h",
"tools/LazyDecodeBitmap.cpp",
"tools/LazyDecodeBitmap.h",
"tools/ProcStats.cpp",
"tools/ProcStats.h",
"tools/Resources.cpp",

View File

@ -6,6 +6,7 @@
*/
#include "SkAtomics.h"
#include "SkImageGenerator.h"
#include "SkMessageBus.h"
#include "SkPicture.h"
#include "SkPictureData.h"
@ -138,6 +139,16 @@ SkPicture* SkPicture::Forwardport(const SkPictInfo& info, const SkPictureData* d
return r.endRecording();
}
static bool default_install(const void* src, size_t length, SkBitmap* dst) {
SkAutoTUnref<SkData> encoded(SkData::NewWithCopy(src, length));
return encoded && SkDEPRECATED_InstallDiscardablePixelRef(
SkImageGenerator::NewFromEncoded(encoded), dst);
}
SkPicture* SkPicture::CreateFromStream(SkStream* stream) {
return CreateFromStream(stream, &default_install, nullptr);
}
SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc proc) {
return CreateFromStream(stream, proc, nullptr);
}

View File

@ -7,6 +7,7 @@
#include "SkColorPriv.h"
#include "SkImageDecoder.h"
#include "SkImageGenerator.h"
#include "SkPixelRef.h"
#include "SkScaledBitmapSampler.h"
#include "SkStream.h"
@ -328,3 +329,101 @@ 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);
}

View File

@ -6,100 +6,8 @@
*/
#include "SkData.h"
#include "SkImageDecoder.h"
#include "SkImageGenerator.h"
#include "SkStream.h"
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;
};
#include "SkCodecImageGenerator.h"
SkImageGenerator* SkImageGenerator::NewFromEncodedImpl(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);
return SkCodecImageGenerator::NewFromEncodedCodec(data);
}

View File

@ -143,6 +143,9 @@ DEF_TEST(KtxReadUnpremul, reporter) {
}
}
// 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
@ -160,7 +163,7 @@ DEF_TEST(KtxReexportPKM, reporter) {
}
bool installDiscardablePixelRefSuccess =
SkDEPRECATED_InstallDiscardablePixelRef(fileData, &etcBitmap);
SkDEPRECATED_InstallDiscardablePixelRef(decoder_image_generator(fileData), &etcBitmap);
if (!installDiscardablePixelRefSuccess) {
ERRORF(reporter, "failed to create discardable pixelRef from KTX file");
return;

View File

@ -17,6 +17,7 @@
#include "SkImageEncoder.h"
#include "SkImageGenerator.h"
#include "SkLayerInfo.h"
#include "SkMD5.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
@ -871,7 +872,18 @@ static void assert_one_parse_error_cb(SkError error, void* context) {
SkGetLastErrorString());
}
static void test_bitmap_with_encoded_data(skiatest::Reporter* reporter) {
static void md5(const SkBitmap& bm, SkMD5::Digest* digest) {
SkAutoLockPixels autoLockPixels(bm);
SkASSERT(bm.getPixels());
SkMD5 md5;
size_t rowLen = bm.info().bytesPerPixel() * bm.width();
for (int y = 0; y < bm.height(); ++y) {
md5.update(static_cast<uint8_t*>(bm.getAddr(0, y)), rowLen);
}
md5.finish(*digest);
}
DEF_TEST(Picture_EncodedData, reporter) {
// Create a bitmap that will be encoded.
SkBitmap original;
make_bm(&original, 100, 100, SK_ColorBLUE, true);
@ -891,6 +903,7 @@ static void test_bitmap_with_encoded_data(skiatest::Reporter* reporter) {
SkAutoDataUnref picture1(serialized_picture_from_bitmap(original));
SkAutoDataUnref picture2(serialized_picture_from_bitmap(bm));
REPORTER_ASSERT(reporter, picture1->equals(picture2));
// Now test that a parse error was generated when trying to create a new SkPicture without
// providing a function to decode the bitmap.
ErrorContext context;
@ -903,6 +916,24 @@ static void test_bitmap_with_encoded_data(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, pictureFromStream.get() != nullptr);
SkClearLastError();
SkSetErrorCallback(nullptr, nullptr);
// Test that using the version of CreateFromStream that just takes a stream also decodes the
// bitmap. Drawing this picture should look exactly like the original bitmap.
SkMD5::Digest referenceDigest;
md5(original, &referenceDigest);
SkBitmap dst;
dst.allocPixels(original.info());
dst.eraseColor(SK_ColorRED);
SkCanvas canvas(dst);
pictureStream.rewind();
pictureFromStream.reset(SkPicture::CreateFromStream(&pictureStream));
canvas.drawPicture(pictureFromStream.get());
SkMD5::Digest digest2;
md5(dst, &digest2);
REPORTER_ASSERT(reporter, referenceDigest == digest2);
}
static void test_clip_bound_opt(skiatest::Reporter* reporter) {
@ -1174,7 +1205,6 @@ DEF_TEST(Picture, reporter) {
test_has_text(reporter);
test_images_are_found_by_willPlayBackBitmaps(reporter);
test_analysis(reporter);
test_bitmap_with_encoded_data(reporter);
test_clip_bound_opt(reporter);
test_clip_expansion(reporter);
test_hierarchical(reporter);

View File

@ -2174,8 +2174,6 @@ DM_SRCS = ['dm/DM.cpp',
'tests/YUVCacheTest.cpp',
'tools/CrashHandler.cpp',
'tools/CrashHandler.h',
'tools/LazyDecodeBitmap.cpp',
'tools/LazyDecodeBitmap.h',
'tools/ProcStats.cpp',
'tools/ProcStats.h',
'tools/Resources.cpp',

View File

@ -1,44 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "LazyDecodeBitmap.h"
#include "SkData.h"
#include "SkDiscardableMemoryPool.h"
#include "SkImageGeneratorPriv.h"
#include "SkForceLinking.h"
#include "SkCommandLineFlags.h"
__SK_FORCE_IMAGE_DECODER_LINKING;
DEFINE_bool(useVolatileCache, false, "Use a volatile cache for deferred image decoding pixels. "
"Only meaningful if --deferImageDecoding is set to true and the platform has an "
"implementation.");
// Fits SkPicture::InstallPixelRefProc call signature.
// Used in SkPictureData::CreateFromStream
bool sk_tools::LazyDecodeBitmap(const void* src, size_t length, SkBitmap* dst) {
SkAutoDataUnref data(SkData::NewWithCopy(src, length));
if (nullptr == data.get()) {
return false;
}
SkAutoTDelete<SkImageGenerator> gen(SkImageGenerator::NewFromEncoded(data));
if (nullptr == gen.get()) {
return false;
}
const SkImageInfo info = gen->getInfo();
SkDiscardableMemory::Factory* pool = nullptr;
if ((!FLAGS_useVolatileCache) || (info.width() * info.height() < 32 * 1024)) {
// how to do switching with SkDiscardableMemory.
pool = SkGetGlobalDiscardableMemoryPool();
// Only meaningful if platform has a default discardable
// memory implementation that differs from the global DM pool.
}
return SkDEPRECATED_InstallDiscardablePixelRef(gen.detach(), nullptr, dst, pool);
}

View File

@ -1,24 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef LazyDecodeBitmap_DEFINED
#define LazyDecodeBitmap_DEFINED
#include "SkTypes.h"
class SkBitmap;
namespace sk_tools {
/**
* Decode the image with DecodeMemoryToTarget but defer the process until it is needed.
*/
bool LazyDecodeBitmap(const void* buffer, size_t size, SkBitmap* bitmap);
}
#endif // LazyDecodeBitmap_DEFINED

View File

@ -6,7 +6,6 @@
*/
#include "DumpRecord.h"
#include "LazyDecodeBitmap.h"
#include "SkCommandLineFlags.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
@ -50,8 +49,7 @@ int tool_main(int argc, char** argv) {
SkDebugf("Could not read %s.\n", FLAGS_skps[i]);
return 1;
}
SkAutoTUnref<SkPicture> src(
SkPicture::CreateFromStream(stream, sk_tools::LazyDecodeBitmap));
SkAutoTUnref<SkPicture> src(SkPicture::CreateFromStream(stream));
if (!src) {
SkDebugf("Could not read %s as an SkPicture.\n", FLAGS_skps[i]);
return 1;

View File

@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
#include "LazyDecodeBitmap.h"
#include "SkCommandLineFlags.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
@ -42,9 +41,7 @@ int tool_main(int argc, char** argv) {
return kError;
}
SkPicture::InstallPixelRefProc proc = &sk_tools::LazyDecodeBitmap;
SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream, proc));
SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream));
if (nullptr == picture.get()) {
if (!FLAGS_quiet) {
SkDebugf("Could not read the SkPicture\n");

View File

@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
#include "LazyDecodeBitmap.h"
#include "SkLua.h"
#include "SkLuaCanvas.h"
#include "SkPicture.h"
@ -44,7 +43,7 @@ static SkPicture* load_picture(const char path[]) {
SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
SkPicture* pic = nullptr;
if (stream.get()) {
pic = SkPicture::CreateFromStream(stream.get(), &sk_tools::LazyDecodeBitmap);
pic = SkPicture::CreateFromStream(stream.get());
}
return pic;
}

View File

@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
#include "LazyDecodeBitmap.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkGraphics.h"
@ -35,7 +34,7 @@ static SkPicture* inspect(const char path[]) {
}
stream.rewind();
SkPicture* pic = SkPicture::CreateFromStream(&stream, &sk_tools::LazyDecodeBitmap);
SkPicture* pic = SkPicture::CreateFromStream(&stream);
if (nullptr == pic) {
SkDebugf("Could not create SkPicture: %s\n", path);
return nullptr;