Make Flattenable not virtual

Fallout from the Flattenable change, update all its uses.

Additionnaly, fix/tighten size checks when (un)flatten()ing
things.

Removed the assumption by some flattenables (e.g.: Fence)
that the size passed to them would be exact (it can
and will be larger in some cases)

The code in Parcel is a bit complicated so that we don't
have to expose the full implementation (and also to
keep the code smallish).

Change-Id: I0bf1c8aca2a3128491b4f45510bc46667e566dde
This commit is contained in:
Mathias Agopian 2013-07-29 21:24:40 -07:00
parent 1d76781b7a
commit e142428a9c
13 changed files with 228 additions and 156 deletions

View File

@ -27,8 +27,8 @@
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
namespace android { namespace android {
template <typename T> class Flattenable;
template <typename T> class LightFlattenable; template <typename T> class LightFlattenable;
class Flattenable;
class IBinder; class IBinder;
class IPCThreadState; class IPCThreadState;
class ProcessState; class ProcessState;
@ -37,8 +37,7 @@ class TextOutput;
struct flat_binder_object; // defined in support_p/binder_module.h struct flat_binder_object; // defined in support_p/binder_module.h
class Parcel class Parcel {
{
public: public:
class ReadableBlob; class ReadableBlob;
class WritableBlob; class WritableBlob;
@ -102,7 +101,9 @@ public:
status_t writeString16(const char16_t* str, size_t len); status_t writeString16(const char16_t* str, size_t len);
status_t writeStrongBinder(const sp<IBinder>& val); status_t writeStrongBinder(const sp<IBinder>& val);
status_t writeWeakBinder(const wp<IBinder>& val); status_t writeWeakBinder(const wp<IBinder>& val);
status_t write(const Flattenable& val);
template<typename T>
status_t write(const Flattenable<T>& val);
template<typename T> template<typename T>
status_t write(const LightFlattenable<T>& val); status_t write(const LightFlattenable<T>& val);
@ -157,7 +158,9 @@ public:
const char16_t* readString16Inplace(size_t* outLen) const; const char16_t* readString16Inplace(size_t* outLen) const;
sp<IBinder> readStrongBinder() const; sp<IBinder> readStrongBinder() const;
wp<IBinder> readWeakBinder() const; wp<IBinder> readWeakBinder() const;
status_t read(Flattenable& val) const;
template<typename T>
status_t read(Flattenable<T>& val) const;
template<typename T> template<typename T>
status_t read(LightFlattenable<T>& val) const; status_t read(LightFlattenable<T>& val) const;
@ -260,6 +263,39 @@ private:
size_t mSize; size_t mSize;
}; };
class FlattenableHelperInterface {
protected:
~FlattenableHelperInterface() { }
public:
virtual size_t getFlattenedSize() const = 0;
virtual size_t getFdCount() const = 0;
virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const = 0;
virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) = 0;
};
template<typename T>
class FlattenableHelper : public FlattenableHelperInterface {
friend class Parcel;
const Flattenable<T>& val;
explicit FlattenableHelper(const Flattenable<T>& val) : val(val) { }
public:
virtual size_t getFlattenedSize() const {
return val.getFlattenedSize();
}
virtual size_t getFdCount() const {
return val.getFdCount();
}
virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const {
return val.flatten(buffer, size, fds, count);
}
virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) {
return const_cast<Flattenable<T>&>(val).unflatten(buffer, size, fds, count);
}
};
status_t write(const FlattenableHelperInterface& val);
status_t read(FlattenableHelperInterface& val) const;
public: public:
class ReadableBlob : public Blob { class ReadableBlob : public Blob {
friend class Parcel; friend class Parcel;
@ -276,9 +312,15 @@ public:
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template<typename T>
status_t Parcel::write(const Flattenable<T>& val) {
const FlattenableHelper<T> helper(val);
return write(helper);
}
template<typename T> template<typename T>
status_t Parcel::write(const LightFlattenable<T>& val) { status_t Parcel::write(const LightFlattenable<T>& val) {
size_t size(val.getSize()); size_t size(val.getFlattenedSize());
if (!val.isFixedSize()) { if (!val.isFixedSize()) {
status_t err = writeInt32(size); status_t err = writeInt32(size);
if (err != NO_ERROR) { if (err != NO_ERROR) {
@ -287,17 +329,24 @@ status_t Parcel::write(const LightFlattenable<T>& val) {
} }
if (size) { if (size) {
void* buffer = writeInplace(size); void* buffer = writeInplace(size);
return buffer == NULL ? NO_MEMORY : if (buffer == NULL)
val.flatten(buffer); return NO_MEMORY;
return val.flatten(buffer, size);
} }
return NO_ERROR; return NO_ERROR;
} }
template<typename T>
status_t Parcel::read(Flattenable<T>& val) const {
FlattenableHelper<T> helper(val);
return read(helper);
}
template<typename T> template<typename T>
status_t Parcel::read(LightFlattenable<T>& val) const { status_t Parcel::read(LightFlattenable<T>& val) const {
size_t size; size_t size;
if (val.isFixedSize()) { if (val.isFixedSize()) {
size = val.getSize(); size = val.getFlattenedSize();
} else { } else {
int32_t s; int32_t s;
status_t err = readInt32(&s); status_t err = readInt32(&s);

View File

@ -105,7 +105,8 @@ public:
// and height of the window and current transform applied to buffers, // and height of the window and current transform applied to buffers,
// respectively. // respectively.
struct QueueBufferInput : public Flattenable { struct QueueBufferInput : public Flattenable<QueueBufferInput> {
friend class Flattenable<QueueBufferInput>;
inline QueueBufferInput(const Parcel& parcel); inline QueueBufferInput(const Parcel& parcel);
inline QueueBufferInput(int64_t timestamp, inline QueueBufferInput(int64_t timestamp,
const Rect& crop, int scalingMode, uint32_t transform, bool async, const Rect& crop, int scalingMode, uint32_t transform, bool async,
@ -123,13 +124,11 @@ public:
*outFence = fence; *outFence = fence;
} }
// Flattenable interface // Flattenable protocol
virtual size_t getFlattenedSize() const; size_t getFlattenedSize() const;
virtual size_t getFdCount() const; size_t getFdCount() const;
virtual status_t flatten(void* buffer, size_t size, status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
int fds[], size_t count) const; status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
virtual status_t unflatten(void const* buffer, size_t size,
int fds[], size_t count);
private: private:
int64_t timestamp; int64_t timestamp;

View File

@ -70,8 +70,8 @@ public:
// LightFlattenable protocol // LightFlattenable protocol
inline bool isFixedSize() const { return false; } inline bool isFixedSize() const { return false; }
size_t getSize() const; size_t getFlattenedSize() const;
status_t flatten(void* buffer) const; status_t flatten(void* buffer, size_t size) const;
status_t unflatten(void const* buffer, size_t size); status_t unflatten(void const* buffer, size_t size);
private: private:

View File

@ -36,7 +36,7 @@ namespace android {
// =========================================================================== // ===========================================================================
class Fence class Fence
: public LightRefBase<Fence>, public Flattenable : public LightRefBase<Fence>, public Flattenable<Fence>
{ {
public: public:
static const sp<Fence> NO_FENCE; static const sp<Fence> NO_FENCE;
@ -96,15 +96,13 @@ public:
// Flattenable interface // Flattenable interface
size_t getFlattenedSize() const; size_t getFlattenedSize() const;
size_t getFdCount() const; size_t getFdCount() const;
status_t flatten(void* buffer, size_t size, status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
int fds[], size_t count) const; status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
status_t unflatten(void const* buffer, size_t size,
int fds[], size_t count);
private: private:
// Only allow instantiation using ref counting. // Only allow instantiation using ref counting.
friend class LightRefBase<Fence>; friend class LightRefBase<Fence>;
virtual ~Fence(); ~Fence();
// Disallow copying // Disallow copying
Fence(const Fence& rhs); Fence(const Fence& rhs);

View File

@ -39,8 +39,9 @@ class GraphicBufferMapper;
class GraphicBuffer class GraphicBuffer
: public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >, : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,
public Flattenable public Flattenable<GraphicBuffer>
{ {
friend class Flattenable<GraphicBuffer>;
public: public:
enum { enum {
@ -106,7 +107,7 @@ public:
static void dumpAllocationsToSystemLog(); static void dumpAllocationsToSystemLog();
private: private:
virtual ~GraphicBuffer(); ~GraphicBuffer();
enum { enum {
ownNone = 0, ownNone = 0,
@ -136,13 +137,11 @@ private:
void free_handle(); void free_handle();
// Flattenable interface // Flattenable protocol
size_t getFlattenedSize() const; size_t getFlattenedSize() const;
size_t getFdCount() const; size_t getFdCount() const;
status_t flatten(void* buffer, size_t size, status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
int fds[], size_t count) const; status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
status_t unflatten(void const* buffer, size_t size,
int fds[], size_t count);
GraphicBufferMapper& mBufferMapper; GraphicBufferMapper& mBufferMapper;

View File

@ -136,8 +136,8 @@ public:
void addRectUnchecked(int l, int t, int r, int b); void addRectUnchecked(int l, int t, int r, int b);
inline bool isFixedSize() const { return false; } inline bool isFixedSize() const { return false; }
size_t getSize() const; size_t getFlattenedSize() const;
status_t flatten(void* buffer) const; status_t flatten(void* buffer, size_t size) const;
status_t unflatten(void const* buffer, size_t size); status_t unflatten(void const* buffer, size_t size);
void dump(String8& out, const char* what, uint32_t flags=0) const; void dump(String8& out, const char* what, uint32_t flags=0) const;

View File

@ -798,13 +798,13 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
return status; return status;
} }
status_t Parcel::write(const Flattenable& val) status_t Parcel::write(const FlattenableHelperInterface& val)
{ {
status_t err; status_t err;
// size if needed // size if needed
size_t len = val.getFlattenedSize(); const size_t len = val.getFlattenedSize();
size_t fd_count = val.getFdCount(); const size_t fd_count = val.getFdCount();
err = this->writeInt32(len); err = this->writeInt32(len);
if (err) return err; if (err) return err;
@ -813,7 +813,7 @@ status_t Parcel::write(const Flattenable& val)
if (err) return err; if (err) return err;
// payload // payload
void* buf = this->writeInplace(PAD_SIZE(len)); void* const buf = this->writeInplace(PAD_SIZE(len));
if (buf == NULL) if (buf == NULL)
return BAD_VALUE; return BAD_VALUE;
@ -1174,14 +1174,14 @@ status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
return NO_ERROR; return NO_ERROR;
} }
status_t Parcel::read(Flattenable& val) const status_t Parcel::read(FlattenableHelperInterface& val) const
{ {
// size // size
const size_t len = this->readInt32(); const size_t len = this->readInt32();
const size_t fd_count = this->readInt32(); const size_t fd_count = this->readInt32();
// payload // payload
void const* buf = this->readInplace(PAD_SIZE(len)); void const* const buf = this->readInplace(PAD_SIZE(len));
if (buf == NULL) if (buf == NULL)
return BAD_VALUE; return BAD_VALUE;

View File

@ -270,8 +270,7 @@ IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel)
parcel.read(*this); parcel.read(*this);
} }
size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
{
return sizeof(timestamp) return sizeof(timestamp)
+ sizeof(crop) + sizeof(crop)
+ sizeof(scalingMode) + sizeof(scalingMode)
@ -280,38 +279,46 @@ size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const
+ fence->getFlattenedSize(); + fence->getFlattenedSize();
} }
size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
{
return fence->getFdCount(); return fence->getFdCount();
} }
status_t IGraphicBufferProducer::QueueBufferInput::flatten(void* buffer, size_t size, status_t IGraphicBufferProducer::QueueBufferInput::flatten(
int fds[], size_t count) const void*& buffer, size_t& size, int*& fds, size_t& count) const
{ {
status_t err = NO_ERROR; if (size < getFlattenedSize()) {
char* p = (char*)buffer; return NO_MEMORY;
memcpy(p, &timestamp, sizeof(timestamp)); p += sizeof(timestamp); }
memcpy(p, &crop, sizeof(crop)); p += sizeof(crop); FlattenableUtils::write(buffer, size, timestamp);
memcpy(p, &scalingMode, sizeof(scalingMode)); p += sizeof(scalingMode); FlattenableUtils::write(buffer, size, crop);
memcpy(p, &transform, sizeof(transform)); p += sizeof(transform); FlattenableUtils::write(buffer, size, scalingMode);
memcpy(p, &async, sizeof(async)); p += sizeof(async); FlattenableUtils::write(buffer, size, transform);
err = fence->flatten(p, size - (p - (char*)buffer), fds, count); FlattenableUtils::write(buffer, size, async);
return err; return fence->flatten(buffer, size, fds, count);
} }
status_t IGraphicBufferProducer::QueueBufferInput::unflatten(void const* buffer, status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
size_t size, int fds[], size_t count) void const*& buffer, size_t& size, int const*& fds, size_t& count)
{ {
status_t err = NO_ERROR; size_t minNeeded =
const char* p = (const char*)buffer; sizeof(timestamp)
memcpy(&timestamp, p, sizeof(timestamp)); p += sizeof(timestamp); + sizeof(crop)
memcpy(&crop, p, sizeof(crop)); p += sizeof(crop); + sizeof(scalingMode)
memcpy(&scalingMode, p, sizeof(scalingMode)); p += sizeof(scalingMode); + sizeof(transform)
memcpy(&transform, p, sizeof(transform)); p += sizeof(transform); + sizeof(async);
memcpy(&async, p, sizeof(async)); p += sizeof(async);
if (size < minNeeded) {
return NO_MEMORY;
}
FlattenableUtils::read(buffer, size, timestamp);
FlattenableUtils::read(buffer, size, crop);
FlattenableUtils::read(buffer, size, scalingMode);
FlattenableUtils::read(buffer, size, transform);
FlattenableUtils::read(buffer, size, async);
fence = new Fence(); fence = new Fence();
err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count); return fence->unflatten(buffer, size, fds, count);
return err;
} }
}; // namespace android }; // namespace android

View File

@ -98,85 +98,85 @@ int32_t Sensor::getVersion() const {
return mVersion; return mVersion;
} }
size_t Sensor::getSize() const size_t Sensor::getFlattenedSize() const
{ {
return sizeof(int32_t) + ((mName.length() + 3) & ~3) + size_t fixedSize =
sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
sizeof(int32_t) * 3 + sizeof(int32_t) * 3 +
sizeof(float) * 4 + sizeof(float) * 4 +
sizeof(int32_t); sizeof(int32_t);
size_t variableSize =
sizeof(int32_t) + FlattenableUtils::align<4>(mName.length()) +
sizeof(int32_t) + FlattenableUtils::align<4>(mVendor.length());
return fixedSize + variableSize;
} }
static inline status_t Sensor::flatten(void* buffer, size_t size) const {
size_t write(void* buffer, size_t offset, const String8& value) { if (size < getFlattenedSize()) {
memcpy(static_cast<char*>(buffer) + offset, value.string(), value.length()); return NO_MEMORY;
return (value.length() + 3) & ~3; }
}
static inline FlattenableUtils::write(buffer, size, mName.length());
size_t write(void* buffer, size_t offset, float value) { memcpy(static_cast<char*>(buffer), mName.string(), mName.length());
*reinterpret_cast<float*>(static_cast<char*>(buffer) + offset) = value; FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mName.length()));
return sizeof(float);
}
static inline FlattenableUtils::write(buffer, size, mVendor.length());
size_t write(void* buffer, size_t offset, int32_t value) { memcpy(static_cast<char*>(buffer), mVendor.string(), mVendor.length());
*reinterpret_cast<int32_t*>(static_cast<char*>(buffer) + offset) = value; FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mVendor.length()));
return sizeof(int32_t);
}
status_t Sensor::flatten(void* buffer) const FlattenableUtils::write(buffer, size, mVersion);
{ FlattenableUtils::write(buffer, size, mHandle);
size_t offset = 0; FlattenableUtils::write(buffer, size, mType);
offset += write(buffer, offset, int32_t(mName.length())); FlattenableUtils::write(buffer, size, mMinValue);
offset += write(buffer, offset, mName); FlattenableUtils::write(buffer, size, mMaxValue);
offset += write(buffer, offset, int32_t(mVendor.length())); FlattenableUtils::write(buffer, size, mResolution);
offset += write(buffer, offset, mVendor); FlattenableUtils::write(buffer, size, mPower);
offset += write(buffer, offset, mVersion); FlattenableUtils::write(buffer, size, mMinDelay);
offset += write(buffer, offset, mHandle);
offset += write(buffer, offset, mType);
offset += write(buffer, offset, mMinValue);
offset += write(buffer, offset, mMaxValue);
offset += write(buffer, offset, mResolution);
offset += write(buffer, offset, mPower);
offset += write(buffer, offset, mMinDelay);
return NO_ERROR; return NO_ERROR;
} }
static inline status_t Sensor::unflatten(void const* buffer, size_t size) {
size_t read(void const* buffer, size_t offset, String8* value, int32_t len) { size_t len;
value->setTo(static_cast<char const*>(buffer) + offset, len);
return (len + 3) & ~3;
}
static inline if (size < sizeof(size_t)) {
size_t read(void const* buffer, size_t offset, float* value) { return NO_MEMORY;
*value = *reinterpret_cast<float const*>(static_cast<char const*>(buffer) + offset); }
return sizeof(float); FlattenableUtils::read(buffer, size, len);
} if (size < len) {
return NO_MEMORY;
}
mName.setTo(static_cast<char const*>(buffer), len);
FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
static inline
size_t read(void const* buffer, size_t offset, int32_t* value) {
*value = *reinterpret_cast<int32_t const*>(static_cast<char const*>(buffer) + offset);
return sizeof(int32_t);
}
status_t Sensor::unflatten(void const* buffer, size_t size) if (size < sizeof(size_t)) {
{ return NO_MEMORY;
int32_t len; }
size_t offset = 0; FlattenableUtils::read(buffer, size, len);
offset += read(buffer, offset, &len); if (size < len) {
offset += read(buffer, offset, &mName, len); return NO_MEMORY;
offset += read(buffer, offset, &len); }
offset += read(buffer, offset, &mVendor, len); mVendor.setTo(static_cast<char const*>(buffer), len);
offset += read(buffer, offset, &mVersion); FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
offset += read(buffer, offset, &mHandle);
offset += read(buffer, offset, &mType); size_t fixedSize =
offset += read(buffer, offset, &mMinValue); sizeof(int32_t) * 3 +
offset += read(buffer, offset, &mMaxValue); sizeof(float) * 4 +
offset += read(buffer, offset, &mResolution); sizeof(int32_t);
offset += read(buffer, offset, &mPower);
offset += read(buffer, offset, &mMinDelay); if (size < fixedSize) {
return NO_MEMORY;
}
FlattenableUtils::read(buffer, size, mVersion);
FlattenableUtils::read(buffer, size, mHandle);
FlattenableUtils::read(buffer, size, mType);
FlattenableUtils::read(buffer, size, mMinValue);
FlattenableUtils::read(buffer, size, mMaxValue);
FlattenableUtils::read(buffer, size, mResolution);
FlattenableUtils::read(buffer, size, mPower);
FlattenableUtils::read(buffer, size, mMinDelay);
return NO_ERROR; return NO_ERROR;
} }

View File

@ -127,37 +127,49 @@ nsecs_t Fence::getSignalTime() const {
} }
size_t Fence::getFlattenedSize() const { size_t Fence::getFlattenedSize() const {
return 0; return 1;
} }
size_t Fence::getFdCount() const { size_t Fence::getFdCount() const {
return isValid() ? 1 : 0; return isValid() ? 1 : 0;
} }
status_t Fence::flatten(void* buffer, size_t size, int fds[], status_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
size_t count) const { if (size < getFlattenedSize() || count < getFdCount()) {
if (size != getFlattenedSize() || count != getFdCount()) { return NO_MEMORY;
return BAD_VALUE;
} }
FlattenableUtils::write(buffer, size, getFdCount());
if (isValid()) { if (isValid()) {
fds[0] = mFenceFd; *fds++ = mFenceFd;
count--;
} }
return NO_ERROR; return NO_ERROR;
} }
status_t Fence::unflatten(void const* buffer, size_t size, int fds[], status_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) {
size_t count) {
if (size != 0 || (count != 0 && count != 1)) {
return BAD_VALUE;
}
if (mFenceFd != -1) { if (mFenceFd != -1) {
// Don't unflatten if we already have a valid fd. // Don't unflatten if we already have a valid fd.
return INVALID_OPERATION; return INVALID_OPERATION;
} }
if (count == 1) { if (size < 1) {
mFenceFd = fds[0]; return NO_MEMORY;
}
size_t numFds;
FlattenableUtils::read(buffer, size, numFds);
if (numFds > 1) {
return BAD_VALUE;
}
if (count < numFds) {
return NO_MEMORY;
}
if (numFds) {
mFenceFd = *fds++;
count--;
} }
return NO_ERROR; return NO_ERROR;

View File

@ -209,9 +209,7 @@ size_t GraphicBuffer::getFdCount() const {
return handle ? handle->numFds : 0; return handle ? handle->numFds : 0;
} }
status_t GraphicBuffer::flatten(void* buffer, size_t size, status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
int fds[], size_t count) const
{
size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
if (size < sizeNeeded) return NO_MEMORY; if (size < sizeNeeded) return NO_MEMORY;
@ -236,12 +234,16 @@ status_t GraphicBuffer::flatten(void* buffer, size_t size,
memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int)); memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
} }
buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded);
size -= sizeNeeded;
fds += handle->numFds;
count -= handle->numFds;
return NO_ERROR; return NO_ERROR;
} }
status_t GraphicBuffer::unflatten(void const* buffer, size_t size, status_t GraphicBuffer::unflatten(
int fds[], size_t count) void const*& buffer, size_t& size, int const*& fds, size_t& count) {
{
if (size < 8*sizeof(int)) return NO_MEMORY; if (size < 8*sizeof(int)) return NO_MEMORY;
int const* buf = static_cast<int const*>(buffer); int const* buf = static_cast<int const*>(buffer);
@ -287,6 +289,11 @@ status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
} }
} }
buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded);
size -= sizeNeeded;
fds += numFds;
count -= numFds;
return NO_ERROR; return NO_ERROR;
} }

