summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2011-04-25 20:22:14 -0700
committerMathias Agopian <mathias@google.com>2011-05-11 18:01:51 -0700
commit0297dcae8fddb18ab9e28ba1858a57a8aec3ef32 (patch)
tree956126b5b62743efbdfbaa63268662e9a3a8aa80 /libs
parentf605a5aae5856d0c6114f36659ff9e8c5f3b5c19 (diff)
downloadframeworks_base-0297dcae8fddb18ab9e28ba1858a57a8aec3ef32.zip
frameworks_base-0297dcae8fddb18ab9e28ba1858a57a8aec3ef32.tar.gz
frameworks_base-0297dcae8fddb18ab9e28ba1858a57a8aec3ef32.tar.bz2
Fix a bug where setgeometry couldn't be undone
This change the binder protocol between SurfaceTextureClient and SurfaceTexture. dequeueBuffer() now takes the requested parameters for the buffer. SurfaceTexture decides if the buffer needs to be reallocated and does the allocation if needed. In that case it returns BUFFER_NEEDS_REALLOCATION to tell SurfaceTextureClient that it needs to call requestBuffer (which all parameters have been removed) to acquire a pointer to the buffer. dequeueBuffer and requestBuffer could be folded into a single IPC call, but we chose to optimize the case where buffers are not created and avoid some complexity in the marshalling code. Change-Id: I097a7f6f40a3491e10f3f3742eab33999286c304
Diffstat (limited to 'libs')
-rw-r--r--libs/gui/ISurfaceTexture.cpp27
-rw-r--r--libs/gui/SurfaceTexture.cpp81
-rw-r--r--libs/gui/SurfaceTextureClient.cpp16
3 files changed, 59 insertions, 65 deletions
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index bc14ad5..44c78ca 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -50,15 +50,10 @@ public:
{
}
- virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
- uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+ virtual sp<GraphicBuffer> requestBuffer(int bufferIdx) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(bufferIdx);
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(usage);
remote()->transact(REQUEST_BUFFER, data, &reply);
sp<GraphicBuffer> buffer;
bool nonNull = reply.readInt32();
@@ -79,9 +74,14 @@ public:
return err;
}
- virtual status_t dequeueBuffer(int *buf) {
+ virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
+ uint32_t format, uint32_t usage) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+ data.writeInt32(w);
+ data.writeInt32(h);
+ data.writeInt32(format);
+ data.writeInt32(usage);
remote()->transact(DEQUEUE_BUFFER, data, &reply);
*buf = reply.readInt32();
int result = reply.readInt32();
@@ -145,12 +145,7 @@ status_t BnSurfaceTexture::onTransact(
case REQUEST_BUFFER: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int bufferIdx = data.readInt32();
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- uint32_t format = data.readInt32();
- uint32_t usage = data.readInt32();
- sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, w, h, format,
- usage));
+ sp<GraphicBuffer> buffer(requestBuffer(bufferIdx));
reply->writeInt32(buffer != 0);
if (buffer != 0) {
reply->write(*buffer);
@@ -166,8 +161,12 @@ status_t BnSurfaceTexture::onTransact(
} break;
case DEQUEUE_BUFFER: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
+ uint32_t w = data.readInt32();
+ uint32_t h = data.readInt32();
+ uint32_t format = data.readInt32();
+ uint32_t usage = data.readInt32();
int buf;
- int result = dequeueBuffer(&buf);
+ int result = dequeueBuffer(&buf, w, h, format, usage);
reply->writeInt32(buf);
reply->writeInt32(result);
return NO_ERROR;
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 2619629..13176df 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -81,7 +81,6 @@ SurfaceTexture::SurfaceTexture(GLuint tex) :
mDefaultWidth(1),
mDefaultHeight(1),
mPixelFormat(PIXEL_FORMAT_RGBA_8888),
- mUseDefaultSize(true),
mBufferCount(MIN_BUFFER_SLOTS),
mCurrentTexture(INVALID_BUFFER_SLOT),
mCurrentTextureTarget(GL_TEXTURE_EXTERNAL_OES),
@@ -133,8 +132,7 @@ status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
return OK;
}
-sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf,
- uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf) {
LOGV("SurfaceTexture::requestBuffer");
Mutex::Autolock lock(mMutex);
if (buf < 0 || mBufferCount <= buf) {
@@ -142,11 +140,34 @@ sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf,
mBufferCount, buf);
return 0;
}
+ return mSlots[buf].mGraphicBuffer;
+}
+
+status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
+ uint32_t format, uint32_t usage) {
+ LOGV("SurfaceTexture::dequeueBuffer");
+
if ((w && !h) || (!w & h)) {
- LOGE("requestBuffer: invalid size: w=%u, h=%u: %d", w, h, buf);
- return 0;
+ LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
+ return BAD_VALUE;
}
+ Mutex::Autolock lock(mMutex);
+ int found = INVALID_BUFFER_SLOT;
+ for (int i = 0; i < mBufferCount; i++) {
+ if (!mSlots[i].mOwnedByClient && i != mCurrentTexture && i != mLastQueued) {
+ mSlots[i].mOwnedByClient = true;
+ found = i;
+ break;
+ }
+ }
+ if (found == INVALID_BUFFER_SLOT) {
+ return -EBUSY;
+ }
+
+ const int buf = found;
+ *outBuf = found;
+
const bool useDefaultSize = !w && !h;
if (useDefaultSize) {
// use the default size
@@ -160,13 +181,20 @@ sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf,
format = mPixelFormat;
}
- usage |= GraphicBuffer::USAGE_HW_TEXTURE;
- sp<GraphicBuffer> graphicBuffer(
- mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage));
- if (graphicBuffer == 0) {
- LOGE("requestBuffer: SurfaceComposer::createGraphicBuffer failed");
- } else {
- mUseDefaultSize = useDefaultSize;
+ const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
+ if ((buffer == NULL) ||
+ (uint32_t(buffer->width) != w) ||
+ (uint32_t(buffer->height) != h) ||
+ (uint32_t(buffer->format) != format) ||
+ ((uint32_t(buffer->usage) & usage) != usage))
+ {
+ usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+ sp<GraphicBuffer> graphicBuffer(
+ mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage));
+ if (graphicBuffer == 0) {
+ LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
+ return NO_MEMORY;
+ }
if (updateFormat) {
mPixelFormat = format;
}
@@ -176,35 +204,6 @@ sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf,
mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
}
- }
- return graphicBuffer;
-}
-
-status_t SurfaceTexture::dequeueBuffer(int *buf) {
- LOGV("SurfaceTexture::dequeueBuffer");
- Mutex::Autolock lock(mMutex);
- int found = INVALID_BUFFER_SLOT;
- for (int i = 0; i < mBufferCount; i++) {
- if (!mSlots[i].mOwnedByClient && i != mCurrentTexture && i != mLastQueued) {
- mSlots[i].mOwnedByClient = true;
- found = i;
- break;
- }
- }
- if (found == INVALID_BUFFER_SLOT) {
- return -EBUSY;
- }
-
- *buf = found;
-
- const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
- if (buffer == NULL) {
- return ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
- }
-
- if ((mUseDefaultSize) &&
- ((uint32_t(buffer->width) != mDefaultWidth) ||
- (uint32_t(buffer->height) != mDefaultHeight))) {
return ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
}
return OK;
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index ec6da43..a46a190 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -97,20 +97,16 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
LOGV("SurfaceTextureClient::dequeueBuffer");
Mutex::Autolock lock(mMutex);
int buf = -1;
- status_t err = mSurfaceTexture->dequeueBuffer(&buf);
+ status_t err = mSurfaceTexture->dequeueBuffer(&buf, mReqWidth, mReqHeight,
+ mReqFormat, mReqUsage);
if (err < 0) {
- LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer failed: %d", err);
+ LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
+ "failed: %d", err, mReqWidth, mReqHeight, mReqFormat, mReqUsage);
return err;
}
sp<GraphicBuffer>& gbuf(mSlots[buf]);
- if (err == ISurfaceTexture::BUFFER_NEEDS_REALLOCATION ||
- gbuf == 0 ||
- (mReqWidth && gbuf->getWidth() != mReqWidth) ||
- (mReqHeight && gbuf->getHeight() != mReqHeight) ||
- (mReqFormat && uint32_t(gbuf->getPixelFormat()) != mReqFormat) ||
- (gbuf->getUsage() & mReqUsage) != mReqUsage) {
- gbuf = mSurfaceTexture->requestBuffer(buf, mReqWidth, mReqHeight,
- mReqFormat, mReqUsage);
+ if (err == ISurfaceTexture::BUFFER_NEEDS_REALLOCATION || gbuf == 0) {
+ gbuf = mSurfaceTexture->requestBuffer(buf);
if (gbuf == 0) {
LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed");
return NO_MEMORY;