diff options
author | Mathias Agopian <mathias@google.com> | 2010-07-28 16:30:56 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-07-28 16:30:56 -0700 |
commit | 9f2a91bc2b01c2cc60f73a0bae673225fdddec09 (patch) | |
tree | 4896baaf07143ebe2be37685c49714b223e3f100 /services | |
parent | bae6fe242ff9a97840ff0c5d9d87c0575d261682 (diff) | |
parent | 51c70e3e41ee8bedc1d951a06a74202dafa13009 (diff) | |
download | frameworks_base-9f2a91bc2b01c2cc60f73a0bae673225fdddec09.zip frameworks_base-9f2a91bc2b01c2cc60f73a0bae673225fdddec09.tar.gz frameworks_base-9f2a91bc2b01c2cc60f73a0bae673225fdddec09.tar.bz2 |
Merge "fix [2873058] Surface::dequeueBuffer blocks on last buffer, i.e. cannot dequeue all allocated buffers at once." into gingerbread
Diffstat (limited to 'services')
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 28 | ||||
-rw-r--r-- | services/surfaceflinger/tests/surface/Android.mk | 18 | ||||
-rw-r--r-- | services/surfaceflinger/tests/surface/surface.cpp | 54 |
3 files changed, 78 insertions, 22 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 758da4e..629d993 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -294,19 +294,9 @@ sp<GraphicBuffer> Layer::requestBuffer(int index, * This is called from the client's Surface::dequeue(). This can happen * at any time, especially while we're in the middle of using the * buffer 'index' as our front buffer. - * - * Make sure the buffer we're resizing is not the front buffer and has been - * dequeued. Once this condition is asserted, we are guaranteed that this - * buffer cannot become the front buffer under our feet, since we're called - * from Surface::dequeue() */ - status_t err = lcblk->assertReallocate(index); - LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err)); - if (err != NO_ERROR) { - // the surface may have died - return buffer; - } + status_t err = NO_ERROR; uint32_t w, h, f; { // scope for the lock Mutex::Autolock _l(mLock); @@ -319,23 +309,17 @@ sp<GraphicBuffer> Layer::requestBuffer(int index, w = reqWidth ? reqWidth : mWidth; h = reqHeight ? reqHeight : mHeight; f = reqFormat ? reqFormat : mFormat; - buffer = mBufferManager.detachBuffer(index); if (fixedSizeChanged || formatChanged) { lcblk->reallocateAllExcept(index); } } + // here we have to reallocate a new buffer because the buffer could be + // used as the front buffer, or by a client in our process + // (eg: status bar), and we can't release the handle under its feet. const uint32_t effectiveUsage = getEffectiveUsage(usage); - if (buffer!=0 && buffer->getStrongCount() == 1) { - err = buffer->reallocate(w, h, f, effectiveUsage); - } else { - // here we have to reallocate a new buffer because we could have a - // client in our process with a reference to it (eg: status bar), - // and we can't release the handle under its feet. - buffer.clear(); - buffer = new GraphicBuffer(w, h, f, effectiveUsage); - err = buffer->initCheck(); - } + buffer = new GraphicBuffer(w, h, f, effectiveUsage); + err = buffer->initCheck(); if (err || buffer->handle == 0) { LOGE_IF(err || buffer->handle == 0, diff --git a/services/surfaceflinger/tests/surface/Android.mk b/services/surfaceflinger/tests/surface/Android.mk new file mode 100644 index 0000000..ce0e807 --- /dev/null +++ b/services/surfaceflinger/tests/surface/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + surface.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libutils \ + libbinder \ + libui \ + libsurfaceflinger_client + +LOCAL_MODULE:= test-surface + +LOCAL_MODULE_TAGS := tests + +include $(BUILD_EXECUTABLE) diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp new file mode 100644 index 0000000..b4de4b4 --- /dev/null +++ b/services/surfaceflinger/tests/surface/surface.cpp @@ -0,0 +1,54 @@ +#include <cutils/memory.h> + +#include <utils/Log.h> + +#include <binder/IPCThreadState.h> +#include <binder/ProcessState.h> +#include <binder/IServiceManager.h> + +#include <surfaceflinger/Surface.h> +#include <surfaceflinger/ISurface.h> +#include <surfaceflinger/SurfaceComposerClient.h> + +#include <ui/Overlay.h> + +using namespace android; + +int main(int argc, char** argv) +{ + // set up the thread-pool + sp<ProcessState> proc(ProcessState::self()); + ProcessState::self()->startThreadPool(); + + // create a client to surfaceflinger + sp<SurfaceComposerClient> client = new SurfaceComposerClient(); + + // create pushbuffer surface + sp<SurfaceControl> surfaceControl = client->createSurface( + getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565); + client->openTransaction(); + surfaceControl->setLayer(100000); + client->closeTransaction(); + + // pretend it went cross-process + Parcel parcel; + SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel); + parcel.setDataPosition(0); + sp<Surface> surface = Surface::readFromParcel(parcel); + ANativeWindow* window = surface.get(); + + printf("window=%p\n", window); + + int err = native_window_set_buffer_count(window, 8); + android_native_buffer_t* buffer; + + for (int i=0 ; i<8 ; i++) { + window->dequeueBuffer(window, &buffer); + printf("buffer %d: %p\n", i, buffer); + } + + printf("test complete. CTRL+C to finish.\n"); + + IPCThreadState::self()->joinThreadPool(); + return 0; +} |