remove a dependency of GraphicBuffer (libui) on Parcel (libbinder).
Add a Flattenable interface to libutils which can be used to flatten an object into bytestream + filedescriptor stream. Parcel is modified to handle Flattenable. And GraphicBuffer implements Flattenable. Except for the overlay classes libui is now independent of libbinder.
This commit is contained in:
parent
e4f5055ad2
commit
98e71ddaed
|
@ -30,6 +30,7 @@ class IBinder;
|
|||
class ProcessState;
|
||||
class String8;
|
||||
class TextOutput;
|
||||
class Flattenable;
|
||||
|
||||
struct flat_binder_object; // defined in support_p/binder_module.h
|
||||
|
||||
|
@ -81,6 +82,7 @@ public:
|
|||
status_t writeString16(const char16_t* str, size_t len);
|
||||
status_t writeStrongBinder(const sp<IBinder>& val);
|
||||
status_t writeWeakBinder(const wp<IBinder>& val);
|
||||
status_t write(const Flattenable& val);
|
||||
|
||||
// Place a native_handle into the parcel (the native_handle's file-
|
||||
// descriptors are dup'ed, so it is safe to delete the native_handle
|
||||
|
@ -119,7 +121,7 @@ public:
|
|||
const char16_t* readString16Inplace(size_t* outLen) const;
|
||||
sp<IBinder> readStrongBinder() const;
|
||||
wp<IBinder> readWeakBinder() const;
|
||||
|
||||
status_t read(Flattenable& val) const;
|
||||
|
||||
// Retrieve native_handle from the parcel. This returns a copy of the
|
||||
// parcel's native_handle (the caller takes ownership). The caller
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <ui/android_native_buffer.h>
|
||||
#include <ui/PixelFormat.h>
|
||||
#include <ui/Rect.h>
|
||||
#include <utils/Flattenable.h>
|
||||
#include <pixelflinger/pixelflinger.h>
|
||||
|
||||
struct android_native_buffer_t;
|
||||
|
@ -30,7 +31,6 @@ struct android_native_buffer_t;
|
|||
namespace android {
|
||||
|
||||
class GraphicBufferMapper;
|
||||
class Parcel;
|
||||
|
||||
// ===========================================================================
|
||||
// GraphicBuffer
|
||||
|
@ -40,7 +40,7 @@ class GraphicBuffer
|
|||
: public EGLNativeBase<
|
||||
android_native_buffer_t,
|
||||
GraphicBuffer,
|
||||
LightRefBase<GraphicBuffer> >
|
||||
LightRefBase<GraphicBuffer> >, public Flattenable
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -97,7 +97,6 @@ public:
|
|||
uint32_t getVerticalStride() const;
|
||||
|
||||
protected:
|
||||
GraphicBuffer(const Parcel& reply);
|
||||
virtual ~GraphicBuffer();
|
||||
|
||||
enum {
|
||||
|
@ -122,8 +121,16 @@ private:
|
|||
status_t initSize(uint32_t w, uint32_t h, PixelFormat format,
|
||||
uint32_t usage);
|
||||
|
||||
static status_t writeToParcel(Parcel* reply,
|
||||
android_native_buffer_t const* buffer);
|
||||
void free_handle();
|
||||
|
||||
// Flattenable interface
|
||||
size_t getFlattenedSize() const;
|
||||
size_t getFdCount() const;
|
||||
status_t flatten(void* buffer, size_t size,
|
||||
int fds[], size_t count) const;
|
||||
status_t unflatten(void const* buffer, size_t size,
|
||||
int fds[], size_t count);
|
||||
|
||||
|
||||
GraphicBufferMapper& mBufferMapper;
|
||||
ssize_t mInitCheck;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_UTILS_FLATTENABLE_H
|
||||
#define ANDROID_UTILS_FLATTENABLE_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Flattenable
|
||||
{
|
||||
public:
|
||||
// size in bytes of the flattened object
|
||||
virtual size_t getFlattenedSize() const = 0;
|
||||
|
||||
// number of file descriptors to flatten
|
||||
virtual size_t getFdCount() const = 0;
|
||||
|
||||
// flattens the object into buffer.
|
||||
// size should be at least of getFlattenedSize()
|
||||
// file descriptors are written in the fds[] array but ownership is
|
||||
// not transfered (ie: they must be dupped by the caller of
|
||||
// flatten() if needed).
|
||||
virtual status_t flatten(void* buffer, size_t size,
|
||||
int fds[], size_t count) const = 0;
|
||||
|
||||
// unflattens the object from buffer.
|
||||
// size should be equal to the value of getFlattenedSize() when the
|
||||
// object was flattened.
|
||||
// unflattened file descriptors are found in the fds[] array and
|
||||
// don't need to be dupped(). ie: the caller of unflatten doesn't
|
||||
// keep ownership. If a fd is not retained by unflatten() it must be
|
||||
// explicitly closed.
|
||||
virtual status_t unflatten(void const* buffer, size_t size,
|
||||
int fds[], size_t count) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Flattenable() = 0;
|
||||
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
#endif /* ANDROID_UTILS_FLATTENABLE_H */
|
|
@ -28,6 +28,7 @@
|
|||
#include <utils/String16.h>
|
||||
#include <utils/TextOutput.h>
|
||||
#include <utils/misc.h>
|
||||
#include <utils/Flattenable.h>
|
||||
|
||||
#include <private/binder/binder_module.h>
|
||||
|
||||
|
@ -675,6 +676,42 @@ status_t Parcel::writeDupFileDescriptor(int fd)
|
|||
return writeObject(obj, true);
|
||||
}
|
||||
|
||||
status_t Parcel::write(const Flattenable& val)
|
||||
{
|
||||
status_t err;
|
||||
|
||||
// size if needed
|
||||
size_t len = val.getFlattenedSize();
|
||||
size_t fd_count = val.getFdCount();
|
||||
|
||||
err = this->writeInt32(len);
|
||||
if (err) return err;
|
||||
|
||||
err = this->writeInt32(fd_count);
|
||||
if (err) return err;
|
||||
|
||||
// payload
|
||||
void* buf = this->writeInplace(PAD_SIZE(len));
|
||||
if (buf == NULL)
|
||||
return BAD_VALUE;
|
||||
|
||||
int* fds = NULL;
|
||||
if (fd_count) {
|
||||
fds = new int[fd_count];
|
||||
}
|
||||
|
||||
err = val.flatten(buf, len, fds, fd_count);
|
||||
for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
|
||||
err = this->writeDupFileDescriptor( fds[i] );
|
||||
}
|
||||
|
||||
if (fd_count) {
|
||||
delete [] fds;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
|
||||
{
|
||||
const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
|
||||
|
@ -713,7 +750,6 @@ restart_write:
|
|||
goto restart_write;
|
||||
}
|
||||
|
||||
|
||||
void Parcel::remove(size_t start, size_t amt)
|
||||
{
|
||||
LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
|
||||
|
@ -940,6 +976,38 @@ int Parcel::readFileDescriptor() const
|
|||
return BAD_TYPE;
|
||||
}
|
||||
|
||||
status_t Parcel::read(Flattenable& val) const
|
||||
{
|
||||
// size
|
||||
const size_t len = this->readInt32();
|
||||
const size_t fd_count = this->readInt32();
|
||||
|
||||
// payload
|
||||
void const* buf = this->readInplace(PAD_SIZE(len));
|
||||
if (buf == NULL)
|
||||
return BAD_VALUE;
|
||||
|
||||
int* fds = NULL;
|
||||
if (fd_count) {
|
||||
fds = new int[fd_count];
|
||||
}
|
||||
|
||||
status_t err = NO_ERROR;
|
||||
for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
|
||||
fds[i] = dup(this->readFileDescriptor());
|
||||
if (fds[i] < 0) err = BAD_VALUE;
|
||||
}
|
||||
|
||||
if (err == NO_ERROR) {
|
||||
err = val.unflatten(buf, len, fds, fd_count);
|
||||
}
|
||||
|
||||
if (fd_count) {
|
||||
delete [] fds;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
|
||||
{
|
||||
const size_t DPOS = mDataPos;
|
||||
|
|
|
@ -78,7 +78,8 @@ public:
|
|||
data.writeInt32(bufferIdx);
|
||||
data.writeInt32(usage);
|
||||
remote()->transact(REQUEST_BUFFER, data, &reply);
|
||||
sp<GraphicBuffer> buffer = new GraphicBuffer(reply);
|
||||
sp<GraphicBuffer> buffer = new GraphicBuffer();
|
||||
reply.read(*buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -141,7 +142,9 @@ status_t BnSurface::onTransact(
|
|||
int bufferIdx = data.readInt32();
|
||||
int usage = data.readInt32();
|
||||
sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage));
|
||||
return GraphicBuffer::writeToParcel(reply, buffer.get());
|
||||
if (buffer == NULL)
|
||||
return BAD_VALUE;
|
||||
return reply->write(*buffer);
|
||||
}
|
||||
case REGISTER_BUFFERS: {
|
||||
CHECK_INTERFACE(ISurface, data, reply);
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "GraphicBuffer"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <binder/Parcel.h>
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
|
@ -77,34 +77,21 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
|
|||
handle = inHandle;
|
||||
}
|
||||
|
||||
GraphicBuffer::GraphicBuffer(const Parcel& data)
|
||||
: BASE(), mOwner(ownHandle), mBufferMapper(GraphicBufferMapper::get()),
|
||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
||||
{
|
||||
// we own the handle in this case
|
||||
width = data.readInt32();
|
||||
if (width < 0) {
|
||||
width = height = stride = format = usage = 0;
|
||||
handle = 0;
|
||||
} else {
|
||||
height = data.readInt32();
|
||||
stride = data.readInt32();
|
||||
format = data.readInt32();
|
||||
usage = data.readInt32();
|
||||
handle = data.readNativeHandle();
|
||||
}
|
||||
}
|
||||
|
||||
GraphicBuffer::~GraphicBuffer()
|
||||
{
|
||||
if (handle) {
|
||||
if (mOwner == ownHandle) {
|
||||
native_handle_close(handle);
|
||||
native_handle_delete(const_cast<native_handle*>(handle));
|
||||
} else if (mOwner == ownData) {
|
||||
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
|
||||
allocator.free(handle);
|
||||
}
|
||||
free_handle();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicBuffer::free_handle()
|
||||
{
|
||||
if (mOwner == ownHandle) {
|
||||
native_handle_close(handle);
|
||||
native_handle_delete(const_cast<native_handle*>(handle));
|
||||
} else if (mOwner == ownData) {
|
||||
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
|
||||
allocator.free(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,29 +179,83 @@ status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage)
|
|||
return res;
|
||||
}
|
||||
|
||||
size_t GraphicBuffer::getFlattenedSize() const {
|
||||
return (8 + (handle ? handle->numInts : 0))*sizeof(int);
|
||||
}
|
||||
|
||||
status_t GraphicBuffer::writeToParcel(Parcel* reply,
|
||||
android_native_buffer_t const* buffer)
|
||||
size_t GraphicBuffer::getFdCount() const {
|
||||
return handle ? handle->numFds : 0;
|
||||
}
|
||||
|
||||
status_t GraphicBuffer::flatten(void* buffer, size_t size,
|
||||
int fds[], size_t count) const
|
||||
{
|
||||
if (buffer == NULL)
|
||||
return BAD_VALUE;
|
||||
size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
|
||||
if (size < sizeNeeded) return NO_MEMORY;
|
||||
|
||||
if (buffer->width < 0 || buffer->height < 0)
|
||||
return BAD_VALUE;
|
||||
size_t fdCountNeeded = GraphicBuffer::getFdCount();
|
||||
if (count < fdCountNeeded) return NO_MEMORY;
|
||||
|
||||
status_t err = NO_ERROR;
|
||||
if (buffer->handle == NULL) {
|
||||
// this buffer doesn't have a handle
|
||||
reply->writeInt32(NO_MEMORY);
|
||||
} else {
|
||||
reply->writeInt32(buffer->width);
|
||||
reply->writeInt32(buffer->height);
|
||||
reply->writeInt32(buffer->stride);
|
||||
reply->writeInt32(buffer->format);
|
||||
reply->writeInt32(buffer->usage);
|
||||
err = reply->writeNativeHandle(buffer->handle);
|
||||
int* buf = static_cast<int*>(buffer);
|
||||
buf[0] = 'GBFR';
|
||||
buf[1] = width;
|
||||
buf[2] = height;
|
||||
buf[3] = stride;
|
||||
buf[4] = format;
|
||||
buf[5] = usage;
|
||||
buf[6] = 0;
|
||||
buf[7] = 0;
|
||||
|
||||
if (handle) {
|
||||
buf[6] = handle->numFds;
|
||||
buf[7] = handle->numInts;
|
||||
native_handle_t const* const h = handle;
|
||||
memcpy(fds, h->data, h->numFds*sizeof(int));
|
||||
memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
|
||||
}
|
||||
return err;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
|
||||
int fds[], size_t count)
|
||||
{
|
||||
if (size < 8*sizeof(int)) return NO_MEMORY;
|
||||
|
||||
int const* buf = static_cast<int const*>(buffer);
|
||||
if (buf[0] != 'GBFR') return BAD_TYPE;
|
||||
|
||||
const size_t numFds = buf[6];
|
||||
const size_t numInts = buf[7];
|
||||
|
||||
const size_t sizeNeeded = (8 + numInts) * sizeof(int);
|
||||
if (size < sizeNeeded) return NO_MEMORY;
|
||||
|
||||
size_t fdCountNeeded = 0;
|
||||
if (count < fdCountNeeded) return NO_MEMORY;
|
||||
|
||||
if (handle) {
|
||||
// free previous handle if any
|
||||
free_handle();
|
||||
}
|
||||
|
||||
if (numFds || numInts) {
|
||||
width = buf[1];
|
||||
height = buf[2];
|
||||
stride = buf[3];
|
||||
format = buf[4];
|
||||
usage = buf[5];
|
||||
native_handle* h = native_handle_create(numFds, numInts);
|
||||
memcpy(h->data, fds, numFds*sizeof(int));
|
||||
memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
|
||||
handle = h;
|
||||
} else {
|
||||
width = height = stride = format = usage = 0;
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
mOwner = ownHandle;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ commonSources:= \
|
|||
CallStack.cpp \
|
||||
Debug.cpp \
|
||||
FileMap.cpp \
|
||||
Flattenable.cpp \
|
||||
RefBase.cpp \
|
||||
ResourceTypes.cpp \
|
||||
SharedBuffer.cpp \
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <utils/Flattenable.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
Flattenable::~Flattenable() {
|
||||
}
|
||||
|
||||
}; // namespace android
|
Loading…
Reference in New Issue