Add SkSpecialImage::extractSubset & NewFromPixmap
This is calved off of: https://codereview.chromium.org/1785643003/ (Switch SkBlurImageFilter over to new onFilterImage interface) GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1787883002 Review URL: https://codereview.chromium.org/1787883002
This commit is contained in:
parent
b3b6beae04
commit
250581493a
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "Benchmark.h"
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColorPriv.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "Benchmark.h"
|
||||
#include "Resources.h"
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkData.h"
|
||||
#include "SkImage.h"
|
||||
#include "SkPDFBitmap.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include "gm.h"
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkData.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkRandom.h"
|
||||
|
@ -23,6 +23,8 @@
|
||||
'<(skia_src_path)/core/SkAlphaRuns.cpp',
|
||||
'<(skia_src_path)/core/SkAntiRun.h',
|
||||
'<(skia_src_path)/core/SkAutoKern.h',
|
||||
'<(skia_src_path)/core/SkAutoPixmapStorage.h',
|
||||
'<(skia_src_path)/core/SkAutoPixmapStorage.cpp',
|
||||
'<(skia_src_path)/core/SkBBHFactory.cpp',
|
||||
'<(skia_src_path)/core/SkBBoxHierarchy.h',
|
||||
'<(skia_src_path)/core/SkBigPicture.cpp',
|
||||
|
@ -187,71 +187,6 @@ private:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SK_API SkAutoPixmapStorage : public SkPixmap {
|
||||
public:
|
||||
SkAutoPixmapStorage();
|
||||
~SkAutoPixmapStorage();
|
||||
|
||||
/**
|
||||
* Try to allocate memory for the pixels needed to match the specified Info. On success
|
||||
* return true and fill out the pixmap to point to that memory. The storage will be freed
|
||||
* when this object is destroyed, or if another call to tryAlloc() or alloc() is made.
|
||||
*
|
||||
* On failure, return false and reset() the pixmap to empty.
|
||||
*/
|
||||
bool tryAlloc(const SkImageInfo&);
|
||||
|
||||
/**
|
||||
* Allocate memory for the pixels needed to match the specified Info and fill out the pixmap
|
||||
* to point to that memory. The storage will be freed when this object is destroyed,
|
||||
* or if another call to tryAlloc() or alloc() is made.
|
||||
*
|
||||
* If the memory cannot be allocated, calls sk_throw().
|
||||
*/
|
||||
void alloc(const SkImageInfo&);
|
||||
|
||||
/**
|
||||
* Gets the size and optionally the rowBytes that would be allocated by SkAutoPixmapStorage if
|
||||
* alloc/tryAlloc was called.
|
||||
*/
|
||||
static size_t AllocSize(const SkImageInfo& info, size_t* rowBytes);
|
||||
|
||||
/**
|
||||
* Returns an SkData object wrapping the allocated pixels memory, and resets the pixmap.
|
||||
* If the storage hasn't been allocated, the result is NULL.
|
||||
*/
|
||||
const SkData* SK_WARN_UNUSED_RESULT detachPixelsAsData();
|
||||
|
||||
// We wrap these so we can clear our internal storage
|
||||
|
||||
void reset() {
|
||||
this->freeStorage();
|
||||
this->INHERITED::reset();
|
||||
}
|
||||
void reset(const SkImageInfo& info, const void* addr, size_t rb, SkColorTable* ctable = NULL) {
|
||||
this->freeStorage();
|
||||
this->INHERITED::reset(info, addr, rb, ctable);
|
||||
}
|
||||
void reset(const SkImageInfo& info) {
|
||||
this->freeStorage();
|
||||
this->INHERITED::reset(info);
|
||||
}
|
||||
bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) {
|
||||
this->freeStorage();
|
||||
return this->INHERITED::reset(mask);
|
||||
}
|
||||
|
||||
private:
|
||||
void* fStorage;
|
||||
|
||||
void freeStorage() {
|
||||
sk_free(fStorage);
|
||||
fStorage = nullptr;
|
||||
}
|
||||
|
||||
typedef SkPixmap INHERITED;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SK_API SkAutoPixmapUnlock : ::SkNoncopyable {
|
||||
|
64
src/core/SkAutoPixmapStorage.cpp
Normal file
64
src/core/SkAutoPixmapStorage.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkData.h"
|
||||
|
||||
SkAutoPixmapStorage::SkAutoPixmapStorage() : fStorage(nullptr) {}
|
||||
|
||||
SkAutoPixmapStorage::~SkAutoPixmapStorage() {
|
||||
this->freeStorage();
|
||||
}
|
||||
|
||||
size_t SkAutoPixmapStorage::AllocSize(const SkImageInfo& info, size_t* rowBytes) {
|
||||
size_t rb = info.minRowBytes();
|
||||
if (rowBytes) {
|
||||
*rowBytes = rb;
|
||||
}
|
||||
return info.getSafeSize(rb);
|
||||
}
|
||||
|
||||
bool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) {
|
||||
this->freeStorage();
|
||||
|
||||
size_t rb;
|
||||
size_t size = AllocSize(info, &rb);
|
||||
if (0 == size) {
|
||||
return false;
|
||||
}
|
||||
void* pixels = sk_malloc_flags(size, 0);
|
||||
if (nullptr == pixels) {
|
||||
return false;
|
||||
}
|
||||
this->reset(info, pixels, rb);
|
||||
fStorage = pixels;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkAutoPixmapStorage::alloc(const SkImageInfo& info) {
|
||||
if (!this->tryAlloc(info)) {
|
||||
sk_throw();
|
||||
}
|
||||
}
|
||||
|
||||
const SkData* SkAutoPixmapStorage::detachPixelsAsData() {
|
||||
if (!fStorage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto data = SkData::MakeFromMalloc(fStorage, this->getSafeSize());
|
||||
fStorage = nullptr;
|
||||
this->INHERITED::reset();
|
||||
|
||||
return data.release();
|
||||
}
|
||||
|
||||
void SkAutoPixmapStorage::release() {
|
||||
fStorage = nullptr;
|
||||
this->INHERITED::reset();
|
||||
}
|
87
src/core/SkAutoPixmapStorage.h
Normal file
87
src/core/SkAutoPixmapStorage.h
Normal file
@ -0,0 +1,87 @@
|
||||
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAutoPixmapStorage_DEFINED
|
||||
#define SkAutoPixmapStorage_DEFINED
|
||||
|
||||
#include "SkPixmap.h"
|
||||
|
||||
class SK_API SkAutoPixmapStorage : public SkPixmap {
|
||||
public:
|
||||
SkAutoPixmapStorage();
|
||||
~SkAutoPixmapStorage();
|
||||
|
||||
/**
|
||||
* Try to allocate memory for the pixels needed to match the specified Info. On success
|
||||
* return true and fill out the pixmap to point to that memory. The storage will be freed
|
||||
* when this object is destroyed, or if another call to tryAlloc() or alloc() is made.
|
||||
*
|
||||
* On failure, return false and reset() the pixmap to empty.
|
||||
*/
|
||||
bool tryAlloc(const SkImageInfo&);
|
||||
|
||||
/**
|
||||
* Allocate memory for the pixels needed to match the specified Info and fill out the pixmap
|
||||
* to point to that memory. The storage will be freed when this object is destroyed,
|
||||
* or if another call to tryAlloc() or alloc() is made.
|
||||
*
|
||||
* If the memory cannot be allocated, calls sk_throw().
|
||||
*/
|
||||
void alloc(const SkImageInfo&);
|
||||
|
||||
/**
|
||||
* Gets the size and optionally the rowBytes that would be allocated by SkAutoPixmapStorage if
|
||||
* alloc/tryAlloc was called.
|
||||
*/
|
||||
static size_t AllocSize(const SkImageInfo& info, size_t* rowBytes);
|
||||
|
||||
/**
|
||||
* Returns an SkData object wrapping the allocated pixels memory, and resets the pixmap.
|
||||
* If the storage hasn't been allocated, the result is NULL.
|
||||
*/
|
||||
const SkData* SK_WARN_UNUSED_RESULT detachPixelsAsData();
|
||||
|
||||
/**
|
||||
* Whereas 'reset' frees the backing memory and then clears the SkPixmap,
|
||||
* this entry point disowns the backing memory before clearing so the memory
|
||||
* isn't freed. It can be used when the Pixmap has been installed into
|
||||
* an SkBitmap and the SkBitmap should manage the memory's lifetime.
|
||||
*/
|
||||
void release();
|
||||
|
||||
// We wrap these so we can clear our internal storage
|
||||
|
||||
void reset() {
|
||||
this->freeStorage();
|
||||
this->INHERITED::reset();
|
||||
}
|
||||
void reset(const SkImageInfo& info, const void* addr, size_t rb, SkColorTable* ctable = NULL) {
|
||||
this->freeStorage();
|
||||
this->INHERITED::reset(info, addr, rb, ctable);
|
||||
}
|
||||
void reset(const SkImageInfo& info) {
|
||||
this->freeStorage();
|
||||
this->INHERITED::reset(info);
|
||||
}
|
||||
bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) {
|
||||
this->freeStorage();
|
||||
return this->INHERITED::reset(mask);
|
||||
}
|
||||
|
||||
private:
|
||||
void* fStorage;
|
||||
|
||||
void freeStorage() {
|
||||
sk_free(fStorage);
|
||||
fStorage = nullptr;
|
||||
}
|
||||
|
||||
typedef SkPixmap INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -281,51 +281,3 @@ bool SkPixmap::scalePixels(const SkPixmap& dst, SkFilterQuality quality) const {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkAutoPixmapStorage::SkAutoPixmapStorage() : fStorage(nullptr) {}
|
||||
|
||||
SkAutoPixmapStorage::~SkAutoPixmapStorage() {
|
||||
this->freeStorage();
|
||||
}
|
||||
|
||||
size_t SkAutoPixmapStorage::AllocSize(const SkImageInfo& info, size_t* rowBytes) {
|
||||
size_t rb = info.minRowBytes();
|
||||
if (rowBytes) {
|
||||
*rowBytes = rb;
|
||||
}
|
||||
return info.getSafeSize(rb);
|
||||
}
|
||||
|
||||
bool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) {
|
||||
this->freeStorage();
|
||||
|
||||
size_t rb;
|
||||
size_t size = AllocSize(info, &rb);
|
||||
if (0 == size) {
|
||||
return false;
|
||||
}
|
||||
void* pixels = sk_malloc_flags(size, 0);
|
||||
if (nullptr == pixels) {
|
||||
return false;
|
||||
}
|
||||
this->reset(info, pixels, rb);
|
||||
fStorage = pixels;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkAutoPixmapStorage::alloc(const SkImageInfo& info) {
|
||||
if (!this->tryAlloc(info)) {
|
||||
sk_throw();
|
||||
}
|
||||
}
|
||||
|
||||
const SkData* SkAutoPixmapStorage::detachPixelsAsData() {
|
||||
if (!fStorage) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto data = SkData::MakeFromMalloc(fStorage, this->getSafeSize());
|
||||
fStorage = nullptr;
|
||||
this->INHERITED::reset();
|
||||
|
||||
return data.release();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkDescriptor.h"
|
||||
#include "SkDraw.h"
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
|
||||
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const = 0;
|
||||
|
||||
virtual bool testingOnlyOnPeekPixels(SkPixmap*) const { return false; }
|
||||
virtual bool onPeekPixels(SkPixmap*) const { return false; }
|
||||
|
||||
virtual GrTexture* onPeekTexture() const { return nullptr; }
|
||||
|
||||
@ -29,7 +29,9 @@ public:
|
||||
// Delete this entry point ASAP (see skbug.com/4965)
|
||||
virtual bool getBitmapDeprecated(SkBitmap* result) const = 0;
|
||||
|
||||
virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { return nullptr; }
|
||||
virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const = 0;
|
||||
|
||||
virtual SkSpecialImage* onExtractSubset(const SkIRect& subset) const = 0;
|
||||
|
||||
private:
|
||||
typedef SkSpecialImage INHERITED;
|
||||
@ -44,8 +46,8 @@ void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain
|
||||
return as_SIB(this)->onDraw(canvas, x, y, paint);
|
||||
}
|
||||
|
||||
bool SkSpecialImage::testingOnlyPeekPixels(SkPixmap* pixmap) const {
|
||||
return as_SIB(this)->testingOnlyOnPeekPixels(pixmap);
|
||||
bool SkSpecialImage::peekPixels(SkPixmap* pixmap) const {
|
||||
return as_SIB(this)->onPeekPixels(pixmap);
|
||||
}
|
||||
|
||||
GrTexture* SkSpecialImage::peekTexture() const {
|
||||
@ -60,6 +62,10 @@ SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const {
|
||||
return as_SIB(this)->onNewSurface(info);
|
||||
}
|
||||
|
||||
SkSpecialImage* SkSpecialImage::extractSubset(const SkIRect& subset) const {
|
||||
return as_SIB(this)->onExtractSubset(subset);
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "SkGr.h"
|
||||
#include "SkGrPixelRef.h"
|
||||
@ -85,8 +91,7 @@ bool SkSpecialImage::internal_getBM(SkBitmap* result) {
|
||||
return ib->getBitmapDeprecated(result);
|
||||
}
|
||||
|
||||
SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() {
|
||||
SkASSERT(fProxy);
|
||||
SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() const {
|
||||
return fProxy;
|
||||
}
|
||||
|
||||
@ -129,7 +134,7 @@ public:
|
||||
dst, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
|
||||
bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override {
|
||||
bool onPeekPixels(SkPixmap* pixmap) const override {
|
||||
return fImage->peekPixels(pixmap);
|
||||
}
|
||||
|
||||
@ -170,6 +175,17 @@ public:
|
||||
return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr);
|
||||
}
|
||||
|
||||
SkSpecialImage* onExtractSubset(const SkIRect& subset) const override {
|
||||
SkAutoTUnref<SkImage> subsetImg(fImage->newSubset(subset));
|
||||
if (!subsetImg) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SkSpecialImage::NewFromImage(this->internal_getProxy(),
|
||||
SkIRect::MakeWH(subset.width(), subset.height()),
|
||||
subsetImg);
|
||||
}
|
||||
|
||||
private:
|
||||
SkAutoTUnref<const SkImage> fImage;
|
||||
|
||||
@ -214,6 +230,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
SkSpecialImage_Raster(SkImageFilter::Proxy* proxy,
|
||||
const SkIRect& subset,
|
||||
const SkPixmap& pixmap,
|
||||
void (*releaseProc)(void* addr, void* context),
|
||||
void* context)
|
||||
: INHERITED(proxy, subset, kNeedNewImageUniqueID_SpecialImage) {
|
||||
fBitmap.installPixels(pixmap.info(), pixmap.writable_addr(),
|
||||
pixmap.rowBytes(), pixmap.ctable(),
|
||||
releaseProc, context);
|
||||
}
|
||||
|
||||
~SkSpecialImage_Raster() override { }
|
||||
|
||||
bool isOpaque() const override { return fBitmap.isOpaque(); }
|
||||
@ -228,19 +255,13 @@ public:
|
||||
dst, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
|
||||
bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override {
|
||||
bool onPeekPixels(SkPixmap* pixmap) const override {
|
||||
const SkImageInfo info = fBitmap.info();
|
||||
if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
|
||||
return false;
|
||||
}
|
||||
const void* pixels = fBitmap.getPixels();
|
||||
if (pixels) {
|
||||
if (pixmap) {
|
||||
pixmap->reset(info, pixels, fBitmap.rowBytes());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return fBitmap.peekPixels(pixmap);
|
||||
}
|
||||
|
||||
bool getBitmapDeprecated(SkBitmap* result) const override {
|
||||
@ -257,6 +278,18 @@ public:
|
||||
return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr);
|
||||
}
|
||||
|
||||
SkSpecialImage* onExtractSubset(const SkIRect& subset) const override {
|
||||
SkBitmap subsetBM;
|
||||
|
||||
if (!fBitmap.extractSubset(&subsetBM, subset)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SkSpecialImage::NewFromRaster(this->internal_getProxy(),
|
||||
SkIRect::MakeWH(subset.width(), subset.height()),
|
||||
subsetBM);
|
||||
}
|
||||
|
||||
private:
|
||||
SkBitmap fBitmap;
|
||||
|
||||
@ -271,6 +304,15 @@ SkSpecialImage* SkSpecialImage::NewFromRaster(SkImageFilter::Proxy* proxy,
|
||||
return new SkSpecialImage_Raster(proxy, subset, bm);
|
||||
}
|
||||
|
||||
SkSpecialImage* SkSpecialImage::NewFromPixmap(SkImageFilter::Proxy* proxy,
|
||||
const SkIRect& subset,
|
||||
const SkPixmap& src,
|
||||
void (*releaseProc)(void* addr, void* context),
|
||||
void* context) {
|
||||
return new SkSpecialImage_Raster(proxy, subset, src, releaseProc, context);
|
||||
}
|
||||
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include "GrTexture.h"
|
||||
@ -315,7 +357,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
result->setPixelRef(new SkGrPixelRef(info, fTexture))->unref();
|
||||
const SkImageInfo prInfo = info.makeWH(fTexture->width(), fTexture->height());
|
||||
|
||||
SkAutoTUnref<SkGrPixelRef> pixelRef(new SkGrPixelRef(prInfo, fTexture));
|
||||
result->setPixelRef(pixelRef, this->subset().fLeft, this->subset().fTop);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -345,6 +390,14 @@ public:
|
||||
return SkSpecialSurface::NewRenderTarget(this->proxy(), fTexture->getContext(), desc);
|
||||
}
|
||||
|
||||
SkSpecialImage* onExtractSubset(const SkIRect& subset) const override {
|
||||
return SkSpecialImage::NewFromGpu(this->internal_getProxy(),
|
||||
subset,
|
||||
this->uniqueID(),
|
||||
fTexture,
|
||||
fAlphaType);
|
||||
}
|
||||
|
||||
private:
|
||||
SkAutoTUnref<GrTexture> fTexture;
|
||||
const SkAlphaType fAlphaType;
|
||||
|
@ -63,16 +63,27 @@ public:
|
||||
uint32_t uniqueID,
|
||||
GrTexture*,
|
||||
SkAlphaType at = kPremul_SkAlphaType);
|
||||
static SkSpecialImage* NewFromPixmap(SkImageFilter::Proxy*,
|
||||
const SkIRect& subset,
|
||||
const SkPixmap&,
|
||||
void (*releaseProc)(void* addr, void* context),
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* Create a new surface with a backend that is compatible with this image.
|
||||
*/
|
||||
SkSpecialSurface* newSurface(const SkImageInfo&) const;
|
||||
|
||||
/**
|
||||
* Extract a subset of this special image and return it as a special image.
|
||||
* It may or may not point to the same backing memory.
|
||||
*/
|
||||
SkSpecialImage* extractSubset(const SkIRect& subset) const;
|
||||
|
||||
// These three internal methods will go away (see skbug.com/4965)
|
||||
bool internal_getBM(SkBitmap* result);
|
||||
static SkSpecialImage* internal_fromBM(SkImageFilter::Proxy*, const SkBitmap&);
|
||||
SkImageFilter::Proxy* internal_getProxy();
|
||||
SkImageFilter::Proxy* internal_getProxy() const;
|
||||
|
||||
// TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063)
|
||||
/**
|
||||
@ -81,6 +92,20 @@ public:
|
||||
*/
|
||||
GrTexture* peekTexture() const;
|
||||
|
||||
// TODO: hide this whe the imagefilter all have a consistent draw path (see skbug.com/5063)
|
||||
/**
|
||||
* If the SpecialImage is backed by cpu pixels, return the const address
|
||||
* of those pixels and, if not null, the ImageInfo, rowBytes, and, if present,
|
||||
* the color table. The returned address(es) is/are only valid while the image object
|
||||
* is in scope.
|
||||
*
|
||||
* The returned ImageInfo represents the backing memory. Use 'subset'
|
||||
* to get the active portion's dimensions.
|
||||
*
|
||||
* On failure, return false and ignore the pixmap parameter.
|
||||
*/
|
||||
bool peekPixels(SkPixmap*) const;
|
||||
|
||||
protected:
|
||||
SkSpecialImage(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID)
|
||||
: fSubset(subset)
|
||||
@ -93,18 +118,6 @@ protected:
|
||||
friend class TestingSpecialImageAccess;
|
||||
friend class TestingSpecialSurfaceAccess;
|
||||
|
||||
/**
|
||||
* If the SpecialImage is backed by cpu pixels, return the const address
|
||||
* of those pixels and, if not null, return the ImageInfo and rowBytes.
|
||||
* The returned address is only valid while the image object is in scope.
|
||||
*
|
||||
* The returned ImageInfo represents the backing memory. Use 'subset'
|
||||
* to get the active portion's dimensions.
|
||||
*
|
||||
* On failure, return false and ignore the pixmap parameter.
|
||||
*/
|
||||
bool testingOnlyPeekPixels(SkPixmap*) const;
|
||||
|
||||
// This entry point is for testing only. It does a readback from VRAM for
|
||||
// GPU-backed special images.
|
||||
bool testingOnlyGetROPixels(SkBitmap*) const;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef GrSWMaskHelper_DEFINED
|
||||
#define GrSWMaskHelper_DEFINED
|
||||
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "GrColor.h"
|
||||
#include "GrPipelineBuilder.h"
|
||||
#include "SkBitmap.h"
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "GrCaps.h"
|
||||
#include "GrContext.h"
|
||||
#include "GrDrawContext.h"
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkDeviceLooper.h"
|
||||
#include "SkRasterClip.h"
|
||||
#include "Test.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "Test.h"
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkHalf.h"
|
||||
#include "SkOpts.h"
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <initializer_list>
|
||||
#include "DMGpuSupport.h"
|
||||
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkData.h"
|
||||
|
@ -5,9 +5,11 @@
|
||||
* found in the LICENSE file
|
||||
*/
|
||||
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkImage.h"
|
||||
#include "SkPixmap.h"
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkSpecialSurface.h"
|
||||
#include "Test.h"
|
||||
@ -48,10 +50,11 @@ static SkBitmap create_bm() {
|
||||
|
||||
// Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw)
|
||||
static void test_image(SkSpecialImage* img, skiatest::Reporter* reporter,
|
||||
bool peekPixelsSucceeds, bool peekTextureSucceeds) {
|
||||
bool peekPixelsSucceeds, bool peekTextureSucceeds,
|
||||
int offset, int size) {
|
||||
const SkIRect subset = TestingSpecialImageAccess::Subset(img);
|
||||
REPORTER_ASSERT(reporter, kPad == subset.left());
|
||||
REPORTER_ASSERT(reporter, kPad == subset.top());
|
||||
REPORTER_ASSERT(reporter, offset == subset.left());
|
||||
REPORTER_ASSERT(reporter, offset == subset.top());
|
||||
REPORTER_ASSERT(reporter, kSmallerSize == subset.width());
|
||||
REPORTER_ASSERT(reporter, kSmallerSize == subset.height());
|
||||
|
||||
@ -63,8 +66,8 @@ static void test_image(SkSpecialImage* img, skiatest::Reporter* reporter,
|
||||
REPORTER_ASSERT(reporter, peekPixelsSucceeds ==
|
||||
!!TestingSpecialImageAccess::PeekPixels(img, &pixmap));
|
||||
if (peekPixelsSucceeds) {
|
||||
REPORTER_ASSERT(reporter, kFullSize == pixmap.width());
|
||||
REPORTER_ASSERT(reporter, kFullSize == pixmap.height());
|
||||
REPORTER_ASSERT(reporter, size == pixmap.width());
|
||||
REPORTER_ASSERT(reporter, size == pixmap.height());
|
||||
}
|
||||
|
||||
//--------------
|
||||
@ -95,10 +98,22 @@ static void test_image(SkSpecialImage* img, skiatest::Reporter* reporter,
|
||||
DEF_TEST(SpecialImage_Raster, reporter) {
|
||||
SkBitmap bm = create_bm();
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> fullSImage(SkSpecialImage::NewFromRaster(
|
||||
nullptr,
|
||||
SkIRect::MakeWH(kFullSize, kFullSize),
|
||||
bm));
|
||||
|
||||
const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromRaster(nullptr, subset, bm));
|
||||
test_image(img, reporter, true, false);
|
||||
{
|
||||
SkAutoTUnref<SkSpecialImage> subSImg1(SkSpecialImage::NewFromRaster(nullptr, subset, bm));
|
||||
test_image(subSImg1, reporter, true, false, kPad, kFullSize);
|
||||
}
|
||||
|
||||
{
|
||||
SkAutoTUnref<SkSpecialImage> subSImg2(fullSImage->extractSubset(subset));
|
||||
test_image(subSImg2, reporter, true, false, 0, kSmallerSize);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(SpecialImage_Image, reporter) {
|
||||
@ -106,12 +121,56 @@ DEF_TEST(SpecialImage_Image, reporter) {
|
||||
|
||||
SkAutoTUnref<SkImage> fullImage(SkImage::NewFromBitmap(bm));
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> fullSImage(SkSpecialImage::NewFromImage(
|
||||
nullptr,
|
||||
SkIRect::MakeWH(kFullSize, kFullSize),
|
||||
fullImage));
|
||||
|
||||
const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromImage(nullptr, subset, fullImage));
|
||||
test_image(img, reporter, true, false);
|
||||
{
|
||||
SkAutoTUnref<SkSpecialImage> subSImg1(SkSpecialImage::NewFromImage(nullptr,
|
||||
subset,
|
||||
fullImage));
|
||||
test_image(subSImg1, reporter, true, false, kPad, kFullSize);
|
||||
}
|
||||
|
||||
{
|
||||
SkAutoTUnref<SkSpecialImage> subSImg2(fullSImage->extractSubset(subset));
|
||||
test_image(subSImg2, reporter, true, false, 0, kSmallerSize);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(SpecialImage_Pixmap, reporter) {
|
||||
SkAutoPixmapStorage pixmap;
|
||||
|
||||
const SkImageInfo info = SkImageInfo::MakeN32(kFullSize, kFullSize, kOpaque_SkAlphaType);
|
||||
pixmap.alloc(info);
|
||||
pixmap.erase(SK_ColorGREEN);
|
||||
|
||||
const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
|
||||
|
||||
pixmap.erase(SK_ColorRED, subset);
|
||||
|
||||
{
|
||||
// The SkAutoPixmapStorage keeps hold of the memory
|
||||
SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromPixmap(nullptr, subset, pixmap,
|
||||
nullptr, nullptr));
|
||||
test_image(img, reporter, true, false, kPad, kFullSize);
|
||||
}
|
||||
|
||||
{
|
||||
// The image takes ownership of the memory
|
||||
SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromPixmap(
|
||||
nullptr, subset, pixmap,
|
||||
[] (void* addr, void*) -> void { sk_free(addr); },
|
||||
nullptr));
|
||||
pixmap.release();
|
||||
test_image(img, reporter, true, false, kPad, kFullSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, context) {
|
||||
SkBitmap bm = create_bm();
|
||||
@ -128,12 +187,26 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, context) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> fullSImg(SkSpecialImage::NewFromGpu(
|
||||
nullptr,
|
||||
SkIRect::MakeWH(kFullSize, kFullSize),
|
||||
kNeedNewImageUniqueID_SpecialImage,
|
||||
texture));
|
||||
|
||||
const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
|
||||
|
||||
SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromGpu(nullptr, subset,
|
||||
kNeedNewImageUniqueID_SpecialImage,
|
||||
texture));
|
||||
test_image(img, reporter, false, true);
|
||||
{
|
||||
SkAutoTUnref<SkSpecialImage> subSImg1(SkSpecialImage::NewFromGpu(
|
||||
nullptr, subset,
|
||||
kNeedNewImageUniqueID_SpecialImage,
|
||||
texture));
|
||||
test_image(subSImg1, reporter, false, true, kPad, kFullSize);
|
||||
}
|
||||
|
||||
{
|
||||
SkAutoTUnref<SkSpecialImage> subSImg2(fullSImg->extractSubset(subset));
|
||||
test_image(subSImg2, reporter, false, true, kPad, kFullSize);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@ public:
|
||||
}
|
||||
|
||||
static bool PeekPixels(const SkSpecialImage* img, SkPixmap* pixmap) {
|
||||
return img->testingOnlyPeekPixels(pixmap);
|
||||
return img->peekPixels(pixmap);
|
||||
}
|
||||
|
||||
static GrTexture* PeekTexture(const SkSpecialImage* img) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkAutoPixmapStorage.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkData.h"
|
||||
#include "SkEndian.h"
|
||||
|
Loading…
Reference in New Issue
Block a user