From 0297dcae8fddb18ab9e28ba1858a57a8aec3ef32 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 25 Apr 2011 20:22:14 -0700 Subject: 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 --- libs/gui/SurfaceTexture.cpp | 81 ++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 41 deletions(-) (limited to 'libs/gui/SurfaceTexture.cpp') diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 2619629be8da..13176df0f782 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 SurfaceTexture::requestBuffer(int buf, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { +sp SurfaceTexture::requestBuffer(int buf) { LOGV("SurfaceTexture::requestBuffer"); Mutex::Autolock lock(mMutex); if (buf < 0 || mBufferCount <= buf) { @@ -142,11 +140,34 @@ sp 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 SurfaceTexture::requestBuffer(int buf, format = mPixelFormat; } - usage |= GraphicBuffer::USAGE_HW_TEXTURE; - sp graphicBuffer( - mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage)); - if (graphicBuffer == 0) { - LOGE("requestBuffer: SurfaceComposer::createGraphicBuffer failed"); - } else { - mUseDefaultSize = useDefaultSize; + const sp& 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( + 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 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& 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; -- cgit v1.2.3-59-g8ed1b