reduce IPC with BufferQueue

collapse setCrop, setTransform and setScalingMode to queueBuffer()
this ends up simplifying things quite a bit and reducing the numnber
of IPC needed per frame.

Change-Id: I3a13c07603abe4e76b8251e6380b107fde22e6d9
This commit is contained in:
Mathias Agopian 2012-03-29 17:10:08 -07:00
parent 9285a16450
commit 851ef8f1bf
6 changed files with 73 additions and 189 deletions

View File

@ -128,11 +128,9 @@ public:
// (zero point, etc) are client-dependent and should be documented by the
// client.
virtual status_t queueBuffer(int buf, int64_t timestamp,
const Rect& crop, int scalingMode, uint32_t transform,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
virtual void cancelBuffer(int buf);
virtual status_t setCrop(const Rect& reg);
virtual status_t setTransform(uint32_t transform);
virtual status_t setScalingMode(int mode);
// setSynchronousMode set whether dequeueBuffer is synchronous or
// asynchronous. In synchronous mode, dequeueBuffer blocks until
@ -180,18 +178,13 @@ public:
// if no buffer has been allocated.
sp<GraphicBuffer> mGraphicBuffer;
// mCrop is the current crop rectangle for this buffer slot. This gets
// set to mNextCrop each time queueBuffer gets called for this buffer.
// mCrop is the current crop rectangle for this buffer slot.
Rect mCrop;
// mTransform is the current transform flags for this buffer slot. This
// gets set to mNextTransform each time queueBuffer gets called for this
// slot.
// mTransform is the current transform flags for this buffer slot.
uint32_t mTransform;
// mScalingMode is the current scaling mode for this buffer slot. This
// gets set to mNextScalingMode each time queueBuffer gets called for
// this slot.
// mScalingMode is the current scaling mode for this buffer slot.
uint32_t mScalingMode;
// mTimestamp is the current timestamp for this buffer slot. This gets
@ -359,18 +352,13 @@ private:
// needed but useful for debugging and catching client bugs.
bool mRequestBufferCalled;
// mCrop is the current crop rectangle for this buffer slot. This gets
// set to mNextCrop each time queueBuffer gets called for this buffer.
// mCrop is the current crop rectangle for this buffer slot.
Rect mCrop;
// mTransform is the current transform flags for this buffer slot. This
// gets set to mNextTransform each time queueBuffer gets called for this
// slot.
// mTransform is the current transform flags for this buffer slot.
uint32_t mTransform;
// mScalingMode is the current scaling mode for this buffer slot. This
// gets set to mNextScalingMode each time queueBuffer gets called for
// this slot.
// mScalingMode is the current scaling mode for this buffer slot.
uint32_t mScalingMode;
// mTimestamp is the current timestamp for this buffer slot. This gets
@ -422,18 +410,6 @@ private:
// mServerBufferCount buffer count requested by the server-side
int mServerBufferCount;
// mNextCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mNextCrop;
// mNextTransform is the transform identifier that will be used for the next
// buffer that gets queued. It is set by calling setTransform.
uint32_t mNextTransform;
// mNextScalingMode is the scaling mode that will be used for the next
// buffers that get queued. It is set by calling setScalingMode.
int mNextScalingMode;
// mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
// allocate new GraphicBuffer objects.
sp<IGraphicBufferAlloc> mGraphicBufferAlloc;

View File

@ -83,6 +83,7 @@ protected:
// and height of the window and current transform applied to buffers,
// respectively.
virtual status_t queueBuffer(int slot, int64_t timestamp,
const Rect& crop, int scalingMode, uint32_t transform,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
// cancelBuffer indicates that the client does not wish to fill in the
@ -90,10 +91,6 @@ protected:
// the server.
virtual void cancelBuffer(int slot) = 0;
virtual status_t setCrop(const Rect& reg) = 0;
virtual status_t setTransform(uint32_t transform) = 0;
virtual status_t setScalingMode(int mode) = 0;
// query retrieves some information for this surface
// 'what' tokens allowed are that of android_natives.h
virtual int query(int what, int* value) = 0;

View File

@ -129,8 +129,8 @@ private:
// operation. It is initialized to 1.
uint32_t mReqWidth;
// mReqHeight is the buffer height that will be requested at the next deuque
// operation. It is initialized to 1.
// mReqHeight is the buffer height that will be requested at the next
// dequeue operation. It is initialized to 1.
uint32_t mReqHeight;
// mReqFormat is the buffer pixel format that will be requested at the next
@ -146,6 +146,18 @@ private:
// a timestamp is auto-generated when queueBuffer is called.
int64_t mTimestamp;
// mCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mCrop;
// mScalingMode is the scaling mode that will be used for the next
// buffers that get queued. It is set by calling setScalingMode.
int mScalingMode;
// mTransform is the transform identifier that will be used for the next
// buffer that gets queued. It is set by calling setTransform.
uint32_t mTransform;
// mDefaultWidth is default width of the window, regardless of the
// native_window_set_buffers_dimensions call
uint32_t mDefaultWidth;

View File

@ -76,8 +76,6 @@ BufferQueue::BufferQueue( bool allowSynchronousMode ) :
mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
mClientBufferCount(0),
mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
mNextTransform(0),
mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mSynchronousMode(false),
mAllowSynchronousMode(allowSynchronousMode),
mConnectedApi(NO_CONNECTED_API),
@ -94,7 +92,6 @@ BufferQueue::BufferQueue( bool allowSynchronousMode ) :
ST_LOGV("BufferQueue");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
mNextCrop.makeInvalid();
}
BufferQueue::~BufferQueue() {
@ -454,9 +451,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
mSlots[buf].mFence = EGL_NO_SYNC_KHR;
mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
}
@ -476,7 +470,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
ALOGE("dequeueBuffer: timeout waiting for fence");
}
eglDestroySyncKHR(dpy, fence);
}
ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
@ -518,6 +511,7 @@ status_t BufferQueue::setSynchronousMode(bool enabled) {
}
status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
const Rect& crop, int scalingMode, uint32_t transform,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
ATRACE_CALL();
ATRACE_BUFFER_INDEX(buf);
@ -571,10 +565,20 @@ status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
}
}
switch (scalingMode) {
case NATIVE_WINDOW_SCALING_MODE_FREEZE:
case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
break;
default:
ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);
scalingMode = mSlots[buf].mScalingMode;
break;
}
mSlots[buf].mBufferState = BufferSlot::QUEUED;
mSlots[buf].mCrop = mNextCrop;
mSlots[buf].mTransform = mNextTransform;
mSlots[buf].mScalingMode = mNextScalingMode;
mSlots[buf].mCrop = crop;
mSlots[buf].mTransform = transform;
mSlots[buf].mScalingMode = scalingMode;
mSlots[buf].mTimestamp = timestamp;
mFrameCounter++;
mSlots[buf].mFrameNumber = mFrameCounter;
@ -620,50 +624,6 @@ void BufferQueue::cancelBuffer(int buf) {
mDequeueCondition.broadcast();
}
status_t BufferQueue::setCrop(const Rect& crop) {
ATRACE_CALL();
ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right,
crop.bottom);
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
ST_LOGE("setCrop: BufferQueue has been abandoned!");
return NO_INIT;
}
mNextCrop = crop;
return OK;
}
status_t BufferQueue::setTransform(uint32_t transform) {
ATRACE_CALL();
ST_LOGV("setTransform: xform=%#x", transform);
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
ST_LOGE("setTransform: BufferQueue has been abandoned!");
return NO_INIT;
}
mNextTransform = transform;
return OK;
}
status_t BufferQueue::setScalingMode(int mode) {
ATRACE_CALL();
ST_LOGV("setScalingMode: mode=%d", mode);
switch (mode) {
case NATIVE_WINDOW_SCALING_MODE_FREEZE:
case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
break;
default:
ST_LOGE("unknown scaling mode: %d", mode);
return BAD_VALUE;
}
Mutex::Autolock lock(mMutex);
mNextScalingMode = mode;
return OK;
}
status_t BufferQueue::connect(int api,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
ATRACE_CALL();
@ -731,9 +691,6 @@ status_t BufferQueue::disconnect(int api) {
if (mConnectedApi == api) {
drainQueueAndFreeBuffersLocked();
mConnectedApi = NO_CONNECTED_API;
mNextCrop.makeInvalid();
mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mNextTransform = 0;
mDequeueCondition.broadcast();
listener = mConsumerListener;
} else {
@ -766,12 +723,6 @@ void BufferQueue::dump(String8& result, const char* prefix,
char* buffer, size_t SIZE) const
{
Mutex::Autolock _l(mMutex);
snprintf(buffer, SIZE,
"%snext : {crop=[%d,%d,%d,%d], transform=0x%02x}\n"
,prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
mNextCrop.bottom, mNextTransform
);
result.append(buffer);
String8 fifo;
int fifoSize = 0;

View File

@ -36,13 +36,10 @@ enum {
DEQUEUE_BUFFER,
QUEUE_BUFFER,
CANCEL_BUFFER,
SET_CROP,
SET_TRANSFORM,
QUERY,
SET_SYNCHRONOUS_MODE,
CONNECT,
DISCONNECT,
SET_SCALING_MODE,
};
@ -102,11 +99,15 @@ public:
}
virtual status_t queueBuffer(int buf, int64_t timestamp,
const Rect& crop, int scalingMode, uint32_t transform,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(buf);
data.writeInt64(timestamp);
memcpy(data.writeInplace(sizeof(Rect)), &crop, sizeof(Rect));
data.writeInt32(scalingMode);
data.writeInt32(transform);
status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
if (result != NO_ERROR) {
return result;
@ -125,45 +126,6 @@ public:
remote()->transact(CANCEL_BUFFER, data, &reply);
}
virtual status_t setCrop(const Rect& reg) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeFloat(reg.left);
data.writeFloat(reg.top);
data.writeFloat(reg.right);
data.writeFloat(reg.bottom);
status_t result = remote()->transact(SET_CROP, data, &reply);
if (result != NO_ERROR) {
return result;
}
result = reply.readInt32();
return result;
}
virtual status_t setTransform(uint32_t transform) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(transform);
status_t result = remote()->transact(SET_TRANSFORM, data, &reply);
if (result != NO_ERROR) {
return result;
}
result = reply.readInt32();
return result;
}
virtual status_t setScalingMode(int mode) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(mode);
status_t result = remote()->transact(SET_SCALING_MODE, data, &reply);
if (result != NO_ERROR) {
return result;
}
result = reply.readInt32();
return result;
}
virtual int query(int what, int* value) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
@ -261,8 +223,12 @@ status_t BnSurfaceTexture::onTransact(
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int buf = data.readInt32();
int64_t timestamp = data.readInt64();
Rect crop( *reinterpret_cast<Rect const *>(data.readInplace(sizeof(Rect))) );
int scalingMode = data.readInt32();
uint32_t transform = data.readInt32();
uint32_t outWidth, outHeight, outTransform;
status_t result = queueBuffer(buf, timestamp,
crop, scalingMode, transform,
&outWidth, &outHeight, &outTransform);
reply->writeInt32(outWidth);
reply->writeInt32(outHeight);
@ -276,31 +242,6 @@ status_t BnSurfaceTexture::onTransact(
cancelBuffer(buf);
return NO_ERROR;
} break;
case SET_CROP: {
Rect reg;
CHECK_INTERFACE(ISurfaceTexture, data, reply);
reg.left = data.readFloat();
reg.top = data.readFloat();
reg.right = data.readFloat();
reg.bottom = data.readFloat();
status_t result = setCrop(reg);
reply->writeInt32(result);
return NO_ERROR;
} break;
case SET_TRANSFORM: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
uint32_t transform = data.readInt32();
status_t result = setTransform(transform);
reply->writeInt32(result);
return NO_ERROR;
} break;
case SET_SCALING_MODE: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int mode = data.readInt32();
status_t result = setScalingMode(mode);
reply->writeInt32(result);
return NO_ERROR;
} break;
case QUERY: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int value;