View File

@ -715,14 +715,17 @@ void Region::translate(Region& dst, const Region& reg, int dx, int dy)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
size_t Region::getSize() const { size_t Region::getFlattenedSize() const {
return mStorage.size() * sizeof(Rect); return mStorage.size() * sizeof(Rect);
} }
status_t Region::flatten(void* buffer) const { status_t Region::flatten(void* buffer, size_t size) const {
#if VALIDATE_REGIONS #if VALIDATE_REGIONS
validate(*this, "Region::flatten"); validate(*this, "Region::flatten");
#endif #endif
if (size < mStorage.size() * sizeof(Rect)) {
return NO_MEMORY;
}
Rect* rects = reinterpret_cast<Rect*>(buffer); Rect* rects = reinterpret_cast<Rect*>(buffer);
memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect)); memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
return NO_ERROR; return NO_ERROR;

View File

@ -253,8 +253,7 @@ void egl_cache_t::saveBlobCacheLocked() {
return; return;
} }
status_t err = mBlobCache->flatten(buf + headerSize, cacheSize, NULL, status_t err = mBlobCache->flatten(buf + headerSize, cacheSize);
0);
if (err != OK) { if (err != OK) {
ALOGE("error writing cache contents: %s (%d)", strerror(-err), ALOGE("error writing cache contents: %s (%d)", strerror(-err),
-err); -err);
@ -335,8 +334,7 @@ void egl_cache_t::loadBlobCacheLocked() {
return; return;
} }
status_t err = mBlobCache->unflatten(buf + headerSize, cacheSize, NULL, status_t err = mBlobCache->unflatten(buf + headerSize, cacheSize);
0);
if (err != OK) { if (err != OK) {
ALOGE("error reading cache contents: %s (%d)", strerror(-err), ALOGE("error reading cache contents: %s (%d)", strerror(-err),
-err); -err);