factor out flattening/unflattening of common fields from SkImageFilter
This is a precursor to changing SkImageFilters (and all effects) to unflatten via a factory instead of a constructor. In that world, each subclass of ImageFilter will need to control/initiate the unflattening of the common fields, so they can be extract and passed to their Factory. R=senorblanco@google.com, robertphillips@google.com, mtklein@google.com, senorblanco@chromium.org Author: reed@google.com Review URL: https://codereview.chromium.org/395273002
This commit is contained in:
parent
3eb258d3f6
commit
b959ec7815
@ -11,6 +11,7 @@
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkColorFilter;
|
||||
@ -199,6 +200,31 @@ public:
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
|
||||
|
||||
protected:
|
||||
class Common {
|
||||
public:
|
||||
Common() {}
|
||||
~Common();
|
||||
|
||||
bool unflatten(SkReadBuffer&, int expectedInputs = -1);
|
||||
|
||||
CropRect cropRect() const { return fCropRect; }
|
||||
int inputCount() const { return fInputs.count(); }
|
||||
SkImageFilter** inputs() const { return fInputs.get(); }
|
||||
|
||||
// If the caller wants a copy of the inputs, call this and it will transfer ownership
|
||||
// of the unflattened input filters to the caller. This is just a short-cut for copying
|
||||
// the inputs, calling ref() on each, and then waiting for Common's destructor to call
|
||||
// unref() on each.
|
||||
void detachInputs(SkImageFilter** inputs);
|
||||
|
||||
private:
|
||||
CropRect fCropRect;
|
||||
// most filters accept at most 2 input-filters
|
||||
SkAutoSTArray<2, SkImageFilter*> fInputs;
|
||||
|
||||
void allocInputs(int count);
|
||||
};
|
||||
|
||||
SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL);
|
||||
|
||||
virtual ~SkImageFilter();
|
||||
|
@ -21,6 +21,55 @@
|
||||
#include "SkGr.h"
|
||||
#endif
|
||||
|
||||
SkImageFilter::Common::~Common() {
|
||||
for (int i = 0; i < fInputs.count(); ++i) {
|
||||
SkSafeUnref(fInputs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SkImageFilter::Common::allocInputs(int count) {
|
||||
const size_t size = count * sizeof(SkImageFilter*);
|
||||
fInputs.reset(count);
|
||||
sk_bzero(fInputs.get(), size);
|
||||
}
|
||||
|
||||
void SkImageFilter::Common::detachInputs(SkImageFilter** inputs) {
|
||||
const size_t size = fInputs.count() * sizeof(SkImageFilter*);
|
||||
memcpy(inputs, fInputs.get(), size);
|
||||
sk_bzero(fInputs.get(), size);
|
||||
}
|
||||
|
||||
bool SkImageFilter::Common::unflatten(SkReadBuffer& buffer, int expectedCount) {
|
||||
int count = buffer.readInt();
|
||||
if (expectedCount < 0) { // means the caller doesn't care how many
|
||||
expectedCount = count;
|
||||
}
|
||||
if (!buffer.validate(count == expectedCount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->allocInputs(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (buffer.readBool()) {
|
||||
fInputs[i] = buffer.readImageFilter();
|
||||
}
|
||||
if (!buffer.isValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
SkRect rect;
|
||||
buffer.readRect(&rect);
|
||||
if (!buffer.isValid() || !buffer.validate(SkIsValidRect(rect))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t flags = buffer.readUInt();
|
||||
fCropRect = CropRect(rect, flags);
|
||||
return buffer.isValid();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkImageFilter::Cache* gExternalCache;
|
||||
|
||||
SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect)
|
||||
@ -41,26 +90,12 @@ SkImageFilter::~SkImageFilter() {
|
||||
}
|
||||
|
||||
SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) {
|
||||
fInputCount = buffer.readInt();
|
||||
if (buffer.validate((fInputCount >= 0) && ((inputCount < 0) || (fInputCount == inputCount)))) {
|
||||
fInputs = new SkImageFilter*[fInputCount];
|
||||
for (int i = 0; i < fInputCount; i++) {
|
||||
if (buffer.readBool()) {
|
||||
fInputs[i] = buffer.readImageFilter();
|
||||
} else {
|
||||
fInputs[i] = NULL;
|
||||
}
|
||||
if (!buffer.isValid()) {
|
||||
fInputCount = i; // Do not use fInputs past that point in the destructor
|
||||
break;
|
||||
}
|
||||
}
|
||||
SkRect rect;
|
||||
buffer.readRect(&rect);
|
||||
if (buffer.isValid() && buffer.validate(SkIsValidRect(rect))) {
|
||||
uint32_t flags = buffer.readUInt();
|
||||
fCropRect = CropRect(rect, flags);
|
||||
}
|
||||
Common common;
|
||||
if (common.unflatten(buffer, inputCount)) {
|
||||
fCropRect = common.cropRect();
|
||||
fInputCount = common.inputCount();
|
||||
fInputs = SkNEW_ARRAY(SkImageFilter*, fInputCount);
|
||||
common.detachInputs(fInputs);
|
||||
} else {
|
||||
fInputCount = 0;
|
||||
fInputs = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user