View File

@ -75,6 +75,9 @@ void SurfaceTextureClient::init() {
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mCrop.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mDefaultWidth = 0;
mDefaultHeight = 0;
mTransformHint = 0;
@ -245,6 +248,7 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
return i;
}
status_t err = mSurfaceTexture->queueBuffer(i, timestamp,
mCrop, mScalingMode, mTransform,
&mDefaultWidth, &mDefaultHeight, &mTransformHint);
if (err != OK) {
ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
@ -444,6 +448,9 @@ int SurfaceTextureClient::disconnect(int api) {
mReqWidth = 0;
mReqHeight = 0;
mReqUsage = 0;
mCrop.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
if (api == NATIVE_WINDOW_API_CPU) {
mConnectedToCpu = false;
}
@ -463,19 +470,17 @@ int SurfaceTextureClient::setCrop(Rect const* rect)
{
ATRACE_CALL();
ALOGV("SurfaceTextureClient::setCrop");
Mutex::Autolock lock(mMutex);
Rect realRect;
if (rect == NULL || rect->isEmpty()) {
realRect = Rect(0, 0);
realRect.clear();
} else {
realRect = *rect;
}
status_t err = mSurfaceTexture->setCrop(*rect);
ALOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err));
return err;
Mutex::Autolock lock(mMutex);
mCrop = *rect;
return NO_ERROR;
}
int SurfaceTextureClient::setBufferCount(int bufferCount)
@ -499,7 +504,6 @@ int SurfaceTextureClient::setBuffersDimensions(int w, int h)
{
ATRACE_CALL();
ALOGV("SurfaceTextureClient::setBuffersDimensions");
Mutex::Autolock lock(mMutex);
if (w<0 || h<0)
return BAD_VALUE;
@ -507,25 +511,22 @@ int SurfaceTextureClient::setBuffersDimensions(int w, int h)
if ((w && !h) || (!w && h))
return BAD_VALUE;
Mutex::Autolock lock(mMutex);
mReqWidth = w;
mReqHeight = h;
status_t err = mSurfaceTexture->setCrop(Rect(0, 0));
ALOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err));
return err;
mCrop.clear();
return NO_ERROR;
}
int SurfaceTextureClient::setBuffersFormat(int format)
{
ALOGV("SurfaceTextureClient::setBuffersFormat");
Mutex::Autolock lock(mMutex);
if (format<0)
return BAD_VALUE;
Mutex::Autolock lock(mMutex);
mReqFormat = format;
return NO_ERROR;
}
@ -533,13 +534,19 @@ int SurfaceTextureClient::setScalingMode(int mode)
{
ATRACE_CALL();
ALOGV("SurfaceTextureClient::setScalingMode(%d)", mode);
Mutex::Autolock lock(mMutex);
// mode is validated on the server
status_t err = mSurfaceTexture->setScalingMode(mode);
ALOGE_IF(err, "ISurfaceTexture::setScalingMode(%d) returned %s",
mode, strerror(-err));
return err;
switch (mode) {
case NATIVE_WINDOW_SCALING_MODE_FREEZE:
case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
break;
default:
ALOGE("unknown scaling mode: %d", mode);
return BAD_VALUE;
}
Mutex::Autolock lock(mMutex);
mScalingMode = mode;
return NO_ERROR;
}
int SurfaceTextureClient::setBuffersTransform(int transform)
@ -547,8 +554,8 @@ int SurfaceTextureClient::setBuffersTransform(int transform)
ATRACE_CALL();
ALOGV("SurfaceTextureClient::setBuffersTransform");
Mutex::Autolock lock(mMutex);
status_t err = mSurfaceTexture->setTransform(transform);
return err;
mTransform = transform;
return NO_ERROR;
}
int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)