remove discardablepixelref
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3883 Change-Id: Ica284be78563a4ccd6e0cb07404064fb5511ba57 Reviewed-on: https://skia-review.googlesource.com/3883 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
67c7c81a82
commit
7614794c9a
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
|
||||
#include "Resources.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkData.h"
|
||||
#include "SkDiscardableMemoryPool.h"
|
||||
#include "SkDiscardablePixelRef.h"
|
||||
#include "SkImageGeneratorPriv.h"
|
||||
#include "SkOSFile.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
namespace skiagm {
|
||||
|
||||
/**
|
||||
* Draw a PNG created by SkBitmapFactory.
|
||||
*/
|
||||
class FactoryGM : public GM {
|
||||
public:
|
||||
FactoryGM() {}
|
||||
|
||||
protected:
|
||||
void onOnceBeforeDraw() override {
|
||||
// Copyright-free file from http://openclipart.org/detail/29213/paper-plane-by-ddoo
|
||||
SkString pngFilename = GetResourcePath("plane.png");
|
||||
sk_sp<SkData> data(SkData::MakeFromFileName(pngFilename.c_str()));
|
||||
if (data) {
|
||||
// Create a cache which will boot the pixels out anytime the
|
||||
// bitmap is unlocked.
|
||||
SkAutoTUnref<SkDiscardableMemoryPool> pool(
|
||||
SkDiscardableMemoryPool::Create(1));
|
||||
SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator::NewFromEncoded(data.get()),
|
||||
nullptr, &fBitmap, pool);
|
||||
}
|
||||
}
|
||||
|
||||
SkString onShortName() override {
|
||||
return SkString("factory");
|
||||
}
|
||||
|
||||
SkISize onISize() override {
|
||||
return SkISize::Make(640, 480);
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
canvas->drawBitmap(fBitmap, 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
SkBitmap fBitmap;
|
||||
|
||||
typedef GM INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static GM* MyFactory(void*) { return new FactoryGM; }
|
||||
static GMRegistry reg(MyFactory);
|
||||
|
||||
} // namespace skiagm
|
@ -104,7 +104,6 @@
|
||||
'<(skia_src_path)/core/SkDeviceProfile.cpp',
|
||||
'<(skia_src_path)/core/SkDiscardableMemory.h',
|
||||
'<(skia_src_path)/lazy/SkDiscardableMemoryPool.cpp',
|
||||
'<(skia_src_path)/lazy/SkDiscardablePixelRef.cpp',
|
||||
'<(skia_src_path)/core/SkDistanceFieldGen.cpp',
|
||||
'<(skia_src_path)/core/SkDistanceFieldGen.h',
|
||||
'<(skia_src_path)/core/SkDither.cpp',
|
||||
@ -158,7 +157,6 @@
|
||||
'<(skia_src_path)/core/SkImageCacherator.h',
|
||||
'<(skia_src_path)/core/SkImageCacherator.cpp',
|
||||
'<(skia_src_path)/core/SkImageGenerator.cpp',
|
||||
'<(skia_src_path)/core/SkImageGeneratorPriv.h',
|
||||
'<(skia_src_path)/core/SkLightingShader.h',
|
||||
'<(skia_src_path)/core/SkLightingShader.cpp',
|
||||
'<(skia_src_path)/core/SkLights.cpp',
|
||||
|
@ -30,36 +30,6 @@ class SkPicture;
|
||||
#define SK_REFENCODEDDATA_CTXPARAM GrContext* ctx
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Takes ownership of SkImageGenerator. If this method fails for
|
||||
* whatever reason, it will return false and immediatetely delete
|
||||
* the generator. If it succeeds, it will modify destination
|
||||
* bitmap.
|
||||
*
|
||||
* If generator is NULL, will safely return false.
|
||||
*
|
||||
* If this fails or when the SkDiscardablePixelRef that is
|
||||
* installed into destination is destroyed, it will
|
||||
* delete the generator. Therefore, generator should be
|
||||
* allocated with new.
|
||||
*
|
||||
* @param destination Upon success, this bitmap will be
|
||||
* configured and have a pixelref installed.
|
||||
*
|
||||
* @return true iff successful.
|
||||
*/
|
||||
SK_API bool SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination);
|
||||
|
||||
/**
|
||||
* On success, installs a discardable pixelref into destination, based on encoded data.
|
||||
* Regardless of success or failure, the caller must still balance their ownership of encoded.
|
||||
*/
|
||||
SK_API bool SkDEPRECATED_InstallDiscardablePixelRef(SkData* encoded, SkBitmap* destination);
|
||||
|
||||
/**
|
||||
* An interface that allows a purgeable PixelRef (such as a
|
||||
* SkDiscardablePixelRef) to decode and re-decode an image as needed.
|
||||
*/
|
||||
class SK_API SkImageGenerator : public SkNoncopyable {
|
||||
public:
|
||||
/**
|
||||
|
@ -1,40 +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.
|
||||
*/
|
||||
|
||||
#ifndef SkImageGeneratorPriv_DEFINED
|
||||
#define SkImageGeneratorPriv_DEFINED
|
||||
|
||||
#include "SkImageGenerator.h"
|
||||
#include "SkDiscardableMemory.h"
|
||||
|
||||
/**
|
||||
* Takes ownership of SkImageGenerator. If this method fails for
|
||||
* whatever reason, it will return false and immediatetely delete
|
||||
* the generator. If it succeeds, it will modify destination
|
||||
* bitmap.
|
||||
*
|
||||
* If generator is nullptr, will safely return false.
|
||||
*
|
||||
* If this fails or when the SkDiscardablePixelRef that is
|
||||
* installed into destination is destroyed, it will call
|
||||
* `delete` on the generator. Therefore, generator should be
|
||||
* allocated with `new`.
|
||||
*
|
||||
* @param destination Upon success, this bitmap will be
|
||||
* configured and have a pixelref installed.
|
||||
*
|
||||
* @param factory If not nullptr, this object will be used as a
|
||||
* source of discardable memory when decoding. If nullptr, then
|
||||
* SkDiscardableMemory::Create() will be called.
|
||||
*
|
||||
* @return true iff successful.
|
||||
*/
|
||||
bool SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator*, const SkIRect* subset,
|
||||
SkBitmap* destination,
|
||||
SkDiscardableMemory::Factory* factory);
|
||||
|
||||
#endif
|
@ -1,155 +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 "SkDiscardablePixelRef.h"
|
||||
#include "SkDiscardableMemory.h"
|
||||
#include "SkImageGenerator.h"
|
||||
|
||||
SkDiscardablePixelRef::SkDiscardablePixelRef(const SkImageInfo& info,
|
||||
SkImageGenerator* generator,
|
||||
size_t rowBytes,
|
||||
SkDiscardableMemory::Factory* fact)
|
||||
: INHERITED(info)
|
||||
, fGenerator(generator)
|
||||
, fDMFactory(fact)
|
||||
, fRowBytes(rowBytes)
|
||||
, fDiscardableMemory(nullptr)
|
||||
, fDiscardableMemoryIsLocked(false)
|
||||
{
|
||||
SkASSERT(fGenerator != nullptr);
|
||||
SkASSERT(fRowBytes > 0);
|
||||
// The SkImageGenerator contract requires fGenerator to always
|
||||
// decode the same image on each call to getPixels().
|
||||
this->setImmutable();
|
||||
SkSafeRef(fDMFactory);
|
||||
}
|
||||
|
||||
SkDiscardablePixelRef::~SkDiscardablePixelRef() {
|
||||
if (fDiscardableMemoryIsLocked) {
|
||||
fDiscardableMemory->unlock();
|
||||
fDiscardableMemoryIsLocked = false;
|
||||
}
|
||||
delete fDiscardableMemory;
|
||||
SkSafeUnref(fDMFactory);
|
||||
delete fGenerator;
|
||||
}
|
||||
|
||||
bool SkDiscardablePixelRef::onNewLockPixels(LockRec* rec) {
|
||||
if (fDiscardableMemory != nullptr) {
|
||||
if (fDiscardableMemory->lock()) {
|
||||
fDiscardableMemoryIsLocked = true;
|
||||
rec->fPixels = fDiscardableMemory->data();
|
||||
rec->fColorTable = fCTable.get();
|
||||
rec->fRowBytes = fRowBytes;
|
||||
return true;
|
||||
}
|
||||
delete fDiscardableMemory;
|
||||
fDiscardableMemory = nullptr;
|
||||
fDiscardableMemoryIsLocked = false;
|
||||
}
|
||||
|
||||
const size_t size = this->info().getSafeSize(fRowBytes);
|
||||
|
||||
if (fDMFactory != nullptr) {
|
||||
fDiscardableMemory = fDMFactory->create(size);
|
||||
fDiscardableMemoryIsLocked = true;
|
||||
} else {
|
||||
fDiscardableMemory = SkDiscardableMemory::Create(size);
|
||||
fDiscardableMemoryIsLocked = true;
|
||||
}
|
||||
if (nullptr == fDiscardableMemory) {
|
||||
fDiscardableMemoryIsLocked = false;
|
||||
return false; // Memory allocation failed.
|
||||
}
|
||||
|
||||
void* pixels = fDiscardableMemory->data();
|
||||
const SkImageInfo& info = this->info();
|
||||
SkPMColor colors[256];
|
||||
int colorCount = 0;
|
||||
|
||||
if (!fGenerator->getPixels(info, pixels, fRowBytes, colors, &colorCount)) {
|
||||
fDiscardableMemory->unlock();
|
||||
fDiscardableMemoryIsLocked = false;
|
||||
delete fDiscardableMemory;
|
||||
fDiscardableMemory = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: our ctable is not purgeable, as it is not stored in the discardablememory block.
|
||||
// This is because SkColorTable is refcntable, and therefore our caller could hold onto it
|
||||
// beyond the scope of a lock/unlock. If we change the API/lifecycle for SkColorTable, we
|
||||
// could move it into the block, but then again perhaps it is small enough that this doesn't
|
||||
// really matter.
|
||||
if (colorCount > 0) {
|
||||
fCTable.reset(new SkColorTable(colors, colorCount));
|
||||
} else {
|
||||
fCTable.reset(nullptr);
|
||||
}
|
||||
|
||||
rec->fPixels = pixels;
|
||||
rec->fColorTable = fCTable.get();
|
||||
rec->fRowBytes = fRowBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkDiscardablePixelRef::onUnlockPixels() {
|
||||
fDiscardableMemory->unlock();
|
||||
fDiscardableMemoryIsLocked = false;
|
||||
}
|
||||
|
||||
bool SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator* generator, const SkIRect* subset,
|
||||
SkBitmap* dst, SkDiscardableMemory::Factory* factory) {
|
||||
SkAutoTDelete<SkImageGenerator> autoGenerator(generator);
|
||||
if (nullptr == autoGenerator.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkImageInfo prInfo = autoGenerator->getInfo();
|
||||
if (prInfo.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkIPoint origin = SkIPoint::Make(0, 0);
|
||||
SkImageInfo bmInfo = prInfo;
|
||||
if (subset) {
|
||||
const SkIRect prBounds = SkIRect::MakeWH(prInfo.width(), prInfo.height());
|
||||
if (subset->isEmpty() || !prBounds.contains(*subset)) {
|
||||
return false;
|
||||
}
|
||||
bmInfo = prInfo.makeWH(subset->width(), subset->height());
|
||||
origin.set(subset->x(), subset->y());
|
||||
}
|
||||
|
||||
// must compute our desired rowBytes w.r.t. the pixelRef's dimensions, not ours, which may be
|
||||
// smaller.
|
||||
if (!dst->setInfo(bmInfo, prInfo.minRowBytes())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Since dst->setInfo() may have changed/fixed-up info, we check from the bitmap
|
||||
SkASSERT(dst->info().colorType() != kUnknown_SkColorType);
|
||||
|
||||
if (dst->empty()) { // Use a normal pixelref.
|
||||
return dst->tryAllocPixels();
|
||||
}
|
||||
SkAutoTUnref<SkDiscardablePixelRef> ref(
|
||||
new SkDiscardablePixelRef(prInfo, autoGenerator.release(), dst->rowBytes(), factory));
|
||||
dst->setPixelRef(ref, origin.x(), origin.y());
|
||||
return true;
|
||||
}
|
||||
|
||||
// These are the public API
|
||||
|
||||
bool SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator* generator, SkBitmap* dst) {
|
||||
return SkDEPRECATED_InstallDiscardablePixelRef(generator, nullptr, dst, nullptr);
|
||||
}
|
||||
|
||||
bool SkDEPRECATED_InstallDiscardablePixelRef(SkData* encoded, SkBitmap* dst) {
|
||||
SkImageGenerator* generator = SkImageGenerator::NewFromEncoded(encoded);
|
||||
return generator ?
|
||||
SkDEPRECATED_InstallDiscardablePixelRef(generator, nullptr, dst, nullptr) : false;
|
||||
}
|
@ -1,81 +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 SkDiscardablePixelRef_DEFINED
|
||||
#define SkDiscardablePixelRef_DEFINED
|
||||
|
||||
#include "SkDiscardableMemory.h"
|
||||
#include "SkImageGeneratorPriv.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkPixelRef.h"
|
||||
|
||||
/**
|
||||
* A PixelRef backed by SkDiscardableMemory, with the ability to
|
||||
* re-generate the pixels (via a SkImageGenerator) if the DM is
|
||||
* purged.
|
||||
*/
|
||||
class SkDiscardablePixelRef : public SkPixelRef {
|
||||
public:
|
||||
|
||||
SkDiscardableMemory* diagnostic_only_getDiscardable() const override {
|
||||
return fDiscardableMemory;
|
||||
}
|
||||
|
||||
protected:
|
||||
~SkDiscardablePixelRef();
|
||||
|
||||
bool onNewLockPixels(LockRec*) override;
|
||||
void onUnlockPixels() override;
|
||||
bool onLockPixelsAreWritable() const override { return false; }
|
||||
|
||||
SkData* onRefEncodedData() override {
|
||||
return fGenerator->refEncodedData();
|
||||
}
|
||||
|
||||
bool onIsLazyGenerated() const override { return true; }
|
||||
|
||||
private:
|
||||
SkImageGenerator* const fGenerator;
|
||||
SkDiscardableMemory::Factory* const fDMFactory;
|
||||
const size_t fRowBytes;
|
||||
// These const members should not change over the life of the
|
||||
// PixelRef, since the SkBitmap doesn't expect them to change.
|
||||
|
||||
SkDiscardableMemory* fDiscardableMemory;
|
||||
bool fDiscardableMemoryIsLocked;
|
||||
SkAutoTUnref<SkColorTable> fCTable;
|
||||
|
||||
/* Takes ownership of SkImageGenerator. */
|
||||
SkDiscardablePixelRef(const SkImageInfo&, SkImageGenerator*,
|
||||
size_t rowBytes,
|
||||
SkDiscardableMemory::Factory* factory);
|
||||
|
||||
bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override {
|
||||
// If the image was already decoded with lockPixels(), favor not
|
||||
// re-decoding to YUV8 planes.
|
||||
if (fDiscardableMemory) {
|
||||
return false;
|
||||
}
|
||||
return fGenerator->queryYUV8(sizeInfo, colorSpace);
|
||||
}
|
||||
|
||||
bool onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) override {
|
||||
// If the image was already decoded with lockPixels(), favor not
|
||||
// re-decoding to YUV8 planes.
|
||||
if (fDiscardableMemory) {
|
||||
return false;
|
||||
}
|
||||
return fGenerator->getYUV8Planes(sizeInfo, planes);
|
||||
}
|
||||
|
||||
friend bool SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator*, const SkIRect*, SkBitmap*,
|
||||
SkDiscardableMemory::Factory*);
|
||||
|
||||
typedef SkPixelRef INHERITED;
|
||||
};
|
||||
|
||||
#endif // SkDiscardablePixelRef_DEFINED
|
@ -11,149 +11,13 @@
|
||||
#include "SkDiscardableMemoryPool.h"
|
||||
#include "SkImage.h"
|
||||
#include "SkImageEncoder.h"
|
||||
#include "SkImageGeneratorPriv.h"
|
||||
#include "SkImageGenerator.h"
|
||||
#include "SkResourceCache.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
/**
|
||||
* Fill this bitmap with some color.
|
||||
*/
|
||||
static void make_test_image(SkBitmap* bm) {
|
||||
const int W = 50, H = 50;
|
||||
bm->allocN32Pixels(W, H);
|
||||
bm->eraseColor(SK_ColorBLACK);
|
||||
SkCanvas canvas(*bm);
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorBLUE);
|
||||
canvas.drawRectCoords(0, 0, SkIntToScalar(W/2),
|
||||
SkIntToScalar(H/2), paint);
|
||||
paint.setColor(SK_ColorWHITE);
|
||||
canvas.drawRectCoords(SkIntToScalar(W/2), SkIntToScalar(H/2),
|
||||
SkIntToScalar(W), SkIntToScalar(H), paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* encode this bitmap into some data via SkImageEncoder
|
||||
*/
|
||||
static sk_sp<SkData> create_data_from_bitmap(const SkBitmap& bm, SkImageEncoder::Type type) {
|
||||
SkDynamicMemoryWStream stream;
|
||||
if (SkImageEncoder::EncodeStream(&stream, bm, type, 100)) {
|
||||
return stream.detachAsData();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void compare_bitmaps(skiatest::Reporter* reporter,
|
||||
const SkBitmap& b1, const SkBitmap& b2,
|
||||
bool pixelPerfect = true) {
|
||||
REPORTER_ASSERT(reporter, b1.empty() == b2.empty());
|
||||
REPORTER_ASSERT(reporter, b1.width() == b2.width());
|
||||
REPORTER_ASSERT(reporter, b1.height() == b2.height());
|
||||
REPORTER_ASSERT(reporter, b1.isNull() == b2.isNull());
|
||||
SkAutoLockPixels autoLockPixels1(b1);
|
||||
SkAutoLockPixels autoLockPixels2(b2);
|
||||
REPORTER_ASSERT(reporter, b1.isNull() == b2.isNull());
|
||||
if (b1.isNull() || b1.empty()) {
|
||||
return;
|
||||
}
|
||||
REPORTER_ASSERT(reporter, b1.getPixels());
|
||||
REPORTER_ASSERT(reporter, b2.getPixels());
|
||||
if ((!(b1.getPixels())) || (!(b2.getPixels()))) {
|
||||
return;
|
||||
}
|
||||
if ((b1.width() != b2.width()) ||
|
||||
(b1.height() != b2.height())) {
|
||||
return;
|
||||
}
|
||||
if (!pixelPerfect) {
|
||||
return;
|
||||
}
|
||||
|
||||
int pixelErrors = 0;
|
||||
for (int y = 0; y < b2.height(); ++y) {
|
||||
for (int x = 0; x < b2.width(); ++x) {
|
||||
if (b1.getColor(x, y) != b2.getColor(x, y)) {
|
||||
++pixelErrors;
|
||||
}
|
||||
}
|
||||
}
|
||||
REPORTER_ASSERT(reporter, 0 == pixelErrors);
|
||||
}
|
||||
|
||||
typedef bool (*InstallEncoded)(SkData* encoded, SkBitmap* dst);
|
||||
|
||||
/**
|
||||
This function tests three differently encoded images against the
|
||||
original bitmap */
|
||||
static void test_three_encodings(skiatest::Reporter* reporter,
|
||||
InstallEncoded install) {
|
||||
SkBitmap original;
|
||||
make_test_image(&original);
|
||||
REPORTER_ASSERT(reporter, !original.empty());
|
||||
REPORTER_ASSERT(reporter, !original.isNull());
|
||||
if (original.empty() || original.isNull()) {
|
||||
return;
|
||||
}
|
||||
static const SkImageEncoder::Type types[] = {
|
||||
SkImageEncoder::kPNG_Type,
|
||||
SkImageEncoder::kJPEG_Type,
|
||||
SkImageEncoder::kWEBP_Type
|
||||
};
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(types); i++) {
|
||||
SkImageEncoder::Type type = types[i];
|
||||
sk_sp<SkData> encoded = create_data_from_bitmap(original, type);
|
||||
REPORTER_ASSERT(reporter, encoded.get() != nullptr);
|
||||
if (nullptr == encoded.get()) {
|
||||
continue;
|
||||
}
|
||||
SkBitmap lazy;
|
||||
bool installSuccess = install(encoded.get(), &lazy);
|
||||
REPORTER_ASSERT(reporter, installSuccess);
|
||||
if (!installSuccess) {
|
||||
continue;
|
||||
}
|
||||
REPORTER_ASSERT(reporter, nullptr == lazy.getPixels());
|
||||
{
|
||||
SkAutoLockPixels autoLockPixels(lazy); // now pixels are good.
|
||||
REPORTER_ASSERT(reporter, lazy.getPixels());
|
||||
if (nullptr == lazy.getPixels()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// pixels should be gone!
|
||||
REPORTER_ASSERT(reporter, nullptr == lazy.getPixels());
|
||||
{
|
||||
SkAutoLockPixels autoLockPixels(lazy); // now pixels are good.
|
||||
REPORTER_ASSERT(reporter, lazy.getPixels());
|
||||
if (nullptr == lazy.getPixels()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
bool comparePixels = (SkImageEncoder::kPNG_Type == type);
|
||||
compare_bitmaps(reporter, original, lazy, comparePixels);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static bool install_skDiscardablePixelRef(SkData* encoded, SkBitmap* dst) {
|
||||
// Use system-default discardable memory.
|
||||
return SkDEPRECATED_InstallDiscardablePixelRef(encoded, dst);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* This checks to see that SkDiscardablePixelRef works as advertised with a
|
||||
* SkDecodingImageGenerator.
|
||||
*/
|
||||
DEF_TEST(DecodingImageGenerator, reporter) {
|
||||
test_three_encodings(reporter, install_skDiscardablePixelRef);
|
||||
}
|
||||
|
||||
class TestImageGenerator : public SkImageGenerator {
|
||||
public:
|
||||
enum TestType {
|
||||
@ -227,82 +91,6 @@ private:
|
||||
typedef SkImageGenerator INHERITED;
|
||||
};
|
||||
|
||||
static void check_test_image_generator_bitmap(skiatest::Reporter* reporter,
|
||||
const SkBitmap& bm) {
|
||||
REPORTER_ASSERT(reporter, TestImageGenerator::Width() == bm.width());
|
||||
REPORTER_ASSERT(reporter, TestImageGenerator::Height() == bm.height());
|
||||
SkAutoLockPixels autoLockPixels(bm);
|
||||
REPORTER_ASSERT(reporter, bm.getPixels());
|
||||
if (nullptr == bm.getPixels()) {
|
||||
return;
|
||||
}
|
||||
int errors = 0;
|
||||
for (int y = 0; y < bm.height(); ++y) {
|
||||
for (int x = 0; x < bm.width(); ++x) {
|
||||
if (TestImageGenerator::Color() != bm.getColor(x, y)) {
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
REPORTER_ASSERT(reporter, 0 == errors);
|
||||
}
|
||||
|
||||
static void check_pixelref(TestImageGenerator::TestType type,
|
||||
skiatest::Reporter* reporter,
|
||||
SkDiscardableMemory::Factory* factory,
|
||||
SkColorType colorType) {
|
||||
SkAutoTDelete<SkImageGenerator> gen(new TestImageGenerator(type, reporter, colorType));
|
||||
REPORTER_ASSERT(reporter, gen.get() != nullptr);
|
||||
SkBitmap lazy;
|
||||
bool success = SkDEPRECATED_InstallDiscardablePixelRef(gen.release(), nullptr, &lazy, factory);
|
||||
|
||||
REPORTER_ASSERT(reporter, success);
|
||||
if (TestImageGenerator::kSucceedGetPixels_TestType == type) {
|
||||
check_test_image_generator_bitmap(reporter, lazy);
|
||||
} else if (TestImageGenerator::kFailGetPixels_TestType == type) {
|
||||
SkAutoLockPixels autoLockPixels(lazy);
|
||||
REPORTER_ASSERT(reporter, nullptr == lazy.getPixels());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests the basic functionality of SkDiscardablePixelRef with a
|
||||
* basic SkImageGenerator implementation and several
|
||||
* SkDiscardableMemory::Factory choices.
|
||||
*/
|
||||
DEF_TEST(DiscardableAndCachingPixelRef, reporter) {
|
||||
const SkColorType testColorTypes[] = {
|
||||
kN32_SkColorType,
|
||||
kIndex_8_SkColorType,
|
||||
kRGB_565_SkColorType
|
||||
};
|
||||
for (const SkColorType testColorType : testColorTypes) {
|
||||
check_pixelref(TestImageGenerator::kFailGetPixels_TestType, reporter, nullptr,
|
||||
testColorType);
|
||||
check_pixelref(TestImageGenerator::kSucceedGetPixels_TestType, reporter, nullptr,
|
||||
testColorType);
|
||||
|
||||
SkAutoTUnref<SkDiscardableMemoryPool> pool(
|
||||
SkDiscardableMemoryPool::Create(1, nullptr));
|
||||
REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
|
||||
check_pixelref(TestImageGenerator::kFailGetPixels_TestType, reporter, pool,
|
||||
testColorType);
|
||||
REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
|
||||
check_pixelref(TestImageGenerator::kSucceedGetPixels_TestType, reporter, pool,
|
||||
testColorType);
|
||||
REPORTER_ASSERT(reporter, 0 == pool->getRAMUsed());
|
||||
|
||||
SkDiscardableMemoryPool* globalPool = SkGetGlobalDiscardableMemoryPool();
|
||||
// Only acts differently from nullptr on a platform that has a
|
||||
// default discardable memory implementation that differs from the
|
||||
// global DM pool.
|
||||
check_pixelref(TestImageGenerator::kFailGetPixels_TestType, reporter, globalPool,
|
||||
testColorType);
|
||||
check_pixelref(TestImageGenerator::kSucceedGetPixels_TestType, reporter, globalPool,
|
||||
testColorType);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_TEST(Image_NewFromGenerator, r) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkData.h"
|
||||
#include "SkDiscardableMemoryPool.h"
|
||||
#include "SkImageGeneratorPriv.h"
|
||||
#include "SkImageGenerator.h"
|
||||
#include "SkMatrixUtils.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
|
@ -15,14 +15,6 @@
|
||||
#include "Resources.h"
|
||||
#include "Test.h"
|
||||
|
||||
// Returned bitmap is lazy. Only lazy bitmaps hold onto the original data.
|
||||
static SkBitmap bitmap_from_data(SkData* data) {
|
||||
SkASSERT(data);
|
||||
SkBitmap bm;
|
||||
SkDEPRECATED_InstallDiscardablePixelRef(data, &bm);
|
||||
return bm;
|
||||
}
|
||||
|
||||
static bool is_subset_of(SkData* smaller, SkData* larger) {
|
||||
SkASSERT(smaller && larger);
|
||||
if (smaller->size() > larger->size()) {
|
||||
@ -70,29 +62,6 @@ DEF_TEST(SkPDF_JpegEmbedTest, r) {
|
||||
|
||||
canvas->clear(SK_ColorLTGRAY);
|
||||
|
||||
SkBitmap bm1(bitmap_from_data(mandrillData.get()));
|
||||
canvas->drawBitmap(bm1, 65.0, 0.0, nullptr);
|
||||
SkBitmap bm2(bitmap_from_data(cmykData.get()));
|
||||
canvas->drawBitmap(bm2, 0.0, 512.0, nullptr);
|
||||
|
||||
canvas->flush();
|
||||
document->endPage();
|
||||
document->close();
|
||||
sk_sp<SkData> pdfData(pdf.detachAsData());
|
||||
SkASSERT(pdfData);
|
||||
|
||||
REPORTER_ASSERT(r, is_subset_of(mandrillData.get(), pdfData.get()));
|
||||
|
||||
// This JPEG uses a nonstandard colorspace - it can not be
|
||||
// embedded into the PDF directly.
|
||||
REPORTER_ASSERT(r, !is_subset_of(cmykData.get(), pdfData.get()));
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
pdf.reset();
|
||||
document = SkDocument::MakePDF(&pdf);
|
||||
canvas = document->beginPage(642, 1028);
|
||||
|
||||
canvas->clear(SK_ColorLTGRAY);
|
||||
|
||||
sk_sp<SkImage> im1(SkImage::MakeFromEncoded(mandrillData));
|
||||
canvas->drawImage(im1.get(), 65.0, 0.0, nullptr);
|
||||
sk_sp<SkImage> im2(SkImage::MakeFromEncoded(cmykData));
|
||||
@ -101,7 +70,7 @@ DEF_TEST(SkPDF_JpegEmbedTest, r) {
|
||||
canvas->flush();
|
||||
document->endPage();
|
||||
document->close();
|
||||
pdfData = pdf.detachAsData();
|
||||
sk_sp<SkData> pdfData = pdf.detachAsData();
|
||||
SkASSERT(pdfData);
|
||||
|
||||
REPORTER_ASSERT(r, is_subset_of(mandrillData.get(), pdfData.get()));
|
||||
|
@ -620,77 +620,6 @@ static void test_bad_bitmap() {
|
||||
}
|
||||
#endif
|
||||
|
||||
static sk_sp<SkData> serialized_picture_from_bitmap(const SkBitmap& bitmap) {
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(bitmap.width()),
|
||||
SkIntToScalar(bitmap.height()));
|
||||
canvas->drawBitmap(bitmap, 0, 0);
|
||||
sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
|
||||
|
||||
SkDynamicMemoryWStream wStream;
|
||||
SkAutoTUnref<SkPixelSerializer> serializer(
|
||||
SkImageEncoder::CreatePixelSerializer());
|
||||
picture->serialize(&wStream, serializer);
|
||||
return wStream.detachAsData();
|
||||
}
|
||||
|
||||
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.write(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);
|
||||
SkDynamicMemoryWStream wStream;
|
||||
if (!SkImageEncoder::EncodeStream(&wStream, original, SkImageEncoder::kPNG_Type, 100)) {
|
||||
return;
|
||||
}
|
||||
sk_sp<SkData> data = wStream.detachAsData();
|
||||
|
||||
SkBitmap bm;
|
||||
bool installSuccess = SkDEPRECATED_InstallDiscardablePixelRef(data.get(), &bm);
|
||||
REPORTER_ASSERT(reporter, installSuccess);
|
||||
|
||||
// Write both bitmaps to pictures, and ensure that the resulting data streams are the same.
|
||||
// Flattening original will follow the old path of performing an encode, while flattening bm
|
||||
// will use the already encoded data.
|
||||
sk_sp<SkData> picture1(serialized_picture_from_bitmap(original));
|
||||
sk_sp<SkData> picture2(serialized_picture_from_bitmap(bm));
|
||||
REPORTER_ASSERT(reporter, picture1->equals(picture2.get()));
|
||||
|
||||
// Now test that a parse error was generated when trying to create a new SkPicture without
|
||||
// providing a function to decode the bitmap.
|
||||
SkMemoryStream pictureStream(std::move(picture1));
|
||||
sk_sp<SkPicture> pictureFromStream(SkPicture::MakeFromStream(&pictureStream));
|
||||
REPORTER_ASSERT(reporter, pictureFromStream.get() != 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 = SkPicture::MakeFromStream(&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) {
|
||||
// Test for crbug.com/229011
|
||||
SkRect rect1 = SkRect::MakeXYWH(SkIntToScalar(4), SkIntToScalar(4),
|
||||
|
Loading…
Reference in New Issue
Block a user